@Override
  public void onAfterAddAssociation(
      Object classPK, String associationClassName, Object associationClassPK)
      throws ModelListenerException {

    try {
      User user = userLocalService.getUser((Long) classPK);

      if (associationClassName.equals(Group.class.getName())
          || associationClassName.equals(Organization.class.getName())
          || associationClassName.equals(UserGroup.class.getName())) {

        Role role =
            roleLocalService.fetchRole(user.getCompanyId(), RoleConstants.SOCIAL_OFFICE_USER);

        if (role == null) {
          return;
        }

        Group group = null;

        if (associationClassName.equals(Group.class.getName())) {
          group = groupLocalService.getGroup((Long) associationClassPK);
        } else if (associationClassName.equals(Organization.class.getName())) {

          group =
              groupLocalService.getOrganizationGroup(
                  user.getCompanyId(), (Long) associationClassPK);
        } else if (associationClassName.equals(UserGroup.class.getName())) {

          group =
              groupLocalService.getUserGroupGroup(user.getCompanyId(), (Long) associationClassPK);
        }

        if (groupLocalService.hasRoleGroup(role.getRoleId(), group.getGroupId())) {

          enableSocialOffice(user.getGroup());
        }
      } else if (associationClassName.equals(Role.class.getName())) {
        Role role = roleLocalService.getRole((Long) associationClassPK);

        String name = role.getName();

        if (name.equals(RoleConstants.SOCIAL_OFFICE_USER)) {
          enableSocialOffice(user.getGroup());
        }
      }
    } catch (NoSuchGroupException nsge) {

      // LPS-52675

      if (_log.isDebugEnabled()) {
        _log.debug(nsge, nsge);
      }
    } catch (Exception e) {
      throw new ModelListenerException(e);
    }
  }
  @Override
  protected void doDispatch(RenderRequest renderRequest, RenderResponse renderResponse)
      throws IOException, PortletException {

    try {
      User user = PortalUtil.getUser(renderRequest);

      RenderRequestImpl renderRequestImpl = (RenderRequestImpl) renderRequest;

      DynamicServletRequest dynamicRequest =
          (DynamicServletRequest) renderRequestImpl.getHttpServletRequest();

      dynamicRequest.setParameter("p_u_i_d", String.valueOf(user.getUserId()));

      Group group = user.getGroup();

      dynamicRequest.setParameter("groupId", String.valueOf(group.getGroupId()));

      ActionUtil.getGroup(renderRequest);
    } catch (Exception e) {
      throw new PortletException(e);
    }

    super.doDispatch(renderRequest, renderResponse);
  }
  @Override
  public void onAfterRemoveAssociation(
      Object classPK, String associationClassName, Object associationClassPK)
      throws ModelListenerException {

    try {
      User user = userLocalService.getUser((Long) classPK);

      FinderCacheUtil.clearCache(_MAPPING_TABLE_USERS_ROLES_NAME_LEFT_TO_RIGHT);
      FinderCacheUtil.clearCache(_MAPPING_TABLE_USERS_ROLES_NAME_RIGHT_TO_LEFT);

      ThreadLocalCacheManager.clearAll(Lifecycle.REQUEST);

      if (userLocalService.hasRoleUser(
          user.getCompanyId(), RoleConstants.SOCIAL_OFFICE_USER, user.getUserId(), true)) {

        return;
      }

      if (associationClassName.equals(Group.class.getName())
          || associationClassName.equals(Organization.class.getName())
          || associationClassName.equals(UserGroup.class.getName())) {

        Role role = roleLocalService.getRole(user.getCompanyId(), RoleConstants.SOCIAL_OFFICE_USER);

        Group group = null;

        if (associationClassName.equals(Group.class.getName())) {
          group = groupLocalService.getGroup((Long) associationClassPK);
        } else if (associationClassName.equals(Organization.class.getName())) {

          group =
              groupLocalService.getOrganizationGroup(
                  user.getCompanyId(), (Long) associationClassPK);
        } else if (associationClassName.equals(UserGroup.class.getName())) {

          group =
              groupLocalService.getUserGroupGroup(user.getCompanyId(), (Long) associationClassPK);
        }

        if (groupLocalService.hasRoleGroup(role.getRoleId(), group.getGroupId())) {

          disableSocialOffice(user.getGroup());
        }
      } else if (associationClassName.equals(Role.class.getName())) {
        Role role = roleLocalService.getRole((Long) associationClassPK);

        String name = role.getName();

        if (name.equals(RoleConstants.SOCIAL_OFFICE_USER)) {
          disableSocialOffice(user.getGroup());
        }
      }
    } catch (NoSuchGroupException nsge) {

      // LPS-52675

      if (_log.isDebugEnabled()) {
        _log.debug(nsge, nsge);
      }
    } catch (Exception e) {
      throw new ModelListenerException(e);
    }
  }
  public void importReferences(
      long userId,
      long groupId,
      boolean privateLayout,
      Map<String, String[]> parameterMap,
      File file)
      throws PortalException {

    User user = UserLocalServiceUtil.getUser(userId);

    // Import into the user's group
    Group group = user.getGroup();
    if (group != null) {
      groupId = group.getGroupId();
    }

    long bibliographyId =
        GetterUtil.getLong(ArrayUtil.getValue(parameterMap.get("bibliographyId"), 0));
    // TODO: read default value from resource bundle
    String title =
        GetterUtil.getString(ArrayUtil.getValue(parameterMap.get("title"), 0), "New Bibliography");
    // TODO: handle update of existing references / bibliographies
    boolean updateExisting =
        GetterUtil.getBoolean(ArrayUtil.getValue(parameterMap.get("updateExisting"), 0));
    // TODO: read default value from resource bundle
    String urlTitle =
        GetterUtil.getString(
            ArrayUtil.getValue(parameterMap.get("urlTitle"), 0), "new-bibliography");

    _log.info("bibliographyId = " + bibliographyId);
    _log.info("title = " + title);
    _log.info("updateExisting = " + updateExisting);
    _log.info("urlTitle = " + urlTitle);

    ServiceContext serviceContext = new ServiceContext();
    serviceContext.setCompanyId(user.getCompanyId());
    serviceContext.setScopeGroupId(groupId);
    serviceContext.setUserId(userId);

    try {

      int numProcessed = 0;
      int numImported = 0;
      int numIgnored = 0;
      int numUpdated = 0;

      StopWatch stopWatch = new StopWatch();

      stopWatch.start();

      InputStream inputStream = new FileInputStream(file);

      BufferedReader bufferedReader =
          new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

      BibTeXParser bibTeXParser = new BibTeXParser();

      BibTeXDatabase database = bibTeXParser.parse(bufferedReader);

      List<BibTeXObject> objects = database.getObjects();

      String uuid = null;

      for (BibTeXObject object : objects) {

        if (object.getClass() == BibTeXComment.class) {
          BibTeXComment comment = (BibTeXComment) object;
          _log.info(comment.getValue().toUserString());

          // TODO: read uuid from comment
        }
      }

      Bibliography bibliography = null;

      // TODO
      if (uuid != null) {
        bibliography = BibliographyServiceUtil.getBibliography(uuid, groupId);
      } else if (bibliographyId > 0) {
        bibliography = BibliographyServiceUtil.getBibliography(bibliographyId);
      } else {
        bibliography =
            BibliographyServiceUtil.addBibliography(userId, title, null, urlTitle, serviceContext);
      }

      bibliographyId = bibliography.getBibliographyId();
      uuid = bibliography.getUuid();

      _log.info("Start import");

      Collection<BibTeXEntry> bibTeXEntries = database.getEntries().values();

      _log.info("bibTeXEntries.size() = " + bibTeXEntries.size());

      for (BibTeXEntry bibTeXEntry : bibTeXEntries) {

        String bibTeX = "";

        bibTeX = BibTeXUtil.format(bibTeXEntry);

        // TODO: check whether a reference with the same uid has
        // already been uploaded

        ReferenceServiceUtil.addReference(userId, bibTeX, new String[] {uuid}, serviceContext);

        if (numProcessed % 100 == 0 && numProcessed > 0) {

          float completed =
              ((Integer) numProcessed).floatValue()
                  / ((Integer) bibTeXEntries.size()).floatValue()
                  * 100;

          _log.info(
              "Processed "
                  + numProcessed
                  + " of "
                  + bibTeXEntries.size()
                  + " references in "
                  + stopWatch.getTime()
                  + " ms ("
                  + completed
                  + "%).");
        }

        numProcessed++;
      }

      _log.info("Import took " + stopWatch.getTime() + " ms");
      _log.info("Processed " + numProcessed + " references.");
      _log.info("Imported " + numImported + " references.");
      _log.info("Ignored " + numIgnored + " references.");
      _log.info("Updated " + numUpdated + " references.");

    } catch (IOException ioe) {
      _log.error(ioe);
    } catch (Exception e) {
      _log.error(e);
    }
  }