class StaticELSpecificationProvider implements ELSpecificationProvider {

    @Override
    public Optional<ELSpecification> getELSpecification(final String agentClass) {
        if (StringUtils.isBlank(agentClass)) {
            throw new IllegalArgumentException("AgentClass is required to obtain the EL specification");
        }

        final List<AgentManifest> agentManifests = agentService.getAgentManifests(agentClass);
        if (agentManifests.isEmpty()) {
            throw new IllegalArgumentException("No manifests exists for the given agent class");
        }

        final AgentManifest agentManifest = agentManifests.get(0);
        if (agentManifest.getAgentType() == null) {
            throw new IllegalArgumentException("AgentManifest AgentType is required to obtain the EL specification");
        }

        // determine the agent type for the key...
        String mappedType;
        final String agentType = agentManifest.getAgentType();
        if (agentType.equals(MINIFI_JAVA_TYPE) || agentType.equals("java")) {
            mappedType = MINIFI_JAVA_TYPE;
        } else if (agentType.equals(MINIFI_CPP_TYPE) || agentType.equals("cpp")) {
            mappedType = MINIFI_CPP_TYPE;
        } else {
            throw new IllegalArgumentException("Unexpected agent type '" + agentType + "'");
        }


        // determine the version for the key...
        String version = null;
        final BuildInfo buildInfo = agentManifest.getBuildInfo();
        if (buildInfo != null && buildInfo.getVersion() != null) {
            final String buildInfoVersion = buildInfo.getVersion();
            final int snapshotIndex = buildInfoVersion.indexOf("-SNAPSHOT");
            if (snapshotIndex > 0) {
                version = buildInfoVersion.substring(0, snapshotIndex);
            } else {
                version = buildInfoVersion;
            }
        }

        // if the type is CPP, check if the EL bundle is included, and if not then return an empty spec
        if (mappedType.equals(MINIFI_CPP_TYPE)) {
            boolean hasELBundle = false;
            if (agentManifest.getBundles() != null) {
                for (final Bundle bundle : agentManifest.getBundles()) {
                    if (MINIFI_CPP_EL_BUNDLE_ARTIFACT.equals(bundle.getArtifact())) {
                        hasELBundle = true;
                        break;
                    }
                }
            }

            if (!hasELBundle) {
                final ELSpecification emptySpec = new ELSpecification();
                emptySpec.setSpecificationKey("missing-el-bundle");
                emptySpec.setOperations(Collections.emptyMap());
                return Optional.of(emptySpec);
            }
        }

        // if version is null then we'll attempt to take the first EL spec using just the type, otherwise look for exact version
        if (version == null) {
            return getCompatibleELSpecification(mappedType);
        } else {
            final String key = getKey(mappedType, version);
            final ELSpecification exactSpecification = specifications.get(key);
            if (exactSpecification == null) {
                LOGGER.warn("No EL specification was found for {}, attempting to find compatible specification", new Object[]{key});
                return getCompatibleELSpecification(mappedType);
            } else {
                return Optional.of(exactSpecification);
            }
        }
    }

    @Autowired public  StaticELSpecificationProvider(final ELSpecificationProperties properties, final AgentService agentService, final ObjectMapper objectMapper);

}