class AlienContextVariables extends PropertySource {

    @Override
    public Object getProperty(String name) {
        if (!name.startsWith("a4c.")) {
            return null;
        }

        switch (name) {
            case "a4c.application":
                return application;

            case "a4c.application.id":
                return ifNotNull(application, Application::getId);

            case "a4c.application.name":
                return ifNotNull(application, Application::getName);

            case "a4c.environment.type":
                return ifNotNull(applicationEnvironment, ApplicationEnvironment::getEnvironmentType);

            case "a4c.environment.name":
                return ifNotNull(applicationEnvironment, ApplicationEnvironment::getName);
        }

        // lookup for a tag
        if (name.startsWith("a4c.application.tags.")) {
            if (application != null && application.getTags() != null) {
                String tagName = StringUtils.removeStart(name, "a4c.application.tags.");

                for (Tag tag : application.getTags()) {
                    if (tag.getName().equals(tagName)) {
                        return tag.getValue();
                    }
                }
            }
        }

        // lookup for meta properties
        String metaName = StringUtils.removeStart(name, "a4c.");
        String metaValue = findMetaProperties(metaName, application);
        if (metaValue != null) {
            return metaValue;
        }
        metaValue = findMetaProperties(metaName, location);
        if (metaValue != null) {
            return metaValue;
        }

        return null;
    }

    public  AlienContextVariables();

}