class StandardProcessorNode extends ProcessorNode implements Connectable {

    @Override
    public <T extends ProcessContext & ControllerServiceLookup> void start(final ScheduledExecutorService taskScheduler,
            final long administrativeYieldMillis, final T processContext, final SchedulingAgentCallback schedulingAgentCallback) {
        if (!this.isValid()) {
            throw new IllegalStateException( "Processor " + this.getName() + " is not in a valid state due to " + this.getValidationErrors());
        }
        final ComponentLog procLog = new SimpleProcessLogger(StandardProcessorNode.this.getIdentifier(), processor);
        if (this.scheduledState.compareAndSet(ScheduledState.STOPPED, ScheduledState.STARTING)) { // will ensure that the Processor represented by this node can only be started once
            final Runnable startProcRunnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        invokeTaskAsCancelableFuture(schedulingAgentCallback, new Callable<Void>() {
                            @Override
                            public Void call() throws Exception {
                                try (final NarCloseable nc = NarCloseable.withComponentNarLoader(processor.getClass(), processor.getIdentifier())) {
                                    ReflectionUtils.invokeMethodsWithAnnotation(OnScheduled.class, processor, processContext);
                                    return null;
                                }
                            }
                        });

                        if (scheduledState.compareAndSet(ScheduledState.STARTING, ScheduledState.RUNNING)) {
                            schedulingAgentCallback.trigger(); // callback provided by StandardProcessScheduler to essentially initiate component's onTrigger() cycle
                        } else { // can only happen if stopProcessor was called before service was transitioned to RUNNING state
                            try (final NarCloseable nc = NarCloseable.withComponentNarLoader(processor.getClass(), processor.getIdentifier())) {
                                ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnUnscheduled.class, processor, processContext);
                            }
                            scheduledState.set(ScheduledState.STOPPED);
                        }
                    } catch (final Exception e) {
                        final Throwable cause = e instanceof InvocationTargetException ? e.getCause() : e;
                        procLog.error("{} failed to invoke @OnScheduled method due to {}; processor will not be scheduled to run for {} seconds",
                            new Object[] {StandardProcessorNode.this.getProcessor(), cause, administrativeYieldMillis / 1000L}, cause);
                        LOG.error("Failed to invoke @OnScheduled method due to {}", cause.toString(), cause);

                        ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnUnscheduled.class, processor, processContext);
                        ReflectionUtils.quietlyInvokeMethodsWithAnnotation(OnStopped.class, processor, processContext);

                        if (scheduledState.get() != ScheduledState.STOPPING) { // make sure we only continue retry loop if STOP action wasn't initiated
                            taskScheduler.schedule(this, administrativeYieldMillis, TimeUnit.MILLISECONDS);
                        } else {
                            scheduledState.set(ScheduledState.STOPPED);
                        }
                    }
                }
            };
            taskScheduler.execute(startProcRunnable);
        } else {
            final String procName = this.processor.getClass().getSimpleName();
            LOG.warn("Can not start '" + procName
                    + "' since it's already in the process of being started or it is DISABLED - "
                    + scheduledState.get());
            procLog.warn("Can not start '" + procName
                    + "' since it's already in the process of being started or it is DISABLED - "
                    + scheduledState.get());
        }
    }

    public  StandardProcessorNode(final Processor processor, final String uuid,
                                 final ValidationContextFactory validationContextFactory, final ProcessScheduler scheduler,
                                 final ControllerServiceProvider controllerServiceProvider, final NiFiProperties nifiProperties,
                                 final VariableRegistry variableRegistry, final ComponentLog logger);
    public  StandardProcessorNode(final Processor processor, final String uuid,
                                 final ValidationContextFactory validationContextFactory, final ProcessScheduler scheduler,
                                 final ControllerServiceProvider controllerServiceProvider,
                                 final String componentType, final String componentCanonicalClass, final NiFiProperties nifiProperties,
                                 final VariableRegistry variableRegistry, final ComponentLog logger);

}