private Uid doUpdate() throws IOException, JSchException {

    if (uid == null || StringUtil.isBlank(uid.getUidValue())) {
      throw new IllegalArgumentException("No Uid attribute provided in the attributes");
    }

    LOG.info("Update user: "******"Wrong object class");
    }

    if (objectClass.equals(ObjectClass.ACCOUNT)) {
      if (!EvaluateCommandsResultOutput.evaluateUserOrGroupExists(
          unixConnection.execute(
              UnixConnector.getCommandGenerator().userExists(uid.getUidValue())))) {
        throw new ConnectorException("User " + uid + " do not exists");
      }
      for (Attribute attr : attrs) {
        if (attr.is(Name.NAME) || attr.is(Uid.NAME)) {
          newUserName = (String) attr.getValue().get(0);
        } else if (attr.is(OperationalAttributes.PASSWORD_NAME)) {
          password = Utilities.getPlainPassword((GuardedString) attr.getValue().get(0));
        } else if (attr.is(OperationalAttributes.ENABLE_NAME)) {
          status = Boolean.parseBoolean(attr.getValue().get(0).toString());
        } else if (attr.is(configuration.getCommentAttribute())) {
          comment = attr.getValue().get(0).toString();
        } else if (attr.is(configuration.getShellAttribute())) {
          shell = (String) attr.getValue().get(0).toString();
        } else if (attr.is(configuration.getHomeDirectoryAttribute())) {
          homeDirectory = (String) attr.getValue().get(0).toString();
        }
      }
      unixConnection.execute(
          UnixConnector.getCommandGenerator()
              .updateUser(
                  uid.getUidValue(), newUserName, password, status, comment, shell, homeDirectory));
      //            unixConnection.execute("mv /home/" + uid.getUidValue() + " /home/" +
      // newUserName);
      unixConnection.execute(
          UnixConnector.getCommandGenerator().moveHomeDirectory(uid.getUidValue(), newUserName));
      if (!status) {
        unixConnection.execute(UnixConnector.getCommandGenerator().lockUser(uid.getUidValue()));
      } else {
        unixConnection.execute(UnixConnector.getCommandGenerator().unlockUser(uid.getUidValue()));
      }
      if (StringUtil.isNotBlank(newUserName) && StringUtil.isNotEmpty(newUserName)) {
        unixConnection.execute(
            UnixConnector.getCommandGenerator().updateGroup(uid.getUidValue(), newUserName));
      }
    } else if (objectClass.equals(ObjectClass.GROUP)) {
      if (!EvaluateCommandsResultOutput.evaluateUserOrGroupExists(
          unixConnection.execute(UnixConnector.getCommandGenerator().groupExists(newUserName)))) {
        throw new ConnectorException("Group do not exists");
      }
      unixConnection.execute(
          UnixConnector.getCommandGenerator().updateGroup(uid.getUidValue(), newUserName));
    }
    return uid;
  }
  private LdapSearchStrategy getSearchStrategy() {
    LdapSearchStrategy strategy;
    if (oclass.is(ObjectClass.ACCOUNT_NAME)) {
      // Only consider paged strategies for accounts,
      // just as the adapter does.

      boolean useBlocks = conn.getConfiguration().isUseBlocks();
      boolean usePagedResultsControl = conn.getConfiguration().isUsePagedResultControl();
      int pageSize = conn.getConfiguration().getBlockSize();

      if (useBlocks
          && !usePagedResultsControl
          && conn.supportsControl(VirtualListViewControl.OID)) {
        String vlvSortAttr = conn.getConfiguration().getVlvSortAttribute();
        strategy = new ADVlvIndexSearchStrategy(vlvSortAttr, pageSize);
      } else if (useBlocks && conn.supportsControl(PagedResultsControl.OID)) {
        strategy = new ADSimplePagedSearchStrategy(pageSize);
      } else {
        strategy = new ADDefaultSearchStrategy(false);
      }
    } else {
      strategy = new ADDefaultSearchStrategy(false);
    }
    return strategy;
  }
  private boolean isAccount(ObjectClass objectClass) {
    if (objectClass == null) {
      return false;
    }

    if (ObjectClass.ACCOUNT.is(objectClass.getObjectClassValue())) {
      return true;
    }

    return false;
  }
  private Uid doUpdate() throws IOException {

    if (!objectClass.equals(ObjectClass.ACCOUNT) && (!objectClass.equals(ObjectClass.GROUP))) {
      throw new IllegalStateException("Wrong object class");
    }

    if (!userExists(
        uid.getUidValue(), configuration.getOpenamRealm(), adminToken.getToken(), connection)) {
      LOG.error("User " + uid.getUidValue() + " do not exists");
      throw new ConnectorException("User " + uid.getUidValue() + " do not exists");
    }

    try {
      connection.update(createUpdateQueryString(uid, attrs, adminToken).toString());
      LOG.ok("User " + uid.getUidValue() + " updated");
    } catch (HttpClientErrorException hcee) {
      throw hcee;
    }
    return uid;
  }
  private LdapInternalSearch getInternalSearch(Set<String> attrsToGet) {
    // This is a bit tricky. If the LdapFilter has an entry DN,
    // we only need to look at that entry and check whether it matches
    // the native filter. Moreover, when looking at the entry DN
    // we must not throw exceptions if the entry DN does not exist or is
    // not valid -- just as no exceptions are thrown when the native
    // filter doesn't return any values.
    //
    // In the simple case when the LdapFilter has no entryDN, we
    // will just search over our base DNs looking for entries
    // matching the native filter.

    LdapSearchStrategy strategy;
    List<String> dns;
    int searchScope;

    final String filterEntryDN = filter != null ? filter.getEntryDN() : null;
    if (filterEntryDN != null) {
      // Would be good to check that filterEntryDN is under the configured
      // base contexts. However, the adapter is likely to pass entries
      // outside the base contexts, so not checking in order to be on the
      // safe side.
      strategy = new ADDefaultSearchStrategy(true);
      dns = singletonList(filterEntryDN);
      searchScope = SearchControls.OBJECT_SCOPE;
    } else {
      strategy = getSearchStrategy();
      dns = getBaseDNs();
      searchScope = getLdapSearchScope();
    }

    final SearchControls controls = LdapInternalSearch.createDefaultSearchControls();
    final Set<String> ldapAttrsToGet = utils.getLdapAttributesToGet(attrsToGet, oclass);

    controls.setReturningAttributes(ldapAttrsToGet.toArray(new String[ldapAttrsToGet.size()]));
    controls.setSearchScope(searchScope);

    final String optionsFilter = LdapConstants.getSearchFilter(options);

    final String searchFilter =
        oclass.equals(ObjectClass.ACCOUNT)
            ? conn.getConfiguration().getAccountSearchFilter()
            : ((ADConfiguration) conn.getConfiguration()).getGroupSearchFilter();

    final String nativeFilter = filter != null ? filter.getNativeFilter() : null;

    return new LdapInternalSearch(
        conn, getSearchFilter(optionsFilter, nativeFilter, searchFilter), dns, strategy, controls);
  }
  private int getLdapSearchScope() {
    String scope = options.getScope();

    if (scope == null) {
      if (oclass.is(ObjectClass.ACCOUNT_NAME)) {
        scope = ((ADConfiguration) conn.getConfiguration()).getUserSearchScope();
      } else {
        scope = ((ADConfiguration) conn.getConfiguration()).getGroupSearchScope();
      }
    }

    if (OperationOptions.SCOPE_OBJECT.equals(scope)) {
      return SearchControls.OBJECT_SCOPE;
    } else if (OperationOptions.SCOPE_ONE_LEVEL.equals(scope)) {
      return SearchControls.ONELEVEL_SCOPE;
    } else if (OperationOptions.SCOPE_SUBTREE.equals(scope) || scope == null) {
      return SearchControls.SUBTREE_SCOPE;
    } else {
      throw new IllegalArgumentException("Invalid search scope " + scope);
    }
  }