/**
  * Finds the object builder, null if one found.
  *
  * @param statementAnnotation
  * @return the object builder, null if none found.
  */
 public ObjectBuilder getObjectBuilder(Statement statementAnnotation) {
   Class<? extends ObjectBuilder> objectBuilderClass = statementAnnotation.objectBuilder();
   if (objectBuilderClass != null
       && !ObjectUtils.equals(NullObjectBuilder.class, objectBuilderClass)) {
     ObjectBuilder instance = instantiate(objectBuilderClass);
     if (instance != null) {
       return instance;
     }
   }
   String beanName = statementAnnotation.objectBuilderBean();
   if (StringUtils.isNotEmpty(beanName)) {
     return applicationContext.getBean(beanName, ObjectBuilder.class);
   }
   return objectBuilder;
 }
  /**
   * Finds the statement builder, null if one found.
   *
   * @param statementAnnotation
   * @return the statement builder, null if one found.
   */
  public StatementBuilder getStatementBuilder(Statement statementAnnotation) {
    String beanName = statementAnnotation.statementBuilderBean();
    if (StringUtils.isNotEmpty(beanName)) {
      return applicationContext.getBean(beanName, StatementBuilder.class);
    }

    Class<? extends StatementBuilder> objectBuilderClass = statementAnnotation.statementBuilder();
    if (objectBuilderClass != null) {
      StatementBuilder instance = instantiate(objectBuilderClass);
      if (instance != null) {
        return instance;
      }
    }

    return statementBuilder;
  }
  /**
   * Runs the {@link Statement} enhancement.
   *
   * @param invocation the invocation of the method call.
   * @param returnValue the return value of the method call.
   * @param statementAnnotation the {@link Statement} annotation.
   */
  protected void processStatement(
      MethodInvocation invocation, Object returnValue, Statement statementAnnotation) {
    ObjectBuilder objectBuilder = getObjectBuilder(statementAnnotation);
    StatementBuilder statementBuilder = getStatementBuilder(statementAnnotation);
    Assert.notNull(
        objectBuilder,
        "An ObjectBuilder is required, please provide an instance of the ObjectBuilder as a bean.");
    // Required
    Actor actor =
        findValueForType(
            nl.edia.xapi.annotation.Actor.class,
            invocation,
            returnValue,
            Actor.class,
            objectBuilder);
    // Required
    Verb verb = objectBuilder.build(statementAnnotation.verb(), Verb.class);
    // Required
    IStatementObject object =
        findValueForType(
            nl.edia.xapi.annotation.StatementObject.class,
            invocation,
            returnValue,
            IStatementObject.class,
            objectBuilder);

    if (actor != null && verb != null && object != null) {
      Context context =
          findValueForType(
              nl.edia.xapi.annotation.Context.class,
              invocation,
              returnValue,
              Context.class,
              objectBuilder);
      Result result =
          findValueForType(
              nl.edia.xapi.annotation.Result.class,
              invocation,
              returnValue,
              Result.class,
              objectBuilder);
      gov.adlnet.xapi.model.Statement statement =
          statementBuilder.build(actor, verb, object, result, context, null, null);
      StatementClient statementClient = statementClientFactory.build(invocation, returnValue);
      if (statementClient != null && statement != null) {
        send(statementClient, statement);
      }
    }
  }