Merge "Remove empty config.md file"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
index 571e8ec..dcc64db 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
@@ -19,7 +19,6 @@
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.restapi.BadRequestException;
-import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.webui.UiAction;
@@ -74,7 +73,7 @@
   }
 
   @Override
-  public Response<String> apply(ProjectResource rsrc, Input input)
+  public ImportStatistic apply(ProjectResource rsrc, Input input)
       throws RestApiException, OrmException, IOException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException {
     if (Strings.isNullOrEmpty(input.name)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProjectCommand.java
index f5b1ed9..8737d98 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProjectCommand.java
@@ -55,7 +55,8 @@
       }
       CopyProject.Input input = new CopyProject.Input();
       input.name = target;
-      copy.apply(srcProject, input);
+      ImportStatistic stats = copy.apply(srcProject, input);
+      stdout.print("Created Changes: " + stats.numChangesCreated + "\n");
     } catch (RestApiException e) {
       throw die(e.getMessage());
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
index 97afa04..7e3a278 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
@@ -17,6 +17,7 @@
 import com.google.gerrit.common.errors.NoSuchAccountException;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.common.AccountInfo;
+import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.PreconditionFailedException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -29,11 +30,14 @@
 import com.google.gerrit.reviewdb.client.AccountGroupName;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.CreateGroupArgs;
 import com.google.gerrit.server.account.GroupCache;
 import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.config.ConfigResource;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.group.GroupJson.GroupInfo;
+import com.google.gerrit.server.validators.GroupCreationValidationListener;
+import com.google.gerrit.server.validators.ValidationException;
 import com.google.gwtorm.server.OrmDuplicateKeyException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -46,7 +50,9 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 @RequiresCapability(ImportCapability.ID)
 class ImportGroup implements RestModifyView<ConfigResource, Input> {
@@ -67,19 +73,22 @@
   private final AccountCache accountCache;
   private final GroupIncludeCache groupIncludeCache;
   private final Config cfg;
+  private final DynamicSet<GroupCreationValidationListener> groupCreationValidationListeners;
   private RemoteApi api;
 
   @Inject
   ImportGroup(AccountUtil accountUtil, GroupCache groupCache,
       AccountCache accountCache, GroupIncludeCache groupIncludeCache,
       ReviewDb db, @Assisted AccountGroup.NameKey group,
-      @GerritServerConfig Config cfg) {
+      @GerritServerConfig Config cfg,
+      DynamicSet<GroupCreationValidationListener> groupCreationValidationListeners) {
     this.db = db;
     this.accountUtil = accountUtil;
     this.groupCache = groupCache;
     this.accountCache = accountCache;
     this.groupIncludeCache = groupIncludeCache;
     this.cfg = cfg;
+    this.groupCreationValidationListeners = groupCreationValidationListeners;
     this.group = group;
   }
 
@@ -98,7 +107,7 @@
 
   private void validate(GroupInfo groupInfo) throws ResourceConflictException,
       PreconditionFailedException, BadRequestException, IOException,
-      OrmException {
+      OrmException, NoSuchAccountException {
     if (groupCache.get(new AccountGroup.NameKey(groupInfo.name)) != null) {
       throw new ResourceConflictException(String.format(
           "Group with name %s already exists", groupInfo.name));
@@ -125,6 +134,38 @@
             "Included group with UUID %s does not exist", include.id));
       }
     }
+
+    for (GroupCreationValidationListener l : groupCreationValidationListeners) {
+      try {
+        l.validateNewGroup(toCreateGroupArgs(groupInfo));
+      } catch (ValidationException e) {
+        throw new ResourceConflictException(e.getMessage(), e);
+      }
+    }
+  }
+
+  private CreateGroupArgs toCreateGroupArgs(GroupInfo groupInfo)
+      throws IOException, OrmException, BadRequestException,
+      NoSuchAccountException {
+    CreateGroupArgs args = new CreateGroupArgs();
+    args.setGroupName(groupInfo.name);
+    args.groupDescription = groupInfo.description;
+    args.visibleToAll = cfg.getBoolean("groups", "newGroupsVisibleToAll", false);
+    if (!groupInfo.ownerId.equals(groupInfo.id)) {
+      args.ownerGroupId =
+          groupCache.get(new AccountGroup.UUID(groupInfo.ownerId)).getId();
+    }
+    Set<Account.Id> initialMembers = new HashSet<>();
+    for (AccountInfo member : groupInfo.members) {
+      initialMembers.add(accountUtil.resolveUser(api, member));
+    }
+    args.initialMembers = initialMembers;
+    Set<AccountGroup.UUID> initialGroups = new HashSet<>();
+    for (GroupInfo member : groupInfo.includes) {
+      initialGroups.add(new AccountGroup.UUID(member.id));
+    }
+    args.initialGroups = initialGroups;
+    return args;
   }
 
   private AccountGroup createGroup(GroupInfo info) throws OrmException,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
index 6d1f3bb..935d588 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
@@ -22,7 +22,6 @@
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
-import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.reviewdb.client.Project;
@@ -132,7 +131,7 @@
   }
 
   @Override
-  public Response<String> apply(ConfigResource rsrc, Input input)
+  public ImportStatistic apply(ConfigResource rsrc, Input input)
       throws RestApiException, OrmException, IOException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException {
     if (input == null) {
@@ -147,7 +146,7 @@
     }
   }
 
-  public Response<String> resume(String user, String pass, boolean force,
+  public ResumeImportStatistic resume(String user, String pass, boolean force,
       File importStatus) throws RestApiException, OrmException, IOException,
       ValidationException, GitAPIException, NoSuchChangeException,
       NoSuchAccountException {
@@ -170,9 +169,10 @@
     }
   }
 
-  private Response<String> apply(LockFile lockFile, Input input, ImportProjectInfo info)
-      throws RestApiException, OrmException, IOException, ValidationException,
-      GitAPIException, NoSuchChangeException, NoSuchAccountException {
+  private ResumeImportStatistic apply(LockFile lockFile, Input input,
+      ImportProjectInfo info) throws RestApiException, OrmException,
+      IOException, ValidationException, GitAPIException, NoSuchChangeException,
+      NoSuchAccountException {
     boolean resume = info != null;
 
     input.validate();
@@ -180,6 +180,7 @@
     ProgressMonitor pm = err != null ? new TextProgressMonitor(err) :
         NullProgressMonitor.INSTANCE;
 
+    ResumeImportStatistic statistic = new ResumeImportStatistic();
     try {
       srcProject = !Strings.isNullOrEmpty(input.name)
           ? new Project.NameKey(input.name) : targetProject;
@@ -193,7 +194,7 @@
         gitFetchStep.fetch(input.user, input.pass, repo, pm);
         configProjectStep.configure(targetProject, parent, pm);
         replayChangesFactory.create(input.from, input.user, input.pass, repo,
-            srcProject, targetProject, force, resume, pm).replay();
+            srcProject, targetProject, force, resume, statistic, pm).replay();
       } finally {
         repo.close();
       }
@@ -210,7 +211,7 @@
       throw e;
     }
 
-    return Response.<String> ok("OK");
+    return statistic;
   }
 
   private void checkProjectInSource(Input input, ProgressMonitor pm)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportStatistic.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportStatistic.java
new file mode 100644
index 0000000..389580f
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportStatistic.java
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.importer;
+
+class ImportStatistic {
+  int numChangesCreated;
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
index 92ae1d2..abaa0e1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
@@ -90,7 +90,8 @@
       if (!quiet) {
         importer.setErr(stderr);
       }
-      importer.apply(new ConfigResource(), input);
+      ImportStatistic stats = importer.apply(new ConfigResource(), input);
+      stdout.print("Created Changes: " + stats.numChangesCreated + "\n");
     } catch (RestApiException e) {
       throw die(e.getMessage());
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
index bffae8c..cb84296 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
@@ -55,6 +55,7 @@
         @Assisted("targetProject") Project.NameKey targetProject,
         @Assisted("force") boolean force,
         @Assisted("resume") boolean resume,
+        ResumeImportStatistic importStatistic,
         ProgressMonitor pm);
   }
 
@@ -75,6 +76,7 @@
   private final Project.NameKey targetProject;
   private final boolean force;
   private final boolean resume;
+  private final ResumeImportStatistic importStatistic;
   private final ProgressMonitor pm;
 
   @Inject
@@ -97,6 +99,7 @@
       @Assisted("targetProject") Project.NameKey targetProject,
       @Assisted("force") boolean force,
       @Assisted("resume") boolean resume,
+      @Assisted ResumeImportStatistic importStatistic,
       @Assisted ProgressMonitor pm) {
     this.replayRevisionsFactory = replayRevisionsFactory;
     this.replayInlineCommentsFactory = replayInlineCommentsFactory;
@@ -115,6 +118,7 @@
     this.targetProject = targetProject;
     this.force = force;
     this.resume = resume;
+    this.importStatistic = importStatistic;
     this.pm = pm;
   }
 
@@ -167,6 +171,12 @@
     insertLinkToOriginalFactory.create(fromGerrit,change, c, resumeChange).insert();
 
     indexer.index(db, change);
+
+    if (resumeChange) {
+      importStatistic.numChangesUpdated++;
+    } else {
+      importStatistic.numChangesCreated++;
+    }
   }
 
   private Change findChange(ChangeInfo c) throws OrmException {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java
index 00e22e1..884ba53 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java
@@ -19,7 +19,6 @@
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
-import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.webui.UiAction;
@@ -73,7 +72,7 @@
   }
 
   @Override
-  public Response<String> apply(ProjectResource rsrc, Input input)
+  public ResumeImportStatistic apply(ProjectResource rsrc, Input input)
       throws RestApiException, IOException, OrmException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException {
     AccountState s = ((IdentifiedUser) currentUserProvider.get()).state();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeImportStatistic.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeImportStatistic.java
new file mode 100644
index 0000000..e6fe3c4
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeImportStatistic.java
@@ -0,0 +1,19 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.importer;
+
+class ResumeImportStatistic extends ImportStatistic {
+  int numChangesUpdated;
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java
index 5dfb115..9104d91 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectCommand.java
@@ -62,7 +62,9 @@
       input.user = user;
       input.pass = pass;
       input.force = force;
-      resume.apply(rsrc, input);
+      ResumeImportStatistic stats = resume.apply(rsrc, input);
+      stdout.print("Created Changes: " + stats.numChangesCreated + "\n");
+      stdout.print("Updated Changes: " + stats.numChangesUpdated + "\n");
     } catch (RestApiException e) {
       throw die(e.getMessage());
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
index ad172d4..b05eaf3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
@@ -21,7 +21,6 @@
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
-import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.webui.UiAction;
@@ -63,7 +62,7 @@
   }
 
   @Override
-  public Response<String> apply(ImportProjectResource rsrc, Input input)
+  public ResumeImportStatistic apply(ImportProjectResource rsrc, Input input)
       throws RestApiException, IOException, OrmException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException {
     if (Strings.isNullOrEmpty(input.user)) {
@@ -102,7 +101,7 @@
     }
 
     @Override
-    public Response<String> apply(ProjectResource rsrc, Input input)
+    public ResumeImportStatistic apply(ProjectResource rsrc, Input input)
         throws RestApiException, IOException, OrmException,
         ValidationException, GitAPIException, NoSuchChangeException,
         NoSuchAccountException {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
index f65ae5c..ee03cb9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportProjectScreen.java
@@ -21,7 +21,6 @@
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
 import com.google.gerrit.plugin.client.screen.Screen;
-import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -92,10 +91,10 @@
     in.parent(getValue(parentTxt));
 
     new RestApi("config").id("server").view(Plugin.get().getName(), "projects")
-        .id(targetName).put(in, new AsyncCallback<JavaScriptObject>() {
+        .id(targetName).put(in, new AsyncCallback<ImportStatisticInfo>() {
 
       @Override
-      public void onSuccess(JavaScriptObject result) {
+      public void onSuccess(ImportStatisticInfo result) {
         clearForm();
         Plugin.get().go("/admin/projects/" + targetName);
 
@@ -106,6 +105,7 @@
         Panel p = new VerticalPanel();
         p.setStyleName("importer-message-panel");
         p.add(new Label("The project was imported."));
+        p.add(new Label("Created Changes: " + result.numChangesCreated()));
         Button okButton = new Button("OK");
         okButton.addClickHandler(new ClickHandler() {
           public void onClick(ClickEvent event) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportStatisticInfo.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportStatisticInfo.java
new file mode 100644
index 0000000..2d82432
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ImportStatisticInfo.java
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.importer.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+public class ImportStatisticInfo extends JavaScriptObject {
+  public final native int numChangesCreated() /*-{ return this.num_changes_created; }-*/;
+
+  protected ImportStatisticInfo() {
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
index 73488f4..ab116c0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportDialog.java
@@ -20,7 +20,6 @@
 
 import com.google.gerrit.plugin.client.Plugin;
 import com.google.gerrit.plugin.client.rpc.RestApi;
-import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.user.client.rpc.AsyncCallback;
@@ -61,9 +60,9 @@
 
         new RestApi("config").id("server")
             .view(Plugin.get().getName(), "projects").id(project)
-            .view("resume").put(in, new AsyncCallback<JavaScriptObject>() {
+            .view("resume").put(in, new AsyncCallback<ResumeImportStatisticInfo>() {
               @Override
-              public void onSuccess(JavaScriptObject result) {
+              public void onSuccess(ResumeImportStatisticInfo result) {
                 Plugin.get().go("/admin/projects/" + project);
 
                 final DialogBox successDialog = new DialogBox();
@@ -73,6 +72,8 @@
                 Panel p = new VerticalPanel();
                 p.setStyleName("importer-message-panel");
                 p.add(new Label("The project import was resumed."));
+                p.add(new Label("Created Changes: " + result.numChangesCreated()));
+                p.add(new Label("Updated Changes: " + result.numChangesUpdated()));
                 Button okButton = new Button("OK");
                 okButton.addClickHandler(new ClickHandler() {
                   public void onClick(ClickEvent event) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportStatisticInfo.java b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportStatisticInfo.java
new file mode 100644
index 0000000..73d99f1
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/client/ResumeImportStatisticInfo.java
@@ -0,0 +1,23 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.importer.client;
+
+
+public class ResumeImportStatisticInfo extends ImportStatisticInfo {
+  public final native int numChangesUpdated() /*-{ return this.num_changes_updated; }-*/;
+
+  protected ResumeImportStatisticInfo() {
+  }
+}
diff --git a/src/main/resources/Documentation/rest-api-config.md b/src/main/resources/Documentation/rest-api-config.md
index 5655414..2048937 100644
--- a/src/main/resources/Documentation/rest-api-config.md
+++ b/src/main/resources/Documentation/rest-api-config.md
@@ -36,6 +36,22 @@
   }
 ```
 
+As result a [ImportStatisticInfo](#import-statistic-info) entity is
+returned.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json; charset=UTF-8
+
+  )]}'
+  {
+    "num\_changes\_created": 5
+  }
+```
+
 ### <a id="list-imported-projects"> List Imported Projects
 _GET /config/server/@PLUGIN@~projects/_
 
@@ -170,6 +186,23 @@
   }
 ```
 
+As result a [ResumeImportStatisticInfo](#resume-import-statistic-info)
+entity is returned.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json; charset=UTF-8
+
+  )]}'
+  {
+    "num\_changes\_created": 1,
+    "num\_changes\_updated": 2
+  }
+```
+
 ### <a id="import-group"> Import Group
 _PUT /config/server/@PLUGIN@~groups/[\{group-name\}](../../../Documentation/rest-api-groups.html#group-name)_
 
@@ -276,6 +309,21 @@
 force changes that have the same last modified timestamp in the source
 and target system are resumed, otherwise they will be skipped.
 
+### <a id="import-statistic-info"></a>ImportStatisticInfo
+
+The `ImportStatisticInfo` entity contains statistics about a project
+import.
+
+* _num\_changes\_created_: Number of created changes.
+
+### <a id="resume-import-statistic-info"></a>ResumeImportStatisticInfo
+
+The `ResumeImportStatisticInfo` entity contains statistics about a
+project import resume.
+
+* _num\_changes\_created_: Number of created changes.
+* _num\_changes\_updated_: Number of updated changes.
+
 
 SEE ALSO
 --------
diff --git a/src/main/resources/Documentation/rest-api-projects.md b/src/main/resources/Documentation/rest-api-projects.md
index 252b33d..53c9d45 100644
--- a/src/main/resources/Documentation/rest-api-projects.md
+++ b/src/main/resources/Documentation/rest-api-projects.md
@@ -33,6 +33,22 @@
   }
 ```
 
+As result a [ImportStatisticInfo](rest-api-config.html#import-statistic-info)
+entity is returned.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json; charset=UTF-8
+
+  )]}'
+  {
+    "num\_changes\_created": 5
+  }
+```
+
 ### <a id="resume-copy-project"> Resume Copy Project
 _PUT /projects/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)/@PLUGIN@~copy.resume_
 
@@ -48,6 +64,23 @@
   PUT /projects/myProjectCopy/@PLUGIN@~copy.resume HTTP/1.0
 ```
 
+As result a [ResumeImportStatisticInfo](rest-api-config.html#resume-import-statistic-info)
+entity is returned.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json; charset=UTF-8
+
+  )]}'
+  {
+    "num\_changes\_created": 1,
+    "num\_changes\_updated": 2
+  }
+```
+
 ### <a id="resume-project-import"> Resume Project Import
 _PUT /projects/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)/@PLUGIN@~import.resume_
 
@@ -73,6 +106,23 @@
   }
 ```
 
+As result a [ResumeImportStatisticInfo](rest-api-config.html#resume-import-statistic-info)
+entity is returned.
+
+#### Response
+
+```
+  HTTP/1.1 200 OK
+  Content-Disposition: attachment
+  Content-Type: application/json; charset=UTF-8
+
+  )]}'
+  {
+    "num\_changes\_created": 1,
+    "num\_changes\_updated": 2
+  }
+```
+
 ### <a id="complete-project-import"> Complete Project Import
 _POST /projects/[\{project-name\}](../../../Documentation/rest-api-projects.html#project-name)/@PLUGIN@~delete)_