private void setDirectoryEnabled(final Directory from, final boolean enabled) {
   transactionTemplate.execute(
       new TransactionCallback() {
         public Object doInTransaction() {
           ImmutableDirectory.Builder builder = ImmutableDirectory.newBuilder(from);
           builder.setActive(enabled);
           Directory updatedDirectory = builder.toDirectory();
           crowdDirectoryService.updateDirectory(updatedDirectory);
           log.info(
               "User directory {}: [ {} ], type: [ {} ]",
               new String[] {
                 enabled ? "enabled" : "disabled", from.getName(), from.getType().toString()
               });
           return null;
         }
       });
 }
  private void migrateUsers(
      final long fromDirectoryId,
      final long toDirectoryId,
      final String remoteUser,
      final MigrateDirectoryUsersCommand migrateUsersCommand,
      final BindException errors) {
    // Check the to & from directories

    Directory from = validateDirectory(fromDirectoryId, errors, "fromDirectoryId");
    Directory to = validateDirectory(toDirectoryId, errors, "toDirectoryId");
    if (to != null && to.equals(from)) {
      errors.addError(
          new FieldError(
              "migration",
              "toDirectoryId",
              i18nResolver.getText("embedded.crowd.directory.migrate.users.field.directory.same")));
    }
    if (errors.hasErrors()) {
      return;
    }

    setDirectoryEnabled(from, false);
    setDirectoryEnabled(to, false);

    // Copy
    SearchRestriction restriction = NullRestrictionImpl.INSTANCE;
    UserQuery<User> query = new UserQuery<User>(User.class, restriction, 0, -1);
    try {
      // TODO: Sucking all users in like this may be problematic for Confluence.  If planning to
      // enable this
      // TODO: feature for other products make sure the performance impacts are understood.
      List<User> users = directoryManager.searchUsers(fromDirectoryId, query);
      final AtomicLong migratedCount = new AtomicLong(0);
      for (Iterator<User> iter = users.iterator(); iter.hasNext(); ) {
        final User user = iter.next();
        transactionTemplate.execute(
            new TransactionCallback() {
              public Object doInTransaction() {
                try {
                  migrateUser(fromDirectoryId, toDirectoryId, remoteUser, user, migratedCount);
                } catch (Exception e) {
                  throw new RuntimeException(e);
                }
                return null;
              }
            });
      }
      migrateUsersCommand.setTestSuccessful(true);
      migrateUsersCommand.setTotalCount(users.size());
      migrateUsersCommand.setMigratedCount(migratedCount.get());
    } catch (Exception e) {
      log.error("User migration failed", e);
      errors.addError(
          new ObjectError(
              "migration",
              i18nResolver.getText(
                  "embedded.crowd.directory.migrate.users.error",
                  htmlEncoder.encode(e.getMessage()))));
    }

    // Enable both directories
    setDirectoryEnabled(from, true);
    setDirectoryEnabled(to, true);
  }