class Syntax {

    public void addStepImplementation(final StepImplementation impl) {

        stepImplementationsUsageMap.put(impl, new ArrayList<StepImplementationUsage>());

        PatternMap<StepImplementation> patternMap = this.stepImplementationMap.get(impl.getKeyword());

        if (patternMap == null) {
            patternMap = new PatternMap<StepImplementation>();
            this.stepImplementationMap.put(impl.getKeyword(), patternMap);
        }

        final String pattern = impl.getValue();
        if (!patternMap.containsPattern(pattern)) {

            try {
                patternMap.put(pattern, impl);
            } catch (final PatternSyntaxException e) {

                log.warn("Invalid step implementation pattern: " + e.getMessage() + "\n" + impl.getClass() + "."
                        + impl.getMethod() + " will not be added to the syntax");
            }

        } else {

            final StepImplementation implAlreadyGot = patternMap.getValueForPattern(pattern);

            if (!implAlreadyGot.getMethod().equals(impl.getMethod())) {

                final StepImplementationException ex = new DuplicateStepImplementationException(pattern,
                        patternMap.getValueForPattern(pattern), impl);
                this.syntaxErrorReporter.reportStepImplError(ex);
                if (this.failOnDuplicateStepImplementations) {
                    throw ex;
                }
            } else {
                // this is the same - no need to make a fuss, just ignore it
            }
        }

    }

    public  Syntax();
    public  Syntax(final SyntaxErrorReporter syntaxErrorReporter);

}