protected boolean isExecutorInvocable(FunctionExecutorContext<R> executor) {

        // Lockable
        try {
            Method invokeMethod = executor.getExecutor().getClass().getMethod("invoke", FunctionInvocation.class, Object[].class);
            if (executor.isLocked() || source.isLocked() && invokeMethod.isAnnotationPresent(Lockable.class)) {
                return false;
            }
        } catch (NoSuchMethodException e) {
            LOGGER.log(Level.SEVERE, "Programmer's fault: Can't find invoke() method (should be defined by interface)", e);
        }

        // Limit
        if (executor.getInvocations() + 1 > (Integer) executor.getValue(Limit.class, "value")) {
            return false;
        }

        // Delay
        int invocation = source.getInvocations() - 1;
        int firstDelay = (Integer) executor.getValue(Delay.class, "firstDelay");
        int delay = (Integer) executor.getValue(Delay.class, "delay");
        if (invocation < firstDelay) {
            return false;
        } else if (delay > 0 && (invocation - firstDelay) % (delay + 1) != 0) {
            return false;
        }

        return true;
    }