public Parser attributeClause() {
        if (attributeClauseParser == null) {
           FutureParser future = scoped("attributeClause");
           attributeClauseParser = future;
           future.setParser(
               plus(
                   choice(
                       sequence(
                           token("ATTRIBUTE"),
                           attributeName(),
                           token("("),
                           star(
                               choice(
                                   sequence(
                                       token("NAME"),
                                       propertyName(),
                                       token("="),
                                       propertyValue()
                                   ),
                                   parameterName()
                               )
                           ),
                           token(")")
                       ),
                       sequence(
                           token("CUSTOM-ATTRIBUTE"),
                           token("IS"),
                           className(),
                           optional(
                               sequence(
                                   token("("),
                                   star(
                                       choice(
                                           sequence(
                                               propertyName(),
                                               token("="),
                                               propertyValue()
                                           ),
                                           parameterName()
                                       )
                                   ),
                                   token(")")
                               )
                           )
                       )
                   )
               )
           );
        }

        return attributeClauseParser;
    }