class StandardProcessorNode extends ProcessorNode implements Connectable {

    @Override
    public Collection<ValidationResult> getValidationErrors() {
        final List<ValidationResult> results = new ArrayList<>();
        try {
            // Processors may go invalid while RUNNING, but only validating while STOPPED is a trade-off
            // we are willing to make in order to save on validation costs that would be unnecessary most of the time.
            if (getScheduledState() == ScheduledState.STOPPED) {
                final ValidationContext validationContext = this.getValidationContextFactory()
                        .newValidationContext(getProperties(), getAnnotationData(), getProcessGroup().getIdentifier(), getIdentifier());

                final Collection<ValidationResult> validationResults;
                try (final NarCloseable narCloseable = NarCloseable.withComponentNarLoader(getProcessor().getClass(), processor.getIdentifier())) {
                    validationResults = getProcessor().validate(validationContext);
                }

                for (final ValidationResult result : validationResults) {
                    if (!result.isValid()) {
                        results.add(result);
                    }
                }

                for (final Relationship relationship : getUndefinedRelationships()) {
                    if (!isAutoTerminated(relationship)) {
                        final ValidationResult error = new ValidationResult.Builder()
                                .explanation("Relationship '" + relationship.getName()
                                        + "' is not connected to any component and is not auto-terminated")
                                .subject("Relationship " + relationship.getName()).valid(false).build();
                        results.add(error);
                    }
                }

                switch (getInputRequirement()) {
                    case INPUT_ALLOWED:
                        break;
                    case INPUT_FORBIDDEN: {
                        final int incomingConnCount = getIncomingNonLoopConnections().size();
                        if (incomingConnCount != 0) {
                            results.add(new ValidationResult.Builder().explanation(
                                    "Processor does not allow upstream connections but currently has " + incomingConnCount)
                                    .subject("Upstream Connections").valid(false).build());
                        }
                        break;
                    }
                    case INPUT_REQUIRED: {
                        if (getIncomingNonLoopConnections().isEmpty()) {
                            results.add(new ValidationResult.Builder()
                                    .explanation("Processor requires an upstream connection but currently has none")
                                    .subject("Upstream Connections").valid(false).build());
                        }
                        break;
                    }
                }
            }
        } catch (final Throwable t) {
            results.add(new ValidationResult.Builder().explanation("Failed to run validation due to " + t.toString())
                    .valid(false).build());
        }
        return results;
    }

    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);

}