@Override
  public void updateDocument(
      String searchEngineId, long companyId, Document document, boolean commitImmediately)
      throws SearchException {

    if (isIndexReadOnly() || (document == null)) {
      return;
    }

    if (_log.isDebugEnabled()) {
      _log.debug("Document " + document.toString());
    }

    SearchEngine searchEngine = _searchEngineHelper.getSearchEngine(searchEngineId);

    IndexWriter indexWriter = searchEngine.getIndexWriter();

    _searchPermissionChecker.addPermissionFields(companyId, document);

    SearchContext searchContext = new SearchContext();

    searchContext.setCompanyId(companyId);
    searchContext.setSearchEngineId(searchEngineId);

    setCommitImmediately(searchContext, commitImmediately || ProxyModeThreadLocal.isForceSync());

    indexWriter.updateDocument(searchContext, document);
  }
  @Override
  public void runBeforeClass(TestContext testContext) {
    Class<?> testClass = testContext.getClazz();

    Sync sync = AnnotationLocator.locate(testClass, Sync.class);

    classSyncHandler.setSync(sync);
    classSyncHandler.setForceSync(ProxyModeThreadLocal.isForceSync());

    classSyncHandler.enableSync();
  }
  @Override
  public void runBeforeTest(TestContext testContext) {
    Method method = testContext.getMethod();
    Class<?> testClass = testContext.getClazz();

    Sync sync = AnnotationLocator.locate(method, testClass, Sync.class);

    methodSyncHandler.setForceSync(ProxyModeThreadLocal.isForceSync());
    methodSyncHandler.setSync(sync);

    methodSyncHandler.enableSync();
  }
  public void editUserGroup(ActionRequest actionRequest, ActionResponse actionResponse)
      throws Exception {

    long userGroupId = ParamUtil.getLong(actionRequest, "userGroupId");

    String name = ParamUtil.getString(actionRequest, "name");
    String description = ParamUtil.getString(actionRequest, "description");

    ServiceContext serviceContext =
        ServiceContextFactory.getInstance(UserGroup.class.getName(), actionRequest);

    UserGroup userGroup = null;

    try (ProxyModeThreadLocalCloseable proxyModeThreadLocalCloseable =
        new ProxyModeThreadLocalCloseable()) {

      ProxyModeThreadLocal.setForceSync(true);

      if (userGroupId <= 0) {

        // Add user group

        userGroup = _userGroupService.addUserGroup(name, description, serviceContext);
      } else {

        // Update user group

        userGroup =
            _userGroupService.updateUserGroup(userGroupId, name, description, serviceContext);
      }
    }

    // Layout set prototypes

    long publicLayoutSetPrototypeId =
        ParamUtil.getLong(actionRequest, "publicLayoutSetPrototypeId");
    long privateLayoutSetPrototypeId =
        ParamUtil.getLong(actionRequest, "privateLayoutSetPrototypeId");
    boolean publicLayoutSetPrototypeLinkEnabled =
        ParamUtil.getBoolean(actionRequest, "publicLayoutSetPrototypeLinkEnabled");
    boolean privateLayoutSetPrototypeLinkEnabled =
        ParamUtil.getBoolean(actionRequest, "privateLayoutSetPrototypeLinkEnabled");

    if ((privateLayoutSetPrototypeId > 0) || (publicLayoutSetPrototypeId > 0)) {

      SitesUtil.updateLayoutSetPrototypesLinks(
          userGroup.getGroup(),
          publicLayoutSetPrototypeId,
          privateLayoutSetPrototypeId,
          publicLayoutSetPrototypeLinkEnabled,
          privateLayoutSetPrototypeLinkEnabled);
    }
  }
    public void enableSync() {
      if (_sync == null) {
        return;
      }

      ProxyModeThreadLocal.setForceSync(true);

      replaceDestination(DestinationNames.ASYNC_SERVICE);
      replaceDestination(DestinationNames.BACKGROUND_TASK);
      replaceDestination(DestinationNames.DOCUMENT_LIBRARY_RAW_METADATA_PROCESSOR);
      replaceDestination(DestinationNames.DOCUMENT_LIBRARY_SYNC_EVENT_PROCESSOR);
      replaceDestination(DestinationNames.MAIL);
      replaceDestination(DestinationNames.SUBSCRIPTION_SENDER);
    }
  public void editUserGroupAssignments(ActionRequest actionRequest, ActionResponse actionResponse)
      throws Exception {

    long userGroupId = ParamUtil.getLong(actionRequest, "userGroupId");

    long[] addUserIds = StringUtil.split(ParamUtil.getString(actionRequest, "addUserIds"), 0L);
    long[] removeUserIds =
        StringUtil.split(ParamUtil.getString(actionRequest, "removeUserIds"), 0L);

    try (ProxyModeThreadLocalCloseable proxyModeThreadLocalCloseable =
        new ProxyModeThreadLocalCloseable()) {

      ProxyModeThreadLocal.setForceSync(true);

      _userService.addUserGroupUsers(userGroupId, addUserIds);
      _userService.unsetUserGroupUsers(userGroupId, removeUserIds);
    }
  }
    public void restorePreviousSync() {
      if (_sync == null) {
        return;
      }

      ProxyModeThreadLocal.setForceSync(_forceSync);

      MessageBus messageBus = MessageBusUtil.getMessageBus();

      for (Destination destination : _asyncServiceDestinations) {
        messageBus.replace(destination);
      }

      _asyncServiceDestinations.clear();

      for (String absentDestinationName : _absentDestinationNames) {
        messageBus.removeDestination(absentDestinationName);
      }
    }