@Override
  public Object before(MethodInvocation methodInvocation) throws Throwable {
    SystemEvent systemEvent = findAnnotation(methodInvocation);

    if (systemEvent == _nullSystemEvent) {
      return null;
    }

    if (systemEvent.action() != SystemEventConstants.ACTION_NONE) {
      if (!isValid(methodInvocation, _PHASE_BEFORE)) {
        return null;
      }

      Object[] arguments = methodInvocation.getArguments();

      ClassedModel classedModel = (ClassedModel) arguments[0];

      SystemEventHierarchyEntry systemEventHierarchyEntry =
          SystemEventHierarchyEntryThreadLocal.push(
              getClassName(classedModel), getClassPK(classedModel), systemEvent.action());

      if (systemEventHierarchyEntry != null) {
        systemEventHierarchyEntry.setUuid(getUuid(classedModel));
      }
    }

    return null;
  }
  @Override
  public void afterReturning(MethodInvocation methodInvocation, Object result) throws Throwable {

    SystemEvent systemEvent = findAnnotation(methodInvocation);

    if ((systemEvent == _nullSystemEvent) || !systemEvent.send()) {
      return;
    }

    if (!isValid(methodInvocation, _PHASE_AFTER_RETURNING)) {
      return;
    }

    Object[] arguments = methodInvocation.getArguments();

    ClassedModel classedModel = (ClassedModel) arguments[0];

    long groupId = getGroupId(classedModel);

    String className = getClassName(classedModel);

    String referrerClassName = null;

    if (classedModel instanceof TypedModel) {
      TypedModel typedModel = (TypedModel) classedModel;

      referrerClassName = typedModel.getClassName();
    }

    long classPK = getClassPK(classedModel);

    SystemEventHierarchyEntry systemEventHierarchyEntry =
        SystemEventHierarchyEntryThreadLocal.peek();

    if ((systemEventHierarchyEntry != null)
        && systemEventHierarchyEntry.hasTypedModel(className, classPK)) {

      if (groupId > 0) {
        SystemEventLocalServiceUtil.addSystemEvent(
            0,
            groupId,
            systemEventHierarchyEntry.getClassName(),
            classPK,
            systemEventHierarchyEntry.getUuid(),
            referrerClassName,
            systemEvent.type(),
            systemEventHierarchyEntry.getExtraData());
      } else {
        SystemEventLocalServiceUtil.addSystemEvent(
            getCompanyId(classedModel),
            systemEventHierarchyEntry.getClassName(),
            classPK,
            systemEventHierarchyEntry.getUuid(),
            referrerClassName,
            systemEvent.type(),
            systemEventHierarchyEntry.getExtraData());
      }
    } else if (groupId > 0) {
      SystemEventLocalServiceUtil.addSystemEvent(
          0,
          groupId,
          className,
          classPK,
          getUuid(classedModel),
          referrerClassName,
          systemEvent.type(),
          StringPool.BLANK);
    } else {
      SystemEventLocalServiceUtil.addSystemEvent(
          getCompanyId(classedModel),
          className,
          classPK,
          getUuid(classedModel),
          referrerClassName,
          systemEvent.type(),
          StringPool.BLANK);
    }
  }