private MuleEvent invokeInternal(MuleEvent event) throws MuleException {
    // Ensure we have event in ThreadLocal
    OptimizedRequestContext.unsafeSetEvent(event);

    if (logger.isTraceEnabled()) {
      logger.trace(
          String.format(
              "Invoking %s component for service %s",
              this.getClass().getName(), flowConstruct.getName()));
    }

    if (!lifecycleManager.getState().isStarted() || lifecycleManager.getState().isStopping()) {
      throw new LifecycleException(CoreMessages.isStopped(flowConstruct.getName()), this);
    }

    // Invoke component implementation and gather statistics
    try {
      fireComponentNotification(
          event.getMessage(), ComponentMessageNotification.COMPONENT_PRE_INVOKE);

      long startTime = 0;
      if (statistics.isEnabled()) {
        startTime = System.currentTimeMillis();
      }

      Object result = doInvoke(event);

      if (statistics.isEnabled()) {
        statistics.addExecutionTime(System.currentTimeMillis() - startTime);
      }

      MuleEvent resultEvent = createResultEvent(event, result);
      // Components only have access to the original event, so propogate the
      // stop further processing
      resultEvent.setStopFurtherProcessing(event.isStopFurtherProcessing());
      fireComponentNotification(
          resultEvent.getMessage(), ComponentMessageNotification.COMPONENT_POST_INVOKE);

      return resultEvent;
    } catch (MuleException me) {
      throw me;
    } catch (Exception e) {
      throw new ComponentException(CoreMessages.failedToInvoke(this.toString()), event, this, e);
    }
  }