Merge "Move remaining REST handlers into restapi subpackage"
diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD
index 49b9450..f42749a 100644
--- a/java/com/google/gerrit/acceptance/BUILD
+++ b/java/com/google/gerrit/acceptance/BUILD
@@ -26,6 +26,7 @@
         "//java/com/google/gerrit/server",
         "//java/com/google/gerrit/server/git/receive",
         "//java/com/google/gerrit/server/project/testing:project-test-util",
+        "//java/com/google/gerrit/server/restapi",
         "//java/com/google/gerrit/sshd",
         "//java/com/google/gerrit/testing:gerrit-test-util",
         "//lib:args4j",
diff --git a/java/com/google/gerrit/httpd/raw/HostPageServlet.java b/java/com/google/gerrit/httpd/raw/HostPageServlet.java
index 51340ae..ad903c7 100644
--- a/java/com/google/gerrit/httpd/raw/HostPageServlet.java
+++ b/java/com/google/gerrit/httpd/raw/HostPageServlet.java
@@ -32,12 +32,12 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountResource;
-import com.google.gerrit.server.account.GetDiffPreferences;
 import com.google.gerrit.server.config.ConfigUtil;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.notedb.NotesMigration;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.account.GetDiffPreferences;
 import com.google.gwtexpui.server.CacheHeaders;
 import com.google.gwtjsonrpc.server.JsonServlet;
 import com.google.gwtjsonrpc.server.RPCServletUtils;
diff --git a/java/com/google/gerrit/httpd/restapi/AccessRestApiServlet.java b/java/com/google/gerrit/httpd/restapi/AccessRestApiServlet.java
index 0d1e53c..7e3e0ca 100644
--- a/java/com/google/gerrit/httpd/restapi/AccessRestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/AccessRestApiServlet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.restapi;
 
-import com.google.gerrit.server.access.AccessCollection;
+import com.google.gerrit.server.restapi.access.AccessCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/restapi/AccountsRestApiServlet.java b/java/com/google/gerrit/httpd/restapi/AccountsRestApiServlet.java
index ee57000..a1effb1 100644
--- a/java/com/google/gerrit/httpd/restapi/AccountsRestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/AccountsRestApiServlet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.restapi;
 
-import com.google.gerrit.server.account.AccountsCollection;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/restapi/ChangesRestApiServlet.java b/java/com/google/gerrit/httpd/restapi/ChangesRestApiServlet.java
index ccafc6d..d35eb3e 100644
--- a/java/com/google/gerrit/httpd/restapi/ChangesRestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/ChangesRestApiServlet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.restapi;
 
-import com.google.gerrit.server.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/restapi/GroupsRestApiServlet.java b/java/com/google/gerrit/httpd/restapi/GroupsRestApiServlet.java
index 5c7502f..fff696a 100644
--- a/java/com/google/gerrit/httpd/restapi/GroupsRestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/GroupsRestApiServlet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.restapi;
 
-import com.google.gerrit.server.group.GroupsCollection;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/restapi/ProjectsRestApiServlet.java b/java/com/google/gerrit/httpd/restapi/ProjectsRestApiServlet.java
index f34608a..d6b5db0 100644
--- a/java/com/google/gerrit/httpd/restapi/ProjectsRestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/ProjectsRestApiServlet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.restapi;
 
-import com.google.gerrit.server.project.ProjectsCollection;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/rpc/project/ChangeProjectAccess.java b/java/com/google/gerrit/httpd/rpc/project/ChangeProjectAccess.java
index 7427c42..4af124f 100644
--- a/java/com/google/gerrit/httpd/rpc/project/ChangeProjectAccess.java
+++ b/java/com/google/gerrit/httpd/rpc/project/ChangeProjectAccess.java
@@ -31,7 +31,7 @@
 import com.google.gerrit.server.project.ContributorAgreementsChecker;
 import com.google.gerrit.server.project.NoSuchProjectException;
 import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.SetParent;
+import com.google.gerrit.server.restapi.project.SetParent;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.assistedinject.Assisted;
diff --git a/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java b/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java
index 14885b3..0240e2e 100644
--- a/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java
+++ b/java/com/google/gerrit/httpd/rpc/project/ProjectAccessHandler.java
@@ -45,7 +45,7 @@
 import com.google.gerrit.server.project.ContributorAgreementsChecker;
 import com.google.gerrit.server.project.NoSuchProjectException;
 import com.google.gerrit.server.project.RefPattern;
-import com.google.gerrit.server.project.SetParent;
+import com.google.gerrit.server.restapi.project.SetParent;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Provider;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java b/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
index bdb7fe5..81957d6 100644
--- a/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
+++ b/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
@@ -35,8 +35,6 @@
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.change.ChangeInserter;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ChangesCollection;
-import com.google.gerrit.server.change.PostReviewers;
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.ProjectConfig;
@@ -47,7 +45,9 @@
 import com.google.gerrit.server.permissions.RefPermission;
 import com.google.gerrit.server.project.ContributorAgreementsChecker;
 import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.SetParent;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.PostReviewers;
+import com.google.gerrit.server.restapi.project.SetParent;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.UpdateException;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/pgm/util/BUILD b/java/com/google/gerrit/pgm/util/BUILD
index d94211c..d6e44bd 100644
--- a/java/com/google/gerrit/pgm/util/BUILD
+++ b/java/com/google/gerrit/pgm/util/BUILD
@@ -13,6 +13,7 @@
         "//java/com/google/gerrit/server:module",
         "//java/com/google/gerrit/server/cache/h2",
         "//java/com/google/gerrit/server/git/receive",
+        "//java/com/google/gerrit/server/restapi",
         "//java/com/google/gerrit/server/schema",
         "//java/com/google/gerrit/util/cli",
         "//lib:args4j",
diff --git a/java/com/google/gerrit/pgm/util/BatchProgramModule.java b/java/com/google/gerrit/pgm/util/BatchProgramModule.java
index 3fc2a4a..d39c73a 100644
--- a/java/com/google/gerrit/pgm/util/BatchProgramModule.java
+++ b/java/com/google/gerrit/pgm/util/BatchProgramModule.java
@@ -56,7 +56,6 @@
 import com.google.gerrit.server.git.TagCache;
 import com.google.gerrit.server.git.VisibleRefFilter;
 import com.google.gerrit.server.git.receive.ReceiveCommitsExecutorModule;
-import com.google.gerrit.server.group.GroupModule;
 import com.google.gerrit.server.mail.send.ReplacePatchSetSender;
 import com.google.gerrit.server.notedb.NoteDbModule;
 import com.google.gerrit.server.patch.DiffExecutorModule;
@@ -70,6 +69,7 @@
 import com.google.gerrit.server.project.SubmitRuleEvaluator;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.ChangeQueryProcessor;
+import com.google.gerrit.server.restapi.group.GroupModule;
 import com.google.gerrit.server.rules.PrologModule;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/access/AccessResource.java b/java/com/google/gerrit/server/access/AccessResource.java
index 22888b8..a1fe0c9 100644
--- a/java/com/google/gerrit/server/access/AccessResource.java
+++ b/java/com/google/gerrit/server/access/AccessResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java b/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
index 7b14725..232cc63 100644
--- a/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
+++ b/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java
@@ -44,38 +44,38 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.account.AccountLoader;
 import com.google.gerrit.server.account.AccountResource;
-import com.google.gerrit.server.account.AddSshKey;
-import com.google.gerrit.server.account.CreateEmail;
-import com.google.gerrit.server.account.DeleteActive;
-import com.google.gerrit.server.account.DeleteEmail;
-import com.google.gerrit.server.account.DeleteExternalIds;
-import com.google.gerrit.server.account.DeleteSshKey;
-import com.google.gerrit.server.account.DeleteWatchedProjects;
-import com.google.gerrit.server.account.GetActive;
-import com.google.gerrit.server.account.GetAgreements;
-import com.google.gerrit.server.account.GetAvatar;
-import com.google.gerrit.server.account.GetDiffPreferences;
-import com.google.gerrit.server.account.GetEditPreferences;
-import com.google.gerrit.server.account.GetEmails;
-import com.google.gerrit.server.account.GetExternalIds;
-import com.google.gerrit.server.account.GetGroups;
-import com.google.gerrit.server.account.GetPreferences;
-import com.google.gerrit.server.account.GetSshKeys;
-import com.google.gerrit.server.account.GetWatchedProjects;
 import com.google.gerrit.server.account.GpgApiAdapter;
-import com.google.gerrit.server.account.Index;
-import com.google.gerrit.server.account.PostWatchedProjects;
-import com.google.gerrit.server.account.PutActive;
-import com.google.gerrit.server.account.PutAgreement;
-import com.google.gerrit.server.account.PutStatus;
-import com.google.gerrit.server.account.SetDiffPreferences;
-import com.google.gerrit.server.account.SetEditPreferences;
-import com.google.gerrit.server.account.SetPreferences;
-import com.google.gerrit.server.account.SshKeys;
-import com.google.gerrit.server.account.StarredChanges;
-import com.google.gerrit.server.account.Stars;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ChangesCollection;
+import com.google.gerrit.server.restapi.account.AddSshKey;
+import com.google.gerrit.server.restapi.account.CreateEmail;
+import com.google.gerrit.server.restapi.account.DeleteActive;
+import com.google.gerrit.server.restapi.account.DeleteEmail;
+import com.google.gerrit.server.restapi.account.DeleteExternalIds;
+import com.google.gerrit.server.restapi.account.DeleteSshKey;
+import com.google.gerrit.server.restapi.account.DeleteWatchedProjects;
+import com.google.gerrit.server.restapi.account.GetActive;
+import com.google.gerrit.server.restapi.account.GetAgreements;
+import com.google.gerrit.server.restapi.account.GetAvatar;
+import com.google.gerrit.server.restapi.account.GetDiffPreferences;
+import com.google.gerrit.server.restapi.account.GetEditPreferences;
+import com.google.gerrit.server.restapi.account.GetEmails;
+import com.google.gerrit.server.restapi.account.GetExternalIds;
+import com.google.gerrit.server.restapi.account.GetGroups;
+import com.google.gerrit.server.restapi.account.GetPreferences;
+import com.google.gerrit.server.restapi.account.GetSshKeys;
+import com.google.gerrit.server.restapi.account.GetWatchedProjects;
+import com.google.gerrit.server.restapi.account.Index;
+import com.google.gerrit.server.restapi.account.PostWatchedProjects;
+import com.google.gerrit.server.restapi.account.PutActive;
+import com.google.gerrit.server.restapi.account.PutAgreement;
+import com.google.gerrit.server.restapi.account.PutStatus;
+import com.google.gerrit.server.restapi.account.SetDiffPreferences;
+import com.google.gerrit.server.restapi.account.SetEditPreferences;
+import com.google.gerrit.server.restapi.account.SetPreferences;
+import com.google.gerrit.server.restapi.account.SshKeys;
+import com.google.gerrit.server.restapi.account.StarredChanges;
+import com.google.gerrit.server.restapi.account.Stars;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
diff --git a/java/com/google/gerrit/server/api/accounts/AccountsImpl.java b/java/com/google/gerrit/server/api/accounts/AccountsImpl.java
index 5257aec..fac16dc 100644
--- a/java/com/google/gerrit/server/api/accounts/AccountsImpl.java
+++ b/java/com/google/gerrit/server/api/accounts/AccountsImpl.java
@@ -29,11 +29,11 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.account.AccountResource;
-import com.google.gerrit.server.account.AccountsCollection;
-import com.google.gerrit.server.account.CreateAccount;
-import com.google.gerrit.server.account.QueryAccounts;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.account.CreateAccount;
+import com.google.gerrit.server.restapi.account.QueryAccounts;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
index f368c17..baf6d36 100644
--- a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -52,46 +52,46 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
-import com.google.gerrit.server.change.Abandon;
-import com.google.gerrit.server.change.ChangeIncludedIn;
 import com.google.gerrit.server.change.ChangeJson;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.Check;
-import com.google.gerrit.server.change.CreateMergePatchSet;
-import com.google.gerrit.server.change.DeleteAssignee;
-import com.google.gerrit.server.change.DeleteChange;
-import com.google.gerrit.server.change.DeletePrivate;
-import com.google.gerrit.server.change.GetAssignee;
-import com.google.gerrit.server.change.GetHashtags;
-import com.google.gerrit.server.change.GetPastAssignees;
-import com.google.gerrit.server.change.GetTopic;
-import com.google.gerrit.server.change.Ignore;
-import com.google.gerrit.server.change.Index;
-import com.google.gerrit.server.change.ListChangeComments;
-import com.google.gerrit.server.change.ListChangeDrafts;
-import com.google.gerrit.server.change.ListChangeRobotComments;
-import com.google.gerrit.server.change.MarkAsReviewed;
-import com.google.gerrit.server.change.MarkAsUnreviewed;
-import com.google.gerrit.server.change.Move;
-import com.google.gerrit.server.change.PostHashtags;
-import com.google.gerrit.server.change.PostPrivate;
-import com.google.gerrit.server.change.PostReviewers;
 import com.google.gerrit.server.change.PureRevert;
-import com.google.gerrit.server.change.PutAssignee;
-import com.google.gerrit.server.change.PutMessage;
-import com.google.gerrit.server.change.PutTopic;
-import com.google.gerrit.server.change.Rebase;
-import com.google.gerrit.server.change.Restore;
-import com.google.gerrit.server.change.Revert;
-import com.google.gerrit.server.change.Reviewers;
 import com.google.gerrit.server.change.Revisions;
-import com.google.gerrit.server.change.SetPrivateOp;
-import com.google.gerrit.server.change.SetReadyForReview;
-import com.google.gerrit.server.change.SetWorkInProgress;
-import com.google.gerrit.server.change.SubmittedTogether;
-import com.google.gerrit.server.change.SuggestChangeReviewers;
-import com.google.gerrit.server.change.Unignore;
 import com.google.gerrit.server.change.WorkInProgressOp;
+import com.google.gerrit.server.restapi.change.Abandon;
+import com.google.gerrit.server.restapi.change.ChangeIncludedIn;
+import com.google.gerrit.server.restapi.change.Check;
+import com.google.gerrit.server.restapi.change.CreateMergePatchSet;
+import com.google.gerrit.server.restapi.change.DeleteAssignee;
+import com.google.gerrit.server.restapi.change.DeleteChange;
+import com.google.gerrit.server.restapi.change.DeletePrivate;
+import com.google.gerrit.server.restapi.change.GetAssignee;
+import com.google.gerrit.server.restapi.change.GetHashtags;
+import com.google.gerrit.server.restapi.change.GetPastAssignees;
+import com.google.gerrit.server.restapi.change.GetTopic;
+import com.google.gerrit.server.restapi.change.Ignore;
+import com.google.gerrit.server.restapi.change.Index;
+import com.google.gerrit.server.restapi.change.ListChangeComments;
+import com.google.gerrit.server.restapi.change.ListChangeDrafts;
+import com.google.gerrit.server.restapi.change.ListChangeRobotComments;
+import com.google.gerrit.server.restapi.change.MarkAsReviewed;
+import com.google.gerrit.server.restapi.change.MarkAsUnreviewed;
+import com.google.gerrit.server.restapi.change.Move;
+import com.google.gerrit.server.restapi.change.PostHashtags;
+import com.google.gerrit.server.restapi.change.PostPrivate;
+import com.google.gerrit.server.restapi.change.PostReviewers;
+import com.google.gerrit.server.restapi.change.PutAssignee;
+import com.google.gerrit.server.restapi.change.PutMessage;
+import com.google.gerrit.server.restapi.change.PutTopic;
+import com.google.gerrit.server.restapi.change.Rebase;
+import com.google.gerrit.server.restapi.change.Restore;
+import com.google.gerrit.server.restapi.change.Revert;
+import com.google.gerrit.server.restapi.change.Reviewers;
+import com.google.gerrit.server.restapi.change.SetPrivateOp;
+import com.google.gerrit.server.restapi.change.SetReadyForReview;
+import com.google.gerrit.server.restapi.change.SetWorkInProgress;
+import com.google.gerrit.server.restapi.change.SubmittedTogether;
+import com.google.gerrit.server.restapi.change.SuggestChangeReviewers;
+import com.google.gerrit.server.restapi.change.Unignore;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java b/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java
index 823e771..92aae03 100644
--- a/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java
@@ -28,11 +28,11 @@
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.change.ChangeEditResource;
-import com.google.gerrit.server.change.ChangeEdits;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.DeleteChangeEdit;
-import com.google.gerrit.server.change.PublishChangeEdit;
-import com.google.gerrit.server.change.RebaseChangeEdit;
+import com.google.gerrit.server.restapi.change.ChangeEdits;
+import com.google.gerrit.server.restapi.change.DeleteChangeEdit;
+import com.google.gerrit.server.restapi.change.PublishChangeEdit;
+import com.google.gerrit.server.restapi.change.RebaseChangeEdit;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
diff --git a/java/com/google/gerrit/server/api/changes/ChangesImpl.java b/java/com/google/gerrit/server/api/changes/ChangesImpl.java
index a372ed6..cefabf4 100644
--- a/java/com/google/gerrit/server/api/changes/ChangesImpl.java
+++ b/java/com/google/gerrit/server/api/changes/ChangesImpl.java
@@ -30,9 +30,9 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.extensions.restapi.Url;
 import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.server.change.ChangesCollection;
-import com.google.gerrit.server.change.CreateChange;
-import com.google.gerrit.server.change.QueryChanges;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.CreateChange;
+import com.google.gerrit.server.restapi.change.QueryChanges;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/api/changes/CommentApiImpl.java b/java/com/google/gerrit/server/api/changes/CommentApiImpl.java
index 6a2501e..418187d 100644
--- a/java/com/google/gerrit/server/api/changes/CommentApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/CommentApiImpl.java
@@ -21,8 +21,8 @@
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.change.CommentResource;
-import com.google.gerrit.server.change.DeleteComment;
-import com.google.gerrit.server.change.GetComment;
+import com.google.gerrit.server.restapi.change.DeleteComment;
+import com.google.gerrit.server.restapi.change.GetComment;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
diff --git a/java/com/google/gerrit/server/api/changes/DraftApiImpl.java b/java/com/google/gerrit/server/api/changes/DraftApiImpl.java
index eada51b..4d26b11 100644
--- a/java/com/google/gerrit/server/api/changes/DraftApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/DraftApiImpl.java
@@ -22,10 +22,10 @@
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.NotImplementedException;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.change.DeleteDraftComment;
 import com.google.gerrit.server.change.DraftCommentResource;
-import com.google.gerrit.server.change.GetDraftComment;
-import com.google.gerrit.server.change.PutDraftComment;
+import com.google.gerrit.server.restapi.change.DeleteDraftComment;
+import com.google.gerrit.server.restapi.change.GetDraftComment;
+import com.google.gerrit.server.restapi.change.PutDraftComment;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
diff --git a/java/com/google/gerrit/server/api/changes/FileApiImpl.java b/java/com/google/gerrit/server/api/changes/FileApiImpl.java
index f51cdac..6e18bb8 100644
--- a/java/com/google/gerrit/server/api/changes/FileApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/FileApiImpl.java
@@ -21,8 +21,8 @@
 import com.google.gerrit.extensions.restapi.BinaryResult;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.change.FileResource;
-import com.google.gerrit.server.change.GetContent;
-import com.google.gerrit.server.change.GetDiff;
+import com.google.gerrit.server.restapi.change.GetContent;
+import com.google.gerrit.server.restapi.change.GetDiff;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
diff --git a/java/com/google/gerrit/server/api/changes/ReviewerApiImpl.java b/java/com/google/gerrit/server/api/changes/ReviewerApiImpl.java
index 2f8b7d8..11536cb 100644
--- a/java/com/google/gerrit/server/api/changes/ReviewerApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/ReviewerApiImpl.java
@@ -20,11 +20,11 @@
 import com.google.gerrit.extensions.api.changes.DeleteVoteInput;
 import com.google.gerrit.extensions.api.changes.ReviewerApi;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.change.DeleteReviewer;
-import com.google.gerrit.server.change.DeleteVote;
 import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.change.VoteResource;
-import com.google.gerrit.server.change.Votes;
+import com.google.gerrit.server.restapi.change.DeleteReviewer;
+import com.google.gerrit.server.restapi.change.DeleteVote;
+import com.google.gerrit.server.restapi.change.Votes;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import java.util.Map;
diff --git a/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java b/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
index 7ecfce7..8357568 100644
--- a/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
@@ -47,35 +47,35 @@
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
-import com.google.gerrit.server.change.ApplyFix;
-import com.google.gerrit.server.change.CherryPick;
-import com.google.gerrit.server.change.Comments;
-import com.google.gerrit.server.change.CreateDraftComment;
-import com.google.gerrit.server.change.DraftComments;
 import com.google.gerrit.server.change.FileResource;
-import com.google.gerrit.server.change.Files;
-import com.google.gerrit.server.change.Fixes;
-import com.google.gerrit.server.change.GetCommit;
-import com.google.gerrit.server.change.GetDescription;
-import com.google.gerrit.server.change.GetMergeList;
-import com.google.gerrit.server.change.GetPatch;
-import com.google.gerrit.server.change.GetRevisionActions;
-import com.google.gerrit.server.change.ListRevisionComments;
-import com.google.gerrit.server.change.ListRevisionDrafts;
-import com.google.gerrit.server.change.ListRobotComments;
-import com.google.gerrit.server.change.Mergeable;
-import com.google.gerrit.server.change.PostReview;
-import com.google.gerrit.server.change.PreviewSubmit;
-import com.google.gerrit.server.change.PutDescription;
-import com.google.gerrit.server.change.Rebase;
 import com.google.gerrit.server.change.RebaseUtil;
-import com.google.gerrit.server.change.Reviewed;
 import com.google.gerrit.server.change.RevisionResource;
-import com.google.gerrit.server.change.RevisionReviewers;
-import com.google.gerrit.server.change.RobotComments;
-import com.google.gerrit.server.change.Submit;
-import com.google.gerrit.server.change.TestSubmitType;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.restapi.change.ApplyFix;
+import com.google.gerrit.server.restapi.change.CherryPick;
+import com.google.gerrit.server.restapi.change.Comments;
+import com.google.gerrit.server.restapi.change.CreateDraftComment;
+import com.google.gerrit.server.restapi.change.DraftComments;
+import com.google.gerrit.server.restapi.change.Files;
+import com.google.gerrit.server.restapi.change.Fixes;
+import com.google.gerrit.server.restapi.change.GetCommit;
+import com.google.gerrit.server.restapi.change.GetDescription;
+import com.google.gerrit.server.restapi.change.GetMergeList;
+import com.google.gerrit.server.restapi.change.GetPatch;
+import com.google.gerrit.server.restapi.change.GetRevisionActions;
+import com.google.gerrit.server.restapi.change.ListRevisionComments;
+import com.google.gerrit.server.restapi.change.ListRevisionDrafts;
+import com.google.gerrit.server.restapi.change.ListRobotComments;
+import com.google.gerrit.server.restapi.change.Mergeable;
+import com.google.gerrit.server.restapi.change.PostReview;
+import com.google.gerrit.server.restapi.change.PreviewSubmit;
+import com.google.gerrit.server.restapi.change.PutDescription;
+import com.google.gerrit.server.restapi.change.Rebase;
+import com.google.gerrit.server.restapi.change.Reviewed;
+import com.google.gerrit.server.restapi.change.RevisionReviewers;
+import com.google.gerrit.server.restapi.change.RobotComments;
+import com.google.gerrit.server.restapi.change.Submit;
+import com.google.gerrit.server.restapi.change.TestSubmitType;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.assistedinject.Assisted;
diff --git a/java/com/google/gerrit/server/api/changes/RevisionReviewerApiImpl.java b/java/com/google/gerrit/server/api/changes/RevisionReviewerApiImpl.java
index 60dc1d2..8cad507 100644
--- a/java/com/google/gerrit/server/api/changes/RevisionReviewerApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/RevisionReviewerApiImpl.java
@@ -19,10 +19,10 @@
 import com.google.gerrit.extensions.api.changes.DeleteVoteInput;
 import com.google.gerrit.extensions.api.changes.RevisionReviewerApi;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.change.DeleteVote;
 import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.change.VoteResource;
-import com.google.gerrit.server.change.Votes;
+import com.google.gerrit.server.restapi.change.DeleteVote;
+import com.google.gerrit.server.restapi.change.Votes;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import java.util.Map;
diff --git a/java/com/google/gerrit/server/api/changes/RobotCommentApiImpl.java b/java/com/google/gerrit/server/api/changes/RobotCommentApiImpl.java
index b19939b..37a56fe 100644
--- a/java/com/google/gerrit/server/api/changes/RobotCommentApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/RobotCommentApiImpl.java
@@ -19,8 +19,8 @@
 import com.google.gerrit.extensions.api.changes.RobotCommentApi;
 import com.google.gerrit.extensions.common.RobotCommentInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.change.GetRobotComment;
 import com.google.gerrit.server.change.RobotCommentResource;
+import com.google.gerrit.server.restapi.change.GetRobotComment;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
diff --git a/java/com/google/gerrit/server/api/groups/GroupApiImpl.java b/java/com/google/gerrit/server/api/groups/GroupApiImpl.java
index 28cc60f..9909ed7 100644
--- a/java/com/google/gerrit/server/api/groups/GroupApiImpl.java
+++ b/java/com/google/gerrit/server/api/groups/GroupApiImpl.java
@@ -26,25 +26,25 @@
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.common.NameInput;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.group.AddMembers;
-import com.google.gerrit.server.group.AddSubgroups;
-import com.google.gerrit.server.group.DeleteMembers;
-import com.google.gerrit.server.group.DeleteSubgroups;
-import com.google.gerrit.server.group.GetAuditLog;
-import com.google.gerrit.server.group.GetDescription;
-import com.google.gerrit.server.group.GetDetail;
-import com.google.gerrit.server.group.GetGroup;
-import com.google.gerrit.server.group.GetName;
-import com.google.gerrit.server.group.GetOptions;
-import com.google.gerrit.server.group.GetOwner;
 import com.google.gerrit.server.group.GroupResource;
-import com.google.gerrit.server.group.Index;
-import com.google.gerrit.server.group.ListMembers;
-import com.google.gerrit.server.group.ListSubgroups;
-import com.google.gerrit.server.group.PutDescription;
-import com.google.gerrit.server.group.PutName;
-import com.google.gerrit.server.group.PutOptions;
-import com.google.gerrit.server.group.PutOwner;
+import com.google.gerrit.server.restapi.group.AddMembers;
+import com.google.gerrit.server.restapi.group.AddSubgroups;
+import com.google.gerrit.server.restapi.group.DeleteMembers;
+import com.google.gerrit.server.restapi.group.DeleteSubgroups;
+import com.google.gerrit.server.restapi.group.GetAuditLog;
+import com.google.gerrit.server.restapi.group.GetDescription;
+import com.google.gerrit.server.restapi.group.GetDetail;
+import com.google.gerrit.server.restapi.group.GetGroup;
+import com.google.gerrit.server.restapi.group.GetName;
+import com.google.gerrit.server.restapi.group.GetOptions;
+import com.google.gerrit.server.restapi.group.GetOwner;
+import com.google.gerrit.server.restapi.group.Index;
+import com.google.gerrit.server.restapi.group.ListMembers;
+import com.google.gerrit.server.restapi.group.ListSubgroups;
+import com.google.gerrit.server.restapi.group.PutDescription;
+import com.google.gerrit.server.restapi.group.PutName;
+import com.google.gerrit.server.restapi.group.PutOptions;
+import com.google.gerrit.server.restapi.group.PutOwner;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import java.util.Arrays;
diff --git a/java/com/google/gerrit/server/api/groups/GroupsImpl.java b/java/com/google/gerrit/server/api/groups/GroupsImpl.java
index f439f7d..0b3bc64 100644
--- a/java/com/google/gerrit/server/api/groups/GroupsImpl.java
+++ b/java/com/google/gerrit/server/api/groups/GroupsImpl.java
@@ -27,15 +27,15 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.AccountsCollection;
-import com.google.gerrit.server.group.CreateGroup;
-import com.google.gerrit.server.group.GroupsCollection;
-import com.google.gerrit.server.group.ListGroups;
-import com.google.gerrit.server.group.QueryGroups;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.project.ProjectResource;
-import com.google.gerrit.server.project.ProjectsCollection;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.group.CreateGroup;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
+import com.google.gerrit.server.restapi.group.ListGroups;
+import com.google.gerrit.server.restapi.group.QueryGroups;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/api/projects/BranchApiImpl.java b/java/com/google/gerrit/server/api/projects/BranchApiImpl.java
index aee9b3f..78b34b8 100644
--- a/java/com/google/gerrit/server/api/projects/BranchApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/BranchApiImpl.java
@@ -26,15 +26,15 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.BranchResource;
-import com.google.gerrit.server.project.BranchesCollection;
-import com.google.gerrit.server.project.CreateBranch;
-import com.google.gerrit.server.project.DeleteBranch;
 import com.google.gerrit.server.project.FileResource;
-import com.google.gerrit.server.project.FilesCollection;
-import com.google.gerrit.server.project.GetBranch;
-import com.google.gerrit.server.project.GetContent;
-import com.google.gerrit.server.project.GetReflog;
 import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.restapi.project.BranchesCollection;
+import com.google.gerrit.server.restapi.project.CreateBranch;
+import com.google.gerrit.server.restapi.project.DeleteBranch;
+import com.google.gerrit.server.restapi.project.FilesCollection;
+import com.google.gerrit.server.restapi.project.GetBranch;
+import com.google.gerrit.server.restapi.project.GetContent;
+import com.google.gerrit.server.restapi.project.GetReflog;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/api/projects/ChildProjectApiImpl.java b/java/com/google/gerrit/server/api/projects/ChildProjectApiImpl.java
index 1595682..d7c9bc7 100644
--- a/java/com/google/gerrit/server/api/projects/ChildProjectApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/ChildProjectApiImpl.java
@@ -18,7 +18,7 @@
 import com.google.gerrit.extensions.common.ProjectInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.project.ChildProjectResource;
-import com.google.gerrit.server.project.GetChildProject;
+import com.google.gerrit.server.restapi.project.GetChildProject;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
diff --git a/java/com/google/gerrit/server/api/projects/CommitApiImpl.java b/java/com/google/gerrit/server/api/projects/CommitApiImpl.java
index cbdd03d..a81e0de 100644
--- a/java/com/google/gerrit/server/api/projects/CommitApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/CommitApiImpl.java
@@ -21,8 +21,8 @@
 import com.google.gerrit.extensions.api.changes.CherryPickInput;
 import com.google.gerrit.extensions.api.projects.CommitApi;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.change.CherryPickCommit;
 import com.google.gerrit.server.project.CommitResource;
+import com.google.gerrit.server.restapi.change.CherryPickCommit;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
diff --git a/java/com/google/gerrit/server/api/projects/DashboardApiImpl.java b/java/com/google/gerrit/server/api/projects/DashboardApiImpl.java
index 12c4244..016a593 100644
--- a/java/com/google/gerrit/server/api/projects/DashboardApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/DashboardApiImpl.java
@@ -25,10 +25,10 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.DashboardResource;
-import com.google.gerrit.server.project.DashboardsCollection;
-import com.google.gerrit.server.project.GetDashboard;
 import com.google.gerrit.server.project.ProjectResource;
-import com.google.gerrit.server.project.SetDashboard;
+import com.google.gerrit.server.restapi.project.DashboardsCollection;
+import com.google.gerrit.server.restapi.project.GetDashboard;
+import com.google.gerrit.server.restapi.project.SetDashboard;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.assistedinject.Assisted;
diff --git a/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java b/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
index fae5bba..501b3a4 100644
--- a/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/ProjectApiImpl.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server.api.projects;
 
 import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
-import static com.google.gerrit.server.project.DashboardsCollection.DEFAULT_DASHBOARD_NAME;
+import static com.google.gerrit.server.restapi.project.DashboardsCollection.DEFAULT_DASHBOARD_NAME;
 import static java.util.stream.Collectors.toList;
 
 import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
@@ -51,30 +51,30 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
-import com.google.gerrit.server.project.CheckAccess;
-import com.google.gerrit.server.project.ChildProjectsCollection;
-import com.google.gerrit.server.project.CommitsCollection;
-import com.google.gerrit.server.project.CreateAccessChange;
-import com.google.gerrit.server.project.CreateProject;
-import com.google.gerrit.server.project.DeleteBranches;
-import com.google.gerrit.server.project.DeleteTags;
-import com.google.gerrit.server.project.GetAccess;
-import com.google.gerrit.server.project.GetConfig;
-import com.google.gerrit.server.project.GetDescription;
-import com.google.gerrit.server.project.GetHead;
-import com.google.gerrit.server.project.GetParent;
-import com.google.gerrit.server.project.ListBranches;
-import com.google.gerrit.server.project.ListChildProjects;
-import com.google.gerrit.server.project.ListDashboards;
-import com.google.gerrit.server.project.ListTags;
 import com.google.gerrit.server.project.ProjectJson;
 import com.google.gerrit.server.project.ProjectResource;
-import com.google.gerrit.server.project.ProjectsCollection;
-import com.google.gerrit.server.project.PutConfig;
-import com.google.gerrit.server.project.PutDescription;
-import com.google.gerrit.server.project.SetAccess;
-import com.google.gerrit.server.project.SetHead;
-import com.google.gerrit.server.project.SetParent;
+import com.google.gerrit.server.restapi.project.CheckAccess;
+import com.google.gerrit.server.restapi.project.ChildProjectsCollection;
+import com.google.gerrit.server.restapi.project.CommitsCollection;
+import com.google.gerrit.server.restapi.project.CreateAccessChange;
+import com.google.gerrit.server.restapi.project.CreateProject;
+import com.google.gerrit.server.restapi.project.DeleteBranches;
+import com.google.gerrit.server.restapi.project.DeleteTags;
+import com.google.gerrit.server.restapi.project.GetAccess;
+import com.google.gerrit.server.restapi.project.GetConfig;
+import com.google.gerrit.server.restapi.project.GetDescription;
+import com.google.gerrit.server.restapi.project.GetHead;
+import com.google.gerrit.server.restapi.project.GetParent;
+import com.google.gerrit.server.restapi.project.ListBranches;
+import com.google.gerrit.server.restapi.project.ListChildProjects;
+import com.google.gerrit.server.restapi.project.ListDashboards;
+import com.google.gerrit.server.restapi.project.ListTags;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
+import com.google.gerrit.server.restapi.project.PutConfig;
+import com.google.gerrit.server.restapi.project.PutDescription;
+import com.google.gerrit.server.restapi.project.SetAccess;
+import com.google.gerrit.server.restapi.project.SetHead;
+import com.google.gerrit.server.restapi.project.SetParent;
 import com.google.inject.Provider;
 import com.google.inject.assistedinject.Assisted;
 import com.google.inject.assistedinject.AssistedInject;
diff --git a/java/com/google/gerrit/server/api/projects/ProjectsImpl.java b/java/com/google/gerrit/server/api/projects/ProjectsImpl.java
index dee9ebb..4552e7a 100644
--- a/java/com/google/gerrit/server/api/projects/ProjectsImpl.java
+++ b/java/com/google/gerrit/server/api/projects/ProjectsImpl.java
@@ -25,10 +25,10 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ListProjects;
-import com.google.gerrit.server.project.ListProjects.FilterType;
-import com.google.gerrit.server.project.ProjectsCollection;
-import com.google.gerrit.server.project.QueryProjects;
+import com.google.gerrit.server.restapi.project.ListProjects;
+import com.google.gerrit.server.restapi.project.ListProjects.FilterType;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
+import com.google.gerrit.server.restapi.project.QueryProjects;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/api/projects/TagApiImpl.java b/java/com/google/gerrit/server/api/projects/TagApiImpl.java
index 9f19c6d..84af4e8 100644
--- a/java/com/google/gerrit/server/api/projects/TagApiImpl.java
+++ b/java/com/google/gerrit/server/api/projects/TagApiImpl.java
@@ -22,12 +22,12 @@
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.project.CreateTag;
-import com.google.gerrit.server.project.DeleteTag;
-import com.google.gerrit.server.project.ListTags;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.TagResource;
-import com.google.gerrit.server.project.TagsCollection;
+import com.google.gerrit.server.restapi.project.CreateTag;
+import com.google.gerrit.server.restapi.project.DeleteTag;
+import com.google.gerrit.server.restapi.project.ListTags;
+import com.google.gerrit.server.restapi.project.TagsCollection;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/change/AccountPatchReviewStore.java b/java/com/google/gerrit/server/change/AccountPatchReviewStore.java
index b7a6e82..69825ea 100644
--- a/java/com/google/gerrit/server/change/AccountPatchReviewStore.java
+++ b/java/com/google/gerrit/server/change/AccountPatchReviewStore.java
@@ -37,9 +37,9 @@
   /** Represents patch set id with reviewed files. */
   @AutoValue
   abstract class PatchSetWithReviewedFiles {
-    abstract PatchSet.Id patchSetId();
+    public abstract PatchSet.Id patchSetId();
 
-    abstract ImmutableSet<String> files();
+    public abstract ImmutableSet<String> files();
 
     public static PatchSetWithReviewedFiles create(PatchSet.Id id, ImmutableSet<String> files) {
       return new AutoValue_AccountPatchReviewStore_PatchSetWithReviewedFiles(id, files);
diff --git a/java/com/google/gerrit/server/change/ArchiveFormat.java b/java/com/google/gerrit/server/change/ArchiveFormat.java
index 3fefcd4..0316c5f 100644
--- a/java/com/google/gerrit/server/change/ArchiveFormat.java
+++ b/java/com/google/gerrit/server/change/ArchiveFormat.java
@@ -48,15 +48,15 @@
     return name().toLowerCase();
   }
 
-  String getMimeType() {
+  public String getMimeType() {
     return mimeType;
   }
 
-  String getDefaultSuffix() {
+  public String getDefaultSuffix() {
     return getSuffixes().iterator().next();
   }
 
-  Iterable<String> getSuffixes() {
+  public Iterable<String> getSuffixes() {
     return format.suffixes();
   }
 
diff --git a/java/com/google/gerrit/server/change/ChangeJson.java b/java/com/google/gerrit/server/change/ChangeJson.java
index a03f60a..81558e3 100644
--- a/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/java/com/google/gerrit/server/change/ChangeJson.java
@@ -1361,7 +1361,7 @@
     return out;
   }
 
-  CommitInfo toCommit(
+  public CommitInfo toCommit(
       Project.NameKey project, RevWalk rw, RevCommit commit, boolean addLinks, boolean fillCommit)
       throws IOException {
     CommitInfo info = new CommitInfo();
diff --git a/java/com/google/gerrit/server/change/CommentResource.java b/java/com/google/gerrit/server/change/CommentResource.java
index f7fc576..1b7cbf8 100644
--- a/java/com/google/gerrit/server/change/CommentResource.java
+++ b/java/com/google/gerrit/server/change/CommentResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -37,19 +37,19 @@
     return rev.getPatchSet();
   }
 
-  Comment getComment() {
+  public Comment getComment() {
     return comment;
   }
 
-  String getId() {
+  public String getId() {
     return comment.key.uuid;
   }
 
-  Account.Id getAuthorId() {
+  public Account.Id getAuthorId() {
     return comment.author.getId();
   }
 
-  RevisionResource getRevisionResource() {
+  public RevisionResource getRevisionResource() {
     return rev;
   }
 }
diff --git a/java/com/google/gerrit/server/change/DraftCommentResource.java b/java/com/google/gerrit/server/change/DraftCommentResource.java
index 0b1b15d..ef31725 100644
--- a/java/com/google/gerrit/server/change/DraftCommentResource.java
+++ b/java/com/google/gerrit/server/change/DraftCommentResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2012 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -46,11 +46,11 @@
     return rev.getPatchSet();
   }
 
-  Comment getComment() {
+  public Comment getComment() {
     return comment;
   }
 
-  String getId() {
+  public String getId() {
     return comment.key.uuid;
   }
 }
diff --git a/java/com/google/gerrit/server/change/FileInfoJson.java b/java/com/google/gerrit/server/change/FileInfoJson.java
index 6ccd460..f4b7457 100644
--- a/java/com/google/gerrit/server/change/FileInfoJson.java
+++ b/java/com/google/gerrit/server/change/FileInfoJson.java
@@ -41,24 +41,25 @@
     this.patchListCache = patchListCache;
   }
 
-  Map<String, FileInfo> toFileInfoMap(Change change, PatchSet patchSet)
+  public Map<String, FileInfo> toFileInfoMap(Change change, PatchSet patchSet)
       throws PatchListNotAvailableException {
     return toFileInfoMap(change, patchSet.getRevision(), null);
   }
 
-  Map<String, FileInfo> toFileInfoMap(Change change, RevId revision, @Nullable PatchSet base)
+  public Map<String, FileInfo> toFileInfoMap(Change change, RevId revision, @Nullable PatchSet base)
       throws PatchListNotAvailableException {
     ObjectId objectId = ObjectId.fromString(revision.get());
     return toFileInfoMap(change, objectId, base);
   }
 
-  Map<String, FileInfo> toFileInfoMap(Change change, ObjectId objectId, @Nullable PatchSet base)
+  public Map<String, FileInfo> toFileInfoMap(
+      Change change, ObjectId objectId, @Nullable PatchSet base)
       throws PatchListNotAvailableException {
     ObjectId a = (base == null) ? null : ObjectId.fromString(base.getRevision().get());
     return toFileInfoMap(change, PatchListKey.againstCommit(a, objectId, Whitespace.IGNORE_NONE));
   }
 
-  Map<String, FileInfo> toFileInfoMap(Change change, RevId revision, int parent)
+  public Map<String, FileInfo> toFileInfoMap(Change change, RevId revision, int parent)
       throws PatchListNotAvailableException {
     ObjectId b = ObjectId.fromString(revision.get());
     return toFileInfoMap(
diff --git a/java/com/google/gerrit/server/change/FileResource.java b/java/com/google/gerrit/server/change/FileResource.java
index ca47fb9..bd7557f 100644
--- a/java/com/google/gerrit/server/change/FileResource.java
+++ b/java/com/google/gerrit/server/change/FileResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -40,7 +40,7 @@
     return rev.isCacheable();
   }
 
-  Account.Id getAccountId() {
+  public Account.Id getAccountId() {
     return rev.getAccountId();
   }
 
diff --git a/java/com/google/gerrit/server/change/RebaseUtil.java b/java/com/google/gerrit/server/change/RebaseUtil.java
index fdb1cfc..bfb1692 100644
--- a/java/com/google/gerrit/server/change/RebaseUtil.java
+++ b/java/com/google/gerrit/server/change/RebaseUtil.java
@@ -78,7 +78,7 @@
   }
 
   @AutoValue
-  abstract static class Base {
+  public abstract static class Base {
     private static Base create(ChangeNotes notes, PatchSet ps) {
       if (notes == null) {
         return null;
@@ -86,12 +86,12 @@
       return new AutoValue_RebaseUtil_Base(notes, ps);
     }
 
-    abstract ChangeNotes notes();
+    public abstract ChangeNotes notes();
 
-    abstract PatchSet patchSet();
+    public abstract PatchSet patchSet();
   }
 
-  Base parseBase(RevisionResource rsrc, String base) throws OrmException {
+  public Base parseBase(RevisionResource rsrc, String base) throws OrmException {
     ReviewDb db = dbProvider.get();
 
     // Try parsing the base as a ref string.
@@ -152,7 +152,7 @@
    * @throws IOException if accessing the repository fails.
    * @throws OrmException if accessing the database fails.
    */
-  ObjectId findBaseRevision(
+  public ObjectId findBaseRevision(
       PatchSet patchSet, Branch.NameKey destBranch, Repository git, RevWalk rw)
       throws RestApiException, IOException, OrmException {
     String baseRev = null;
diff --git a/java/com/google/gerrit/server/change/ReviewerResource.java b/java/com/google/gerrit/server/change/ReviewerResource.java
index 47e25b04..778897e 100644
--- a/java/com/google/gerrit/server/change/ReviewerResource.java
+++ b/java/com/google/gerrit/server/change/ReviewerResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2012 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -64,14 +64,14 @@
     this.address = null;
   }
 
-  ReviewerResource(ChangeResource change, Address address) {
+  public ReviewerResource(ChangeResource change, Address address) {
     this.change = change;
     this.address = address;
     this.revision = null;
     this.user = null;
   }
 
-  ReviewerResource(RevisionResource revision, Address address) {
+  public ReviewerResource(RevisionResource revision, Address address) {
     this.revision = revision;
     this.change = revision.getChangeResource();
     this.address = address;
diff --git a/java/com/google/gerrit/server/change/RevisionResource.java b/java/com/google/gerrit/server/change/RevisionResource.java
index b9b2d1d..3ddfc63 100644
--- a/java/com/google/gerrit/server/change/RevisionResource.java
+++ b/java/com/google/gerrit/server/change/RevisionResource.java
@@ -84,21 +84,22 @@
     return h.hash().toString();
   }
 
-  void prepareETag(Hasher h, CurrentUser user) {
+  public void prepareETag(Hasher h, CurrentUser user) {
     // Conservative estimate: refresh the revision if its parent change has changed, so we don't
     // have to check whether a given modification affected this revision specifically.
     change.prepareETag(h, user);
   }
 
-  Account.Id getAccountId() {
+  public Account.Id getAccountId() {
     return getUser().getAccountId();
   }
 
-  CurrentUser getUser() {
+  public CurrentUser getUser() {
     return getChangeResource().getUser();
   }
 
-  RevisionResource doNotCache() {
+  public RevisionResource doNotCache() {
+    // TODO(hanwen): return a copy so cacheable can be final.
     cacheable = false;
     return this;
   }
diff --git a/java/com/google/gerrit/server/change/RobotCommentResource.java b/java/com/google/gerrit/server/change/RobotCommentResource.java
index 856c777..c4fab58 100644
--- a/java/com/google/gerrit/server/change/RobotCommentResource.java
+++ b/java/com/google/gerrit/server/change/RobotCommentResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2016 The Android Open Source Project
+// Copyright (C) 2017 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.
@@ -37,15 +37,15 @@
     return rev.getPatchSet();
   }
 
-  RobotComment getComment() {
+  public RobotComment getComment() {
     return comment;
   }
 
-  String getId() {
+  public String getId() {
     return comment.key.uuid;
   }
 
-  Account.Id getAuthorId() {
+  public Account.Id getAuthorId() {
     return comment.author.getId();
   }
 }
diff --git a/java/com/google/gerrit/server/change/TestSubmitInput.java b/java/com/google/gerrit/server/change/TestSubmitInput.java
new file mode 100644
index 0000000..b681bf8
--- /dev/null
+++ b/java/com/google/gerrit/server/change/TestSubmitInput.java
@@ -0,0 +1,20 @@
+package com.google.gerrit.server.change;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.gerrit.extensions.api.changes.SubmitInput;
+import java.util.Queue;
+
+/**
+ * Subclass of {@link SubmitInput} with special bits that may be flipped for testing purposes only.
+ */
+@VisibleForTesting
+public class TestSubmitInput extends SubmitInput {
+  public boolean failAfterRefUpdates;
+
+  /**
+   * For each change being submitted, an element is removed from this queue and, if the value is
+   * true, a bogus ref update is added to the batch, in order to generate a lock failure during
+   * execution.
+   */
+  public Queue<Boolean> generateLockFailures;
+}
diff --git a/java/com/google/gerrit/server/change/VoteResource.java b/java/com/google/gerrit/server/change/VoteResource.java
index 4dfaff0..27b5bec 100644
--- a/java/com/google/gerrit/server/change/VoteResource.java
+++ b/java/com/google/gerrit/server/change/VoteResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/change/WalkSorter.java b/java/com/google/gerrit/server/change/WalkSorter.java
index 56d7ec0..509f774 100644
--- a/java/com/google/gerrit/server/change/WalkSorter.java
+++ b/java/com/google/gerrit/server/change/WalkSorter.java
@@ -62,7 +62,7 @@
  * timestamp, as it will not unexpectedly reorder large groups of changes on subsequent calls if one
  * of the changes was updated.
  */
-class WalkSorter {
+public class WalkSorter {
   private static final Logger log = LoggerFactory.getLogger(WalkSorter.class);
 
   private static final Ordering<List<PatchSetData>> PROJECT_LIST_SORTER =
@@ -254,13 +254,13 @@
   }
 
   @AutoValue
-  abstract static class PatchSetData {
+  public abstract static class PatchSetData {
     @VisibleForTesting
     static PatchSetData create(ChangeData cd, PatchSet ps, RevCommit commit) {
       return new AutoValue_WalkSorter_PatchSetData(cd, ps, commit);
     }
 
-    abstract ChangeData data();
+    public abstract ChangeData data();
 
     abstract PatchSet patchSet();
 
diff --git a/java/com/google/gerrit/server/change/WorkInProgressOp.java b/java/com/google/gerrit/server/change/WorkInProgressOp.java
index 43de55c3..75a9323 100644
--- a/java/com/google/gerrit/server/change/WorkInProgressOp.java
+++ b/java/com/google/gerrit/server/change/WorkInProgressOp.java
@@ -38,9 +38,9 @@
 /* Set work in progress or ready for review state on a change */
 public class WorkInProgressOp implements BatchUpdateOp {
   public static class Input {
-    @Nullable String message;
+    @Nullable public String message;
 
-    @Nullable NotifyHandling notify;
+    @Nullable public NotifyHandling notify;
 
     public Input() {}
 
diff --git a/java/com/google/gerrit/server/config/GerritGlobalModule.java b/java/com/google/gerrit/server/config/GerritGlobalModule.java
index e0d4827..1dda0e5 100644
--- a/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -137,7 +137,6 @@
 import com.google.gerrit.server.git.validators.RefOperationValidators;
 import com.google.gerrit.server.git.validators.UploadValidationListener;
 import com.google.gerrit.server.git.validators.UploadValidators;
-import com.google.gerrit.server.group.GroupModule;
 import com.google.gerrit.server.index.change.ReindexAfterRefUpdate;
 import com.google.gerrit.server.mail.EmailModule;
 import com.google.gerrit.server.mail.ListMailFilter;
@@ -176,6 +175,7 @@
 import com.google.gerrit.server.query.change.ChangeQueryProcessor;
 import com.google.gerrit.server.query.change.ConflictsCacheImpl;
 import com.google.gerrit.server.restapi.config.ConfigRestModule;
+import com.google.gerrit.server.restapi.group.GroupModule;
 import com.google.gerrit.server.rules.PrologModule;
 import com.google.gerrit.server.rules.RulesCache;
 import com.google.gerrit.server.ssh.SshAddressesModule;
@@ -305,12 +305,13 @@
 
     install(new AuditModule());
     bind(UiActions.class);
-    install(new com.google.gerrit.server.access.Module());
-    install(new com.google.gerrit.server.account.Module());
-    install(new com.google.gerrit.server.change.Module());
+    install(new com.google.gerrit.server.restapi.access.Module());
     install(new ConfigRestModule());
+    install(new com.google.gerrit.server.restapi.change.Module());
     install(new com.google.gerrit.server.group.Module(groupsMigration));
-    install(new com.google.gerrit.server.project.Module());
+    install(new com.google.gerrit.server.restapi.account.Module());
+    install(new com.google.gerrit.server.restapi.project.Module());
+    install(new com.google.gerrit.server.restapi.group.Module());
 
     bind(GitReferenceUpdated.class);
     DynamicMap.mapOf(binder(), new TypeLiteral<Cache<?, ?>>() {});
diff --git a/java/com/google/gerrit/server/git/MergeSuperSet.java b/java/com/google/gerrit/server/git/MergeSuperSet.java
index be4add0..84676d7 100644
--- a/java/com/google/gerrit/server/git/MergeSuperSet.java
+++ b/java/com/google/gerrit/server/git/MergeSuperSet.java
@@ -22,7 +22,6 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.change.Submit;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.index.change.ChangeField;
 import com.google.gerrit.server.permissions.ChangePermission;
@@ -96,6 +95,10 @@
     this.permissionBackend = permissionBackend;
   }
 
+  public static boolean wholeTopicEnabled(Config config) {
+    return config.getBoolean("change", null, "submitWholeTopic", false);
+  }
+
   public MergeSuperSet setMergeOpRepoManager(MergeOpRepoManager orm) {
     checkState(this.orm == null);
     this.orm = checkNotNull(orm);
@@ -115,7 +118,7 @@
       ChangeSet changeSet =
           new ChangeSet(
               cd, permissionBackend.user(user).change(cd).database(db).test(ChangePermission.READ));
-      if (Submit.wholeTopicEnabled(cfg)) {
+      if (wholeTopicEnabled(cfg)) {
         return completeChangeSetIncludingTopics(db, changeSet, user);
       }
       return mergeSuperSetComputation.get().completeWithoutTopic(db, orm, changeSet, user);
diff --git a/java/com/google/gerrit/server/git/strategy/SubmitStrategy.java b/java/com/google/gerrit/server/git/strategy/SubmitStrategy.java
index 79c0cdb..5a5a751 100644
--- a/java/com/google/gerrit/server/git/strategy/SubmitStrategy.java
+++ b/java/com/google/gerrit/server/git/strategy/SubmitStrategy.java
@@ -33,7 +33,7 @@
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.change.RebaseChangeOp;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.server.extensions.events.ChangeMerged;
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
diff --git a/java/com/google/gerrit/server/git/strategy/SubmitStrategyListener.java b/java/com/google/gerrit/server/git/strategy/SubmitStrategyListener.java
index 97291e5..57094af 100644
--- a/java/com/google/gerrit/server/git/strategy/SubmitStrategyListener.java
+++ b/java/com/google/gerrit/server/git/strategy/SubmitStrategyListener.java
@@ -19,7 +19,7 @@
 import com.google.gerrit.extensions.api.changes.SubmitInput;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.IntegrationException;
 import com.google.gerrit.server.git.MergeOp.CommitStatus;
diff --git a/java/com/google/gerrit/server/git/strategy/TestHelperOp.java b/java/com/google/gerrit/server/git/strategy/TestHelperOp.java
index 8d95045..a0ebb4c 100644
--- a/java/com/google/gerrit/server/git/strategy/TestHelperOp.java
+++ b/java/com/google/gerrit/server/git/strategy/TestHelperOp.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.server.git.strategy;
 
 import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.RepoContext;
 import com.google.gerrit.server.util.RequestId;
diff --git a/java/com/google/gerrit/server/group/GroupResource.java b/java/com/google/gerrit/server/group/GroupResource.java
index 44e770f..1050314 100644
--- a/java/com/google/gerrit/server/group/GroupResource.java
+++ b/java/com/google/gerrit/server/group/GroupResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/group/MemberResource.java b/java/com/google/gerrit/server/group/MemberResource.java
index 52a37a8..b12cadd 100644
--- a/java/com/google/gerrit/server/group/MemberResource.java
+++ b/java/com/google/gerrit/server/group/MemberResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/group/Module.java b/java/com/google/gerrit/server/group/Module.java
index acef16d..f40e3b9 100644
--- a/java/com/google/gerrit/server/group/Module.java
+++ b/java/com/google/gerrit/server/group/Module.java
@@ -1,37 +1,11 @@
-// 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.google.gerrit.server.group;
 
-import static com.google.gerrit.server.group.GroupResource.GROUP_KIND;
-import static com.google.gerrit.server.group.MemberResource.MEMBER_KIND;
-import static com.google.gerrit.server.group.SubgroupResource.SUBGROUP_KIND;
-
-import com.google.gerrit.extensions.registration.DynamicMap;
+import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.registration.DynamicSet;
-import com.google.gerrit.extensions.restapi.RestApiModule;
-import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.audit.GroupMemberAuditListener;
-import com.google.gerrit.server.group.AddMembers.UpdateMember;
-import com.google.gerrit.server.group.AddSubgroups.UpdateSubgroup;
-import com.google.gerrit.server.group.DeleteMembers.DeleteMember;
-import com.google.gerrit.server.group.DeleteSubgroups.DeleteSubgroup;
-import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.notedb.GroupsMigration;
-import com.google.inject.Provides;
 
-public class Module extends RestApiModule {
+public class Module extends FactoryModule {
   private final GroupsMigration groupsMigration;
 
   public Module(GroupsMigration groupsMigration) {
@@ -40,47 +14,6 @@
 
   @Override
   protected void configure() {
-    bind(GroupsCollection.class);
-
-    DynamicMap.mapOf(binder(), GROUP_KIND);
-    DynamicMap.mapOf(binder(), MEMBER_KIND);
-    DynamicMap.mapOf(binder(), SUBGROUP_KIND);
-
-    get(GROUP_KIND).to(GetGroup.class);
-    put(GROUP_KIND).to(PutGroup.class);
-    get(GROUP_KIND, "detail").to(GetDetail.class);
-    post(GROUP_KIND, "index").to(Index.class);
-    post(GROUP_KIND, "members").to(AddMembers.class);
-    post(GROUP_KIND, "members.add").to(AddMembers.class);
-    post(GROUP_KIND, "members.delete").to(DeleteMembers.class);
-    post(GROUP_KIND, "groups").to(AddSubgroups.class);
-    post(GROUP_KIND, "groups.add").to(AddSubgroups.class);
-    post(GROUP_KIND, "groups.delete").to(DeleteSubgroups.class);
-    get(GROUP_KIND, "description").to(GetDescription.class);
-    put(GROUP_KIND, "description").to(PutDescription.class);
-    delete(GROUP_KIND, "description").to(PutDescription.class);
-    get(GROUP_KIND, "name").to(GetName.class);
-    put(GROUP_KIND, "name").to(PutName.class);
-    get(GROUP_KIND, "owner").to(GetOwner.class);
-    put(GROUP_KIND, "owner").to(PutOwner.class);
-    get(GROUP_KIND, "options").to(GetOptions.class);
-    put(GROUP_KIND, "options").to(PutOptions.class);
-    get(GROUP_KIND, "log.audit").to(GetAuditLog.class);
-    post(GROUP_KIND, "rebuild").to(Rebuild.class);
-
-    child(GROUP_KIND, "members").to(MembersCollection.class);
-    get(MEMBER_KIND).to(GetMember.class);
-    put(MEMBER_KIND).to(UpdateMember.class);
-    delete(MEMBER_KIND).to(DeleteMember.class);
-
-    child(GROUP_KIND, "groups").to(SubgroupsCollection.class);
-    get(SUBGROUP_KIND).to(GetSubgroup.class);
-    put(SUBGROUP_KIND).to(UpdateSubgroup.class);
-    delete(SUBGROUP_KIND).to(DeleteSubgroup.class);
-
-    factory(CreateGroup.Factory.class);
-    factory(GroupsUpdate.Factory.class);
-
     if (!groupsMigration.disableGroupReviewDb()) {
       // DbGroupMemberAuditListener is used solely for the ReviewDb audit log. It does not respect
       // ReviewDb wrappers that disable reads. Hence, we don't want to bind it if ReviewDb is
@@ -89,17 +22,4 @@
           .to(DbGroupMemberAuditListener.class);
     }
   }
-
-  @Provides
-  @ServerInitiated
-  GroupsUpdate provideServerInitiatedGroupsUpdate(GroupsUpdate.Factory groupsUpdateFactory) {
-    return groupsUpdateFactory.create(null);
-  }
-
-  @Provides
-  @UserInitiated
-  GroupsUpdate provideUserInitiatedGroupsUpdate(
-      GroupsUpdate.Factory groupsUpdateFactory, IdentifiedUser currentUser) {
-    return groupsUpdateFactory.create(currentUser);
-  }
 }
diff --git a/java/com/google/gerrit/server/group/SubgroupResource.java b/java/com/google/gerrit/server/group/SubgroupResource.java
index 50c769d..a33e96b 100644
--- a/java/com/google/gerrit/server/group/SubgroupResource.java
+++ b/java/com/google/gerrit/server/group/SubgroupResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/project/ChildProjectResource.java b/java/com/google/gerrit/server/project/ChildProjectResource.java
index b372b38..4b641ca 100644
--- a/java/com/google/gerrit/server/project/ChildProjectResource.java
+++ b/java/com/google/gerrit/server/project/ChildProjectResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/project/CommitResource.java b/java/com/google/gerrit/server/project/CommitResource.java
index 0925524..f71c7fe 100644
--- a/java/com/google/gerrit/server/project/CommitResource.java
+++ b/java/com/google/gerrit/server/project/CommitResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/project/DashboardResource.java b/java/com/google/gerrit/server/project/DashboardResource.java
index 87b6fdf..54f958a 100644
--- a/java/com/google/gerrit/server/project/DashboardResource.java
+++ b/java/com/google/gerrit/server/project/DashboardResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2012 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/project/FileResource.java b/java/com/google/gerrit/server/project/FileResource.java
index 82462b2..6e5375a 100644
--- a/java/com/google/gerrit/server/project/FileResource.java
+++ b/java/com/google/gerrit/server/project/FileResource.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 The Android Open Source Project
+// Copyright (C) 2017 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.
diff --git a/java/com/google/gerrit/server/project/ProjectControl.java b/java/com/google/gerrit/server/project/ProjectControl.java
index 97d0173..3e6d10e 100644
--- a/java/com/google/gerrit/server/project/ProjectControl.java
+++ b/java/com/google/gerrit/server/project/ProjectControl.java
@@ -62,8 +62,8 @@
 import org.eclipse.jgit.revwalk.RevCommit;
 
 /** Access control management for a user accessing a project's data. */
-class ProjectControl {
-  static class GenericFactory {
+public class ProjectControl {
+  public static class GenericFactory {
     private final ProjectCache projectCache;
 
     @Inject
@@ -71,7 +71,7 @@
       projectCache = pc;
     }
 
-    ProjectControl controlFor(Project.NameKey nameKey, CurrentUser user)
+    public ProjectControl controlFor(Project.NameKey nameKey, CurrentUser user)
         throws NoSuchProjectException, IOException {
       final ProjectState p = projectCache.checkedGet(nameKey);
       if (p == null) {
@@ -151,7 +151,7 @@
     return controlForRef(ref.get());
   }
 
-  RefControl controlForRef(String refName) {
+  public RefControl controlForRef(String refName) {
     if (refControls == null) {
       refControls = new HashMap<>();
     }
diff --git a/java/com/google/gerrit/server/project/RefControl.java b/java/com/google/gerrit/server/project/RefControl.java
index d674039..0651b1d 100644
--- a/java/com/google/gerrit/server/project/RefControl.java
+++ b/java/com/google/gerrit/server/project/RefControl.java
@@ -45,7 +45,7 @@
 import java.util.Set;
 
 /** Manages access control for Git references (aka branches, tags). */
-class RefControl {
+public class RefControl {
   private final ProjectControl projectControl;
   private final String refName;
 
@@ -377,7 +377,7 @@
   }
 
   /** True if the user has this permission. Works only for non labels. */
-  boolean canPerform(String permissionName) {
+  public boolean canPerform(String permissionName) {
     return canPerform(permissionName, false);
   }
 
diff --git a/java/com/google/gerrit/server/project/RefUtil.java b/java/com/google/gerrit/server/project/RefUtil.java
index 8a7e5f1..62e48be 100644
--- a/java/com/google/gerrit/server/project/RefUtil.java
+++ b/java/com/google/gerrit/server/project/RefUtil.java
@@ -120,7 +120,7 @@
   }
 
   /** Error indicating the revision is invalid as supplied. */
-  static class InvalidRevisionException extends Exception {
+  public static class InvalidRevisionException extends Exception {
     private static final long serialVersionUID = 1L;
 
     public static final String MESSAGE = "Invalid Revision";
diff --git a/java/com/google/gerrit/server/restapi/BUILD b/java/com/google/gerrit/server/restapi/BUILD
index e0262bb..5b9800b 100644
--- a/java/com/google/gerrit/server/restapi/BUILD
+++ b/java/com/google/gerrit/server/restapi/BUILD
@@ -6,16 +6,29 @@
     name = "restapi",
     srcs = glob(["**/*.java"]),
     deps = [
+        "//java/com/google/gerrit/common:annotations",
         "//java/com/google/gerrit/common:server",
         "//java/com/google/gerrit/extensions:api",
+        "//java/com/google/gerrit/index",
+        "//java/com/google/gerrit/index:query_exception",
+        "//java/com/google/gerrit/metrics",
+        "//java/com/google/gerrit/prettify:server",
         "//java/com/google/gerrit/reviewdb:server",
         "//java/com/google/gerrit/server",
+        "//java/com/google/gerrit/server/ioutil",
         "//java/org/eclipse/jgit:server",
         "//lib:args4j",
+        "//lib:blame-cache",
+        "//lib:gson",
         "//lib:guava",
         "//lib:gwtorm",
         "//lib:servlet-api-3_1",
+        "//lib/auto:auto-value",
+        "//lib/commons:codec",
+        "//lib/commons:compress",
+        "//lib/commons:lang",
         "//lib/guice",
+        "//lib/guice:guice-assistedinject",
         "//lib/jgit/org.eclipse.jgit:jgit",
         "//lib/log:api",
     ],
diff --git a/java/com/google/gerrit/server/access/AccessCollection.java b/java/com/google/gerrit/server/restapi/access/AccessCollection.java
similarity index 94%
rename from java/com/google/gerrit/server/access/AccessCollection.java
rename to java/com/google/gerrit/server/restapi/access/AccessCollection.java
index 2e90889..4e12291 100644
--- a/java/com/google/gerrit/server/access/AccessCollection.java
+++ b/java/com/google/gerrit/server/restapi/access/AccessCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.access;
+package com.google.gerrit.server.restapi.access;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.IdString;
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.restapi.RestCollection;
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
+import com.google.gerrit.server.access.AccessResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/access/ListAccess.java b/java/com/google/gerrit/server/restapi/access/ListAccess.java
similarity index 94%
rename from java/com/google/gerrit/server/access/ListAccess.java
rename to java/com/google/gerrit/server/restapi/access/ListAccess.java
index 99e6a9f..a79afd2 100644
--- a/java/com/google/gerrit/server/access/ListAccess.java
+++ b/java/com/google/gerrit/server/restapi/access/ListAccess.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.access;
+package com.google.gerrit.server.restapi.access;
 
 import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -21,7 +21,7 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.GetAccess;
+import com.google.gerrit.server.restapi.project.GetAccess;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/access/Module.java b/java/com/google/gerrit/server/restapi/access/Module.java
similarity index 94%
rename from java/com/google/gerrit/server/access/Module.java
rename to java/com/google/gerrit/server/restapi/access/Module.java
index cd0d334..21357fa 100644
--- a/java/com/google/gerrit/server/access/Module.java
+++ b/java/com/google/gerrit/server/restapi/access/Module.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.access;
+package com.google.gerrit.server.restapi.access;
 
 import static com.google.gerrit.server.access.AccessResource.ACCESS_KIND;
 
diff --git a/java/com/google/gerrit/server/account/AccountsCollection.java b/java/com/google/gerrit/server/restapi/account/AccountsCollection.java
similarity index 96%
rename from java/com/google/gerrit/server/account/AccountsCollection.java
rename to java/com/google/gerrit/server/restapi/account/AccountsCollection.java
index 19a8259..197dadb 100644
--- a/java/com/google/gerrit/server/account/AccountsCollection.java
+++ b/java/com/google/gerrit/server/restapi/account/AccountsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -28,6 +28,9 @@
 import com.google.gerrit.server.AnonymousUser;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountControl;
+import com.google.gerrit.server.account.AccountResolver;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/account/AddSshKey.java b/java/com/google/gerrit/server/restapi/account/AddSshKey.java
similarity index 95%
rename from java/com/google/gerrit/server/account/AddSshKey.java
rename to java/com/google/gerrit/server/restapi/account/AddSshKey.java
index 5680b56..be0ca6a 100644
--- a/java/com/google/gerrit/server/account/AddSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/AddSshKey.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
@@ -29,6 +29,8 @@
 import com.google.gerrit.reviewdb.client.AccountSshKey;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAuthorizedKeys;
 import com.google.gerrit.server.mail.send.AddKeySender;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/account/Capabilities.java b/java/com/google/gerrit/server/restapi/account/Capabilities.java
similarity index 96%
rename from java/com/google/gerrit/server/account/Capabilities.java
rename to java/com/google/gerrit/server/restapi/account/Capabilities.java
index 08eecd7..e337662 100644
--- a/java/com/google/gerrit/server/account/Capabilities.java
+++ b/java/com/google/gerrit/server/restapi/account/Capabilities.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
 import com.google.gerrit.extensions.api.access.PluginPermission;
@@ -24,6 +24,7 @@
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AccountResource.Capability;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/account/CreateAccount.java b/java/com/google/gerrit/server/restapi/account/CreateAccount.java
similarity index 95%
rename from java/com/google/gerrit/server/account/CreateAccount.java
rename to java/com/google/gerrit/server/restapi/account/CreateAccount.java
index 2ce13ea..45128f1 100644
--- a/java/com/google/gerrit/server/account/CreateAccount.java
+++ b/java/com/google/gerrit/server/restapi/account/CreateAccount.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
@@ -38,13 +38,17 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.Sequences;
+import com.google.gerrit.server.account.AccountExternalIdCreator;
+import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.account.AccountsUpdate;
+import com.google.gerrit.server.account.VersionedAuthorizedKeys;
 import com.google.gerrit.server.account.externalids.DuplicateExternalIdKeyException;
 import com.google.gerrit.server.account.externalids.ExternalId;
-import com.google.gerrit.server.group.GroupsCollection;
 import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
 import com.google.gerrit.server.mail.send.OutgoingEmailValidator;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.gerrit.server.ssh.SshKeyCache;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/account/CreateEmail.java b/java/com/google/gerrit/server/restapi/account/CreateEmail.java
similarity index 94%
rename from java/com/google/gerrit/server/account/CreateEmail.java
rename to java/com/google/gerrit/server/restapi/account/CreateEmail.java
index dd02b0b..8ec024e 100644
--- a/java/com/google/gerrit/server/account/CreateEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/CreateEmail.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.extensions.client.AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT;
 
@@ -29,6 +29,11 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountException;
+import com.google.gerrit.server.account.AccountManager;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.AuthRequest;
+import com.google.gerrit.server.account.Realm;
 import com.google.gerrit.server.config.AuthConfig;
 import com.google.gerrit.server.mail.send.OutgoingEmailValidator;
 import com.google.gerrit.server.mail.send.RegisterNewEmailSender;
diff --git a/java/com/google/gerrit/server/account/DeleteActive.java b/java/com/google/gerrit/server/restapi/account/DeleteActive.java
similarity index 92%
rename from java/com/google/gerrit/server/account/DeleteActive.java
rename to java/com/google/gerrit/server/restapi/account/DeleteActive.java
index 4b3bf39..fda28c9 100644
--- a/java/com/google/gerrit/server/account/DeleteActive.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteActive.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -22,6 +22,8 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.SetInactiveFlag;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/account/DeleteEmail.java b/java/com/google/gerrit/server/restapi/account/DeleteEmail.java
similarity index 93%
rename from java/com/google/gerrit/server/account/DeleteEmail.java
rename to java/com/google/gerrit/server/restapi/account/DeleteEmail.java
index cccac63..d36dfe9 100644
--- a/java/com/google/gerrit/server/account/DeleteEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteEmail.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static java.util.stream.Collectors.toSet;
 
@@ -26,6 +26,10 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountException;
+import com.google.gerrit.server.account.AccountManager;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.Realm;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.account.externalids.ExternalIds;
 import com.google.gerrit.server.permissions.GlobalPermission;
diff --git a/java/com/google/gerrit/server/account/DeleteExternalIds.java b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
similarity index 94%
rename from java/com/google/gerrit/server/account/DeleteExternalIds.java
rename to java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
index 72c1a41..3d103ec 100644
--- a/java/com/google/gerrit/server/account/DeleteExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteExternalIds.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
 import static java.util.stream.Collectors.toMap;
@@ -25,6 +25,9 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountException;
+import com.google.gerrit.server.account.AccountManager;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.account.externalids.ExternalIds;
 import com.google.gerrit.server.permissions.GlobalPermission;
diff --git a/java/com/google/gerrit/server/account/DeleteSshKey.java b/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
similarity index 93%
rename from java/com/google/gerrit/server/account/DeleteSshKey.java
rename to java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
index 8dec7d9..f6f3045 100644
--- a/java/com/google/gerrit/server/account/DeleteSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
@@ -12,13 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAuthorizedKeys;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/DeleteWatchedProjects.java b/java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java
similarity index 93%
rename from java/com/google/gerrit/server/account/DeleteWatchedProjects.java
rename to java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java
index ffb405c..1388523 100644
--- a/java/com/google/gerrit/server/account/DeleteWatchedProjects.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteWatchedProjects.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static java.util.stream.Collectors.toList;
 
@@ -24,6 +24,9 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.WatchConfig;
 import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/account/EmailsCollection.java b/java/com/google/gerrit/server/restapi/account/EmailsCollection.java
similarity index 96%
rename from java/com/google/gerrit/server/account/EmailsCollection.java
rename to java/com/google/gerrit/server/restapi/account/EmailsCollection.java
index c8c1db8..d75a01a 100644
--- a/java/com/google/gerrit/server/account/EmailsCollection.java
+++ b/java/com/google/gerrit/server/restapi/account/EmailsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -23,6 +23,7 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AccountResource.Email;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/account/GetAccount.java b/java/com/google/gerrit/server/restapi/account/GetAccount.java
similarity index 88%
rename from java/com/google/gerrit/server/account/GetAccount.java
rename to java/com/google/gerrit/server/restapi/account/GetAccount.java
index 05f8300..0d8e25e 100644
--- a/java/com/google/gerrit/server/account/GetAccount.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAccount.java
@@ -12,10 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/account/GetActive.java b/java/com/google/gerrit/server/restapi/account/GetActive.java
similarity index 90%
rename from java/com/google/gerrit/server/account/GetActive.java
rename to java/com/google/gerrit/server/restapi/account/GetActive.java
index 9864b45..66493f8 100644
--- a/java/com/google/gerrit/server/account/GetActive.java
+++ b/java/com/google/gerrit/server/restapi/account/GetActive.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/account/GetAgreements.java b/java/com/google/gerrit/server/restapi/account/GetAgreements.java
similarity index 95%
rename from java/com/google/gerrit/server/account/GetAgreements.java
rename to java/com/google/gerrit/server/restapi/account/GetAgreements.java
index dfbde96..719cb21 100644
--- a/java/com/google/gerrit/server/account/GetAgreements.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAgreements.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.common.data.ContributorAgreement;
 import com.google.gerrit.common.data.PermissionRule;
@@ -25,9 +25,10 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.config.AgreementJson;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.restapi.config.AgreementJson;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/account/GetAvatar.java b/java/com/google/gerrit/server/restapi/account/GetAvatar.java
similarity index 94%
rename from java/com/google/gerrit/server/account/GetAvatar.java
rename to java/com/google/gerrit/server/restapi/account/GetAvatar.java
index 0818a0e..2f8570e 100644
--- a/java/com/google/gerrit/server/account/GetAvatar.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAvatar.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.registration.DynamicItem;
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.avatar.AvatarProvider;
 import com.google.inject.Inject;
 import java.util.concurrent.TimeUnit;
diff --git a/java/com/google/gerrit/server/account/GetAvatarChangeUrl.java b/java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java
similarity index 93%
rename from java/com/google/gerrit/server/account/GetAvatarChangeUrl.java
rename to java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java
index d340772..904b15f 100644
--- a/java/com/google/gerrit/server/account/GetAvatarChangeUrl.java
+++ b/java/com/google/gerrit/server/restapi/account/GetAvatarChangeUrl.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.avatar.AvatarProvider;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/account/GetCapabilities.java b/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
similarity index 96%
rename from java/com/google/gerrit/server/account/GetCapabilities.java
rename to java/com/google/gerrit/server/restapi/account/GetCapabilities.java
index 616ea79..5260bef0 100644
--- a/java/com/google/gerrit/server/account/GetCapabilities.java
+++ b/java/com/google/gerrit/server/restapi/account/GetCapabilities.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.common.data.GlobalCapability.PRIORITY;
 
@@ -29,6 +29,8 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.OptionUtil;
 import com.google.gerrit.server.OutputFormat;
+import com.google.gerrit.server.account.AccountLimits;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AccountResource.Capability;
 import com.google.gerrit.server.git.QueueProvider;
 import com.google.gerrit.server.permissions.GlobalPermission;
diff --git a/java/com/google/gerrit/server/account/GetDetail.java b/java/com/google/gerrit/server/restapi/account/GetDetail.java
similarity index 92%
rename from java/com/google/gerrit/server/account/GetDetail.java
rename to java/com/google/gerrit/server/restapi/account/GetDetail.java
index 30eb377..de9928c 100644
--- a/java/com/google/gerrit/server/account/GetDetail.java
+++ b/java/com/google/gerrit/server/restapi/account/GetDetail.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Throwables;
 import com.google.gerrit.extensions.common.AccountInfo;
@@ -20,6 +20,8 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.account.AccountDirectory.DirectoryException;
 import com.google.gerrit.server.account.AccountDirectory.FillOptions;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.InternalAccountDirectory;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/account/GetDiffPreferences.java b/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
similarity index 96%
rename from java/com/google/gerrit/server/account/GetDiffPreferences.java
rename to java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
index 8215c6b..c173079 100644
--- a/java/com/google/gerrit/server/account/GetDiffPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetDiffPreferences.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.config.ConfigUtil.loadSection;
 import static com.google.gerrit.server.config.ConfigUtil.skipField;
@@ -22,6 +22,8 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAccountPreferences;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.UserConfigSections;
diff --git a/java/com/google/gerrit/server/account/GetEditPreferences.java b/java/com/google/gerrit/server/restapi/account/GetEditPreferences.java
similarity index 94%
rename from java/com/google/gerrit/server/account/GetEditPreferences.java
rename to java/com/google/gerrit/server/restapi/account/GetEditPreferences.java
index bb207f0..95a6e7c 100644
--- a/java/com/google/gerrit/server/account/GetEditPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEditPreferences.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.config.ConfigUtil.loadSection;
 
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAccountPreferences;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.UserConfigSections;
diff --git a/java/com/google/gerrit/server/account/GetEmail.java b/java/com/google/gerrit/server/restapi/account/GetEmail.java
similarity index 91%
rename from java/com/google/gerrit/server/account/GetEmail.java
rename to java/com/google/gerrit/server/restapi/account/GetEmail.java
index 82e0944..3118380 100644
--- a/java/com/google/gerrit/server/account/GetEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEmail.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.EmailInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/account/GetEmails.java b/java/com/google/gerrit/server/restapi/account/GetEmails.java
similarity index 93%
rename from java/com/google/gerrit/server/account/GetEmails.java
rename to java/com/google/gerrit/server/restapi/account/GetEmails.java
index 184780f..9c482a3 100644
--- a/java/com/google/gerrit/server/account/GetEmails.java
+++ b/java/com/google/gerrit/server/restapi/account/GetEmails.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.EmailInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Singleton;
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/java/com/google/gerrit/server/account/GetExternalIds.java b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
similarity index 96%
rename from java/com/google/gerrit/server/account/GetExternalIds.java
rename to java/com/google/gerrit/server/restapi/account/GetExternalIds.java
index 709bfc3..8e456a2 100644
--- a/java/com/google/gerrit/server/account/GetExternalIds.java
+++ b/java/com/google/gerrit/server/restapi/account/GetExternalIds.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
 
@@ -22,6 +22,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.account.externalids.ExternalIds;
 import com.google.gerrit.server.config.AuthConfig;
diff --git a/java/com/google/gerrit/server/account/GetGroups.java b/java/com/google/gerrit/server/restapi/account/GetGroups.java
similarity index 90%
rename from java/com/google/gerrit/server/account/GetGroups.java
rename to java/com/google/gerrit/server/restapi/account/GetGroups.java
index 757cb44d..992a85a 100644
--- a/java/com/google/gerrit/server/account/GetGroups.java
+++ b/java/com/google/gerrit/server/restapi/account/GetGroups.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.common.errors.NoSuchGroupException;
 import com.google.gerrit.extensions.common.GroupInfo;
@@ -20,7 +20,9 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.group.GroupJson;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.restapi.group.GroupJson;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/account/GetName.java b/java/com/google/gerrit/server/restapi/account/GetName.java
similarity index 89%
rename from java/com/google/gerrit/server/account/GetName.java
rename to java/com/google/gerrit/server/restapi/account/GetName.java
index 7add77a..bdf379e 100644
--- a/java/com/google/gerrit/server/account/GetName.java
+++ b/java/com/google/gerrit/server/restapi/account/GetName.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/account/GetOAuthToken.java b/java/com/google/gerrit/server/restapi/account/GetOAuthToken.java
similarity index 96%
rename from java/com/google/gerrit/server/account/GetOAuthToken.java
rename to java/com/google/gerrit/server/restapi/account/GetOAuthToken.java
index 587f268..43838e8 100644
--- a/java/com/google/gerrit/server/account/GetOAuthToken.java
+++ b/java/com/google/gerrit/server/restapi/account/GetOAuthToken.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.auth.oauth.OAuthToken;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.auth.oauth.OAuthTokenCache;
 import com.google.gerrit.server.config.CanonicalWebUrl;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/account/GetPreferences.java b/java/com/google/gerrit/server/restapi/account/GetPreferences.java
similarity index 92%
rename from java/com/google/gerrit/server/account/GetPreferences.java
rename to java/com/google/gerrit/server/restapi/account/GetPreferences.java
index 3ebf864..b071ade 100644
--- a/java/com/google/gerrit/server/account/GetPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/GetPreferences.java
@@ -12,13 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/GetSshKey.java b/java/com/google/gerrit/server/restapi/account/GetSshKey.java
similarity index 90%
rename from java/com/google/gerrit/server/account/GetSshKey.java
rename to java/com/google/gerrit/server/restapi/account/GetSshKey.java
index ee75432..dc72663 100644
--- a/java/com/google/gerrit/server/account/GetSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/GetSshKey.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.SshKeyInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AccountResource.SshKey;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/account/GetSshKeys.java b/java/com/google/gerrit/server/restapi/account/GetSshKeys.java
similarity index 94%
rename from java/com/google/gerrit/server/account/GetSshKeys.java
rename to java/com/google/gerrit/server/restapi/account/GetSshKeys.java
index 9f5b9d5..362812c 100644
--- a/java/com/google/gerrit/server/account/GetSshKeys.java
+++ b/java/com/google/gerrit/server/restapi/account/GetSshKeys.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
@@ -22,6 +22,8 @@
 import com.google.gerrit.reviewdb.client.AccountSshKey;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAuthorizedKeys;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/GetStatus.java b/java/com/google/gerrit/server/restapi/account/GetStatus.java
similarity index 89%
rename from java/com/google/gerrit/server/account/GetStatus.java
rename to java/com/google/gerrit/server/restapi/account/GetStatus.java
index 5d57c4c..bc7094f 100644
--- a/java/com/google/gerrit/server/account/GetStatus.java
+++ b/java/com/google/gerrit/server/restapi/account/GetStatus.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/account/GetUsername.java b/java/com/google/gerrit/server/restapi/account/GetUsername.java
similarity index 91%
rename from java/com/google/gerrit/server/account/GetUsername.java
rename to java/com/google/gerrit/server/restapi/account/GetUsername.java
index 6541f55..34eb701 100644
--- a/java/com/google/gerrit/server/account/GetUsername.java
+++ b/java/com/google/gerrit/server/restapi/account/GetUsername.java
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/account/GetWatchedProjects.java b/java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java
similarity index 95%
rename from java/com/google/gerrit/server/account/GetWatchedProjects.java
rename to java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java
index c2c0547..b465029 100644
--- a/java/com/google/gerrit/server/account/GetWatchedProjects.java
+++ b/java/com/google/gerrit/server/restapi/account/GetWatchedProjects.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ComparisonChain;
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.WatchConfig;
 import com.google.gerrit.server.account.WatchConfig.NotifyType;
 import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
 import com.google.gerrit.server.permissions.GlobalPermission;
diff --git a/java/com/google/gerrit/server/account/Index.java b/java/com/google/gerrit/server/restapi/account/Index.java
similarity index 92%
rename from java/com/google/gerrit/server/account/Index.java
rename to java/com/google/gerrit/server/restapi/account/Index.java
index 8436d1d..2f4a87c 100644
--- a/java/com/google/gerrit/server/account/Index.java
+++ b/java/com/google/gerrit/server/restapi/account/Index.java
@@ -12,13 +12,15 @@
 //See the License for the specific language governing permissions and
 //limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/Module.java b/java/com/google/gerrit/server/restapi/account/Module.java
similarity index 98%
rename from java/com/google/gerrit/server/account/Module.java
rename to java/com/google/gerrit/server/restapi/account/Module.java
index 44060be..dad84e5 100644
--- a/java/com/google/gerrit/server/account/Module.java
+++ b/java/com/google/gerrit/server/restapi/account/Module.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.account.AccountResource.ACCOUNT_KIND;
 import static com.google.gerrit.server.account.AccountResource.CAPABILITY_KIND;
diff --git a/java/com/google/gerrit/server/account/PostWatchedProjects.java b/java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java
similarity index 94%
rename from java/com/google/gerrit/server/account/PostWatchedProjects.java
rename to java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java
index 38887f6..145ce0e 100644
--- a/java/com/google/gerrit/server/account/PostWatchedProjects.java
+++ b/java/com/google/gerrit/server/restapi/account/PostWatchedProjects.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.client.ProjectWatchInfo;
 import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -21,12 +21,15 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.WatchConfig;
 import com.google.gerrit.server.account.WatchConfig.NotifyType;
 import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ProjectsCollection;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/account/PutAccount.java b/java/com/google/gerrit/server/restapi/account/PutAccount.java
similarity index 91%
rename from java/com/google/gerrit/server/account/PutAccount.java
rename to java/com/google/gerrit/server/restapi/account/PutAccount.java
index da5a58f..4c84c19 100644
--- a/java/com/google/gerrit/server/account/PutAccount.java
+++ b/java/com/google/gerrit/server/restapi/account/PutAccount.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.api.accounts.AccountInput;
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/account/PutActive.java b/java/com/google/gerrit/server/restapi/account/PutActive.java
similarity index 91%
rename from java/com/google/gerrit/server/account/PutActive.java
rename to java/com/google/gerrit/server/restapi/account/PutActive.java
index cbfa172..147b20f 100644
--- a/java/com/google/gerrit/server/account/PutActive.java
+++ b/java/com/google/gerrit/server/restapi/account/PutActive.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -20,6 +20,8 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.SetInactiveFlag;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/account/PutAgreement.java b/java/com/google/gerrit/server/restapi/account/PutAgreement.java
similarity index 95%
rename from java/com/google/gerrit/server/account/PutAgreement.java
rename to java/com/google/gerrit/server/restapi/account/PutAgreement.java
index dab05a4..ae84081 100644
--- a/java/com/google/gerrit/server/account/PutAgreement.java
+++ b/java/com/google/gerrit/server/restapi/account/PutAgreement.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableSet;
@@ -30,10 +30,11 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.extensions.events.AgreementSignup;
-import com.google.gerrit.server.group.AddMembers;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.restapi.group.AddMembers;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/account/PutEmail.java b/java/com/google/gerrit/server/restapi/account/PutEmail.java
similarity index 91%
rename from java/com/google/gerrit/server/account/PutEmail.java
rename to java/com/google/gerrit/server/restapi/account/PutEmail.java
index acdbbf4..6ee9003 100644
--- a/java/com/google/gerrit/server/account/PutEmail.java
+++ b/java/com/google/gerrit/server/restapi/account/PutEmail.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.api.accounts.EmailInput;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/account/PutHttpPassword.java b/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
similarity index 96%
rename from java/com/google/gerrit/server/account/PutHttpPassword.java
rename to java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
index 1d36e9d..25b3f76 100644
--- a/java/com/google/gerrit/server/account/PutHttpPassword.java
+++ b/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
 
@@ -25,6 +25,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.AccountsUpdate;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.account.externalids.ExternalIds;
 import com.google.gerrit.server.permissions.GlobalPermission;
diff --git a/java/com/google/gerrit/server/account/PutName.java b/java/com/google/gerrit/server/restapi/account/PutName.java
similarity index 94%
rename from java/com/google/gerrit/server/account/PutName.java
rename to java/com/google/gerrit/server/restapi/account/PutName.java
index b63c548..4981e7a 100644
--- a/java/com/google/gerrit/server/account/PutName.java
+++ b/java/com/google/gerrit/server/restapi/account/PutName.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.client.AccountFieldName;
@@ -25,6 +25,9 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.AccountsUpdate;
+import com.google.gerrit.server.account.Realm;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/PutPreferred.java b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
similarity index 95%
rename from java/com/google/gerrit/server/account/PutPreferred.java
rename to java/com/google/gerrit/server/restapi/account/PutPreferred.java
index 40e2f7a..b66a611 100644
--- a/java/com/google/gerrit/server/account/PutPreferred.java
+++ b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -22,6 +22,8 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.AccountsUpdate;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/PutStatus.java b/java/com/google/gerrit/server/restapi/account/PutStatus.java
similarity index 94%
rename from java/com/google/gerrit/server/account/PutStatus.java
rename to java/com/google/gerrit/server/restapi/account/PutStatus.java
index 85db1da..23958a2 100644
--- a/java/com/google/gerrit/server/account/PutStatus.java
+++ b/java/com/google/gerrit/server/restapi/account/PutStatus.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.api.accounts.StatusInput;
@@ -23,6 +23,8 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.AccountsUpdate;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/PutUsername.java b/java/com/google/gerrit/server/restapi/account/PutUsername.java
similarity index 92%
rename from java/com/google/gerrit/server/account/PutUsername.java
rename to java/com/google/gerrit/server/restapi/account/PutUsername.java
index f4ff79d..646fd44 100644
--- a/java/com/google/gerrit/server/account/PutUsername.java
+++ b/java/com/google/gerrit/server/restapi/account/PutUsername.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.common.errors.NameAlreadyUsedException;
 import com.google.gerrit.extensions.api.accounts.UsernameInput;
@@ -23,6 +23,10 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.ChangeUserName;
+import com.google.gerrit.server.account.InvalidUserNameException;
+import com.google.gerrit.server.account.Realm;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/QueryAccounts.java b/java/com/google/gerrit/server/restapi/account/QueryAccounts.java
similarity index 96%
rename from java/com/google/gerrit/server/account/QueryAccounts.java
rename to java/com/google/gerrit/server/restapi/account/QueryAccounts.java
index 88f0bbc..f508fa2 100644
--- a/java/com/google/gerrit/server/account/QueryAccounts.java
+++ b/java/com/google/gerrit/server/restapi/account/QueryAccounts.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
@@ -28,6 +28,9 @@
 import com.google.gerrit.index.query.QueryResult;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.account.AccountDirectory.FillOptions;
+import com.google.gerrit.server.account.AccountInfoComparator;
+import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.account.AccountState;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.query.account.AccountPredicates;
 import com.google.gerrit.server.query.account.AccountQueryBuilder;
diff --git a/java/com/google/gerrit/server/account/SetDiffPreferences.java b/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
similarity index 91%
rename from java/com/google/gerrit/server/account/SetDiffPreferences.java
rename to java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
index 88e9e20..c16e0f2 100644
--- a/java/com/google/gerrit/server/account/SetDiffPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetDiffPreferences.java
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
-import static com.google.gerrit.server.account.GetDiffPreferences.readDefaultsFromGit;
-import static com.google.gerrit.server.account.GetDiffPreferences.readFromGit;
 import static com.google.gerrit.server.config.ConfigUtil.loadSection;
 import static com.google.gerrit.server.config.ConfigUtil.storeSection;
+import static com.google.gerrit.server.restapi.account.GetDiffPreferences.readDefaultsFromGit;
+import static com.google.gerrit.server.restapi.account.GetDiffPreferences.readFromGit;
 
 import com.google.gerrit.extensions.client.DiffPreferencesInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -25,6 +25,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAccountPreferences;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MetaDataUpdate;
diff --git a/java/com/google/gerrit/server/account/SetEditPreferences.java b/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
similarity index 93%
rename from java/com/google/gerrit/server/account/SetEditPreferences.java
rename to java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
index 53285db..3574377 100644
--- a/java/com/google/gerrit/server/account/SetEditPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetEditPreferences.java
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
-import static com.google.gerrit.server.account.GetEditPreferences.readFromGit;
 import static com.google.gerrit.server.config.ConfigUtil.loadSection;
 import static com.google.gerrit.server.config.ConfigUtil.storeSection;
+import static com.google.gerrit.server.restapi.account.GetEditPreferences.readFromGit;
 
 import com.google.gerrit.extensions.client.EditPreferencesInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -24,6 +24,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAccountPreferences;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MetaDataUpdate;
diff --git a/java/com/google/gerrit/server/account/SetPreferences.java b/java/com/google/gerrit/server/restapi/account/SetPreferences.java
similarity index 95%
rename from java/com/google/gerrit/server/account/SetPreferences.java
rename to java/com/google/gerrit/server/restapi/account/SetPreferences.java
index d25a5a7..2c9f97a 100644
--- a/java/com/google/gerrit/server/account/SetPreferences.java
+++ b/java/com/google/gerrit/server/restapi/account/SetPreferences.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import static com.google.gerrit.server.config.ConfigUtil.storeSection;
 import static com.google.gerrit.server.git.UserConfigSections.CHANGE_TABLE_COLUMN;
@@ -34,6 +34,10 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.GeneralPreferencesLoader;
+import com.google.gerrit.server.account.VersionedAccountPreferences;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.UserConfigSections;
diff --git a/java/com/google/gerrit/server/account/SshKeys.java b/java/com/google/gerrit/server/restapi/account/SshKeys.java
similarity index 95%
rename from java/com/google/gerrit/server/account/SshKeys.java
rename to java/com/google/gerrit/server/restapi/account/SshKeys.java
index 70c02a1..20fd5cc 100644
--- a/java/com/google/gerrit/server/account/SshKeys.java
+++ b/java/com/google/gerrit/server/restapi/account/SshKeys.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -23,6 +23,8 @@
 import com.google.gerrit.reviewdb.client.AccountSshKey;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountResource;
+import com.google.gerrit.server.account.VersionedAuthorizedKeys;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/account/StarredChanges.java b/java/com/google/gerrit/server/restapi/account/StarredChanges.java
similarity index 96%
rename from java/com/google/gerrit/server/account/StarredChanges.java
rename to java/com/google/gerrit/server/restapi/account/StarredChanges.java
index 6dfd132..f908d9f 100644
--- a/java/com/google/gerrit/server/account/StarredChanges.java
+++ b/java/com/google/gerrit/server/restapi/account/StarredChanges.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AcceptsCreate;
@@ -34,10 +34,11 @@
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
 import com.google.gerrit.server.StarredChangesUtil.MutuallyExclusiveLabelsException;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ChangesCollection;
-import com.google.gerrit.server.change.QueryChanges;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.QueryChanges;
 import com.google.gwtorm.server.OrmDuplicateKeyException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/account/Stars.java b/java/com/google/gerrit/server/restapi/account/Stars.java
similarity index 95%
rename from java/com/google/gerrit/server/account/Stars.java
rename to java/com/google/gerrit/server/restapi/account/Stars.java
index 5eb8d7b..2ee6aef 100644
--- a/java/com/google/gerrit/server/account/Stars.java
+++ b/java/com/google/gerrit/server/restapi/account/Stars.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.account;
+package com.google.gerrit.server.restapi.account;
 
 import com.google.gerrit.extensions.api.changes.StarsInput;
 import com.google.gerrit.extensions.common.ChangeInfo;
@@ -30,11 +30,12 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
+import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AccountResource.Star;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ChangesCollection;
-import com.google.gerrit.server.change.QueryChanges;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.QueryChanges;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/Abandon.java b/java/com/google/gerrit/server/restapi/change/Abandon.java
similarity index 95%
rename from java/com/google/gerrit/server/change/Abandon.java
rename to java/com/google/gerrit/server/restapi/change/Abandon.java
index f07efea..5e2b166 100644
--- a/java/com/google/gerrit/server/change/Abandon.java
+++ b/java/com/google/gerrit/server/restapi/change/Abandon.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 
@@ -29,6 +29,10 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.AbandonOp;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.NotifyUtil;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/AllowedFormats.java b/java/com/google/gerrit/server/restapi/change/AllowedFormats.java
similarity index 94%
rename from java/com/google/gerrit/server/change/AllowedFormats.java
rename to java/com/google/gerrit/server/restapi/change/AllowedFormats.java
index 20e586f..2e313a1 100644
--- a/java/com/google/gerrit/server/change/AllowedFormats.java
+++ b/java/com/google/gerrit/server/restapi/change/AllowedFormats.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
+import com.google.gerrit.server.change.ArchiveFormat;
 import com.google.gerrit.server.config.DownloadConfig;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/ApplyFix.java b/java/com/google/gerrit/server/restapi/change/ApplyFix.java
similarity index 95%
rename from java/com/google/gerrit/server/change/ApplyFix.java
rename to java/com/google/gerrit/server/restapi/change/ApplyFix.java
index fa26eec..e4940ec 100644
--- a/java/com/google/gerrit/server/change/ApplyFix.java
+++ b/java/com/google/gerrit/server/restapi/change/ApplyFix.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.EditInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -22,6 +22,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.change.FixResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.edit.ChangeEdit;
 import com.google.gerrit.server.edit.ChangeEditJson;
 import com.google.gerrit.server.edit.ChangeEditModifier;
diff --git a/java/com/google/gerrit/server/change/ChangeEdits.java b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java
similarity index 97%
rename from java/com/google/gerrit/server/change/ChangeEdits.java
rename to java/com/google/gerrit/server/restapi/change/ChangeEdits.java
index 1ca98b7..334b7aa 100644
--- a/java/com/google/gerrit/server/change/ChangeEdits.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.common.DiffWebLinkInfo;
@@ -40,6 +40,12 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.WebLinks;
+import com.google.gerrit.server.change.ChangeEditResource;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.FileContentUtil;
+import com.google.gerrit.server.change.FileInfoJson;
+import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.server.change.Revisions;
 import com.google.gerrit.server.edit.ChangeEdit;
 import com.google.gerrit.server.edit.ChangeEditJson;
 import com.google.gerrit.server.edit.ChangeEditModifier;
diff --git a/java/com/google/gerrit/server/change/ChangeIncludedIn.java b/java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java
similarity index 91%
rename from java/com/google/gerrit/server/change/ChangeIncludedIn.java
rename to java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java
index 47f5a16..12b3797 100644
--- a/java/com/google/gerrit/server/change/ChangeIncludedIn.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.IncludedInInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
@@ -20,6 +20,8 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.IncludedIn;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/ChangesCollection.java b/java/com/google/gerrit/server/restapi/change/ChangesCollection.java
similarity index 97%
rename from java/com/google/gerrit/server/change/ChangesCollection.java
rename to java/com/google/gerrit/server/restapi/change/ChangesCollection.java
index 6ce661e..9203134 100644
--- a/java/com/google/gerrit/server/change/ChangesCollection.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangesCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AcceptsPost;
@@ -27,6 +27,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeFinder;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/change/Check.java b/java/com/google/gerrit/server/restapi/change/Check.java
similarity index 94%
rename from java/com/google/gerrit/server/change/Check.java
rename to java/com/google/gerrit/server/restapi/change/Check.java
index c07659f..15f013d 100644
--- a/java/com/google/gerrit/server/change/Check.java
+++ b/java/com/google/gerrit/server/restapi/change/Check.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.FixInput;
 import com.google.gerrit.extensions.client.ListChangesOption;
@@ -23,6 +23,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/CherryPick.java b/java/com/google/gerrit/server/restapi/change/CherryPick.java
similarity index 96%
rename from java/com/google/gerrit/server/change/CherryPick.java
rename to java/com/google/gerrit/server/restapi/change/CherryPick.java
index 7fffd3a..c1479b7 100644
--- a/java/com/google/gerrit/server/change/CherryPick.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPick.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 
@@ -26,6 +26,8 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.IntegrationException;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/CherryPickChange.java b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
similarity index 98%
rename from java/com/google/gerrit/server/change/CherryPickChange.java
rename to java/com/google/gerrit/server/restapi/change/CherryPickChange.java
index 8b84f2b..279cc57 100644
--- a/java/com/google/gerrit/server/change/CherryPickChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.FooterConstants;
@@ -39,6 +39,9 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.ReviewerSet;
 import com.google.gerrit.server.Sequences;
+import com.google.gerrit.server.change.ChangeInserter;
+import com.google.gerrit.server.change.NotifyUtil;
+import com.google.gerrit.server.change.PatchSetInserter;
 import com.google.gerrit.server.git.CodeReviewCommit;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
 import com.google.gerrit.server.git.GitRepositoryManager;
diff --git a/java/com/google/gerrit/server/change/CherryPickCommit.java b/java/com/google/gerrit/server/restapi/change/CherryPickCommit.java
similarity index 97%
rename from java/com/google/gerrit/server/change/CherryPickCommit.java
rename to java/com/google/gerrit/server/restapi/change/CherryPickCommit.java
index 4980975..039c3ca6 100644
--- a/java/com/google/gerrit/server/change/CherryPickCommit.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPickCommit.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.api.changes.CherryPickInput;
@@ -25,6 +25,7 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.ChangeJson;
 import com.google.gerrit.server.git.IntegrationException;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/CommentJson.java b/java/com/google/gerrit/server/restapi/change/CommentJson.java
similarity index 99%
rename from java/com/google/gerrit/server/change/CommentJson.java
rename to java/com/google/gerrit/server/restapi/change/CommentJson.java
index 0ebd84b..4d06c73 100644
--- a/java/com/google/gerrit/server/change/CommentJson.java
+++ b/java/com/google/gerrit/server/restapi/change/CommentJson.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.server.CommentsUtil.COMMENT_INFO_ORDER;
 import static java.util.stream.Collectors.toList;
diff --git a/java/com/google/gerrit/server/change/Comments.java b/java/com/google/gerrit/server/restapi/change/Comments.java
similarity index 93%
rename from java/com/google/gerrit/server/change/Comments.java
rename to java/com/google/gerrit/server/restapi/change/Comments.java
index 935aa4e..f563cc6 100644
--- a/java/com/google/gerrit/server/change/Comments.java
+++ b/java/com/google/gerrit/server/restapi/change/Comments.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -22,6 +22,8 @@
 import com.google.gerrit.reviewdb.client.Comment;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.CommentResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/CreateChange.java b/java/com/google/gerrit/server/restapi/change/CreateChange.java
similarity index 97%
rename from java/com/google/gerrit/server/change/CreateChange.java
rename to java/com/google/gerrit/server/restapi/change/CreateChange.java
index 56ad000..d4e1c40 100644
--- a/java/com/google/gerrit/server/change/CreateChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateChange.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static org.eclipse.jgit.lib.Constants.SIGNED_OFF_BY_TAG;
 
@@ -47,6 +47,9 @@
 import com.google.gerrit.server.Sequences;
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.change.ChangeInserter;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.NotifyUtil;
 import com.google.gerrit.server.config.AnonymousCowardName;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.GitRepositoryManager;
@@ -56,12 +59,12 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
-import com.google.gerrit.server.project.CommitsCollection;
 import com.google.gerrit.server.project.ContributorAgreementsChecker;
 import com.google.gerrit.server.project.InvalidChangeOperationException;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.ProjectState;
-import com.google.gerrit.server.project.ProjectsCollection;
+import com.google.gerrit.server.restapi.project.CommitsCollection;
+import com.google.gerrit.server.restapi.project.ProjectsCollection;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.RetryingRestModifyView;
diff --git a/java/com/google/gerrit/server/change/CreateDraftComment.java b/java/com/google/gerrit/server/restapi/change/CreateDraftComment.java
similarity index 97%
rename from java/com/google/gerrit/server/change/CreateDraftComment.java
rename to java/com/google/gerrit/server/restapi/change/CreateDraftComment.java
index 002c8b7..afcc8f7 100644
--- a/java/com/google/gerrit/server/change/CreateDraftComment.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateDraftComment.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.server.CommentsUtil.setCommentRevId;
 
@@ -32,6 +32,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.patch.PatchListCache;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
diff --git a/java/com/google/gerrit/server/change/CreateMergePatchSet.java b/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
similarity index 97%
rename from java/com/google/gerrit/server/change/CreateMergePatchSet.java
rename to java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
index 35a57cb..33a7453 100644
--- a/java/com/google/gerrit/server/change/CreateMergePatchSet.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
@@ -41,6 +41,9 @@
 import com.google.gerrit.server.GerritPersonIdent;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.PatchSetInserter;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MergeIdenticalTreeException;
 import com.google.gerrit.server.git.MergeUtil;
@@ -48,10 +51,10 @@
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.CommitsCollection;
 import com.google.gerrit.server.project.InvalidChangeOperationException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.project.CommitsCollection;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.RetryingRestModifyView;
diff --git a/java/com/google/gerrit/server/change/DeleteAssignee.java b/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
similarity index 97%
rename from java/com/google/gerrit/server/change/DeleteAssignee.java
rename to java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
index 8d8d72e..2eae7ad 100644
--- a/java/com/google/gerrit/server/change/DeleteAssignee.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.extensions.common.AccountInfo;
@@ -26,6 +26,7 @@
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.extensions.events.AssigneeChanged;
 import com.google.gerrit.server.notedb.ChangeUpdate;
 import com.google.gerrit.server.permissions.ChangePermission;
diff --git a/java/com/google/gerrit/server/change/DeleteChange.java b/java/com/google/gerrit/server/restapi/change/DeleteChange.java
similarity index 96%
rename from java/com/google/gerrit/server/change/DeleteChange.java
rename to java/com/google/gerrit/server/restapi/change/DeleteChange.java
index 69f6178..e33b4a4 100644
--- a/java/com/google/gerrit/server/change/DeleteChange.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteChange.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 
@@ -24,6 +24,7 @@
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/DeleteChangeEdit.java b/java/com/google/gerrit/server/restapi/change/DeleteChangeEdit.java
similarity index 94%
rename from java/com/google/gerrit/server/change/DeleteChangeEdit.java
rename to java/com/google/gerrit/server/restapi/change/DeleteChangeEdit.java
index 480aca1..942b191 100644
--- a/java/com/google/gerrit/server/change/DeleteChangeEdit.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteChangeEdit.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.edit.ChangeEdit;
 import com.google.gerrit.server.edit.ChangeEditUtil;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/DeleteChangeOp.java b/java/com/google/gerrit/server/restapi/change/DeleteChangeOp.java
similarity index 97%
rename from java/com/google/gerrit/server/change/DeleteChangeOp.java
rename to java/com/google/gerrit/server/restapi/change/DeleteChangeOp.java
index 130d040..1853853 100644
--- a/java/com/google/gerrit/server/change/DeleteChangeOp.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteChangeOp.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkState;
 
@@ -25,6 +25,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.StarredChangesUtil;
+import com.google.gerrit.server.change.AccountPatchReviewStore;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.BatchUpdateReviewDb;
diff --git a/java/com/google/gerrit/server/change/DeleteComment.java b/java/com/google/gerrit/server/restapi/change/DeleteComment.java
similarity index 97%
rename from java/com/google/gerrit/server/change/DeleteComment.java
rename to java/com/google/gerrit/server/restapi/change/DeleteComment.java
index 17665b0..4320cd6 100644
--- a/java/com/google/gerrit/server/change/DeleteComment.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteComment.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.TimeUtil;
@@ -26,6 +26,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.CommentResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/change/DeleteDraftComment.java b/java/com/google/gerrit/server/restapi/change/DeleteDraftComment.java
similarity index 97%
rename from java/com/google/gerrit/server/change/DeleteDraftComment.java
rename to java/com/google/gerrit/server/restapi/change/DeleteDraftComment.java
index 6d82139..ee57c20 100644
--- a/java/com/google/gerrit/server/change/DeleteDraftComment.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteDraftComment.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.server.CommentsUtil.setCommentRevId;
 
@@ -27,6 +27,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.DraftCommentResource;
 import com.google.gerrit.server.patch.PatchListCache;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
diff --git a/java/com/google/gerrit/server/change/DeletePrivate.java b/java/com/google/gerrit/server/restapi/change/DeletePrivate.java
similarity index 96%
rename from java/com/google/gerrit/server/change/DeletePrivate.java
rename to java/com/google/gerrit/server/restapi/change/DeletePrivate.java
index ba5403a..4ff1b66 100644
--- a/java/com/google/gerrit/server/change/DeletePrivate.java
+++ b/java/com/google/gerrit/server/restapi/change/DeletePrivate.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.or;
 
@@ -24,6 +24,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.update.BatchUpdate;
diff --git a/java/com/google/gerrit/server/change/DeletePrivateByPost.java b/java/com/google/gerrit/server/restapi/change/DeletePrivateByPost.java
similarity index 94%
rename from java/com/google/gerrit/server/change/DeletePrivateByPost.java
rename to java/com/google/gerrit/server/restapi/change/DeletePrivateByPost.java
index a392492..cf0143a 100644
--- a/java/com/google/gerrit/server/change/DeletePrivateByPost.java
+++ b/java/com/google/gerrit/server/restapi/change/DeletePrivateByPost.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/DeleteReviewer.java b/java/com/google/gerrit/server/restapi/change/DeleteReviewer.java
similarity index 96%
rename from java/com/google/gerrit/server/change/DeleteReviewer.java
rename to java/com/google/gerrit/server/restapi/change/DeleteReviewer.java
index c2bcd69..3210a95 100644
--- a/java/com/google/gerrit/server/change/DeleteReviewer.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteReviewer.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.extensions.api.changes.DeleteReviewerInput;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.RetryHelper;
diff --git a/java/com/google/gerrit/server/change/DeleteReviewerByEmailOp.java b/java/com/google/gerrit/server/restapi/change/DeleteReviewerByEmailOp.java
similarity index 97%
rename from java/com/google/gerrit/server/change/DeleteReviewerByEmailOp.java
rename to java/com/google/gerrit/server/restapi/change/DeleteReviewerByEmailOp.java
index c8b5bea..f06709d 100644
--- a/java/com/google/gerrit/server/change/DeleteReviewerByEmailOp.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteReviewerByEmailOp.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.DeleteReviewerInput;
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
@@ -20,6 +20,7 @@
 import com.google.gerrit.reviewdb.client.ChangeMessage;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.change.NotifyUtil;
 import com.google.gerrit.server.mail.Address;
 import com.google.gerrit.server.mail.send.DeleteReviewerSender;
 import com.google.gerrit.server.update.BatchUpdateOp;
diff --git a/java/com/google/gerrit/server/change/DeleteReviewerOp.java b/java/com/google/gerrit/server/restapi/change/DeleteReviewerOp.java
similarity index 98%
rename from java/com/google/gerrit/server/change/DeleteReviewerOp.java
rename to java/com/google/gerrit/server/restapi/change/DeleteReviewerOp.java
index a398195..aac16660 100644
--- a/java/com/google/gerrit/server/change/DeleteReviewerOp.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteReviewerOp.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.Iterables;
 import com.google.gerrit.common.data.LabelType;
@@ -33,6 +33,7 @@
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.NotifyUtil;
 import com.google.gerrit.server.extensions.events.ReviewerDeleted;
 import com.google.gerrit.server.mail.send.DeleteReviewerSender;
 import com.google.gerrit.server.notedb.ChangeUpdate;
diff --git a/java/com/google/gerrit/server/change/DeleteVote.java b/java/com/google/gerrit/server/restapi/change/DeleteVote.java
similarity index 97%
rename from java/com/google/gerrit/server/change/DeleteVote.java
rename to java/com/google/gerrit/server/restapi/change/DeleteVote.java
index 8c6c3cc..268425e 100644
--- a/java/com/google/gerrit/server/change/DeleteVote.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteVote.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -37,6 +37,9 @@
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.NotifyUtil;
+import com.google.gerrit.server.change.ReviewerResource;
+import com.google.gerrit.server.change.VoteResource;
 import com.google.gerrit.server.extensions.events.VoteDeleted;
 import com.google.gerrit.server.mail.send.DeleteVoteSender;
 import com.google.gerrit.server.mail.send.ReplyToChangeSender;
diff --git a/java/com/google/gerrit/server/change/DownloadContent.java b/java/com/google/gerrit/server/restapi/change/DownloadContent.java
similarity index 89%
rename from java/com/google/gerrit/server/change/DownloadContent.java
rename to java/com/google/gerrit/server/restapi/change/DownloadContent.java
index 311a25c..b6564c0 100644
--- a/java/com/google/gerrit/server/change/DownloadContent.java
+++ b/java/com/google/gerrit/server/restapi/change/DownloadContent.java
@@ -12,11 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.restapi.BinaryResult;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.FileContentUtil;
+import com.google.gerrit.server.change.FileResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/DraftComments.java b/java/com/google/gerrit/server/restapi/change/DraftComments.java
similarity index 94%
rename from java/com/google/gerrit/server/change/DraftComments.java
rename to java/com/google/gerrit/server/restapi/change/DraftComments.java
index 4befc5b..b8e24a5 100644
--- a/java/com/google/gerrit/server/change/DraftComments.java
+++ b/java/com/google/gerrit/server/restapi/change/DraftComments.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -24,6 +24,8 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.DraftCommentResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/Files.java b/java/com/google/gerrit/server/restapi/change/Files.java
similarity index 97%
rename from java/com/google/gerrit/server/change/Files.java
rename to java/com/google/gerrit/server/restapi/change/Files.java
index c167e31..8d24942 100644
--- a/java/com/google/gerrit/server/change/Files.java
+++ b/java/com/google/gerrit/server/restapi/change/Files.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.Lists;
 import com.google.common.hash.Hasher;
@@ -36,7 +36,12 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.AccountPatchReviewStore;
 import com.google.gerrit.server.change.AccountPatchReviewStore.PatchSetWithReviewedFiles;
+import com.google.gerrit.server.change.FileInfoJson;
+import com.google.gerrit.server.change.FileResource;
+import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.server.change.Revisions;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.patch.PatchList;
 import com.google.gerrit.server.patch.PatchListCache;
diff --git a/java/com/google/gerrit/server/change/Fixes.java b/java/com/google/gerrit/server/restapi/change/Fixes.java
similarity index 93%
rename from java/com/google/gerrit/server/change/Fixes.java
rename to java/com/google/gerrit/server/restapi/change/Fixes.java
index af9f60a..1d8726d 100644
--- a/java/com/google/gerrit/server/change/Fixes.java
+++ b/java/com/google/gerrit/server/restapi/change/Fixes.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -22,6 +22,8 @@
 import com.google.gerrit.reviewdb.client.FixSuggestion;
 import com.google.gerrit.reviewdb.client.RobotComment;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.FixResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/GetArchive.java b/java/com/google/gerrit/server/restapi/change/GetArchive.java
similarity index 95%
rename from java/com/google/gerrit/server/change/GetArchive.java
rename to java/com/google/gerrit/server/restapi/change/GetArchive.java
index 7269a60..1bd1bce 100644
--- a/java/com/google/gerrit/server/change/GetArchive.java
+++ b/java/com/google/gerrit/server/restapi/change/GetArchive.java
@@ -12,13 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.BinaryResult;
 import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ArchiveFormat;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/change/GetAssignee.java b/java/com/google/gerrit/server/restapi/change/GetAssignee.java
similarity index 93%
rename from java/com/google/gerrit/server/change/GetAssignee.java
rename to java/com/google/gerrit/server/restapi/change/GetAssignee.java
index d491b91..f78fae2 100644
--- a/java/com/google/gerrit/server/change/GetAssignee.java
+++ b/java/com/google/gerrit/server/restapi/change/GetAssignee.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/GetBlame.java b/java/com/google/gerrit/server/restapi/change/GetBlame.java
similarity index 98%
rename from java/com/google/gerrit/server/change/GetBlame.java
rename to java/com/google/gerrit/server/restapi/change/GetBlame.java
index 4702b5a..6bba936 100644
--- a/java/com/google/gerrit/server/change/GetBlame.java
+++ b/java/com/google/gerrit/server/restapi/change/GetBlame.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.MultimapBuilder;
@@ -25,6 +25,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.change.FileResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MergeUtil;
diff --git a/java/com/google/gerrit/server/change/GetChange.java b/java/com/google/gerrit/server/restapi/change/GetChange.java
similarity index 89%
rename from java/com/google/gerrit/server/change/GetChange.java
rename to java/com/google/gerrit/server/restapi/change/GetChange.java
index 22b0b1c..a8f8bbb 100644
--- a/java/com/google/gerrit/server/change/GetChange.java
+++ b/java/com/google/gerrit/server/restapi/change/GetChange.java
@@ -12,12 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.client.ListChangesOption;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import java.util.EnumSet;
diff --git a/java/com/google/gerrit/server/change/GetComment.java b/java/com/google/gerrit/server/restapi/change/GetComment.java
similarity index 92%
rename from java/com/google/gerrit/server/change/GetComment.java
rename to java/com/google/gerrit/server/restapi/change/GetComment.java
index d601737..b8db6a5 100644
--- a/java/com/google/gerrit/server/change/GetComment.java
+++ b/java/com/google/gerrit/server/restapi/change/GetComment.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.CommentResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/GetCommit.java b/java/com/google/gerrit/server/restapi/change/GetCommit.java
similarity index 93%
rename from java/com/google/gerrit/server/change/GetCommit.java
rename to java/com/google/gerrit/server/restapi/change/GetCommit.java
index 694379e..645d7d1 100644
--- a/java/com/google/gerrit/server/change/GetCommit.java
+++ b/java/com/google/gerrit/server/restapi/change/GetCommit.java
@@ -12,13 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.CommitInfo;
 import com.google.gerrit.extensions.restapi.CacheControl;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/change/GetContent.java b/java/com/google/gerrit/server/restapi/change/GetContent.java
similarity index 96%
rename from java/com/google/gerrit/server/change/GetContent.java
rename to java/com/google/gerrit/server/restapi/change/GetContent.java
index f6b24b8..6b9bf17 100644
--- a/java/com/google/gerrit/server/change/GetContent.java
+++ b/java/com/google/gerrit/server/restapi/change/GetContent.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.BinaryResult;
@@ -23,6 +23,8 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.FileContentUtil;
+import com.google.gerrit.server.change.FileResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.patch.ComparisonType;
diff --git a/java/com/google/gerrit/server/change/GetDescription.java b/java/com/google/gerrit/server/restapi/change/GetDescription.java
similarity index 89%
rename from java/com/google/gerrit/server/change/GetDescription.java
rename to java/com/google/gerrit/server/restapi/change/GetDescription.java
index b8a34d2..1a7ec63 100644
--- a/java/com/google/gerrit/server/change/GetDescription.java
+++ b/java/com/google/gerrit/server/restapi/change/GetDescription.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/change/GetDetail.java b/java/com/google/gerrit/server/restapi/change/GetDetail.java
similarity index 94%
rename from java/com/google/gerrit/server/change/GetDetail.java
rename to java/com/google/gerrit/server/restapi/change/GetDetail.java
index 8213193..ab75ab7 100644
--- a/java/com/google/gerrit/server/change/GetDetail.java
+++ b/java/com/google/gerrit/server/restapi/change/GetDetail.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.client.ListChangesOption;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import org.kohsuke.args4j.Option;
diff --git a/java/com/google/gerrit/server/change/GetDiff.java b/java/com/google/gerrit/server/restapi/change/GetDiff.java
similarity index 98%
rename from java/com/google/gerrit/server/change/GetDiff.java
rename to java/com/google/gerrit/server/restapi/change/GetDiff.java
index 25902b9..29ca382 100644
--- a/java/com/google/gerrit/server/change/GetDiff.java
+++ b/java/com/google/gerrit/server/restapi/change/GetDiff.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkState;
 
@@ -44,6 +44,10 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.WebLinks;
+import com.google.gerrit.server.change.FileContentUtil;
+import com.google.gerrit.server.change.FileResource;
+import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.server.change.Revisions;
 import com.google.gerrit.server.git.LargeObjectException;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.patch.PatchScriptFactory;
diff --git a/java/com/google/gerrit/server/change/GetDraftComment.java b/java/com/google/gerrit/server/restapi/change/GetDraftComment.java
similarity index 91%
rename from java/com/google/gerrit/server/change/GetDraftComment.java
rename to java/com/google/gerrit/server/restapi/change/GetDraftComment.java
index a380ce3..787c93e 100644
--- a/java/com/google/gerrit/server/change/GetDraftComment.java
+++ b/java/com/google/gerrit/server/restapi/change/GetDraftComment.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.DraftCommentResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/GetHashtags.java b/java/com/google/gerrit/server/restapi/change/GetHashtags.java
similarity index 93%
rename from java/com/google/gerrit/server/change/GetHashtags.java
rename to java/com/google/gerrit/server/restapi/change/GetHashtags.java
index c285734..8369acf 100644
--- a/java/com/google/gerrit/server/change/GetHashtags.java
+++ b/java/com/google/gerrit/server/restapi/change/GetHashtags.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/GetMergeList.java b/java/com/google/gerrit/server/restapi/change/GetMergeList.java
similarity index 95%
rename from java/com/google/gerrit/server/change/GetMergeList.java
rename to java/com/google/gerrit/server/restapi/change/GetMergeList.java
index 88677d6..2f3b536 100644
--- a/java/com/google/gerrit/server/change/GetMergeList.java
+++ b/java/com/google/gerrit/server/restapi/change/GetMergeList.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.extensions.common.CommitInfo;
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.patch.MergeListBuilder;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/GetPastAssignees.java b/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
similarity index 94%
rename from java/com/google/gerrit/server/change/GetPastAssignees.java
rename to java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
index 76114ac..354558b 100644
--- a/java/com/google/gerrit/server/change/GetPastAssignees.java
+++ b/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static java.util.stream.Collectors.toList;
 
@@ -21,6 +21,7 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/GetPatch.java b/java/com/google/gerrit/server/restapi/change/GetPatch.java
similarity index 98%
rename from java/com/google/gerrit/server/change/GetPatch.java
rename to java/com/google/gerrit/server/restapi/change/GetPatch.java
index b59c17c..ccad9e0 100644
--- a/java/com/google/gerrit/server/change/GetPatch.java
+++ b/java/com/google/gerrit/server/restapi/change/GetPatch.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/change/GetPureRevert.java b/java/com/google/gerrit/server/restapi/change/GetPureRevert.java
similarity index 91%
rename from java/com/google/gerrit/server/change/GetPureRevert.java
rename to java/com/google/gerrit/server/restapi/change/GetPureRevert.java
index 815ce07..4b26c5c 100644
--- a/java/com/google/gerrit/server/change/GetPureRevert.java
+++ b/java/com/google/gerrit/server/restapi/change/GetPureRevert.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.extensions.common.PureRevertInfo;
@@ -20,6 +20,8 @@
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.PureRevert;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/change/GetRelated.java b/java/com/google/gerrit/server/restapi/change/GetRelated.java
similarity index 97%
rename from java/com/google/gerrit/server/change/GetRelated.java
rename to java/com/google/gerrit/server/restapi/change/GetRelated.java
index 3728b9f..57ec2d9 100644
--- a/java/com/google/gerrit/server/change/GetRelated.java
+++ b/java/com/google/gerrit/server/restapi/change/GetRelated.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static java.util.stream.Collectors.toSet;
 
@@ -29,7 +29,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommonConverters;
 import com.google.gerrit.server.PatchSetUtil;
-import com.google.gerrit.server.change.RelatedChangesSorter.PatchSetData;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchProjectException;
@@ -101,7 +101,7 @@
 
     reloadChangeIfStale(cds, basePs);
 
-    for (PatchSetData d : sorter.sort(cds, basePs, rsrc.getUser())) {
+    for (RelatedChangesSorter.PatchSetData d : sorter.sort(cds, basePs, rsrc.getUser())) {
       PatchSet ps = d.patchSet();
       RevCommit commit;
       if (isEdit && ps.getId().equals(basePs.getId())) {
diff --git a/java/com/google/gerrit/server/change/GetReview.java b/java/com/google/gerrit/server/restapi/change/GetReview.java
similarity index 92%
rename from java/com/google/gerrit/server/change/GetReview.java
rename to java/com/google/gerrit/server/restapi/change/GetReview.java
index f379d83..40e132d 100644
--- a/java/com/google/gerrit/server/change/GetReview.java
+++ b/java/com/google/gerrit/server/restapi/change/GetReview.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.client.ListChangesOption;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/GetReviewer.java b/java/com/google/gerrit/server/restapi/change/GetReviewer.java
similarity index 92%
rename from java/com/google/gerrit/server/change/GetReviewer.java
rename to java/com/google/gerrit/server/restapi/change/GetReviewer.java
index db9af1d..b9b6b09 100644
--- a/java/com/google/gerrit/server/change/GetReviewer.java
+++ b/java/com/google/gerrit/server/restapi/change/GetReviewer.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.ReviewerInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/GetRevisionActions.java b/java/com/google/gerrit/server/restapi/change/GetRevisionActions.java
similarity index 91%
rename from java/com/google/gerrit/server/change/GetRevisionActions.java
rename to java/com/google/gerrit/server/restapi/change/GetRevisionActions.java
index 2a7bd4b..1d6d068 100644
--- a/java/com/google/gerrit/server/change/GetRevisionActions.java
+++ b/java/com/google/gerrit/server/restapi/change/GetRevisionActions.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.hash.Hasher;
 import com.google.common.hash.Hashing;
@@ -21,6 +21,9 @@
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.ActionJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.ChangeSet;
 import com.google.gerrit.server.git.MergeSuperSet;
@@ -68,7 +71,7 @@
     CurrentUser user = rsrc.getUser();
     try {
       rsrc.getChangeResource().prepareETag(h, user);
-      h.putBoolean(Submit.wholeTopicEnabled(config));
+      h.putBoolean(MergeSuperSet.wholeTopicEnabled(config));
       ReviewDb db = dbProvider.get();
       ChangeSet cs = mergeSuperSet.get().completeChangeSet(db, rsrc.getChange(), user);
       for (ChangeData cd : cs.changes()) {
diff --git a/java/com/google/gerrit/server/change/GetRobotComment.java b/java/com/google/gerrit/server/restapi/change/GetRobotComment.java
similarity index 92%
rename from java/com/google/gerrit/server/change/GetRobotComment.java
rename to java/com/google/gerrit/server/restapi/change/GetRobotComment.java
index d4d53ad..bd1f66a 100644
--- a/java/com/google/gerrit/server/change/GetRobotComment.java
+++ b/java/com/google/gerrit/server/restapi/change/GetRobotComment.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.RobotCommentInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.RobotCommentResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/GetTopic.java b/java/com/google/gerrit/server/restapi/change/GetTopic.java
similarity index 89%
rename from java/com/google/gerrit/server/change/GetTopic.java
rename to java/com/google/gerrit/server/restapi/change/GetTopic.java
index 0746588..7ab1cb1 100644
--- a/java/com/google/gerrit/server/change/GetTopic.java
+++ b/java/com/google/gerrit/server/restapi/change/GetTopic.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/change/Ignore.java b/java/com/google/gerrit/server/restapi/change/Ignore.java
similarity index 96%
rename from java/com/google/gerrit/server/change/Ignore.java
rename to java/com/google/gerrit/server/restapi/change/Ignore.java
index c2c2d1f..d710539 100644
--- a/java/com/google/gerrit/server/change/Ignore.java
+++ b/java/com/google/gerrit/server/restapi/change/Ignore.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -24,6 +24,7 @@
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
 import com.google.gerrit.server.StarredChangesUtil.MutuallyExclusiveLabelsException;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/Index.java b/java/com/google/gerrit/server/restapi/change/Index.java
similarity index 95%
rename from java/com/google/gerrit/server/change/Index.java
rename to java/com/google/gerrit/server/restapi/change/Index.java
index 85e13cc..55f53a6 100644
--- a/java/com/google/gerrit/server/change/Index.java
+++ b/java/com/google/gerrit/server/restapi/change/Index.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.index.change.ChangeIndexer;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/change/ListChangeComments.java b/java/com/google/gerrit/server/restapi/change/ListChangeComments.java
similarity index 95%
rename from java/com/google/gerrit/server/change/ListChangeComments.java
rename to java/com/google/gerrit/server/restapi/change/ListChangeComments.java
index 0048657..37dc207 100644
--- a/java/com/google/gerrit/server/change/ListChangeComments.java
+++ b/java/com/google/gerrit/server/restapi/change/ListChangeComments.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/ListChangeDrafts.java b/java/com/google/gerrit/server/restapi/change/ListChangeDrafts.java
similarity index 95%
rename from java/com/google/gerrit/server/change/ListChangeDrafts.java
rename to java/com/google/gerrit/server/restapi/change/ListChangeDrafts.java
index 02713de..d7a102a 100644
--- a/java/com/google/gerrit/server/change/ListChangeDrafts.java
+++ b/java/com/google/gerrit/server/restapi/change/ListChangeDrafts.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -20,6 +20,7 @@
 import com.google.gerrit.reviewdb.client.Comment;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/ListChangeRobotComments.java b/java/com/google/gerrit/server/restapi/change/ListChangeRobotComments.java
similarity index 95%
rename from java/com/google/gerrit/server/change/ListChangeRobotComments.java
rename to java/com/google/gerrit/server/restapi/change/ListChangeRobotComments.java
index fff7f82..dd8de6f 100644
--- a/java/com/google/gerrit/server/change/ListChangeRobotComments.java
+++ b/java/com/google/gerrit/server/restapi/change/ListChangeRobotComments.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.RobotCommentInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/ListReviewers.java b/java/com/google/gerrit/server/restapi/change/ListReviewers.java
similarity index 93%
rename from java/com/google/gerrit/server/change/ListReviewers.java
rename to java/com/google/gerrit/server/restapi/change/ListReviewers.java
index ba2a10b..750e74f 100644
--- a/java/com/google/gerrit/server/change/ListReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/ListReviewers.java
@@ -12,13 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.ReviewerInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.mail.Address;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/ListRevisionComments.java b/java/com/google/gerrit/server/restapi/change/ListRevisionComments.java
similarity index 93%
rename from java/com/google/gerrit/server/change/ListRevisionComments.java
rename to java/com/google/gerrit/server/restapi/change/ListRevisionComments.java
index 037a856..964e560 100644
--- a/java/com/google/gerrit/server/change/ListRevisionComments.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRevisionComments.java
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.reviewdb.client.Comment;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/ListRevisionDrafts.java b/java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java
similarity index 95%
rename from java/com/google/gerrit/server/change/ListRevisionDrafts.java
rename to java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java
index 0463601..b7dc553 100644
--- a/java/com/google/gerrit/server/change/ListRevisionDrafts.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.CommentInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Comment;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/ListRevisionReviewers.java b/java/com/google/gerrit/server/restapi/change/ListRevisionReviewers.java
similarity index 94%
rename from java/com/google/gerrit/server/change/ListRevisionReviewers.java
rename to java/com/google/gerrit/server/restapi/change/ListRevisionReviewers.java
index 6d9dc79..d0630b7 100644
--- a/java/com/google/gerrit/server/change/ListRevisionReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRevisionReviewers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.ReviewerInfo;
 import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
@@ -20,6 +20,8 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
+import com.google.gerrit.server.change.ReviewerResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.mail.Address;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/change/ListRobotComments.java b/java/com/google/gerrit/server/restapi/change/ListRobotComments.java
similarity index 95%
rename from java/com/google/gerrit/server/change/ListRobotComments.java
rename to java/com/google/gerrit/server/restapi/change/ListRobotComments.java
index de2b91a..61219d3 100644
--- a/java/com/google/gerrit/server/change/ListRobotComments.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRobotComments.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.RobotCommentInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.RobotComment;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/MarkAsReviewed.java b/java/com/google/gerrit/server/restapi/change/MarkAsReviewed.java
similarity index 96%
rename from java/com/google/gerrit/server/change/MarkAsReviewed.java
rename to java/com/google/gerrit/server/restapi/change/MarkAsReviewed.java
index 9e77805..af64a92 100644
--- a/java/com/google/gerrit/server/change/MarkAsReviewed.java
+++ b/java/com/google/gerrit/server/restapi/change/MarkAsReviewed.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.Response;
@@ -22,6 +22,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/MarkAsUnreviewed.java b/java/com/google/gerrit/server/restapi/change/MarkAsUnreviewed.java
similarity index 96%
rename from java/com/google/gerrit/server/change/MarkAsUnreviewed.java
rename to java/com/google/gerrit/server/restapi/change/MarkAsUnreviewed.java
index 436548b..2e74d61 100644
--- a/java/com/google/gerrit/server/change/MarkAsUnreviewed.java
+++ b/java/com/google/gerrit/server/restapi/change/MarkAsUnreviewed.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.Response;
@@ -21,6 +21,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/Mergeable.java b/java/com/google/gerrit/server/restapi/change/Mergeable.java
similarity index 97%
rename from java/com/google/gerrit/server/change/Mergeable.java
rename to java/com/google/gerrit/server/restapi/change/Mergeable.java
index d1c085a..26f755b 100644
--- a/java/com/google/gerrit/server/change/Mergeable.java
+++ b/java/com/google/gerrit/server/restapi/change/Mergeable.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.data.SubmitTypeRecord;
 import com.google.gerrit.extensions.client.SubmitType;
@@ -27,6 +27,8 @@
 import com.google.gerrit.reviewdb.server.ReviewDbUtil;
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.change.MergeabilityCache;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.BranchOrderSection;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.MergeUtil;
diff --git a/java/com/google/gerrit/server/change/Module.java b/java/com/google/gerrit/server/restapi/change/Module.java
similarity index 90%
rename from java/com/google/gerrit/server/change/Module.java
rename to java/com/google/gerrit/server/restapi/change/Module.java
index b4f71af..c18a8c5c 100644
--- a/java/com/google/gerrit/server/change/Module.java
+++ b/java/com/google/gerrit/server/restapi/change/Module.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.server.change.ChangeEditResource.CHANGE_EDIT_KIND;
 import static com.google.gerrit.server.change.ChangeResource.CHANGE_KIND;
@@ -24,12 +24,23 @@
 import static com.google.gerrit.server.change.RevisionResource.REVISION_KIND;
 import static com.google.gerrit.server.change.RobotCommentResource.ROBOT_COMMENT_KIND;
 import static com.google.gerrit.server.change.VoteResource.VOTE_KIND;
+import static com.google.gerrit.server.project.CommitResource.COMMIT_KIND;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.RestApiModule;
 import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.change.Reviewed.DeleteReviewed;
-import com.google.gerrit.server.change.Reviewed.PutReviewed;
+import com.google.gerrit.server.change.ChangeInserter;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.EmailReviewComments;
+import com.google.gerrit.server.change.PatchSetInserter;
+import com.google.gerrit.server.change.RebaseChangeOp;
+import com.google.gerrit.server.change.ReviewerResource;
+import com.google.gerrit.server.change.Revisions;
+import com.google.gerrit.server.change.SetAssigneeOp;
+import com.google.gerrit.server.change.SetHashtagsOp;
+import com.google.gerrit.server.change.WorkInProgressOp;
+import com.google.gerrit.server.restapi.change.Reviewed.DeleteReviewed;
+import com.google.gerrit.server.restapi.change.Reviewed.PutReviewed;
 
 public class Module extends RestApiModule {
   @Override
@@ -162,6 +173,7 @@
     delete(CHANGE_EDIT_KIND).to(ChangeEdits.DeleteContent.class);
     get(CHANGE_EDIT_KIND, "/").to(ChangeEdits.Get.class);
     get(CHANGE_EDIT_KIND, "meta").to(ChangeEdits.GetMeta.class);
+    post(COMMIT_KIND, "cherrypick").to(CherryPickCommit.class);
 
     factory(AccountLoader.Factory.class);
     factory(ChangeEdits.Create.Factory.class);
diff --git a/java/com/google/gerrit/server/change/Move.java b/java/com/google/gerrit/server/restapi/change/Move.java
similarity index 98%
rename from java/com/google/gerrit/server/change/Move.java
rename to java/com/google/gerrit/server/restapi/change/Move.java
index 27d4eb1..2607f9c 100644
--- a/java/com/google/gerrit/server/change/Move.java
+++ b/java/com/google/gerrit/server/restapi/change/Move.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 import static com.google.gerrit.server.permissions.ChangePermission.ABANDON;
@@ -44,6 +44,8 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.notedb.ChangeUpdate;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/change/PostHashtags.java b/java/com/google/gerrit/server/restapi/change/PostHashtags.java
similarity index 94%
rename from java/com/google/gerrit/server/change/PostHashtags.java
rename to java/com/google/gerrit/server/restapi/change/PostHashtags.java
index 1ff0fdd..f31d04e 100644
--- a/java/com/google/gerrit/server/change/PostHashtags.java
+++ b/java/com/google/gerrit/server/restapi/change/PostHashtags.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.gerrit.common.TimeUtil;
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.SetHashtagsOp;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.update.BatchUpdate;
diff --git a/java/com/google/gerrit/server/change/PostPrivate.java b/java/com/google/gerrit/server/restapi/change/PostPrivate.java
similarity index 97%
rename from java/com/google/gerrit/server/change/PostPrivate.java
rename to java/com/google/gerrit/server/restapi/change/PostPrivate.java
index 307d6df..9f02fa8 100644
--- a/java/com/google/gerrit/server/change/PostPrivate.java
+++ b/java/com/google/gerrit/server/restapi/change/PostPrivate.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 import static com.google.gerrit.extensions.conditions.BooleanCondition.or;
@@ -26,6 +26,7 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.update.BatchUpdate;
diff --git a/java/com/google/gerrit/server/change/PostReview.java b/java/com/google/gerrit/server/restapi/change/PostReview.java
similarity index 98%
rename from java/com/google/gerrit/server/change/PostReview.java
rename to java/com/google/gerrit/server/restapi/change/PostReview.java
index 0022656..7507666 100644
--- a/java/com/google/gerrit/server/change/PostReview.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReview.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
@@ -86,7 +86,11 @@
 import com.google.gerrit.server.OutputFormat;
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.ReviewerSet;
-import com.google.gerrit.server.account.AccountsCollection;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.EmailReviewComments;
+import com.google.gerrit.server.change.NotifyUtil;
+import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.server.change.WorkInProgressOp;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.extensions.events.CommentAdded;
 import com.google.gerrit.server.mail.Address;
@@ -105,6 +109,7 @@
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.ChangeContext;
diff --git a/java/com/google/gerrit/server/change/PostReviewers.java b/java/com/google/gerrit/server/restapi/change/PostReviewers.java
similarity index 97%
rename from java/com/google/gerrit/server/change/PostReviewers.java
rename to java/com/google/gerrit/server/restapi/change/PostReviewers.java
index 782980b..84dc3e3 100644
--- a/java/com/google/gerrit/server/change/PostReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReviewers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.gerrit.extensions.client.ReviewerState.CC;
@@ -47,10 +47,13 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.account.AccountsCollection;
 import com.google.gerrit.server.account.GroupMembers;
+import com.google.gerrit.server.change.ChangeMessages;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.NotifyUtil;
+import com.google.gerrit.server.change.ReviewerResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.config.GerritServerConfig;
-import com.google.gerrit.server.group.GroupsCollection;
 import com.google.gerrit.server.group.SystemGroupBackend;
 import com.google.gerrit.server.mail.Address;
 import com.google.gerrit.server.mail.send.OutgoingEmailValidator;
@@ -63,6 +66,8 @@
 import com.google.gerrit.server.project.NoSuchProjectException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.RetryingRestModifyView;
diff --git a/java/com/google/gerrit/server/change/PostReviewersOp.java b/java/com/google/gerrit/server/restapi/change/PostReviewersOp.java
similarity index 98%
rename from java/com/google/gerrit/server/change/PostReviewersOp.java
rename to java/com/google/gerrit/server/restapi/change/PostReviewersOp.java
index aed6cd0..9ec8414 100644
--- a/java/com/google/gerrit/server/change/PostReviewersOp.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReviewersOp.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.gerrit.extensions.client.ReviewerState.CC;
@@ -37,6 +37,7 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.extensions.events.ReviewerAdded;
 import com.google.gerrit.server.mail.Address;
 import com.google.gerrit.server.mail.send.AddReviewerSender;
diff --git a/java/com/google/gerrit/server/change/PreviewSubmit.java b/java/com/google/gerrit/server/restapi/change/PreviewSubmit.java
similarity index 97%
rename from java/com/google/gerrit/server/change/PreviewSubmit.java
rename to java/com/google/gerrit/server/restapi/change/PreviewSubmit.java
index 21266a0..e90c60f 100644
--- a/java/com/google/gerrit/server/change/PreviewSubmit.java
+++ b/java/com/google/gerrit/server/restapi/change/PreviewSubmit.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.api.changes.SubmitInput;
@@ -29,6 +29,8 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.change.ArchiveFormat;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.MergeOp;
 import com.google.gerrit.server.git.MergeOpRepoManager;
diff --git a/java/com/google/gerrit/server/change/PublishChangeEdit.java b/java/com/google/gerrit/server/restapi/change/PublishChangeEdit.java
similarity index 94%
rename from java/com/google/gerrit/server/change/PublishChangeEdit.java
rename to java/com/google/gerrit/server/restapi/change/PublishChangeEdit.java
index c4e2f3b..b356f18 100644
--- a/java/com/google/gerrit/server/change/PublishChangeEdit.java
+++ b/java/com/google/gerrit/server/restapi/change/PublishChangeEdit.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.api.changes.PublishChangeEditInput;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -24,6 +24,9 @@
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestView;
+import com.google.gerrit.server.change.ChangeEditResource;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.NotifyUtil;
 import com.google.gerrit.server.edit.ChangeEdit;
 import com.google.gerrit.server.edit.ChangeEditUtil;
 import com.google.gerrit.server.project.ContributorAgreementsChecker;
diff --git a/java/com/google/gerrit/server/change/PutAssignee.java b/java/com/google/gerrit/server/restapi/change/PutAssignee.java
similarity index 94%
rename from java/com/google/gerrit/server/change/PutAssignee.java
rename to java/com/google/gerrit/server/restapi/change/PutAssignee.java
index d53c85c..b6fc010 100644
--- a/java/com/google/gerrit/server/change/PutAssignee.java
+++ b/java/com/google/gerrit/server/restapi/change/PutAssignee.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.TimeUtil;
@@ -29,10 +29,12 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.account.AccountsCollection;
-import com.google.gerrit.server.change.PostReviewers.Addition;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.SetAssigneeOp;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.change.PostReviewers.Addition;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.RetryingRestModifyView;
diff --git a/java/com/google/gerrit/server/change/PutDescription.java b/java/com/google/gerrit/server/restapi/change/PutDescription.java
similarity index 97%
rename from java/com/google/gerrit/server/change/PutDescription.java
rename to java/com/google/gerrit/server/restapi/change/PutDescription.java
index 0d932ec..38fc2e2 100644
--- a/java/com/google/gerrit/server/change/PutDescription.java
+++ b/java/com/google/gerrit/server/restapi/change/PutDescription.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.TimeUtil;
@@ -25,6 +25,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.notedb.ChangeUpdate;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/PutDraftComment.java b/java/com/google/gerrit/server/restapi/change/PutDraftComment.java
similarity index 98%
rename from java/com/google/gerrit/server/change/PutDraftComment.java
rename to java/com/google/gerrit/server/restapi/change/PutDraftComment.java
index c5693c6..3017d89 100644
--- a/java/com/google/gerrit/server/change/PutDraftComment.java
+++ b/java/com/google/gerrit/server/restapi/change/PutDraftComment.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.server.CommentsUtil.setCommentRevId;
 
@@ -30,6 +30,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.DraftCommentResource;
 import com.google.gerrit.server.notedb.ChangeUpdate;
 import com.google.gerrit.server.patch.PatchListCache;
 import com.google.gerrit.server.update.BatchUpdate;
diff --git a/java/com/google/gerrit/server/change/PutMessage.java b/java/com/google/gerrit/server/restapi/change/PutMessage.java
similarity index 97%
rename from java/com/google/gerrit/server/change/PutMessage.java
rename to java/com/google/gerrit/server/restapi/change/PutMessage.java
index 419d789..f277d2c 100644
--- a/java/com/google/gerrit/server/change/PutMessage.java
+++ b/java/com/google/gerrit/server/restapi/change/PutMessage.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.FooterConstants;
 import com.google.gerrit.common.TimeUtil;
@@ -30,6 +30,9 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.GerritPersonIdent;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.NotifyUtil;
+import com.google.gerrit.server.change.PatchSetInserter;
 import com.google.gerrit.server.edit.UnchangedCommitMessageException;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.notedb.ChangeNotes;
diff --git a/java/com/google/gerrit/server/change/PutTopic.java b/java/com/google/gerrit/server/restapi/change/PutTopic.java
similarity index 97%
rename from java/com/google/gerrit/server/change/PutTopic.java
rename to java/com/google/gerrit/server/restapi/change/PutTopic.java
index a461bf0..4685905 100644
--- a/java/com/google/gerrit/server/change/PutTopic.java
+++ b/java/com/google/gerrit/server/restapi/change/PutTopic.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.TimeUtil;
@@ -26,6 +26,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.extensions.events.TopicEdited;
 import com.google.gerrit.server.notedb.ChangeUpdate;
 import com.google.gerrit.server.permissions.ChangePermission;
diff --git a/java/com/google/gerrit/server/change/QueryChanges.java b/java/com/google/gerrit/server/restapi/change/QueryChanges.java
similarity index 97%
rename from java/com/google/gerrit/server/change/QueryChanges.java
rename to java/com/google/gerrit/server/restapi/change/QueryChanges.java
index 51f53b7..7beef20 100644
--- a/java/com/google/gerrit/server/change/QueryChanges.java
+++ b/java/com/google/gerrit/server/restapi/change/QueryChanges.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -26,6 +26,7 @@
 import com.google.gerrit.index.query.QueryParseException;
 import com.google.gerrit.index.query.QueryRequiresAuthException;
 import com.google.gerrit.index.query.QueryResult;
+import com.google.gerrit.server.change.ChangeJson;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.ChangeQueryBuilder;
 import com.google.gerrit.server.query.change.ChangeQueryProcessor;
diff --git a/java/com/google/gerrit/server/change/Rebase.java b/java/com/google/gerrit/server/restapi/change/Rebase.java
similarity index 96%
rename from java/com/google/gerrit/server/change/Rebase.java
rename to java/com/google/gerrit/server/restapi/change/Rebase.java
index 59ab190..7ee5709 100644
--- a/java/com/google/gerrit/server/change/Rebase.java
+++ b/java/com/google/gerrit/server/restapi/change/Rebase.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 
@@ -36,7 +36,12 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.RebaseChangeOp;
+import com.google.gerrit.server.change.RebaseUtil;
 import com.google.gerrit.server.change.RebaseUtil.Base;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
diff --git a/java/com/google/gerrit/server/change/RebaseChangeEdit.java b/java/com/google/gerrit/server/restapi/change/RebaseChangeEdit.java
similarity index 95%
rename from java/com/google/gerrit/server/change/RebaseChangeEdit.java
rename to java/com/google/gerrit/server/restapi/change/RebaseChangeEdit.java
index 2909827..7e1bb4d 100644
--- a/java/com/google/gerrit/server/change/RebaseChangeEdit.java
+++ b/java/com/google/gerrit/server/restapi/change/RebaseChangeEdit.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -27,6 +27,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.change.ChangeEditResource;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.edit.ChangeEditModifier;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/change/Rebuild.java b/java/com/google/gerrit/server/restapi/change/Rebuild.java
similarity index 97%
rename from java/com/google/gerrit/server/change/Rebuild.java
rename to java/com/google/gerrit/server/restapi/change/Rebuild.java
index a3ed670..4508a99 100644
--- a/java/com/google/gerrit/server/change/Rebuild.java
+++ b/java/com/google/gerrit/server/restapi/change/Rebuild.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static java.util.stream.Collectors.joining;
 
@@ -24,6 +24,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.reviewdb.server.ReviewDbUtil;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.notedb.ChangeBundle;
 import com.google.gerrit.server.notedb.ChangeBundleReader;
 import com.google.gerrit.server.notedb.ChangeNotes;
diff --git a/java/com/google/gerrit/server/change/RelatedChangesSorter.java b/java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java
similarity index 99%
rename from java/com/google/gerrit/server/change/RelatedChangesSorter.java
rename to java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java
index 22ff2b7..1261373 100644
--- a/java/com/google/gerrit/server/change/RelatedChangesSorter.java
+++ b/java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/java/com/google/gerrit/server/change/Restore.java b/java/com/google/gerrit/server/restapi/change/Restore.java
similarity index 97%
rename from java/com/google/gerrit/server/change/Restore.java
rename to java/com/google/gerrit/server/restapi/change/Restore.java
index 05e8b4a2..4bf1254 100644
--- a/java/com/google/gerrit/server/change/Restore.java
+++ b/java/com/google/gerrit/server/restapi/change/Restore.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 
@@ -31,6 +31,8 @@
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.extensions.events.ChangeRestored;
 import com.google.gerrit.server.mail.send.ReplyToChangeSender;
 import com.google.gerrit.server.mail.send.RestoredSender;
diff --git a/java/com/google/gerrit/server/change/Revert.java b/java/com/google/gerrit/server/restapi/change/Revert.java
similarity index 97%
rename from java/com/google/gerrit/server/change/Revert.java
rename to java/com/google/gerrit/server/restapi/change/Revert.java
index 2dfda08..bdab012 100644
--- a/java/com/google/gerrit/server/change/Revert.java
+++ b/java/com/google/gerrit/server/restapi/change/Revert.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.conditions.BooleanCondition.and;
 import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE;
@@ -39,6 +39,10 @@
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.ReviewerSet;
 import com.google.gerrit.server.Sequences;
+import com.google.gerrit.server.change.ChangeInserter;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeMessages;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.extensions.events.ChangeReverted;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.mail.send.RevertedSender;
diff --git a/java/com/google/gerrit/server/change/Reviewed.java b/java/com/google/gerrit/server/restapi/change/Reviewed.java
similarity index 93%
rename from java/com/google/gerrit/server/change/Reviewed.java
rename to java/com/google/gerrit/server/restapi/change/Reviewed.java
index c412adf..d1a2168 100644
--- a/java/com/google/gerrit/server/change/Reviewed.java
+++ b/java/com/google/gerrit/server/restapi/change/Reviewed.java
@@ -12,12 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.change.AccountPatchReviewStore;
+import com.google.gerrit.server.change.FileResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/ReviewerJson.java b/java/com/google/gerrit/server/restapi/change/ReviewerJson.java
similarity index 97%
rename from java/com/google/gerrit/server/change/ReviewerJson.java
rename to java/com/google/gerrit/server/restapi/change/ReviewerJson.java
index c2c69d8..228eb47 100644
--- a/java/com/google/gerrit/server/change/ReviewerJson.java
+++ b/java/com/google/gerrit/server/restapi/change/ReviewerJson.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.common.data.LabelValue.formatValue;
 
@@ -29,6 +29,7 @@
 import com.google.gerrit.server.ApprovalsUtil;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.permissions.LabelPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
diff --git a/java/com/google/gerrit/server/ReviewerRecommender.java b/java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java
similarity index 98%
rename from java/com/google/gerrit/server/ReviewerRecommender.java
rename to java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java
index 50289dd..a27d376 100644
--- a/java/com/google/gerrit/server/ReviewerRecommender.java
+++ b/java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
 import static java.util.stream.Collectors.toList;
@@ -27,8 +27,8 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.ApprovalsUtil;
 import com.google.gerrit.server.change.ReviewerSuggestion;
-import com.google.gerrit.server.change.SuggestReviewers;
 import com.google.gerrit.server.change.SuggestedReviewer;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.WorkQueue;
diff --git a/java/com/google/gerrit/server/change/Reviewers.java b/java/com/google/gerrit/server/restapi/change/Reviewers.java
similarity index 93%
rename from java/com/google/gerrit/server/change/Reviewers.java
rename to java/com/google/gerrit/server/restapi/change/Reviewers.java
index 8794083..a4cfbd2 100644
--- a/java/com/google/gerrit/server/change/Reviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/Reviewers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -24,8 +24,10 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
-import com.google.gerrit.server.account.AccountsCollection;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.mail.Address;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/ReviewersUtil.java b/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
similarity index 98%
rename from java/com/google/gerrit/server/ReviewersUtil.java
rename to java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
index a8410d8..70ebbc1 100644
--- a/java/com/google/gerrit/server/ReviewersUtil.java
+++ b/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server;
+package com.google.gerrit.server.restapi.change;
 
 import static java.util.stream.Collectors.toList;
 
@@ -41,8 +41,6 @@
 import com.google.gerrit.server.account.AccountLoader;
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.account.GroupMembers;
-import com.google.gerrit.server.change.PostReviewers;
-import com.google.gerrit.server.change.SuggestReviewers;
 import com.google.gerrit.server.index.account.AccountField;
 import com.google.gerrit.server.index.account.AccountIndexCollection;
 import com.google.gerrit.server.notedb.ChangeNotes;
diff --git a/java/com/google/gerrit/server/change/RevisionReviewers.java b/java/com/google/gerrit/server/restapi/change/RevisionReviewers.java
similarity index 93%
rename from java/com/google/gerrit/server/change/RevisionReviewers.java
rename to java/com/google/gerrit/server/restapi/change/RevisionReviewers.java
index be8bce0..7cf30e2 100644
--- a/java/com/google/gerrit/server/change/RevisionReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/RevisionReviewers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -25,8 +25,10 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
-import com.google.gerrit.server.account.AccountsCollection;
+import com.google.gerrit.server.change.ReviewerResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.mail.Address;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/RobotComments.java b/java/com/google/gerrit/server/restapi/change/RobotComments.java
similarity index 92%
rename from java/com/google/gerrit/server/change/RobotComments.java
rename to java/com/google/gerrit/server/restapi/change/RobotComments.java
index d1443af..6570ae0 100644
--- a/java/com/google/gerrit/server/change/RobotComments.java
+++ b/java/com/google/gerrit/server/restapi/change/RobotComments.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.reviewdb.client.RobotComment;
 import com.google.gerrit.server.CommentsUtil;
+import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.server.change.RobotCommentResource;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/change/SetPrivateOp.java b/java/com/google/gerrit/server/restapi/change/SetPrivateOp.java
similarity index 98%
rename from java/com/google/gerrit/server/change/SetPrivateOp.java
rename to java/com/google/gerrit/server/restapi/change/SetPrivateOp.java
index 9aa4636..1b50834 100644
--- a/java/com/google/gerrit/server/change/SetPrivateOp.java
+++ b/java/com/google/gerrit/server/restapi/change/SetPrivateOp.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
diff --git a/java/com/google/gerrit/server/change/SetReadyForReview.java b/java/com/google/gerrit/server/restapi/change/SetReadyForReview.java
similarity index 94%
rename from java/com/google/gerrit/server/change/SetReadyForReview.java
rename to java/com/google/gerrit/server/restapi/change/SetReadyForReview.java
index 3d258c3..e701bb0 100644
--- a/java/com/google/gerrit/server/change/SetReadyForReview.java
+++ b/java/com/google/gerrit/server/restapi/change/SetReadyForReview.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -24,6 +24,8 @@
 import com.google.gerrit.reviewdb.client.Change.Status;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.WorkInProgressOp;
 import com.google.gerrit.server.change.WorkInProgressOp.Input;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
diff --git a/java/com/google/gerrit/server/change/SetWorkInProgress.java b/java/com/google/gerrit/server/restapi/change/SetWorkInProgress.java
similarity index 94%
rename from java/com/google/gerrit/server/change/SetWorkInProgress.java
rename to java/com/google/gerrit/server/restapi/change/SetWorkInProgress.java
index 565f67f..9f82433 100644
--- a/java/com/google/gerrit/server/change/SetWorkInProgress.java
+++ b/java/com/google/gerrit/server/restapi/change/SetWorkInProgress.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -24,6 +24,8 @@
 import com.google.gerrit.reviewdb.client.Change.Status;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.WorkInProgressOp;
 import com.google.gerrit.server.change.WorkInProgressOp.Input;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
diff --git a/java/com/google/gerrit/server/change/Submit.java b/java/com/google/gerrit/server/restapi/change/Submit.java
similarity index 95%
rename from java/com/google/gerrit/server/change/Submit.java
rename to java/com/google/gerrit/server/restapi/change/Submit.java
index 84ba88e..04aafff 100644
--- a/java/com/google/gerrit/server/change/Submit.java
+++ b/java/com/google/gerrit/server/restapi/change/Submit.java
@@ -12,11 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static java.util.stream.Collectors.joining;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 import com.google.common.collect.FluentIterable;
@@ -45,7 +44,9 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.ProjectUtil;
-import com.google.gerrit.server.account.AccountsCollection;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.ChangeSet;
 import com.google.gerrit.server.git.GitRepositoryManager;
@@ -58,6 +59,7 @@
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
 import com.google.gerrit.server.update.UpdateException;
 import com.google.gwtorm.server.OrmException;
 import com.google.gwtorm.server.OrmRuntimeException;
@@ -71,7 +73,6 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Queue;
 import java.util.Set;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -113,22 +114,6 @@
     }
   }
 
-  /**
-   * Subclass of {@link SubmitInput} with special bits that may be flipped for testing purposes
-   * only.
-   */
-  @VisibleForTesting
-  public static class TestSubmitInput extends SubmitInput {
-    public boolean failAfterRefUpdates;
-
-    /**
-     * For each change being submitted, an element is removed from this queue and, if the value is
-     * true, a bogus ref update is added to the batch, in order to generate a lock failure during
-     * execution.
-     */
-    public Queue<Boolean> generateLockFailures;
-  }
-
   private final Provider<ReviewDb> dbProvider;
   private final GitRepositoryManager repoManager;
   private final PermissionBackend permissionBackend;
@@ -187,7 +172,7 @@
             MoreObjects.firstNonNull(
                 cfg.getString("change", null, "submitTooltipAncestors"),
                 DEFAULT_TOOLTIP_ANCESTORS));
-    submitWholeTopic = wholeTopicEnabled(cfg);
+    submitWholeTopic = MergeSuperSet.wholeTopicEnabled(cfg);
     this.submitTopicLabel =
         MoreObjects.firstNonNull(
             Strings.emptyToNull(cfg.getString("change", null, "submitTopicLabel")),
@@ -489,10 +474,6 @@
     return submitter;
   }
 
-  public static boolean wholeTopicEnabled(Config config) {
-    return config.getBoolean("change", null, "submitWholeTopic", false);
-  }
-
   private List<ChangeData> getChangesByTopic(String topic) {
     try {
       return queryProvider.get().byTopicOpen(topic);
diff --git a/java/com/google/gerrit/server/change/SubmittedTogether.java b/java/com/google/gerrit/server/restapi/change/SubmittedTogether.java
similarity index 96%
rename from java/com/google/gerrit/server/change/SubmittedTogether.java
rename to java/com/google/gerrit/server/restapi/change/SubmittedTogether.java
index 98e47a9..9e7769c 100644
--- a/java/com/google/gerrit/server/change/SubmittedTogether.java
+++ b/java/com/google/gerrit/server/restapi/change/SubmittedTogether.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import static com.google.gerrit.extensions.api.changes.SubmittedTogetherOption.NON_VISIBLE_CHANGES;
 
@@ -26,6 +26,9 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.change.ChangeJson;
+import com.google.gerrit.server.change.ChangeResource;
+import com.google.gerrit.server.change.WalkSorter;
 import com.google.gerrit.server.change.WalkSorter.PatchSetData;
 import com.google.gerrit.server.git.ChangeSet;
 import com.google.gerrit.server.git.MergeSuperSet;
diff --git a/java/com/google/gerrit/server/change/SuggestChangeReviewers.java b/java/com/google/gerrit/server/restapi/change/SuggestChangeReviewers.java
similarity index 95%
rename from java/com/google/gerrit/server/change/SuggestChangeReviewers.java
rename to java/com/google/gerrit/server/restapi/change/SuggestChangeReviewers.java
index fe21858..b8792c4 100644
--- a/java/com/google/gerrit/server/change/SuggestChangeReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/SuggestChangeReviewers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.AccountVisibility;
 import com.google.gerrit.extensions.common.SuggestedReviewerInfo;
@@ -24,12 +24,12 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.IdentifiedUser.GenericFactory;
-import com.google.gerrit.server.ReviewersUtil;
-import com.google.gerrit.server.ReviewersUtil.VisibilityControl;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.RefPermission;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.restapi.change.ReviewersUtil.VisibilityControl;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/SuggestReviewers.java b/java/com/google/gerrit/server/restapi/change/SuggestReviewers.java
similarity index 97%
rename from java/com/google/gerrit/server/change/SuggestReviewers.java
rename to java/com/google/gerrit/server/restapi/change/SuggestReviewers.java
index 2ed80718..dcb35ab 100644
--- a/java/com/google/gerrit/server/change/SuggestReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/SuggestReviewers.java
@@ -12,12 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.AccountVisibility;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.ReviewersUtil;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/change/TestSubmitRule.java b/java/com/google/gerrit/server/restapi/change/TestSubmitRule.java
similarity index 97%
rename from java/com/google/gerrit/server/change/TestSubmitRule.java
rename to java/com/google/gerrit/server/restapi/change/TestSubmitRule.java
index 3b8d439..efb0f4d 100644
--- a/java/com/google/gerrit/server/change/TestSubmitRule.java
+++ b/java/com/google/gerrit/server/restapi/change/TestSubmitRule.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Lists;
@@ -24,6 +24,7 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.project.SubmitRuleEvaluator;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.rules.RulesCache;
diff --git a/java/com/google/gerrit/server/change/TestSubmitType.java b/java/com/google/gerrit/server/restapi/change/TestSubmitType.java
similarity index 96%
rename from java/com/google/gerrit/server/change/TestSubmitType.java
rename to java/com/google/gerrit/server/restapi/change/TestSubmitType.java
index 1d869a3..2782a66 100644
--- a/java/com/google/gerrit/server/change/TestSubmitType.java
+++ b/java/com/google/gerrit/server/restapi/change/TestSubmitType.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.common.base.MoreObjects;
 import com.google.gerrit.common.data.SubmitTypeRecord;
@@ -24,6 +24,7 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.project.SubmitRuleEvaluator;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.rules.RulesCache;
diff --git a/java/com/google/gerrit/server/change/Unignore.java b/java/com/google/gerrit/server/restapi/change/Unignore.java
similarity index 94%
rename from java/com/google/gerrit/server/change/Unignore.java
rename to java/com/google/gerrit/server/restapi/change/Unignore.java
index 39a82d7..d1be312 100644
--- a/java/com/google/gerrit/server/change/Unignore.java
+++ b/java/com/google/gerrit/server/restapi/change/Unignore.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.Response;
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.StarredChangesUtil.IllegalLabelException;
+import com.google.gerrit.server.change.ChangeResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/change/Votes.java b/java/com/google/gerrit/server/restapi/change/Votes.java
similarity index 95%
rename from java/com/google/gerrit/server/change/Votes.java
rename to java/com/google/gerrit/server/restapi/change/Votes.java
index c2631d5..b931c7e 100644
--- a/java/com/google/gerrit/server/change/Votes.java
+++ b/java/com/google/gerrit/server/restapi/change/Votes.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.change;
+package com.google.gerrit.server.restapi.change;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -25,6 +25,8 @@
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
+import com.google.gerrit.server.change.ReviewerResource;
+import com.google.gerrit.server.change.VoteResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/config/AgreementJson.java b/java/com/google/gerrit/server/restapi/config/AgreementJson.java
similarity index 96%
rename from java/com/google/gerrit/server/config/AgreementJson.java
rename to java/com/google/gerrit/server/restapi/config/AgreementJson.java
index 83eca9c..3ad965d 100644
--- a/java/com/google/gerrit/server/config/AgreementJson.java
+++ b/java/com/google/gerrit/server/restapi/config/AgreementJson.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.config;
+package com.google.gerrit.server.restapi.config;
 
 import com.google.gerrit.common.data.ContributorAgreement;
 import com.google.gerrit.common.data.GroupReference;
@@ -21,8 +21,8 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.GroupControl;
-import com.google.gerrit.server.group.GroupJson;
 import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.restapi.group.GroupJson;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
index c353c5b..4c23f59 100644
--- a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
+++ b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
@@ -45,10 +45,7 @@
 import com.google.gerrit.server.account.AccountVisibilityProvider;
 import com.google.gerrit.server.account.Realm;
 import com.google.gerrit.server.avatar.AvatarProvider;
-import com.google.gerrit.server.change.AllowedFormats;
 import com.google.gerrit.server.change.ArchiveFormat;
-import com.google.gerrit.server.change.Submit;
-import com.google.gerrit.server.config.AgreementJson;
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.config.AnonymousCowardName;
@@ -59,10 +56,12 @@
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.documentation.QueryDocumentationExecutor;
+import com.google.gerrit.server.git.MergeSuperSet;
 import com.google.gerrit.server.index.change.ChangeField;
 import com.google.gerrit.server.index.change.ChangeIndexCollection;
 import com.google.gerrit.server.notedb.NotesMigration;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.restapi.change.AllowedFormats;
 import com.google.inject.Inject;
 import java.net.MalformedURLException;
 import java.nio.file.Files;
@@ -246,7 +245,7 @@
         Optional.ofNullable(cfg.getString("change", null, "replyLabel")).orElse("Reply") + "\u2026";
     info.updateDelay =
         (int) ConfigUtil.getTimeUnit(cfg, "change", null, "updateDelay", 300, TimeUnit.SECONDS);
-    info.submitWholeTopic = Submit.wholeTopicEnabled(cfg);
+    info.submitWholeTopic = MergeSuperSet.wholeTopicEnabled(cfg);
     return info;
   }
 
diff --git a/java/com/google/gerrit/server/restapi/config/SetPreferences.java b/java/com/google/gerrit/server/restapi/config/SetPreferences.java
index 89dc9e5..17908c3 100644
--- a/java/com/google/gerrit/server/restapi/config/SetPreferences.java
+++ b/java/com/google/gerrit/server/restapi/config/SetPreferences.java
@@ -83,8 +83,8 @@
       p.load(md);
       storeSection(
           p.getConfig(), UserConfigSections.GENERAL, null, i, GeneralPreferencesInfo.defaults());
-      com.google.gerrit.server.account.SetPreferences.storeMyMenus(p, i.my);
-      com.google.gerrit.server.account.SetPreferences.storeUrlAliases(p, i.urlAliases);
+      com.google.gerrit.server.restapi.account.SetPreferences.storeMyMenus(p, i.my);
+      com.google.gerrit.server.restapi.account.SetPreferences.storeUrlAliases(p, i.urlAliases);
       p.commit(md);
 
       accountCache.evictAllNoReindex();
diff --git a/java/com/google/gerrit/server/group/AddMembers.java b/java/com/google/gerrit/server/restapi/group/AddMembers.java
similarity index 95%
rename from java/com/google/gerrit/server/group/AddMembers.java
rename to java/com/google/gerrit/server/restapi/group/AddMembers.java
index b57a462..8971531 100644
--- a/java/com/google/gerrit/server/group/AddMembers.java
+++ b/java/com/google/gerrit/server/restapi/group/AddMembers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
@@ -35,13 +35,16 @@
 import com.google.gerrit.server.account.AccountLoader;
 import com.google.gerrit.server.account.AccountManager;
 import com.google.gerrit.server.account.AccountResolver;
-import com.google.gerrit.server.account.AccountsCollection;
 import com.google.gerrit.server.account.AuthRequest;
 import com.google.gerrit.server.account.GroupControl;
 import com.google.gerrit.server.config.AuthConfig;
-import com.google.gerrit.server.group.AddMembers.Input;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.MemberResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.group.AddMembers.Input;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/group/AddSubgroups.java b/java/com/google/gerrit/server/restapi/group/AddSubgroups.java
similarity index 95%
rename from java/com/google/gerrit/server/group/AddSubgroups.java
rename to java/com/google/gerrit/server/restapi/group/AddSubgroups.java
index af0657a..48e6651 100644
--- a/java/com/google/gerrit/server/group/AddSubgroups.java
+++ b/java/com/google/gerrit/server/restapi/group/AddSubgroups.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
@@ -30,9 +30,12 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.account.GroupControl;
-import com.google.gerrit.server.group.AddSubgroups.Input;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.SubgroupResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
+import com.google.gerrit.server.restapi.group.AddSubgroups.Input;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/group/CreateGroup.java b/java/com/google/gerrit/server/restapi/group/CreateGroup.java
similarity index 96%
rename from java/com/google/gerrit/server/group/CreateGroup.java
rename to java/com/google/gerrit/server/restapi/group/CreateGroup.java
index b1c8e9b..6201a19 100644
--- a/java/com/google/gerrit/server/group/CreateGroup.java
+++ b/java/com/google/gerrit/server/restapi/group/CreateGroup.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
@@ -42,6 +42,10 @@
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.account.GroupUUID;
 import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.group.InternalGroupDescription;
+import com.google.gerrit.server.group.SystemGroupBackend;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupCreation;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
diff --git a/java/com/google/gerrit/server/group/DeleteMembers.java b/java/com/google/gerrit/server/restapi/group/DeleteMembers.java
similarity index 92%
rename from java/com/google/gerrit/server/group/DeleteMembers.java
rename to java/com/google/gerrit/server/restapi/group/DeleteMembers.java
index 3c04187..f8304d4 100644
--- a/java/com/google/gerrit/server/group/DeleteMembers.java
+++ b/java/com/google/gerrit/server/restapi/group/DeleteMembers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.collect.Sets;
 import com.google.gerrit.common.data.GroupDescription;
@@ -26,11 +26,14 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.account.AccountsCollection;
 import com.google.gerrit.server.account.GroupControl;
-import com.google.gerrit.server.group.AddMembers.Input;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.MemberResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.group.AddMembers.Input;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/group/DeleteSubgroups.java b/java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java
similarity index 94%
rename from java/com/google/gerrit/server/group/DeleteSubgroups.java
rename to java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java
index 901847c..e12fe12 100644
--- a/java/com/google/gerrit/server/group/DeleteSubgroups.java
+++ b/java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
@@ -27,9 +27,12 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.account.GroupControl;
-import com.google.gerrit.server.group.AddSubgroups.Input;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.SubgroupResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
+import com.google.gerrit.server.restapi.group.AddSubgroups.Input;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/group/GetAuditLog.java b/java/com/google/gerrit/server/restapi/group/GetAuditLog.java
similarity index 96%
rename from java/com/google/gerrit/server/group/GetAuditLog.java
rename to java/com/google/gerrit/server/restapi/group/GetAuditLog.java
index 52a9dd9..000df6c 100644
--- a/java/com/google/gerrit/server/group/GetAuditLog.java
+++ b/java/com/google/gerrit/server/restapi/group/GetAuditLog.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static java.util.Comparator.comparing;
 
@@ -33,6 +33,9 @@
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.group.InternalGroupDescription;
 import com.google.gerrit.server.group.db.Groups;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/group/GetDescription.java b/java/com/google/gerrit/server/restapi/group/GetDescription.java
similarity index 92%
rename from java/com/google/gerrit/server/group/GetDescription.java
rename to java/com/google/gerrit/server/restapi/group/GetDescription.java
index 0610843..284ff2e 100644
--- a/java/com/google/gerrit/server/group/GetDescription.java
+++ b/java/com/google/gerrit/server/restapi/group/GetDescription.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/group/GetDetail.java b/java/com/google/gerrit/server/restapi/group/GetDetail.java
similarity index 92%
rename from java/com/google/gerrit/server/group/GetDetail.java
rename to java/com/google/gerrit/server/restapi/group/GetDetail.java
index 47fe319..e7b240e 100644
--- a/java/com/google/gerrit/server/group/GetDetail.java
+++ b/java/com/google/gerrit/server/restapi/group/GetDetail.java
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.client.ListGroupsOption;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/group/GetGroup.java b/java/com/google/gerrit/server/restapi/group/GetGroup.java
similarity index 91%
rename from java/com/google/gerrit/server/group/GetGroup.java
rename to java/com/google/gerrit/server/restapi/group/GetGroup.java
index 03c6d6c..81057fd 100644
--- a/java/com/google/gerrit/server/group/GetGroup.java
+++ b/java/com/google/gerrit/server/restapi/group/GetGroup.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/group/GetMember.java b/java/com/google/gerrit/server/restapi/group/GetMember.java
similarity index 92%
rename from java/com/google/gerrit/server/group/GetMember.java
rename to java/com/google/gerrit/server/restapi/group/GetMember.java
index 9d270ec..db33785 100644
--- a/java/com/google/gerrit/server/group/GetMember.java
+++ b/java/com/google/gerrit/server/restapi/group/GetMember.java
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.group.MemberResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/group/GetName.java b/java/com/google/gerrit/server/restapi/group/GetName.java
similarity index 89%
rename from java/com/google/gerrit/server/group/GetName.java
rename to java/com/google/gerrit/server/restapi/group/GetName.java
index ce4df2a..8cc1fe0 100644
--- a/java/com/google/gerrit/server/group/GetName.java
+++ b/java/com/google/gerrit/server/restapi/group/GetName.java
@@ -12,9 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/group/GetOptions.java b/java/com/google/gerrit/server/restapi/group/GetOptions.java
similarity index 90%
rename from java/com/google/gerrit/server/group/GetOptions.java
rename to java/com/google/gerrit/server/restapi/group/GetOptions.java
index 7b55666..e5bfe30 100644
--- a/java/com/google/gerrit/server/group/GetOptions.java
+++ b/java/com/google/gerrit/server/restapi/group/GetOptions.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.common.GroupOptionsInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/group/GetOwner.java b/java/com/google/gerrit/server/restapi/group/GetOwner.java
similarity index 94%
rename from java/com/google/gerrit/server/group/GetOwner.java
rename to java/com/google/gerrit/server/restapi/group/GetOwner.java
index 03d0788..f46826f 100644
--- a/java/com/google/gerrit/server/group/GetOwner.java
+++ b/java/com/google/gerrit/server/restapi/group/GetOwner.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.common.errors.NoSuchGroupException;
@@ -21,6 +21,7 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/group/GetSubgroup.java b/java/com/google/gerrit/server/restapi/group/GetSubgroup.java
similarity index 91%
rename from java/com/google/gerrit/server/group/GetSubgroup.java
rename to java/com/google/gerrit/server/restapi/group/GetSubgroup.java
index a710188..98e6ce5 100644
--- a/java/com/google/gerrit/server/group/GetSubgroup.java
+++ b/java/com/google/gerrit/server/restapi/group/GetSubgroup.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.group.SubgroupResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/group/GroupJson.java b/java/com/google/gerrit/server/restapi/group/GroupJson.java
similarity index 97%
rename from java/com/google/gerrit/server/group/GroupJson.java
rename to java/com/google/gerrit/server/restapi/group/GroupJson.java
index aed4358..3c7799b 100644
--- a/java/com/google/gerrit/server/group/GroupJson.java
+++ b/java/com/google/gerrit/server/restapi/group/GroupJson.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static com.google.gerrit.extensions.client.ListGroupsOption.INCLUDES;
 import static com.google.gerrit.extensions.client.ListGroupsOption.MEMBERS;
@@ -27,6 +27,7 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/group/GroupModule.java b/java/com/google/gerrit/server/restapi/group/GroupModule.java
similarity index 93%
rename from java/com/google/gerrit/server/group/GroupModule.java
rename to java/com/google/gerrit/server/restapi/group/GroupModule.java
index 5939fd6..2bf6bcc 100644
--- a/java/com/google/gerrit/server/group/GroupModule.java
+++ b/java/com/google/gerrit/server/restapi/group/GroupModule.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static com.google.inject.Scopes.SINGLETON;
 
@@ -23,6 +23,7 @@
 import com.google.gerrit.server.account.IncludingGroupMembership;
 import com.google.gerrit.server.account.InternalGroupBackend;
 import com.google.gerrit.server.account.UniversalGroupBackend;
+import com.google.gerrit.server.group.SystemGroupBackend;
 
 public class GroupModule extends FactoryModule {
 
diff --git a/java/com/google/gerrit/server/group/GroupsCollection.java b/java/com/google/gerrit/server/restapi/group/GroupsCollection.java
similarity index 98%
rename from java/com/google/gerrit/server/group/GroupsCollection.java
rename to java/com/google/gerrit/server/restapi/group/GroupsCollection.java
index 4d3bd11..b7a8d55 100644
--- a/java/com/google/gerrit/server/group/GroupsCollection.java
+++ b/java/com/google/gerrit/server/restapi/group/GroupsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.collect.ListMultimap;
 import com.google.gerrit.common.data.GroupDescription;
@@ -35,6 +35,7 @@
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.account.GroupBackends;
 import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 
diff --git a/java/com/google/gerrit/server/group/Index.java b/java/com/google/gerrit/server/restapi/group/Index.java
similarity index 92%
rename from java/com/google/gerrit/server/group/Index.java
rename to java/com/google/gerrit/server/restapi/group/Index.java
index b2845fa..22003c0 100644
--- a/java/com/google/gerrit/server/group/Index.java
+++ b/java/com/google/gerrit/server/restapi/group/Index.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.account.GroupCache;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.InternalGroup;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/group/ListGroups.java b/java/com/google/gerrit/server/restapi/group/ListGroups.java
similarity index 98%
rename from java/com/google/gerrit/server/group/ListGroups.java
rename to java/com/google/gerrit/server/restapi/group/ListGroups.java
index 77778f3..91aee6d 100644
--- a/java/com/google/gerrit/server/group/ListGroups.java
+++ b/java/com/google/gerrit/server/restapi/group/ListGroups.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static com.google.common.collect.ImmutableList.toImmutableList;
 
@@ -37,12 +37,13 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountResource;
-import com.google.gerrit.server.account.GetGroups;
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.InternalGroupDescription;
 import com.google.gerrit.server.group.db.Groups;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.account.GetGroups;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/group/ListMembers.java b/java/com/google/gerrit/server/restapi/group/ListMembers.java
similarity index 96%
rename from java/com/google/gerrit/server/group/ListMembers.java
rename to java/com/google/gerrit/server/restapi/group/ListMembers.java
index fa33957..de0decd 100644
--- a/java/com/google/gerrit/server/group/ListMembers.java
+++ b/java/com/google/gerrit/server/restapi/group/ListMembers.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.ImmutableSet.toImmutableSet;
@@ -30,6 +30,9 @@
 import com.google.gerrit.server.account.AccountLoader;
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.group.InternalGroupDescription;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import java.util.ArrayList;
diff --git a/java/com/google/gerrit/server/group/ListSubgroups.java b/java/com/google/gerrit/server/restapi/group/ListSubgroups.java
similarity index 96%
rename from java/com/google/gerrit/server/group/ListSubgroups.java
rename to java/com/google/gerrit/server/restapi/group/ListSubgroups.java
index 42dcad3..bea079f 100644
--- a/java/com/google/gerrit/server/group/ListSubgroups.java
+++ b/java/com/google/gerrit/server/restapi/group/ListSubgroups.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static com.google.common.base.Strings.nullToEmpty;
 
@@ -23,6 +23,7 @@
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.account.GroupControl;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/group/MembersCollection.java b/java/com/google/gerrit/server/restapi/group/MembersCollection.java
similarity index 91%
rename from java/com/google/gerrit/server/group/MembersCollection.java
rename to java/com/google/gerrit/server/restapi/group/MembersCollection.java
index 59bd62f..1523a343 100644
--- a/java/com/google/gerrit/server/group/MembersCollection.java
+++ b/java/com/google/gerrit/server/restapi/group/MembersCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -25,8 +25,10 @@
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.account.AccountsCollection;
-import com.google.gerrit.server.group.AddMembers.PutMember;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.MemberResource;
+import com.google.gerrit.server.restapi.account.AccountsCollection;
+import com.google.gerrit.server.restapi.group.AddMembers.PutMember;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/restapi/group/Module.java b/java/com/google/gerrit/server/restapi/group/Module.java
new file mode 100644
index 0000000..cfe4efb
--- /dev/null
+++ b/java/com/google/gerrit/server/restapi/group/Module.java
@@ -0,0 +1,91 @@
+// 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.google.gerrit.server.restapi.group;
+
+import static com.google.gerrit.server.group.GroupResource.GROUP_KIND;
+import static com.google.gerrit.server.group.MemberResource.MEMBER_KIND;
+import static com.google.gerrit.server.group.SubgroupResource.SUBGROUP_KIND;
+
+import com.google.gerrit.extensions.registration.DynamicMap;
+import com.google.gerrit.extensions.restapi.RestApiModule;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.group.ServerInitiated;
+import com.google.gerrit.server.group.UserInitiated;
+import com.google.gerrit.server.group.db.GroupsUpdate;
+import com.google.gerrit.server.restapi.group.AddMembers.UpdateMember;
+import com.google.gerrit.server.restapi.group.AddSubgroups.UpdateSubgroup;
+import com.google.gerrit.server.restapi.group.DeleteMembers.DeleteMember;
+import com.google.gerrit.server.restapi.group.DeleteSubgroups.DeleteSubgroup;
+import com.google.inject.Provides;
+
+public class Module extends RestApiModule {
+
+  @Override
+  protected void configure() {
+    bind(GroupsCollection.class);
+
+    DynamicMap.mapOf(binder(), GROUP_KIND);
+    DynamicMap.mapOf(binder(), MEMBER_KIND);
+    DynamicMap.mapOf(binder(), SUBGROUP_KIND);
+
+    get(GROUP_KIND).to(GetGroup.class);
+    put(GROUP_KIND).to(PutGroup.class);
+    get(GROUP_KIND, "detail").to(GetDetail.class);
+    post(GROUP_KIND, "index").to(Index.class);
+    post(GROUP_KIND, "members").to(AddMembers.class);
+    post(GROUP_KIND, "members.add").to(AddMembers.class);
+    post(GROUP_KIND, "members.delete").to(DeleteMembers.class);
+    post(GROUP_KIND, "groups").to(AddSubgroups.class);
+    post(GROUP_KIND, "groups.add").to(AddSubgroups.class);
+    post(GROUP_KIND, "groups.delete").to(DeleteSubgroups.class);
+    get(GROUP_KIND, "description").to(GetDescription.class);
+    put(GROUP_KIND, "description").to(PutDescription.class);
+    delete(GROUP_KIND, "description").to(PutDescription.class);
+    get(GROUP_KIND, "name").to(GetName.class);
+    put(GROUP_KIND, "name").to(PutName.class);
+    get(GROUP_KIND, "owner").to(GetOwner.class);
+    put(GROUP_KIND, "owner").to(PutOwner.class);
+    get(GROUP_KIND, "options").to(GetOptions.class);
+    put(GROUP_KIND, "options").to(PutOptions.class);
+    get(GROUP_KIND, "log.audit").to(GetAuditLog.class);
+    post(GROUP_KIND, "rebuild").to(Rebuild.class);
+
+    child(GROUP_KIND, "members").to(MembersCollection.class);
+    get(MEMBER_KIND).to(GetMember.class);
+    put(MEMBER_KIND).to(UpdateMember.class);
+    delete(MEMBER_KIND).to(DeleteMember.class);
+
+    child(GROUP_KIND, "groups").to(SubgroupsCollection.class);
+    get(SUBGROUP_KIND).to(GetSubgroup.class);
+    put(SUBGROUP_KIND).to(UpdateSubgroup.class);
+    delete(SUBGROUP_KIND).to(DeleteSubgroup.class);
+
+    factory(CreateGroup.Factory.class);
+    factory(GroupsUpdate.Factory.class);
+  }
+
+  @Provides
+  @ServerInitiated
+  GroupsUpdate provideServerInitiatedGroupsUpdate(GroupsUpdate.Factory groupsUpdateFactory) {
+    return groupsUpdateFactory.create(null);
+  }
+
+  @Provides
+  @UserInitiated
+  GroupsUpdate provideUserInitiatedGroupsUpdate(
+      GroupsUpdate.Factory groupsUpdateFactory, IdentifiedUser currentUser) {
+    return groupsUpdateFactory.create(currentUser);
+  }
+}
diff --git a/java/com/google/gerrit/server/group/PutDescription.java b/java/com/google/gerrit/server/restapi/group/PutDescription.java
similarity index 95%
rename from java/com/google/gerrit/server/group/PutDescription.java
rename to java/com/google/gerrit/server/restapi/group/PutDescription.java
index bf9f9a0..d48637d 100644
--- a/java/com/google/gerrit/server/group/PutDescription.java
+++ b/java/com/google/gerrit/server/restapi/group/PutDescription.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.data.GroupDescription;
@@ -25,6 +25,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/group/PutGroup.java b/java/com/google/gerrit/server/restapi/group/PutGroup.java
similarity index 91%
rename from java/com/google/gerrit/server/group/PutGroup.java
rename to java/com/google/gerrit/server/restapi/group/PutGroup.java
index abaa317..33dcb8d 100644
--- a/java/com/google/gerrit/server/group/PutGroup.java
+++ b/java/com/google/gerrit/server/restapi/group/PutGroup.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.extensions.api.groups.GroupInput;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/group/PutName.java b/java/com/google/gerrit/server/restapi/group/PutName.java
similarity index 95%
rename from java/com/google/gerrit/server/group/PutName.java
rename to java/com/google/gerrit/server/restapi/group/PutName.java
index 404c918..a86cea0 100644
--- a/java/com/google/gerrit/server/group/PutName.java
+++ b/java/com/google/gerrit/server/restapi/group/PutName.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.data.GroupDescription;
@@ -26,6 +26,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
 import com.google.gwtorm.server.OrmDuplicateKeyException;
diff --git a/java/com/google/gerrit/server/group/PutOptions.java b/java/com/google/gerrit/server/restapi/group/PutOptions.java
similarity index 95%
rename from java/com/google/gerrit/server/group/PutOptions.java
rename to java/com/google/gerrit/server/restapi/group/PutOptions.java
index 7486066..c7f8552 100644
--- a/java/com/google/gerrit/server/group/PutOptions.java
+++ b/java/com/google/gerrit/server/restapi/group/PutOptions.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.common.errors.NoSuchGroupException;
@@ -24,6 +24,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/group/PutOwner.java b/java/com/google/gerrit/server/restapi/group/PutOwner.java
similarity index 95%
rename from java/com/google/gerrit/server/group/PutOwner.java
rename to java/com/google/gerrit/server/restapi/group/PutOwner.java
index 792640d..6fb3698 100644
--- a/java/com/google/gerrit/server/group/PutOwner.java
+++ b/java/com/google/gerrit/server/restapi/group/PutOwner.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.data.GroupDescription;
@@ -27,6 +27,8 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.UserInitiated;
 import com.google.gerrit.server.group.db.GroupsUpdate;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/group/QueryGroups.java b/java/com/google/gerrit/server/restapi/group/QueryGroups.java
similarity index 96%
rename from java/com/google/gerrit/server/group/QueryGroups.java
rename to java/com/google/gerrit/server/restapi/group/QueryGroups.java
index 0a89b2a..df04a2c 100644
--- a/java/com/google/gerrit/server/group/QueryGroups.java
+++ b/java/com/google/gerrit/server/restapi/group/QueryGroups.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
@@ -24,6 +24,8 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.index.query.QueryParseException;
 import com.google.gerrit.index.query.QueryResult;
+import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.group.InternalGroupDescription;
 import com.google.gerrit.server.query.group.GroupQueryBuilder;
 import com.google.gerrit.server.query.group.GroupQueryProcessor;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/group/Rebuild.java b/java/com/google/gerrit/server/restapi/group/Rebuild.java
similarity index 96%
rename from java/com/google/gerrit/server/group/Rebuild.java
rename to java/com/google/gerrit/server/restapi/group/Rebuild.java
index d3d59f8..9e8cb3f 100644
--- a/java/com/google/gerrit/server/group/Rebuild.java
+++ b/java/com/google/gerrit/server/restapi/group/Rebuild.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import static com.google.common.base.MoreObjects.firstNonNull;
 import static java.util.stream.Collectors.joining;
@@ -29,10 +29,11 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.group.Rebuild.Input;
+import com.google.gerrit.server.group.GroupResource;
 import com.google.gerrit.server.group.db.GroupBundle;
 import com.google.gerrit.server.group.db.GroupRebuilder;
 import com.google.gerrit.server.notedb.GroupsMigration;
+import com.google.gerrit.server.restapi.group.Rebuild.Input;
 import com.google.gerrit.server.update.RefUpdateUtil;
 import com.google.gwtorm.server.OrmDuplicateKeyException;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/group/SubgroupsCollection.java b/java/com/google/gerrit/server/restapi/group/SubgroupsCollection.java
similarity index 92%
rename from java/com/google/gerrit/server/group/SubgroupsCollection.java
rename to java/com/google/gerrit/server/restapi/group/SubgroupsCollection.java
index 96300ad..10b9e04 100644
--- a/java/com/google/gerrit/server/group/SubgroupsCollection.java
+++ b/java/com/google/gerrit/server/restapi/group/SubgroupsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.group;
+package com.google.gerrit.server.restapi.group;
 
 import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -24,7 +24,9 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
-import com.google.gerrit.server.group.AddSubgroups.PutSubgroup;
+import com.google.gerrit.server.group.GroupResource;
+import com.google.gerrit.server.group.SubgroupResource;
+import com.google.gerrit.server.restapi.group.AddSubgroups.PutSubgroup;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/project/BanCommit.java b/java/com/google/gerrit/server/restapi/project/BanCommit.java
similarity index 94%
rename from java/com/google/gerrit/server/project/BanCommit.java
rename to java/com/google/gerrit/server/restapi/project/BanCommit.java
index c3623c6..3d101b2 100644
--- a/java/com/google/gerrit/server/project/BanCommit.java
+++ b/java/com/google/gerrit/server/restapi/project/BanCommit.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.Lists;
 import com.google.gerrit.extensions.api.projects.BanCommitInput;
@@ -20,7 +20,8 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.server.git.BanCommitResult;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.BanCommit.BanResultInfo;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.restapi.project.BanCommit.BanResultInfo;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.RetryingRestModifyView;
diff --git a/java/com/google/gerrit/server/project/BranchesCollection.java b/java/com/google/gerrit/server/restapi/project/BranchesCollection.java
similarity index 95%
rename from java/com/google/gerrit/server/project/BranchesCollection.java
rename to java/com/google/gerrit/server/restapi/project/BranchesCollection.java
index 52072d8..b90bd9c 100644
--- a/java/com/google/gerrit/server/project/BranchesCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/BranchesCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AcceptsCreate;
@@ -28,6 +28,8 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.BranchResource;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/CheckAccess.java b/java/com/google/gerrit/server/restapi/project/CheckAccess.java
similarity index 97%
rename from java/com/google/gerrit/server/project/CheckAccess.java
rename to java/com/google/gerrit/server/restapi/project/CheckAccess.java
index b8d3fbc..deefa1a 100644
--- a/java/com/google/gerrit/server/project/CheckAccess.java
+++ b/java/com/google/gerrit/server/restapi/project/CheckAccess.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.api.config.AccessCheckInfo;
@@ -31,6 +31,7 @@
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/CheckMergeability.java b/java/com/google/gerrit/server/restapi/project/CheckMergeability.java
similarity index 97%
rename from java/com/google/gerrit/server/project/CheckMergeability.java
rename to java/com/google/gerrit/server/restapi/project/CheckMergeability.java
index 1ab2dbd..dd1c9a5 100644
--- a/java/com/google/gerrit/server/project/CheckMergeability.java
+++ b/java/com/google/gerrit/server/restapi/project/CheckMergeability.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.client.SubmitType;
 import com.google.gerrit.extensions.common.MergeableInfo;
@@ -23,6 +23,7 @@
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.InMemoryInserter;
 import com.google.gerrit.server.git.MergeUtil;
+import com.google.gerrit.server.project.BranchResource;
 import com.google.inject.Inject;
 import java.io.IOException;
 import org.eclipse.jgit.lib.Config;
diff --git a/java/com/google/gerrit/server/project/ChildProjectsCollection.java b/java/com/google/gerrit/server/restapi/project/ChildProjectsCollection.java
similarity index 91%
rename from java/com/google/gerrit/server/project/ChildProjectsCollection.java
rename to java/com/google/gerrit/server/restapi/project/ChildProjectsCollection.java
index e008d66..8f0e03c 100644
--- a/java/com/google/gerrit/server/project/ChildProjectsCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/ChildProjectsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AuthException;
@@ -22,6 +22,9 @@
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.ChildProjectResource;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/CommitIncludedIn.java b/java/com/google/gerrit/server/restapi/project/CommitIncludedIn.java
similarity index 93%
rename from java/com/google/gerrit/server/project/CommitIncludedIn.java
rename to java/com/google/gerrit/server/restapi/project/CommitIncludedIn.java
index 5b36916..d43edfb 100644
--- a/java/com/google/gerrit/server/project/CommitIncludedIn.java
+++ b/java/com/google/gerrit/server/restapi/project/CommitIncludedIn.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.changes.IncludedInInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.change.IncludedIn;
+import com.google.gerrit.server.project.CommitResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/CommitsCollection.java b/java/com/google/gerrit/server/restapi/project/CommitsCollection.java
similarity index 93%
rename from java/com/google/gerrit/server/project/CommitsCollection.java
rename to java/com/google/gerrit/server/restapi/project/CommitsCollection.java
index 481c2c8..6aa639f 100644
--- a/java/com/google/gerrit/server/project/CommitsCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/CommitsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -21,6 +21,10 @@
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.project.CommitResource;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.project.Reachable;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/project/ConfigInfoImpl.java b/java/com/google/gerrit/server/restapi/project/ConfigInfoImpl.java
similarity index 96%
rename from java/com/google/gerrit/server/project/ConfigInfoImpl.java
rename to java/com/google/gerrit/server/restapi/project/ConfigInfoImpl.java
index 943f606..70dc317 100644
--- a/java/com/google/gerrit/server/project/ConfigInfoImpl.java
+++ b/java/com/google/gerrit/server/restapi/project/ConfigInfoImpl.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Iterables;
@@ -33,6 +33,9 @@
 import com.google.gerrit.server.config.ProjectConfigEntry;
 import com.google.gerrit.server.extensions.webui.UiActions;
 import com.google.gerrit.server.git.TransferConfig;
+import com.google.gerrit.server.project.BooleanProjectConfigTransformations;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.Map;
diff --git a/java/com/google/gerrit/server/project/CreateAccessChange.java b/java/com/google/gerrit/server/restapi/project/CreateAccessChange.java
similarity index 98%
rename from java/com/google/gerrit/server/project/CreateAccessChange.java
rename to java/com/google/gerrit/server/restapi/project/CreateAccessChange.java
index 31b48cd..a06c8c5 100644
--- a/java/com/google/gerrit/server/project/CreateAccessChange.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateAccessChange.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.gerrit.common.TimeUtil;
@@ -40,6 +40,7 @@
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.UpdateException;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/project/CreateBranch.java b/java/com/google/gerrit/server/restapi/project/CreateBranch.java
similarity index 95%
rename from java/com/google/gerrit/server/project/CreateBranch.java
rename to java/com/google/gerrit/server/restapi/project/CreateBranch.java
index 0a648d9..0b62c15 100644
--- a/java/com/google/gerrit/server/project/CreateBranch.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateBranch.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.BranchInfo;
 import com.google.gerrit.extensions.api.projects.BranchInput;
@@ -28,6 +28,11 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.CreateRefControl;
+import com.google.gerrit.server.project.NoSuchProjectException;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.RefUtil;
+import com.google.gerrit.server.project.RefValidationHelper;
 import com.google.gerrit.server.util.MagicBranch;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -157,6 +162,7 @@
               }
               refPrefix = RefUtil.getRefPrefix(refPrefix);
             }
+            // fall through
             // $FALL-THROUGH$
           case FORCED:
           case IO_FAILURE:
diff --git a/java/com/google/gerrit/server/project/CreateProject.java b/java/com/google/gerrit/server/restapi/project/CreateProject.java
similarity index 97%
rename from java/com/google/gerrit/server/project/CreateProject.java
rename to java/com/google/gerrit/server/restapi/project/CreateProject.java
index 6a4de1c..56c004a 100644
--- a/java/com/google/gerrit/server/project/CreateProject.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateProject.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
@@ -56,8 +56,13 @@
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.git.RepositoryCaseMismatchException;
-import com.google.gerrit.server.group.GroupsCollection;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.CreateProjectArgs;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectJson;
+import com.google.gerrit.server.project.ProjectNameLockManager;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.gerrit.server.validators.ProjectCreationValidationListener;
 import com.google.gerrit.server.validators.ValidationException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/project/CreateTag.java b/java/com/google/gerrit/server/restapi/project/CreateTag.java
similarity index 95%
rename from java/com/google/gerrit/server/project/CreateTag.java
rename to java/com/google/gerrit/server/restapi/project/CreateTag.java
index 8e706a2..0b0ce10 100644
--- a/java/com/google/gerrit/server/project/CreateTag.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateTag.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static org.eclipse.jgit.lib.Constants.R_TAGS;
 
@@ -35,6 +35,11 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.NoSuchProjectException;
+import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.RefControl;
+import com.google.gerrit.server.project.RefUtil;
 import com.google.gerrit.server.project.RefUtil.InvalidRevisionException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/project/DashboardsCollection.java b/java/com/google/gerrit/server/restapi/project/DashboardsCollection.java
similarity index 97%
rename from java/com/google/gerrit/server/project/DashboardsCollection.java
rename to java/com/google/gerrit/server/restapi/project/DashboardsCollection.java
index d5c591f..e3ffa4d 100644
--- a/java/com/google/gerrit/server/project/DashboardsCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/DashboardsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
 
@@ -41,6 +41,9 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.DashboardResource;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/DeleteBranch.java b/java/com/google/gerrit/server/restapi/project/DeleteBranch.java
similarity index 95%
rename from java/com/google/gerrit/server/project/DeleteBranch.java
rename to java/com/google/gerrit/server/restapi/project/DeleteBranch.java
index 7c7d6af..09bbca9 100644
--- a/java/com/google/gerrit/server/project/DeleteBranch.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteBranch.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static org.eclipse.jgit.lib.Constants.R_HEADS;
 
@@ -25,6 +25,7 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.BranchResource;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/project/DeleteBranches.java b/java/com/google/gerrit/server/restapi/project/DeleteBranches.java
similarity index 94%
rename from java/com/google/gerrit/server/project/DeleteBranches.java
rename to java/com/google/gerrit/server/restapi/project/DeleteBranches.java
index fa7e917..d8166e1 100644
--- a/java/com/google/gerrit/server/project/DeleteBranches.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteBranches.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static org.eclipse.jgit.lib.Constants.R_HEADS;
 
@@ -22,6 +22,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/DeleteDashboard.java b/java/com/google/gerrit/server/restapi/project/DeleteDashboard.java
similarity index 94%
rename from java/com/google/gerrit/server/project/DeleteDashboard.java
rename to java/com/google/gerrit/server/restapi/project/DeleteDashboard.java
index 958de55..0aa5752 100644
--- a/java/com/google/gerrit/server/project/DeleteDashboard.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteDashboard.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.DashboardInfo;
 import com.google.gerrit.extensions.common.SetDashboardInput;
@@ -21,6 +21,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.DashboardResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/DeleteRef.java b/java/com/google/gerrit/server/restapi/project/DeleteRef.java
similarity index 98%
rename from java/com/google/gerrit/server/project/DeleteRef.java
rename to java/com/google/gerrit/server/restapi/project/DeleteRef.java
index 3b4638f..b1b575b 100644
--- a/java/com/google/gerrit/server/project/DeleteRef.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteRef.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static java.lang.String.format;
 import static java.util.stream.Collectors.toList;
@@ -29,6 +29,8 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.RefValidationHelper;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/server/project/DeleteTag.java b/java/com/google/gerrit/server/restapi/project/DeleteTag.java
similarity index 93%
rename from java/com/google/gerrit/server/project/DeleteTag.java
rename to java/com/google/gerrit/server/restapi/project/DeleteTag.java
index 234f1d5..cce7103 100644
--- a/java/com/google/gerrit/server/project/DeleteTag.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteTag.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.extensions.restapi.Response;
@@ -22,6 +22,8 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.RefUtil;
+import com.google.gerrit.server.project.TagResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/project/DeleteTags.java b/java/com/google/gerrit/server/restapi/project/DeleteTags.java
similarity index 94%
rename from java/com/google/gerrit/server/project/DeleteTags.java
rename to java/com/google/gerrit/server/restapi/project/DeleteTags.java
index c020351..83fa1ea 100644
--- a/java/com/google/gerrit/server/project/DeleteTags.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteTags.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static org.eclipse.jgit.lib.Constants.R_TAGS;
 
@@ -22,6 +22,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/FilesCollection.java b/java/com/google/gerrit/server/restapi/project/FilesCollection.java
similarity index 92%
rename from java/com/google/gerrit/server/project/FilesCollection.java
rename to java/com/google/gerrit/server/restapi/project/FilesCollection.java
index dd32f85..888ecf2 100644
--- a/java/com/google/gerrit/server/project/FilesCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/FilesCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -20,6 +20,8 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.project.BranchResource;
+import com.google.gerrit.server.project.FileResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/FilesInCommitCollection.java b/java/com/google/gerrit/server/restapi/project/FilesInCommitCollection.java
similarity index 92%
rename from java/com/google/gerrit/server/project/FilesInCommitCollection.java
rename to java/com/google/gerrit/server/restapi/project/FilesInCommitCollection.java
index 7144099..53411b8 100644
--- a/java/com/google/gerrit/server/project/FilesInCommitCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/FilesInCommitCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.ChildCollection;
@@ -21,6 +21,8 @@
 import com.google.gerrit.extensions.restapi.RestView;
 import com.google.gerrit.reviewdb.client.Patch;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.project.CommitResource;
+import com.google.gerrit.server.project.FileResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/GarbageCollect.java b/java/com/google/gerrit/server/restapi/project/GarbageCollect.java
similarity index 96%
rename from java/com/google/gerrit/server/project/GarbageCollect.java
rename to java/com/google/gerrit/server/restapi/project/GarbageCollect.java
index f81a0f3..ea1620b 100644
--- a/java/com/google/gerrit/server/project/GarbageCollect.java
+++ b/java/com/google/gerrit/server/restapi/project/GarbageCollect.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
@@ -29,7 +29,8 @@
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.LocalDiskRepositoryManager;
 import com.google.gerrit.server.git.WorkQueue;
-import com.google.gerrit.server.project.GarbageCollect.Input;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.restapi.project.GarbageCollect.Input;
 import com.google.gerrit.server.util.IdGenerator;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/project/GetAccess.java b/java/com/google/gerrit/server/restapi/project/GetAccess.java
similarity index 97%
rename from java/com/google/gerrit/server/project/GetAccess.java
rename to java/com/google/gerrit/server/restapi/project/GetAccess.java
index d85a03b..1568a4c 100644
--- a/java/com/google/gerrit/server/project/GetAccess.java
+++ b/java/com/google/gerrit/server/restapi/project/GetAccess.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
 import static com.google.gerrit.server.permissions.ProjectPermission.CREATE_REF;
@@ -46,12 +46,16 @@
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.ProjectConfig;
-import com.google.gerrit.server.group.GroupJson;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectJson;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.group.GroupJson;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/project/GetBranch.java b/java/com/google/gerrit/server/restapi/project/GetBranch.java
similarity index 92%
rename from java/com/google/gerrit/server/project/GetBranch.java
rename to java/com/google/gerrit/server/restapi/project/GetBranch.java
index d312bde..7d32f3d 100644
--- a/java/com/google/gerrit/server/project/GetBranch.java
+++ b/java/com/google/gerrit/server/restapi/project/GetBranch.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.BranchInfo;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.BranchResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/GetChildProject.java b/java/com/google/gerrit/server/restapi/project/GetChildProject.java
similarity index 90%
rename from java/com/google/gerrit/server/project/GetChildProject.java
rename to java/com/google/gerrit/server/restapi/project/GetChildProject.java
index afffdfc..e69907e 100644
--- a/java/com/google/gerrit/server/project/GetChildProject.java
+++ b/java/com/google/gerrit/server/restapi/project/GetChildProject.java
@@ -12,11 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.common.ProjectInfo;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.project.ChildProjectResource;
+import com.google.gerrit.server.project.ProjectJson;
 import com.google.inject.Inject;
 import org.kohsuke.args4j.Option;
 
diff --git a/java/com/google/gerrit/server/project/GetCommit.java b/java/com/google/gerrit/server/restapi/project/GetCommit.java
similarity index 90%
rename from java/com/google/gerrit/server/project/GetCommit.java
rename to java/com/google/gerrit/server/restapi/project/GetCommit.java
index d8fc5b6..1c1ae90 100644
--- a/java/com/google/gerrit/server/project/GetCommit.java
+++ b/java/com/google/gerrit/server/restapi/project/GetCommit.java
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.common.CommitInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.git.CommitUtil;
+import com.google.gerrit.server.project.CommitResource;
 import com.google.inject.Singleton;
 import java.io.IOException;
 
diff --git a/java/com/google/gerrit/server/project/GetConfig.java b/java/com/google/gerrit/server/restapi/project/GetConfig.java
similarity index 95%
rename from java/com/google/gerrit/server/project/GetConfig.java
rename to java/com/google/gerrit/server/restapi/project/GetConfig.java
index c2f816e..aafff9e 100644
--- a/java/com/google/gerrit/server/project/GetConfig.java
+++ b/java/com/google/gerrit/server/restapi/project/GetConfig.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.ConfigInfo;
 import com.google.gerrit.extensions.registration.DynamicMap;
@@ -24,6 +24,7 @@
 import com.google.gerrit.server.config.ProjectConfigEntry;
 import com.google.gerrit.server.extensions.webui.UiActions;
 import com.google.gerrit.server.git.TransferConfig;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/project/GetContent.java b/java/com/google/gerrit/server/restapi/project/GetContent.java
similarity index 93%
rename from java/com/google/gerrit/server/project/GetContent.java
rename to java/com/google/gerrit/server/restapi/project/GetContent.java
index b5294c4..132b644 100644
--- a/java/com/google/gerrit/server/project/GetContent.java
+++ b/java/com/google/gerrit/server/restapi/project/GetContent.java
@@ -12,13 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.BinaryResult;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.change.FileContentUtil;
+import com.google.gerrit.server.project.FileResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/GetDashboard.java b/java/com/google/gerrit/server/restapi/project/GetDashboard.java
similarity index 92%
rename from java/com/google/gerrit/server/project/GetDashboard.java
rename to java/com/google/gerrit/server/restapi/project/GetDashboard.java
index d4d9a54..dde77e5 100644
--- a/java/com/google/gerrit/server/project/GetDashboard.java
+++ b/java/com/google/gerrit/server/restapi/project/GetDashboard.java
@@ -12,10 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
-import static com.google.gerrit.server.project.DashboardsCollection.isDefaultDashboard;
+import static com.google.gerrit.server.restapi.project.DashboardsCollection.isDefaultDashboard;
 
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
@@ -30,6 +30,9 @@
 import com.google.gerrit.extensions.restapi.Url;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.DashboardResource;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import java.io.IOException;
 import java.util.List;
diff --git a/java/com/google/gerrit/server/project/GetDescription.java b/java/com/google/gerrit/server/restapi/project/GetDescription.java
similarity index 89%
rename from java/com/google/gerrit/server/project/GetDescription.java
rename to java/com/google/gerrit/server/restapi/project/GetDescription.java
index dd03e97..d387ff1 100644
--- a/java/com/google/gerrit/server/project/GetDescription.java
+++ b/java/com/google/gerrit/server/restapi/project/GetDescription.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/project/GetHead.java b/java/com/google/gerrit/server/restapi/project/GetHead.java
similarity index 96%
rename from java/com/google/gerrit/server/project/GetHead.java
rename to java/com/google/gerrit/server/restapi/project/GetHead.java
index daaf4ef..a6533ff 100644
--- a/java/com/google/gerrit/server/project/GetHead.java
+++ b/java/com/google/gerrit/server/restapi/project/GetHead.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -22,6 +22,7 @@
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/GetParent.java b/java/com/google/gerrit/server/restapi/project/GetParent.java
similarity index 92%
rename from java/com/google/gerrit/server/project/GetParent.java
rename to java/com/google/gerrit/server/restapi/project/GetParent.java
index df87575..a4942e3 100644
--- a/java/com/google/gerrit/server/project/GetParent.java
+++ b/java/com/google/gerrit/server/restapi/project/GetParent.java
@@ -12,11 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/project/GetProject.java b/java/com/google/gerrit/server/restapi/project/GetProject.java
similarity index 87%
rename from java/com/google/gerrit/server/project/GetProject.java
rename to java/com/google/gerrit/server/restapi/project/GetProject.java
index 8288610..a1b2fb1 100644
--- a/java/com/google/gerrit/server/project/GetProject.java
+++ b/java/com/google/gerrit/server/restapi/project/GetProject.java
@@ -12,10 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.common.ProjectInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.project.ProjectJson;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
diff --git a/java/com/google/gerrit/server/project/GetReflog.java b/java/com/google/gerrit/server/restapi/project/GetReflog.java
similarity index 97%
rename from java/com/google/gerrit/server/project/GetReflog.java
rename to java/com/google/gerrit/server/restapi/project/GetReflog.java
index 9643e09..0339e15 100644
--- a/java/com/google/gerrit/server/project/GetReflog.java
+++ b/java/com/google/gerrit/server/restapi/project/GetReflog.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.Lists;
 import com.google.gerrit.extensions.api.projects.ReflogEntryInfo;
@@ -26,6 +26,7 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.BranchResource;
 import com.google.inject.Inject;
 import java.io.IOException;
 import java.sql.Timestamp;
diff --git a/java/com/google/gerrit/server/project/GetStatistics.java b/java/com/google/gerrit/server/restapi/project/GetStatistics.java
similarity index 95%
rename from java/com/google/gerrit/server/project/GetStatistics.java
rename to java/com/google/gerrit/server/restapi/project/GetStatistics.java
index 36d558c..048c018 100644
--- a/java/com/google/gerrit/server/project/GetStatistics.java
+++ b/java/com/google/gerrit/server/restapi/project/GetStatistics.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -20,6 +20,7 @@
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/GetTag.java b/java/com/google/gerrit/server/restapi/project/GetTag.java
similarity index 89%
rename from java/com/google/gerrit/server/project/GetTag.java
rename to java/com/google/gerrit/server/restapi/project/GetTag.java
index a94d17e..6d5a510 100644
--- a/java/com/google/gerrit/server/project/GetTag.java
+++ b/java/com/google/gerrit/server/restapi/project/GetTag.java
@@ -12,10 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.TagInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.server.project.TagResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/project/Index.java b/java/com/google/gerrit/server/restapi/project/Index.java
similarity index 96%
rename from java/com/google/gerrit/server/project/Index.java
rename to java/com/google/gerrit/server/restapi/project/Index.java
index 8c8314b..24f32f6 100644
--- a/java/com/google/gerrit/server/project/Index.java
+++ b/java/com/google/gerrit/server/restapi/project/Index.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.server.git.QueueProvider.QueueType.BATCH;
 
@@ -29,6 +29,7 @@
 import com.google.gerrit.server.index.IndexExecutor;
 import com.google.gerrit.server.index.change.AllChangesIndexer;
 import com.google.gerrit.server.index.change.ChangeIndexer;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/ListBranches.java b/java/com/google/gerrit/server/restapi/project/ListBranches.java
similarity index 96%
rename from java/com/google/gerrit/server/project/ListBranches.java
rename to java/com/google/gerrit/server/restapi/project/ListBranches.java
index 645058f..5675be1 100644
--- a/java/com/google/gerrit/server/project/ListBranches.java
+++ b/java/com/google/gerrit/server/restapi/project/ListBranches.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.ImmutableList;
@@ -35,6 +35,10 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.BranchResource;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.project.RefFilter;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/ListChildProjects.java b/java/com/google/gerrit/server/restapi/project/ListChildProjects.java
similarity index 90%
rename from java/com/google/gerrit/server/project/ListChildProjects.java
rename to java/com/google/gerrit/server/restapi/project/ListChildProjects.java
index 9de0c87..c514f90 100644
--- a/java/com/google/gerrit/server/project/ListChildProjects.java
+++ b/java/com/google/gerrit/server/restapi/project/ListChildProjects.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static java.util.stream.Collectors.toList;
 
@@ -24,6 +24,11 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.ChildProjects;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectJson;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.util.HashMap;
diff --git a/java/com/google/gerrit/server/project/ListDashboards.java b/java/com/google/gerrit/server/restapi/project/ListDashboards.java
similarity index 96%
rename from java/com/google/gerrit/server/project/ListDashboards.java
rename to java/com/google/gerrit/server/restapi/project/ListDashboards.java
index 6960b47..829d409 100644
--- a/java/com/google/gerrit/server/project/ListDashboards.java
+++ b/java/com/google/gerrit/server/restapi/project/ListDashboards.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
 
@@ -26,6 +26,8 @@
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/ListProjects.java b/java/com/google/gerrit/server/restapi/project/ListProjects.java
similarity index 98%
rename from java/com/google/gerrit/server/project/ListProjects.java
rename to java/com/google/gerrit/server/restapi/project/ListProjects.java
index 19a5f55..d2aecca 100644
--- a/java/com/google/gerrit/server/project/ListProjects.java
+++ b/java/com/google/gerrit/server/restapi/project/ListProjects.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.extensions.client.ProjectState.HIDDEN;
 import static java.nio.charset.StandardCharsets.UTF_8;
@@ -41,12 +41,15 @@
 import com.google.gerrit.server.WebLinks;
 import com.google.gerrit.server.account.GroupControl;
 import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.group.GroupsCollection;
 import com.google.gerrit.server.ioutil.StringUtil;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectNode;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.gerrit.server.util.RegexListSearcher;
 import com.google.gerrit.server.util.TreeFormatter;
 import com.google.gson.reflect.TypeToken;
diff --git a/java/com/google/gerrit/server/project/ListTags.java b/java/com/google/gerrit/server/restapi/project/ListTags.java
similarity index 97%
rename from java/com/google/gerrit/server/project/ListTags.java
rename to java/com/google/gerrit/server/restapi/project/ListTags.java
index 02544ac..a2b7082 100644
--- a/java/com/google/gerrit/server/project/ListTags.java
+++ b/java/com/google/gerrit/server/restapi/project/ListTags.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.gerrit.extensions.api.projects.ProjectApi.ListRefsRequest;
@@ -30,6 +30,9 @@
 import com.google.gerrit.server.git.VisibleRefFilter;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.project.RefFilter;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/Module.java b/java/com/google/gerrit/server/restapi/project/Module.java
similarity index 96%
rename from java/com/google/gerrit/server/project/Module.java
rename to java/com/google/gerrit/server/restapi/project/Module.java
index d0753eb..b74b640 100644
--- a/java/com/google/gerrit/server/project/Module.java
+++ b/java/com/google/gerrit/server/restapi/project/Module.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.gerrit.server.project.BranchResource.BRANCH_KIND;
 import static com.google.gerrit.server.project.ChildProjectResource.CHILD_PROJECT_KIND;
@@ -24,7 +24,7 @@
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.RestApiModule;
-import com.google.gerrit.server.change.CherryPickCommit;
+import com.google.gerrit.server.project.RefValidationHelper;
 
 public class Module extends RestApiModule {
   @Override
@@ -98,7 +98,6 @@
 
     get(PROJECT_KIND, "config").to(GetConfig.class);
     put(PROJECT_KIND, "config").to(PutConfig.class);
-    post(COMMIT_KIND, "cherrypick").to(CherryPickCommit.class);
 
     factory(DeleteRef.Factory.class);
   }
diff --git a/java/com/google/gerrit/server/project/ProjectsCollection.java b/java/com/google/gerrit/server/restapi/project/ProjectsCollection.java
similarity index 96%
rename from java/com/google/gerrit/server/project/ProjectsCollection.java
rename to java/com/google/gerrit/server/restapi/project/ProjectsCollection.java
index 8d7b156..186ff99 100644
--- a/java/com/google/gerrit/server/project/ProjectsCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/ProjectsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.ListMultimap;
 import com.google.gerrit.common.Nullable;
@@ -33,6 +33,9 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/PutBranch.java b/java/com/google/gerrit/server/restapi/project/PutBranch.java
similarity index 91%
rename from java/com/google/gerrit/server/project/PutBranch.java
rename to java/com/google/gerrit/server/restapi/project/PutBranch.java
index 8e8efaf..fec8abf 100644
--- a/java/com/google/gerrit/server/project/PutBranch.java
+++ b/java/com/google/gerrit/server/restapi/project/PutBranch.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.BranchInfo;
 import com.google.gerrit.extensions.api.projects.BranchInput;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.project.BranchResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/project/PutConfig.java b/java/com/google/gerrit/server/restapi/project/PutConfig.java
similarity index 97%
rename from java/com/google/gerrit/server/project/PutConfig.java
rename to java/com/google/gerrit/server/restapi/project/PutConfig.java
index 77e60d0..69c4c05 100644
--- a/java/com/google/gerrit/server/project/PutConfig.java
+++ b/java/com/google/gerrit/server/restapi/project/PutConfig.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Strings;
@@ -43,6 +43,10 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.BooleanProjectConfigTransformations;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/PutDescription.java b/java/com/google/gerrit/server/restapi/project/PutDescription.java
similarity index 95%
rename from java/com/google/gerrit/server/project/PutDescription.java
rename to java/com/google/gerrit/server/restapi/project/PutDescription.java
index a2808fc..9be9ee0 100644
--- a/java/com/google/gerrit/server/project/PutDescription.java
+++ b/java/com/google/gerrit/server/restapi/project/PutDescription.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
@@ -29,6 +29,8 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/PutProject.java b/java/com/google/gerrit/server/restapi/project/PutProject.java
similarity index 91%
rename from java/com/google/gerrit/server/project/PutProject.java
rename to java/com/google/gerrit/server/restapi/project/PutProject.java
index 1d2384f..5b11143 100644
--- a/java/com/google/gerrit/server/project/PutProject.java
+++ b/java/com/google/gerrit/server/restapi/project/PutProject.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.ProjectInput;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Singleton;
 
 @Singleton
diff --git a/java/com/google/gerrit/server/project/PutTag.java b/java/com/google/gerrit/server/restapi/project/PutTag.java
similarity index 91%
rename from java/com/google/gerrit/server/project/PutTag.java
rename to java/com/google/gerrit/server/restapi/project/PutTag.java
index b8a8f6d..06c5157 100644
--- a/java/com/google/gerrit/server/project/PutTag.java
+++ b/java/com/google/gerrit/server/restapi/project/PutTag.java
@@ -12,12 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.TagInfo;
 import com.google.gerrit.extensions.api.projects.TagInput;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.server.project.TagResource;
 
 public class PutTag implements RestModifyView<TagResource, TagInput> {
 
diff --git a/java/com/google/gerrit/server/project/QueryProjects.java b/java/com/google/gerrit/server/restapi/project/QueryProjects.java
similarity index 95%
rename from java/com/google/gerrit/server/project/QueryProjects.java
rename to java/com/google/gerrit/server/restapi/project/QueryProjects.java
index 998bdb2..9a1c36a 100644
--- a/java/com/google/gerrit/server/project/QueryProjects.java
+++ b/java/com/google/gerrit/server/restapi/project/QueryProjects.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
@@ -25,6 +25,8 @@
 import com.google.gerrit.index.query.QueryResult;
 import com.google.gerrit.server.index.project.ProjectIndex;
 import com.google.gerrit.server.index.project.ProjectIndexCollection;
+import com.google.gerrit.server.project.ProjectData;
+import com.google.gerrit.server.project.ProjectJson;
 import com.google.gerrit.server.query.project.ProjectQueryBuilder;
 import com.google.gerrit.server.query.project.ProjectQueryProcessor;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/server/project/RepositoryStatistics.java b/java/com/google/gerrit/server/restapi/project/RepositoryStatistics.java
similarity index 89%
rename from java/com/google/gerrit/server/project/RepositoryStatistics.java
rename to java/com/google/gerrit/server/restapi/project/RepositoryStatistics.java
index 3cb4bac..2a2fc866 100644
--- a/java/com/google/gerrit/server/project/RepositoryStatistics.java
+++ b/java/com/google/gerrit/server/restapi/project/RepositoryStatistics.java
@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.CaseFormat;
 import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.TreeMap;
 
-class RepositoryStatistics extends TreeMap<String, Object> {
+public class RepositoryStatistics extends TreeMap<String, Object> {
   private static final long serialVersionUID = 1L;
 
   RepositoryStatistics(Properties p) {
diff --git a/java/com/google/gerrit/server/project/SetAccess.java b/java/com/google/gerrit/server/restapi/project/SetAccess.java
similarity index 97%
rename from java/com/google/gerrit/server/project/SetAccess.java
rename to java/com/google/gerrit/server/restapi/project/SetAccess.java
index a1b2b0f..5a34522 100644
--- a/java/com/google/gerrit/server/project/SetAccess.java
+++ b/java/com/google/gerrit/server/restapi/project/SetAccess.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.Iterables;
@@ -36,6 +36,8 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
diff --git a/java/com/google/gerrit/server/project/SetAccessUtil.java b/java/com/google/gerrit/server/restapi/project/SetAccessUtil.java
similarity index 97%
rename from java/com/google/gerrit/server/project/SetAccessUtil.java
rename to java/com/google/gerrit/server/restapi/project/SetAccessUtil.java
index fefefaa..3fb9bb9 100644
--- a/java/com/google/gerrit/server/project/SetAccessUtil.java
+++ b/java/com/google/gerrit/server/restapi/project/SetAccessUtil.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.collect.Iterables;
 import com.google.gerrit.common.data.AccessSection;
@@ -33,8 +33,9 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.git.ProjectConfig;
-import com.google.gerrit.server.group.GroupsCollection;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.RefPattern;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/SetDashboard.java b/java/com/google/gerrit/server/restapi/project/SetDashboard.java
similarity index 94%
rename from java/com/google/gerrit/server/project/SetDashboard.java
rename to java/com/google/gerrit/server/restapi/project/SetDashboard.java
index 21ec077..891978b 100644
--- a/java/com/google/gerrit/server/project/SetDashboard.java
+++ b/java/com/google/gerrit/server/restapi/project/SetDashboard.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.api.projects.DashboardInfo;
 import com.google.gerrit.extensions.common.SetDashboardInput;
@@ -21,6 +21,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.DashboardResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/SetDefaultDashboard.java b/java/com/google/gerrit/server/restapi/project/SetDefaultDashboard.java
similarity index 96%
rename from java/com/google/gerrit/server/project/SetDefaultDashboard.java
rename to java/com/google/gerrit/server/restapi/project/SetDefaultDashboard.java
index 0dd5f85..4fd46c5 100644
--- a/java/com/google/gerrit/server/project/SetDefaultDashboard.java
+++ b/java/com/google/gerrit/server/restapi/project/SetDefaultDashboard.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
@@ -31,6 +31,9 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
+import com.google.gerrit.server.project.DashboardResource;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/SetHead.java b/java/com/google/gerrit/server/restapi/project/SetHead.java
similarity index 97%
rename from java/com/google/gerrit/server/project/SetHead.java
rename to java/com/google/gerrit/server/restapi/project/SetHead.java
index a8d93c1..aa1bf63 100644
--- a/java/com/google/gerrit/server/project/SetHead.java
+++ b/java/com/google/gerrit/server/restapi/project/SetHead.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.api.projects.HeadInput;
@@ -31,6 +31,7 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.RefPermission;
+import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/server/project/SetParent.java b/java/com/google/gerrit/server/restapi/project/SetParent.java
similarity index 96%
rename from java/com/google/gerrit/server/project/SetParent.java
rename to java/com/google/gerrit/server/restapi/project/SetParent.java
index 60efa6f..21fef97 100644
--- a/java/com/google/gerrit/server/project/SetParent.java
+++ b/java/com/google/gerrit/server/restapi/project/SetParent.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -35,6 +35,9 @@
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/server/project/TagsCollection.java b/java/com/google/gerrit/server/restapi/project/TagsCollection.java
similarity index 93%
rename from java/com/google/gerrit/server/project/TagsCollection.java
rename to java/com/google/gerrit/server/restapi/project/TagsCollection.java
index 7ee0a8e..a1b0395 100644
--- a/java/com/google/gerrit/server/project/TagsCollection.java
+++ b/java/com/google/gerrit/server/restapi/project/TagsCollection.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.project;
+package com.google.gerrit.server.restapi.project;
 
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.restapi.AcceptsCreate;
@@ -20,6 +20,8 @@
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestView;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.TagResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/sshd/ChangeArgumentParser.java b/java/com/google/gerrit/sshd/ChangeArgumentParser.java
index d5fc4547..f442032 100644
--- a/java/com/google/gerrit/sshd/ChangeArgumentParser.java
+++ b/java/com/google/gerrit/sshd/ChangeArgumentParser.java
@@ -22,13 +22,13 @@
 import com.google.gerrit.server.ChangeFinder;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ChangesCollection;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
 import com.google.gerrit.sshd.BaseCommand.UnloggedFailure;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/AdminSetParent.java b/java/com/google/gerrit/sshd/commands/AdminSetParent.java
index c6e00aa..d9a0a37 100644
--- a/java/com/google/gerrit/sshd/commands/AdminSetParent.java
+++ b/java/com/google/gerrit/sshd/commands/AdminSetParent.java
@@ -24,10 +24,10 @@
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ListChildProjects;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.project.ListChildProjects;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/BanCommitCommand.java b/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
index d514e2c..cceb16b 100644
--- a/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
+++ b/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
@@ -19,10 +19,10 @@
 import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 import com.google.gerrit.extensions.api.projects.BanCommitInput;
-import com.google.gerrit.server.project.BanCommit;
-import com.google.gerrit.server.project.BanCommit.BanResultInfo;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.project.BanCommit;
+import com.google.gerrit.server.restapi.project.BanCommit.BanResultInfo;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/BaseTestPrologCommand.java b/java/com/google/gerrit/sshd/commands/BaseTestPrologCommand.java
index 56ff5ea..68490f7 100644
--- a/java/com/google/gerrit/sshd/commands/BaseTestPrologCommand.java
+++ b/java/com/google/gerrit/sshd/commands/BaseTestPrologCommand.java
@@ -20,9 +20,9 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.OutputFormat;
-import com.google.gerrit.server.change.ChangesCollection;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.change.Revisions;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
 import java.nio.ByteBuffer;
diff --git a/java/com/google/gerrit/sshd/commands/CreateAccountCommand.java b/java/com/google/gerrit/sshd/commands/CreateAccountCommand.java
index 0c63fb3..32bff8c 100644
--- a/java/com/google/gerrit/sshd/commands/CreateAccountCommand.java
+++ b/java/com/google/gerrit/sshd/commands/CreateAccountCommand.java
@@ -23,7 +23,7 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.server.account.CreateAccount;
+import com.google.gerrit.server.restapi.account.CreateAccount;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/sshd/commands/CreateGroupCommand.java b/java/com/google/gerrit/sshd/commands/CreateGroupCommand.java
index 83a62fd..1e1e254 100644
--- a/java/com/google/gerrit/sshd/commands/CreateGroupCommand.java
+++ b/java/com/google/gerrit/sshd/commands/CreateGroupCommand.java
@@ -25,11 +25,11 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.server.group.AddMembers;
-import com.google.gerrit.server.group.AddSubgroups;
-import com.google.gerrit.server.group.CreateGroup;
 import com.google.gerrit.server.group.GroupResource;
-import com.google.gerrit.server.group.GroupsCollection;
+import com.google.gerrit.server.restapi.group.AddMembers;
+import com.google.gerrit.server.restapi.group.AddSubgroups;
+import com.google.gerrit.server.restapi.group.CreateGroup;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java b/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java
index bb33dea..3ed856b 100644
--- a/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java
+++ b/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java
@@ -17,8 +17,8 @@
 import com.google.gerrit.extensions.common.Input;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.Index;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.change.Index;
 import com.google.gerrit.sshd.ChangeArgumentParser;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
diff --git a/java/com/google/gerrit/sshd/commands/IndexProjectCommand.java b/java/com/google/gerrit/sshd/commands/IndexProjectCommand.java
index ba937a2..e6abc17 100644
--- a/java/com/google/gerrit/sshd/commands/IndexProjectCommand.java
+++ b/java/com/google/gerrit/sshd/commands/IndexProjectCommand.java
@@ -17,9 +17,9 @@
 import static com.google.gerrit.common.data.GlobalCapability.MAINTAIN_SERVER;
 
 import com.google.gerrit.extensions.annotations.RequiresAnyCapability;
-import com.google.gerrit.server.project.Index;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.project.Index;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java b/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java
index ac3784a..473cb0c 100644
--- a/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java
+++ b/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java
@@ -23,8 +23,8 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.group.InternalGroup;
-import com.google.gerrit.server.group.ListGroups;
 import com.google.gerrit.server.ioutil.ColumnFormatter;
+import com.google.gerrit.server.restapi.group.ListGroups;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gerrit.util.cli.Options;
diff --git a/java/com/google/gerrit/sshd/commands/ListMembersCommand.java b/java/com/google/gerrit/sshd/commands/ListMembersCommand.java
index 2585e5c..bf3dd44 100644
--- a/java/com/google/gerrit/sshd/commands/ListMembersCommand.java
+++ b/java/com/google/gerrit/sshd/commands/ListMembersCommand.java
@@ -24,8 +24,8 @@
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.account.GroupControl;
 import com.google.gerrit.server.group.InternalGroup;
-import com.google.gerrit.server.group.ListMembers;
 import com.google.gerrit.server.ioutil.ColumnFormatter;
+import com.google.gerrit.server.restapi.group.ListMembers;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gwtorm.server.OrmException;
@@ -35,7 +35,7 @@
 import java.util.Optional;
 import org.kohsuke.args4j.Argument;
 
-/** Implements a command that allows the user to see the members of a group. */
+/** Implements a command that allows the user to see the members of a account. */
 @CommandMetaData(
   name = "ls-members",
   description = "List the members of a given group",
diff --git a/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java b/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
index 7ef1e20..664f87b 100644
--- a/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
+++ b/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
@@ -16,7 +16,7 @@
 
 import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
 
-import com.google.gerrit.server.project.ListProjects;
+import com.google.gerrit.server.restapi.project.ListProjects;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gerrit.util.cli.Options;
diff --git a/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java b/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java
index e8e104c..9e334e6 100644
--- a/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java
+++ b/java/com/google/gerrit/sshd/commands/RenameGroupCommand.java
@@ -19,8 +19,8 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.server.group.GroupResource;
-import com.google.gerrit.server.group.GroupsCollection;
-import com.google.gerrit.server.group.PutName;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
+import com.google.gerrit.server.restapi.group.PutName;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/sshd/commands/SetAccountCommand.java b/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
index 16cc49a..a7cc790 100644
--- a/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
+++ b/java/com/google/gerrit/sshd/commands/SetAccountCommand.java
@@ -35,18 +35,18 @@
 import com.google.gerrit.reviewdb.client.AccountSshKey;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountResource;
-import com.google.gerrit.server.account.AddSshKey;
-import com.google.gerrit.server.account.CreateEmail;
-import com.google.gerrit.server.account.DeleteActive;
-import com.google.gerrit.server.account.DeleteEmail;
-import com.google.gerrit.server.account.DeleteSshKey;
-import com.google.gerrit.server.account.GetEmails;
-import com.google.gerrit.server.account.GetSshKeys;
-import com.google.gerrit.server.account.PutActive;
-import com.google.gerrit.server.account.PutHttpPassword;
-import com.google.gerrit.server.account.PutName;
-import com.google.gerrit.server.account.PutPreferred;
 import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.restapi.account.AddSshKey;
+import com.google.gerrit.server.restapi.account.CreateEmail;
+import com.google.gerrit.server.restapi.account.DeleteActive;
+import com.google.gerrit.server.restapi.account.DeleteEmail;
+import com.google.gerrit.server.restapi.account.DeleteSshKey;
+import com.google.gerrit.server.restapi.account.GetEmails;
+import com.google.gerrit.server.restapi.account.GetSshKeys;
+import com.google.gerrit.server.restapi.account.PutActive;
+import com.google.gerrit.server.restapi.account.PutHttpPassword;
+import com.google.gerrit.server.restapi.account.PutName;
+import com.google.gerrit.server.restapi.account.PutPreferred;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gwtorm.server.OrmException;
diff --git a/java/com/google/gerrit/sshd/commands/SetHeadCommand.java b/java/com/google/gerrit/sshd/commands/SetHeadCommand.java
index ef7ab916..fd7ef75 100644
--- a/java/com/google/gerrit/sshd/commands/SetHeadCommand.java
+++ b/java/com/google/gerrit/sshd/commands/SetHeadCommand.java
@@ -18,7 +18,7 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.ProjectState;
-import com.google.gerrit.server.project.SetHead;
+import com.google.gerrit.server.restapi.project.SetHead;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/SetMembersCommand.java b/java/com/google/gerrit/sshd/commands/SetMembersCommand.java
index 9062b52..fdb4b1e9 100644
--- a/java/com/google/gerrit/sshd/commands/SetMembersCommand.java
+++ b/java/com/google/gerrit/sshd/commands/SetMembersCommand.java
@@ -26,13 +26,13 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.account.GroupCache;
-import com.google.gerrit.server.group.AddMembers;
-import com.google.gerrit.server.group.AddSubgroups;
-import com.google.gerrit.server.group.DeleteMembers;
-import com.google.gerrit.server.group.DeleteSubgroups;
 import com.google.gerrit.server.group.GroupResource;
-import com.google.gerrit.server.group.GroupsCollection;
 import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.restapi.group.AddMembers;
+import com.google.gerrit.server.restapi.group.AddSubgroups;
+import com.google.gerrit.server.restapi.group.DeleteMembers;
+import com.google.gerrit.server.restapi.group.DeleteSubgroups;
+import com.google.gerrit.server.restapi.group.GroupsCollection;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/SetProjectCommand.java b/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
index a963a35..a5759f0 100644
--- a/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
+++ b/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
@@ -22,7 +22,7 @@
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.project.ProjectState;
-import com.google.gerrit.server.project.PutConfig;
+import com.google.gerrit.server.restapi.project.PutConfig;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/sshd/commands/SetReviewersCommand.java b/java/com/google/gerrit/sshd/commands/SetReviewersCommand.java
index 85cf467..4c7d59d 100644
--- a/java/com/google/gerrit/sshd/commands/SetReviewersCommand.java
+++ b/java/com/google/gerrit/sshd/commands/SetReviewersCommand.java
@@ -20,11 +20,11 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.DeleteReviewer;
-import com.google.gerrit.server.change.PostReviewers;
 import com.google.gerrit.server.change.ReviewerResource;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectState;
+import com.google.gerrit.server.restapi.change.DeleteReviewer;
+import com.google.gerrit.server.restapi.change.PostReviewers;
 import com.google.gerrit.sshd.ChangeArgumentParser;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
diff --git a/java/com/google/gerrit/sshd/commands/TestSubmitRuleCommand.java b/java/com/google/gerrit/sshd/commands/TestSubmitRuleCommand.java
index a7d529b..ce43c3d 100644
--- a/java/com/google/gerrit/sshd/commands/TestSubmitRuleCommand.java
+++ b/java/com/google/gerrit/sshd/commands/TestSubmitRuleCommand.java
@@ -17,7 +17,7 @@
 import com.google.gerrit.extensions.common.TestSubmitRuleInput;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.change.RevisionResource;
-import com.google.gerrit.server.change.TestSubmitRule;
+import com.google.gerrit.server.restapi.change.TestSubmitRule;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.inject.Inject;
 
diff --git a/java/com/google/gerrit/sshd/commands/TestSubmitTypeCommand.java b/java/com/google/gerrit/sshd/commands/TestSubmitTypeCommand.java
index ebe8925..90d54d5 100644
--- a/java/com/google/gerrit/sshd/commands/TestSubmitTypeCommand.java
+++ b/java/com/google/gerrit/sshd/commands/TestSubmitTypeCommand.java
@@ -18,7 +18,7 @@
 import com.google.gerrit.extensions.common.TestSubmitRuleInput;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.change.RevisionResource;
-import com.google.gerrit.server.change.TestSubmitType;
+import com.google.gerrit.server.restapi.change.TestSubmitType;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.inject.Inject;
 
diff --git a/java/com/google/gerrit/sshd/commands/UploadArchive.java b/java/com/google/gerrit/sshd/commands/UploadArchive.java
index 41cc485b..7518cbb 100644
--- a/java/com/google/gerrit/sshd/commands/UploadArchive.java
+++ b/java/com/google/gerrit/sshd/commands/UploadArchive.java
@@ -18,12 +18,12 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.server.change.AllowedFormats;
 import com.google.gerrit.server.change.ArchiveFormat;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
-import com.google.gerrit.server.project.CommitsCollection;
+import com.google.gerrit.server.restapi.change.AllowedFormats;
+import com.google.gerrit.server.restapi.project.CommitsCollection;
 import com.google.gerrit.sshd.AbstractGitCommand;
 import com.google.inject.Inject;
 import java.io.IOException;
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 7aa7fd0..fa683cf 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -130,12 +130,12 @@
 import com.google.gerrit.server.ChangeMessagesUtil;
 import com.google.gerrit.server.StarredChangesUtil;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.PostReview;
 import com.google.gerrit.server.git.ChangeMessageModifier;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.group.SystemGroupBackend;
 import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.restapi.change.PostReview;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.ChangeContext;
diff --git a/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java b/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java
index 6f4495e..37a86d2 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java
@@ -30,7 +30,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.project.DashboardsCollection;
+import com.google.gerrit.server.restapi.project.DashboardsCollection;
 import java.util.List;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Repository;
diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index 9c7f7fb..e3d0699 100644
--- a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -81,9 +81,9 @@
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.server.change.GetRevisionActions;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.restapi.change.GetRevisionActions;
 import com.google.inject.Inject;
 import java.io.ByteArrayOutputStream;
 import java.sql.Timestamp;
diff --git a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
index 9d32e3a..28c1641 100644
--- a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
+++ b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
@@ -56,11 +56,11 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
-import com.google.gerrit.server.change.ChangeEdits.EditMessage;
-import com.google.gerrit.server.change.ChangeEdits.Post;
-import com.google.gerrit.server.change.ChangeEdits.Put;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.restapi.change.ChangeEdits.EditMessage;
+import com.google.gerrit.server.restapi.change.ChangeEdits.Post;
+import com.google.gerrit.server.restapi.change.ChangeEdits.Put;
 import com.google.gerrit.testing.TestTimeUtil;
 import com.google.gson.reflect.TypeToken;
 import com.google.gson.stream.JsonReader;
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
index adfbdef..95b6a2a 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
@@ -26,7 +26,7 @@
 import com.google.gerrit.extensions.client.SubmitType;
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.testing.ConfigSuite;
 import java.util.ArrayDeque;
 import java.util.Map;
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/GetAccountDetailIT.java b/javatests/com/google/gerrit/acceptance/rest/account/GetAccountDetailIT.java
index dcd40b9..08322d8 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/GetAccountDetailIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/GetAccountDetailIT.java
@@ -20,7 +20,7 @@
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.server.account.GetDetail.AccountDetailInfo;
+import com.google.gerrit.server.restapi.account.GetDetail.AccountDetailInfo;
 import org.junit.Test;
 
 public class GetAccountDetailIT extends AbstractDaemonTest {
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index 3a41fae..67307e2 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -66,12 +66,12 @@
 import com.google.gerrit.server.ApprovalsUtil;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.change.RevisionResource;
-import com.google.gerrit.server.change.Submit;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.git.validators.OnSubmitValidationListener;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.restapi.change.Submit;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.ChangeContext;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java
index b4d8557..29a81ca 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java
@@ -27,7 +27,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
index 5269329..d551595 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
@@ -35,7 +35,7 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.project.testing.Util;
 import org.eclipse.jgit.lib.ObjectId;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/BUILD b/javatests/com/google/gerrit/acceptance/rest/change/BUILD
index dd675cb..6a4b4a7 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/BUILD
+++ b/javatests/com/google/gerrit/acceptance/rest/change/BUILD
@@ -33,5 +33,6 @@
     srcs = SUBMIT_UTIL_SRCS,
     deps = [
         "//java/com/google/gerrit/acceptance:lib",
+        "//java/com/google/gerrit/server/restapi",
     ],
 )
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
index 3abd290..f1bba8a 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
@@ -47,8 +47,8 @@
 import com.google.gerrit.extensions.common.ReviewerUpdateInfo;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.change.PostReviewers;
 import com.google.gerrit.server.mail.Address;
+import com.google.gerrit.server.restapi.change.PostReviewers;
 import com.google.gerrit.testing.FakeEmailSender.Message;
 import com.google.gson.stream.JsonReader;
 import java.util.ArrayList;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java
index d895bc7..e508664 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java
@@ -35,7 +35,7 @@
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import com.google.gerrit.server.git.ChangeMessageModifier;
 import com.google.gerrit.server.git.strategy.CommitMergeStatus;
 import com.google.inject.Inject;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
index d4397d64..2ebf3ca 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
@@ -29,7 +29,7 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.server.change.Submit.TestSubmitInput;
+import com.google.gerrit.server.change.TestSubmitInput;
 import java.util.Map;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitResolvingMergeCommitIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitResolvingMergeCommitIT.java
index 05abd4c..8e3618d 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitResolvingMergeCommitIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitResolvingMergeCommitIT.java
@@ -23,11 +23,11 @@
 import com.google.gerrit.acceptance.PushOneCommit;
 import com.google.gerrit.extensions.client.ChangeStatus;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.change.Submit;
 import com.google.gerrit.server.git.ChangeSet;
 import com.google.gerrit.server.git.MergeSuperSet;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.restapi.change.Submit;
 import com.google.gerrit.testing.ConfigSuite;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
index 9b7a8cb..21a1e76 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
@@ -32,8 +32,8 @@
 import com.google.gerrit.extensions.restapi.TopLevelResource;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.group.CreateGroup;
 import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.restapi.group.CreateGroup;
 import com.google.inject.Inject;
 import java.util.Arrays;
 import java.util.List;
diff --git a/javatests/com/google/gerrit/acceptance/rest/group/GroupsIT.java b/javatests/com/google/gerrit/acceptance/rest/group/GroupsIT.java
index 2acd358..a52dd6d 100644
--- a/javatests/com/google/gerrit/acceptance/rest/group/GroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/group/GroupsIT.java
@@ -22,9 +22,9 @@
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.group.Rebuild;
 import com.google.gerrit.server.group.db.GroupBundle;
 import com.google.gerrit.server.notedb.GroupsMigration;
+import com.google.gerrit.server.restapi.group.Rebuild;
 import com.google.inject.Inject;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.ObjectId;
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/BanCommitIT.java b/javatests/com/google/gerrit/acceptance/rest/project/BanCommitIT.java
index 14fa715..19f6295 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/BanCommitIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/BanCommitIT.java
@@ -22,7 +22,7 @@
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.extensions.api.projects.BanCommitInput;
-import com.google.gerrit.server.project.BanCommit.BanResultInfo;
+import com.google.gerrit.server.restapi.project.BanCommit.BanResultInfo;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.junit.Test;
diff --git a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
index 348f027..343eacc 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
@@ -49,11 +49,11 @@
 import com.google.gerrit.reviewdb.client.Patch;
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ChangesCollection;
-import com.google.gerrit.server.change.PostReview;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.notedb.ChangeNoteUtil;
 import com.google.gerrit.server.notedb.DeleteCommentRewriter;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.PostReview;
 import com.google.gerrit.testing.FakeEmailSender;
 import com.google.gerrit.testing.FakeEmailSender.Message;
 import com.google.inject.Inject;
diff --git a/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java b/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
index 615fee0..3877239 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
@@ -33,11 +33,11 @@
 import com.google.gerrit.index.IndexConfig;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.server.change.ChangesCollection;
-import com.google.gerrit.server.change.GetRelated;
-import com.google.gerrit.server.change.GetRelated.ChangeAndCommit;
-import com.google.gerrit.server.change.GetRelated.RelatedInfo;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.restapi.change.ChangesCollection;
+import com.google.gerrit.server.restapi.change.GetRelated;
+import com.google.gerrit.server.restapi.change.GetRelated.ChangeAndCommit;
+import com.google.gerrit.server.restapi.change.GetRelated.RelatedInfo;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.ChangeContext;
diff --git a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
index cce54fc..11edb50 100644
--- a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
@@ -46,9 +46,9 @@
 import com.google.gerrit.extensions.client.ReviewerState;
 import com.google.gerrit.extensions.common.CommitInfo;
 import com.google.gerrit.extensions.common.CommitMessageInput;
-import com.google.gerrit.server.change.PostReview;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.restapi.change.PostReview;
 import org.junit.Before;
 import org.junit.Test;
 
diff --git a/javatests/com/google/gerrit/acceptance/server/notedb/ChangeRebuilderIT.java b/javatests/com/google/gerrit/acceptance/server/notedb/ChangeRebuilderIT.java
index be0f793..79fed8b 100644
--- a/javatests/com/google/gerrit/acceptance/server/notedb/ChangeRebuilderIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/notedb/ChangeRebuilderIT.java
@@ -58,8 +58,6 @@
 import com.google.gerrit.server.ChangeUtil;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.Sequences;
-import com.google.gerrit.server.change.PostReview;
-import com.google.gerrit.server.change.Rebuild;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.git.RepoRefCache;
@@ -75,6 +73,8 @@
 import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
 import com.google.gerrit.server.project.testing.Util;
 import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.restapi.change.PostReview;
+import com.google.gerrit.server.restapi.change.Rebuild;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.BatchUpdateOp;
 import com.google.gerrit.server.update.ChangeContext;
diff --git a/javatests/com/google/gerrit/acceptance/server/notedb/ReflogIT.java b/javatests/com/google/gerrit/acceptance/server/notedb/ReflogIT.java
index 312974f..834dbfa 100644
--- a/javatests/com/google/gerrit/acceptance/server/notedb/ReflogIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/notedb/ReflogIT.java
@@ -51,7 +51,7 @@
       gApi.changes().id(id.get()).topic("foo");
       ReflogEntry last = repo.getReflogReader(changeMetaRef(id)).getLastEntry();
       assertThat(last).named("last RefLogEntry").isNotNull();
-      assertThat(last.getComment()).isEqualTo("change.PutTopic");
+      assertThat(last.getComment()).isEqualTo("restapi.change.PutTopic");
     }
   }
 }
diff --git a/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java b/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java
index 620fee7..267c622 100644
--- a/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java
+++ b/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java
@@ -35,6 +35,7 @@
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.ProjectConfig;
 import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.restapi.project.CommitsCollection;
 import com.google.gerrit.server.schema.SchemaCreator;
 import com.google.gerrit.server.util.RequestContext;
 import com.google.gerrit.server.util.ThreadLocalRequestContext;
diff --git a/javatests/com/google/gerrit/server/schema/Schema_150_to_151_Test.java b/javatests/com/google/gerrit/server/schema/Schema_150_to_151_Test.java
index ec6f1ea..7dd265e 100644
--- a/javatests/com/google/gerrit/server/schema/Schema_150_to_151_Test.java
+++ b/javatests/com/google/gerrit/server/schema/Schema_150_to_151_Test.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.AccountGroup.Id;
 import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.group.CreateGroup;
+import com.google.gerrit.server.restapi.group.CreateGroup;
 import com.google.gerrit.testing.SchemaUpgradeTestEnvironment;
 import com.google.gerrit.testing.TestUpdateUI;
 import com.google.gwtorm.jdbc.JdbcSchema;