private void migrateUser(
      final long fromDirectoryId,
      final long toDirectoryId,
      final String remoteUser,
      final User user,
      final AtomicLong migratedCount)
      throws Exception {
    if (!user.getName().equalsIgnoreCase(remoteUser)) {
      UserWithAttributes userWithAttributes =
          directoryManager.findUserWithAttributesByName(fromDirectoryId, user.getName());
      try {
        final UserTemplate newUser = new UserTemplate(user);
        newUser.setDirectoryId(toDirectoryId);
        directoryManager.addUser(
            toDirectoryId, newUser, new PasswordCredential(generatePassword()));
      } catch (InvalidUserException e) {
        // That's fine just go on to the next user.  Don't copy the groups.
        return;
      }
      // Migrate attributes
      Set<String> keys = userWithAttributes.getKeys();
      Map<String, Set<String>> attributes = new HashMap<String, Set<String>>();
      for (String key : keys) {
        Set<String> values = userWithAttributes.getValues(key);
        attributes.put(key, values);
      }
      directoryManager.storeUserAttributes(toDirectoryId, user.getName(), attributes);

      MembershipQuery<Group> groupQuery =
          QueryBuilder.queryFor(Group.class, EntityDescriptor.group())
              .parentsOf(EntityDescriptor.user())
              .withName(user.getName())
              .returningAtMost(EntityQuery.ALL_RESULTS);
      List<Group> groups =
          directoryManager.searchDirectGroupRelationships(fromDirectoryId, groupQuery);
      for (Group group : groups) {
        // We may need to add the group first
        try {
          directoryManager.findGroupByName(toDirectoryId, group.getName());
        } catch (GroupNotFoundException ex) {
          final GroupTemplate newGroup = new GroupTemplate(group);
          newGroup.setDirectoryId(toDirectoryId);
          directoryManager.addGroup(toDirectoryId, newGroup);
        }
        directoryManager.addUserToGroup(toDirectoryId, user.getName(), group.getName());
        directoryManager.removeUserFromGroup(fromDirectoryId, user.getName(), group.getName());
      }
      directoryManager.removeUser(fromDirectoryId, user.getName());
      migratedCount.addAndGet(1);
    }
  }
  @Test
  public void testRemoveAttribute() throws Exception {
    final User createdUser = userDao.add(TestData.User.getTestData(), TestData.User.CREDENTIAL);
    userDao.storeAttributes(createdUser, TestData.Attributes.getTestData());

    TestData.Attributes.assertEqualsTestData(
        userDao.findByNameWithAttributes(TestData.DIRECTORY_ID, TestData.User.NAME));

    userDao.removeAttribute(createdUser, TestData.Attributes.ATTRIBUTE1);
    final UserWithAttributes userWithLessAttributes =
        userDao.findByNameWithAttributes(TestData.DIRECTORY_ID, TestData.User.NAME);

    assertNull(userWithLessAttributes.getValue(TestData.Attributes.ATTRIBUTE1));
  }