/*
 * generated by Xtext
 */
package org.polarsys.chess.xtext.services;

import com.google.inject.Singleton;
import com.google.inject.Inject;

import java.util.List;

import org.eclipse.xtext.*;
import org.eclipse.xtext.service.GrammarProvider;
import org.eclipse.xtext.service.AbstractElementFinder.*;

import org.eclipse.xtext.common.services.TerminalsGrammarAccess;

@Singleton
public class FlaDslGrammarAccess extends AbstractGrammarElementFinder {
	
	
	public class BehaviourElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Behaviour");
		private final Assignment cRulesAssignment = (Assignment)rule.eContents().get(1);
		private final RuleCall cRulesExpressionParserRuleCall_0 = (RuleCall)cRulesAssignment.eContents().get(0);
		
		///*
		// * FLA Grammar
		// */ Behaviour:
		//	rules+=Expression+;
		@Override public ParserRule getRule() { return rule; }

		//rules+=Expression+
		public Assignment getRulesAssignment() { return cRulesAssignment; }

		//Expression
		public RuleCall getRulesExpressionParserRuleCall_0() { return cRulesExpressionParserRuleCall_0; }
	}

	public class ExpressionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Expression");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cFLAKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cLhsAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cLhsLhsParserRuleCall_1_0 = (RuleCall)cLhsAssignment_1.eContents().get(0);
		private final Keyword cHyphenMinusGreaterThanSignKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cRhsAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cRhsRhsParserRuleCall_3_0 = (RuleCall)cRhsAssignment_3.eContents().get(0);
		private final Keyword cSemicolonKeyword_4 = (Keyword)cGroup.eContents().get(4);
		
		//Expression:
		//	'FLA:' lhs=Lhs '->' rhs=Rhs ';';
		@Override public ParserRule getRule() { return rule; }

		//'FLA:' lhs=Lhs '->' rhs=Rhs ';'
		public Group getGroup() { return cGroup; }

		//'FLA:'
		public Keyword getFLAKeyword_0() { return cFLAKeyword_0; }

		//lhs=Lhs
		public Assignment getLhsAssignment_1() { return cLhsAssignment_1; }

		//Lhs
		public RuleCall getLhsLhsParserRuleCall_1_0() { return cLhsLhsParserRuleCall_1_0; }

		//'->'
		public Keyword getHyphenMinusGreaterThanSignKeyword_2() { return cHyphenMinusGreaterThanSignKeyword_2; }

		//rhs=Rhs
		public Assignment getRhsAssignment_3() { return cRhsAssignment_3; }

		//Rhs
		public RuleCall getRhsRhsParserRuleCall_3_0() { return cRhsRhsParserRuleCall_3_0; }

		//';'
		public Keyword getSemicolonKeyword_4() { return cSemicolonKeyword_4; }
	}

	public class LhsElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Lhs");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cFailuresAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cFailuresInputExpressionParserRuleCall_0_0 = (RuleCall)cFailuresAssignment_0.eContents().get(0);
		private final Group cGroup_1 = (Group)cGroup.eContents().get(1);
		private final Keyword cCommaKeyword_1_0 = (Keyword)cGroup_1.eContents().get(0);
		private final Assignment cFailuresAssignment_1_1 = (Assignment)cGroup_1.eContents().get(1);
		private final RuleCall cFailuresInputExpressionParserRuleCall_1_1_0 = (RuleCall)cFailuresAssignment_1_1.eContents().get(0);
		
		//Lhs:
		//	failures+=InputExpression (',' failures+=InputExpression)*;
		@Override public ParserRule getRule() { return rule; }

		//failures+=InputExpression (',' failures+=InputExpression)*
		public Group getGroup() { return cGroup; }

		//failures+=InputExpression
		public Assignment getFailuresAssignment_0() { return cFailuresAssignment_0; }

		//InputExpression
		public RuleCall getFailuresInputExpressionParserRuleCall_0_0() { return cFailuresInputExpressionParserRuleCall_0_0; }

		//(',' failures+=InputExpression)*
		public Group getGroup_1() { return cGroup_1; }

		//','
		public Keyword getCommaKeyword_1_0() { return cCommaKeyword_1_0; }

		//failures+=InputExpression
		public Assignment getFailuresAssignment_1_1() { return cFailuresAssignment_1_1; }

		//InputExpression
		public RuleCall getFailuresInputExpressionParserRuleCall_1_1_0() { return cFailuresInputExpressionParserRuleCall_1_1_0; }
	}

	public class RhsElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Rhs");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cFailuresAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cFailuresOutputExpressionParserRuleCall_0_0 = (RuleCall)cFailuresAssignment_0.eContents().get(0);
		private final Group cGroup_1 = (Group)cGroup.eContents().get(1);
		private final Keyword cCommaKeyword_1_0 = (Keyword)cGroup_1.eContents().get(0);
		private final Assignment cFailuresAssignment_1_1 = (Assignment)cGroup_1.eContents().get(1);
		private final RuleCall cFailuresOutputExpressionParserRuleCall_1_1_0 = (RuleCall)cFailuresAssignment_1_1.eContents().get(0);
		
		//Rhs:
		//	failures+=OutputExpression (',' failures+=OutputExpression)*;
		@Override public ParserRule getRule() { return rule; }

		//failures+=OutputExpression (',' failures+=OutputExpression)*
		public Group getGroup() { return cGroup; }

		//failures+=OutputExpression
		public Assignment getFailuresAssignment_0() { return cFailuresAssignment_0; }

		//OutputExpression
		public RuleCall getFailuresOutputExpressionParserRuleCall_0_0() { return cFailuresOutputExpressionParserRuleCall_0_0; }

		//(',' failures+=OutputExpression)*
		public Group getGroup_1() { return cGroup_1; }

		//','
		public Keyword getCommaKeyword_1_0() { return cCommaKeyword_1_0; }

		//failures+=OutputExpression
		public Assignment getFailuresAssignment_1_1() { return cFailuresAssignment_1_1; }

		//OutputExpression
		public RuleCall getFailuresOutputExpressionParserRuleCall_1_1_0() { return cFailuresOutputExpressionParserRuleCall_1_1_0; }
	}

	public class InputExpressionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.InputExpression");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Alternatives cAlternatives_0 = (Alternatives)cGroup.eContents().get(0);
		private final Assignment cRefAssignment_0_0 = (Assignment)cAlternatives_0.eContents().get(0);
		private final CrossReference cRefPortCrossReference_0_0_0 = (CrossReference)cRefAssignment_0_0.eContents().get(0);
		private final RuleCall cRefPortIDTerminalRuleCall_0_0_0_1 = (RuleCall)cRefPortCrossReference_0_0_0.eContents().get(1);
		private final Keyword cUndefinedKeyword_0_1 = (Keyword)cAlternatives_0.eContents().get(1);
		private final Keyword cFullStopKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cFailureExprAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cFailureExprInFailureExprParserRuleCall_2_0 = (RuleCall)cFailureExprAssignment_2.eContents().get(0);
		
		//InputExpression:
		//	(ref=[uml::Port] | "undefined") '.' failureExpr=InFailureExpr;
		@Override public ParserRule getRule() { return rule; }

		//(ref=[uml::Port] | "undefined") '.' failureExpr=InFailureExpr
		public Group getGroup() { return cGroup; }

		//ref=[uml::Port] | "undefined"
		public Alternatives getAlternatives_0() { return cAlternatives_0; }

		//ref=[uml::Port]
		public Assignment getRefAssignment_0_0() { return cRefAssignment_0_0; }

		//[uml::Port]
		public CrossReference getRefPortCrossReference_0_0_0() { return cRefPortCrossReference_0_0_0; }

		//ID
		public RuleCall getRefPortIDTerminalRuleCall_0_0_0_1() { return cRefPortIDTerminalRuleCall_0_0_0_1; }

		//"undefined"
		public Keyword getUndefinedKeyword_0_1() { return cUndefinedKeyword_0_1; }

		//'.'
		public Keyword getFullStopKeyword_1() { return cFullStopKeyword_1; }

		//failureExpr=InFailureExpr
		public Assignment getFailureExprAssignment_2() { return cFailureExprAssignment_2; }

		//InFailureExpr
		public RuleCall getFailureExprInFailureExprParserRuleCall_2_0() { return cFailureExprInFailureExprParserRuleCall_2_0; }
	}

	public class OutputExpressionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.OutputExpression");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Alternatives cAlternatives_0 = (Alternatives)cGroup.eContents().get(0);
		private final Assignment cRefAssignment_0_0 = (Assignment)cAlternatives_0.eContents().get(0);
		private final CrossReference cRefPortCrossReference_0_0_0 = (CrossReference)cRefAssignment_0_0.eContents().get(0);
		private final RuleCall cRefPortIDTerminalRuleCall_0_0_0_1 = (RuleCall)cRefPortCrossReference_0_0_0.eContents().get(1);
		private final Keyword cUndefinedKeyword_0_1 = (Keyword)cAlternatives_0.eContents().get(1);
		private final Keyword cFullStopKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cFailureExprAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cFailureExprOutFailureExprParserRuleCall_2_0 = (RuleCall)cFailureExprAssignment_2.eContents().get(0);
		
		//OutputExpression:
		//	(ref=[uml::Port] | "undefined") '.' failureExpr=OutFailureExpr;
		@Override public ParserRule getRule() { return rule; }

		//(ref=[uml::Port] | "undefined") '.' failureExpr=OutFailureExpr
		public Group getGroup() { return cGroup; }

		//ref=[uml::Port] | "undefined"
		public Alternatives getAlternatives_0() { return cAlternatives_0; }

		//ref=[uml::Port]
		public Assignment getRefAssignment_0_0() { return cRefAssignment_0_0; }

		//[uml::Port]
		public CrossReference getRefPortCrossReference_0_0_0() { return cRefPortCrossReference_0_0_0; }

		//ID
		public RuleCall getRefPortIDTerminalRuleCall_0_0_0_1() { return cRefPortIDTerminalRuleCall_0_0_0_1; }

		//"undefined"
		public Keyword getUndefinedKeyword_0_1() { return cUndefinedKeyword_0_1; }

		//'.'
		public Keyword getFullStopKeyword_1() { return cFullStopKeyword_1; }

		//failureExpr=OutFailureExpr
		public Assignment getFailureExprAssignment_2() { return cFailureExprAssignment_2; }

		//OutFailureExpr
		public RuleCall getFailureExprOutFailureExprParserRuleCall_2_0() { return cFailureExprOutFailureExprParserRuleCall_2_0; }
	}

	public class InFailureExprElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.InFailureExpr");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final Assignment cFailuresAssignment_0 = (Assignment)cAlternatives.eContents().get(0);
		private final RuleCall cFailuresWildcardDefinitionParserRuleCall_0_0 = (RuleCall)cFailuresAssignment_0.eContents().get(0);
		private final Assignment cFailuresAssignment_1 = (Assignment)cAlternatives.eContents().get(1);
		private final RuleCall cFailuresNoFailureDefinitionParserRuleCall_1_0 = (RuleCall)cFailuresAssignment_1.eContents().get(0);
		private final Assignment cFailuresAssignment_2 = (Assignment)cAlternatives.eContents().get(2);
		private final RuleCall cFailuresFailureDefinitionParserRuleCall_2_0 = (RuleCall)cFailuresAssignment_2.eContents().get(0);
		private final Group cGroup_3 = (Group)cAlternatives.eContents().get(3);
		private final Keyword cLeftCurlyBracketKeyword_3_0 = (Keyword)cGroup_3.eContents().get(0);
		private final Assignment cFailuresAssignment_3_1 = (Assignment)cGroup_3.eContents().get(1);
		private final RuleCall cFailuresFailureDefinitionParserRuleCall_3_1_0 = (RuleCall)cFailuresAssignment_3_1.eContents().get(0);
		private final Group cGroup_3_2 = (Group)cGroup_3.eContents().get(2);
		private final Keyword cCommaKeyword_3_2_0 = (Keyword)cGroup_3_2.eContents().get(0);
		private final Assignment cFailuresAssignment_3_2_1 = (Assignment)cGroup_3_2.eContents().get(1);
		private final RuleCall cFailuresFailureDefinitionParserRuleCall_3_2_1_0 = (RuleCall)cFailuresAssignment_3_2_1.eContents().get(0);
		private final Keyword cRightCurlyBracketKeyword_3_3 = (Keyword)cGroup_3.eContents().get(3);
		private final Assignment cFailuresAssignment_4 = (Assignment)cAlternatives.eContents().get(4);
		private final RuleCall cFailuresVariableDefinitionParserRuleCall_4_0 = (RuleCall)cFailuresAssignment_4.eContents().get(0);
		
		//InFailureExpr:
		//	failures+=WildcardDefinition | failures+=NoFailureDefinition | failures+=FailureDefinition |
		//	'{' failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}' | failures+=VariableDefinition;
		@Override public ParserRule getRule() { return rule; }

		//failures+=WildcardDefinition | failures+=NoFailureDefinition | failures+=FailureDefinition | '{'
		//failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}' | failures+=VariableDefinition
		public Alternatives getAlternatives() { return cAlternatives; }

		//failures+=WildcardDefinition
		public Assignment getFailuresAssignment_0() { return cFailuresAssignment_0; }

		//WildcardDefinition
		public RuleCall getFailuresWildcardDefinitionParserRuleCall_0_0() { return cFailuresWildcardDefinitionParserRuleCall_0_0; }

		//failures+=NoFailureDefinition
		public Assignment getFailuresAssignment_1() { return cFailuresAssignment_1; }

		//NoFailureDefinition
		public RuleCall getFailuresNoFailureDefinitionParserRuleCall_1_0() { return cFailuresNoFailureDefinitionParserRuleCall_1_0; }

		//failures+=FailureDefinition
		public Assignment getFailuresAssignment_2() { return cFailuresAssignment_2; }

		//FailureDefinition
		public RuleCall getFailuresFailureDefinitionParserRuleCall_2_0() { return cFailuresFailureDefinitionParserRuleCall_2_0; }

		//'{' failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}'
		public Group getGroup_3() { return cGroup_3; }

		//'{'
		public Keyword getLeftCurlyBracketKeyword_3_0() { return cLeftCurlyBracketKeyword_3_0; }

		//failures+=FailureDefinition
		public Assignment getFailuresAssignment_3_1() { return cFailuresAssignment_3_1; }

		//FailureDefinition
		public RuleCall getFailuresFailureDefinitionParserRuleCall_3_1_0() { return cFailuresFailureDefinitionParserRuleCall_3_1_0; }

		//(',' failures+=FailureDefinition)+
		public Group getGroup_3_2() { return cGroup_3_2; }

		//','
		public Keyword getCommaKeyword_3_2_0() { return cCommaKeyword_3_2_0; }

		//failures+=FailureDefinition
		public Assignment getFailuresAssignment_3_2_1() { return cFailuresAssignment_3_2_1; }

		//FailureDefinition
		public RuleCall getFailuresFailureDefinitionParserRuleCall_3_2_1_0() { return cFailuresFailureDefinitionParserRuleCall_3_2_1_0; }

		//'}'
		public Keyword getRightCurlyBracketKeyword_3_3() { return cRightCurlyBracketKeyword_3_3; }

		//failures+=VariableDefinition
		public Assignment getFailuresAssignment_4() { return cFailuresAssignment_4; }

		//VariableDefinition
		public RuleCall getFailuresVariableDefinitionParserRuleCall_4_0() { return cFailuresVariableDefinitionParserRuleCall_4_0; }
	}

	public class OutFailureExprElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.OutFailureExpr");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final Assignment cFailuresAssignment_0 = (Assignment)cAlternatives.eContents().get(0);
		private final RuleCall cFailuresNoFailureDefinitionParserRuleCall_0_0 = (RuleCall)cFailuresAssignment_0.eContents().get(0);
		private final Assignment cFailuresAssignment_1 = (Assignment)cAlternatives.eContents().get(1);
		private final RuleCall cFailuresComplexNofailureDefinitionParserRuleCall_1_0 = (RuleCall)cFailuresAssignment_1.eContents().get(0);
		private final Assignment cFailuresAssignment_2 = (Assignment)cAlternatives.eContents().get(2);
		private final RuleCall cFailuresFailureDefinitionParserRuleCall_2_0 = (RuleCall)cFailuresAssignment_2.eContents().get(0);
		private final Group cGroup_3 = (Group)cAlternatives.eContents().get(3);
		private final Keyword cLeftCurlyBracketKeyword_3_0 = (Keyword)cGroup_3.eContents().get(0);
		private final Assignment cFailuresAssignment_3_1 = (Assignment)cGroup_3.eContents().get(1);
		private final RuleCall cFailuresFailureDefinitionParserRuleCall_3_1_0 = (RuleCall)cFailuresAssignment_3_1.eContents().get(0);
		private final Group cGroup_3_2 = (Group)cGroup_3.eContents().get(2);
		private final Keyword cCommaKeyword_3_2_0 = (Keyword)cGroup_3_2.eContents().get(0);
		private final Assignment cFailuresAssignment_3_2_1 = (Assignment)cGroup_3_2.eContents().get(1);
		private final RuleCall cFailuresFailureDefinitionParserRuleCall_3_2_1_0 = (RuleCall)cFailuresAssignment_3_2_1.eContents().get(0);
		private final Keyword cRightCurlyBracketKeyword_3_3 = (Keyword)cGroup_3.eContents().get(3);
		private final Assignment cFailuresAssignment_4 = (Assignment)cAlternatives.eContents().get(4);
		private final RuleCall cFailuresVariableDefinitionParserRuleCall_4_0 = (RuleCall)cFailuresAssignment_4.eContents().get(0);
		
		//OutFailureExpr:
		//	failures+=NoFailureDefinition | failures+=ComplexNofailureDefinition | failures+=FailureDefinition |
		//	'{' failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}' | failures+=VariableDefinition;
		@Override public ParserRule getRule() { return rule; }

		//failures+=NoFailureDefinition | failures+=ComplexNofailureDefinition | failures+=FailureDefinition | '{'
		//failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}' | failures+=VariableDefinition
		public Alternatives getAlternatives() { return cAlternatives; }

		//failures+=NoFailureDefinition
		public Assignment getFailuresAssignment_0() { return cFailuresAssignment_0; }

		//NoFailureDefinition
		public RuleCall getFailuresNoFailureDefinitionParserRuleCall_0_0() { return cFailuresNoFailureDefinitionParserRuleCall_0_0; }

		//failures+=ComplexNofailureDefinition
		public Assignment getFailuresAssignment_1() { return cFailuresAssignment_1; }

		//ComplexNofailureDefinition
		public RuleCall getFailuresComplexNofailureDefinitionParserRuleCall_1_0() { return cFailuresComplexNofailureDefinitionParserRuleCall_1_0; }

		//failures+=FailureDefinition
		public Assignment getFailuresAssignment_2() { return cFailuresAssignment_2; }

		//FailureDefinition
		public RuleCall getFailuresFailureDefinitionParserRuleCall_2_0() { return cFailuresFailureDefinitionParserRuleCall_2_0; }

		//'{' failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}'
		public Group getGroup_3() { return cGroup_3; }

		//'{'
		public Keyword getLeftCurlyBracketKeyword_3_0() { return cLeftCurlyBracketKeyword_3_0; }

		//failures+=FailureDefinition
		public Assignment getFailuresAssignment_3_1() { return cFailuresAssignment_3_1; }

		//FailureDefinition
		public RuleCall getFailuresFailureDefinitionParserRuleCall_3_1_0() { return cFailuresFailureDefinitionParserRuleCall_3_1_0; }

		//(',' failures+=FailureDefinition)+
		public Group getGroup_3_2() { return cGroup_3_2; }

		//','
		public Keyword getCommaKeyword_3_2_0() { return cCommaKeyword_3_2_0; }

		//failures+=FailureDefinition
		public Assignment getFailuresAssignment_3_2_1() { return cFailuresAssignment_3_2_1; }

		//FailureDefinition
		public RuleCall getFailuresFailureDefinitionParserRuleCall_3_2_1_0() { return cFailuresFailureDefinitionParserRuleCall_3_2_1_0; }

		//'}'
		public Keyword getRightCurlyBracketKeyword_3_3() { return cRightCurlyBracketKeyword_3_3; }

		//failures+=VariableDefinition
		public Assignment getFailuresAssignment_4() { return cFailuresAssignment_4; }

		//VariableDefinition
		public RuleCall getFailuresVariableDefinitionParserRuleCall_4_0() { return cFailuresVariableDefinitionParserRuleCall_4_0; }
	}

	public class DefinitionsElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Definitions");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final RuleCall cFailureDefinitionParserRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0);
		private final RuleCall cNoFailureDefinitionParserRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1);
		private final RuleCall cComplexNofailureDefinitionParserRuleCall_2 = (RuleCall)cAlternatives.eContents().get(2);
		private final RuleCall cWildcardDefinitionParserRuleCall_3 = (RuleCall)cAlternatives.eContents().get(3);
		private final RuleCall cVariableDefinitionParserRuleCall_4 = (RuleCall)cAlternatives.eContents().get(4);
		
		//Definitions:
		//	FailureDefinition | NoFailureDefinition | ComplexNofailureDefinition | WildcardDefinition | VariableDefinition;
		@Override public ParserRule getRule() { return rule; }

		//FailureDefinition | NoFailureDefinition | ComplexNofailureDefinition | WildcardDefinition | VariableDefinition
		public Alternatives getAlternatives() { return cAlternatives; }

		//FailureDefinition
		public RuleCall getFailureDefinitionParserRuleCall_0() { return cFailureDefinitionParserRuleCall_0; }

		//NoFailureDefinition
		public RuleCall getNoFailureDefinitionParserRuleCall_1() { return cNoFailureDefinitionParserRuleCall_1; }

		//ComplexNofailureDefinition
		public RuleCall getComplexNofailureDefinitionParserRuleCall_2() { return cComplexNofailureDefinitionParserRuleCall_2; }

		//WildcardDefinition
		public RuleCall getWildcardDefinitionParserRuleCall_3() { return cWildcardDefinitionParserRuleCall_3; }

		//VariableDefinition
		public RuleCall getVariableDefinitionParserRuleCall_4() { return cVariableDefinitionParserRuleCall_4; }
	}

	public class FailureDefinitionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.FailureDefinition");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cFailureDefinitionAction_0 = (Action)cGroup.eContents().get(0);
		private final Assignment cTypeAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cTypeActualFailureTypeEnumRuleCall_1_0 = (RuleCall)cTypeAssignment_1.eContents().get(0);
		private final Group cGroup_2 = (Group)cGroup.eContents().get(2);
		private final Keyword cFullStopKeyword_2_0 = (Keyword)cGroup_2.eContents().get(0);
		private final Assignment cAcidAvoidableAssignment_2_1 = (Assignment)cGroup_2.eContents().get(1);
		private final RuleCall cAcidAvoidableACIDavoidableParserRuleCall_2_1_0 = (RuleCall)cAcidAvoidableAssignment_2_1.eContents().get(0);
		
		//FailureDefinition:
		//	{FailureDefinition} type=ActualFailureType ('.' acidAvoidable=ACIDavoidable)?;
		@Override public ParserRule getRule() { return rule; }

		//{FailureDefinition} type=ActualFailureType ('.' acidAvoidable=ACIDavoidable)?
		public Group getGroup() { return cGroup; }

		//{FailureDefinition}
		public Action getFailureDefinitionAction_0() { return cFailureDefinitionAction_0; }

		//type=ActualFailureType
		public Assignment getTypeAssignment_1() { return cTypeAssignment_1; }

		//ActualFailureType
		public RuleCall getTypeActualFailureTypeEnumRuleCall_1_0() { return cTypeActualFailureTypeEnumRuleCall_1_0; }

		//('.' acidAvoidable=ACIDavoidable)?
		public Group getGroup_2() { return cGroup_2; }

		//'.'
		public Keyword getFullStopKeyword_2_0() { return cFullStopKeyword_2_0; }

		//acidAvoidable=ACIDavoidable
		public Assignment getAcidAvoidableAssignment_2_1() { return cAcidAvoidableAssignment_2_1; }

		//ACIDavoidable
		public RuleCall getAcidAvoidableACIDavoidableParserRuleCall_2_1_0() { return cAcidAvoidableACIDavoidableParserRuleCall_2_1_0; }
	}

	public class NoFailureDefinitionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.NoFailureDefinition");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cNoFailureDefinitionAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cNoFailureKeyword_1 = (Keyword)cGroup.eContents().get(1);
		
		//NoFailureDefinition:
		//	{NoFailureDefinition} 'noFailure';
		@Override public ParserRule getRule() { return rule; }

		//{NoFailureDefinition} 'noFailure'
		public Group getGroup() { return cGroup; }

		//{NoFailureDefinition}
		public Action getNoFailureDefinitionAction_0() { return cNoFailureDefinitionAction_0; }

		//'noFailure'
		public Keyword getNoFailureKeyword_1() { return cNoFailureKeyword_1; }
	}

	public class ComplexNofailureDefinitionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.ComplexNofailureDefinition");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cNoFailureDefinitionAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cNoFailureKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Keyword cFullStopKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cAcidMitigationAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cAcidMitigationACIDMitigationParserRuleCall_3_0 = (RuleCall)cAcidMitigationAssignment_3.eContents().get(0);
		
		//ComplexNofailureDefinition:
		//	{NoFailureDefinition} 'noFailure' '.' acidMitigation=ACIDMitigation;
		@Override public ParserRule getRule() { return rule; }

		//{NoFailureDefinition} 'noFailure' '.' acidMitigation=ACIDMitigation
		public Group getGroup() { return cGroup; }

		//{NoFailureDefinition}
		public Action getNoFailureDefinitionAction_0() { return cNoFailureDefinitionAction_0; }

		//'noFailure'
		public Keyword getNoFailureKeyword_1() { return cNoFailureKeyword_1; }

		//'.'
		public Keyword getFullStopKeyword_2() { return cFullStopKeyword_2; }

		//acidMitigation=ACIDMitigation
		public Assignment getAcidMitigationAssignment_3() { return cAcidMitigationAssignment_3; }

		//ACIDMitigation
		public RuleCall getAcidMitigationACIDMitigationParserRuleCall_3_0() { return cAcidMitigationACIDMitigationParserRuleCall_3_0; }
	}

	public class WildcardDefinitionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.WildcardDefinition");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cWildcardDefinitionAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cWildcardKeyword_1 = (Keyword)cGroup.eContents().get(1);
		
		//WildcardDefinition:
		//	{WildcardDefinition} 'wildcard';
		@Override public ParserRule getRule() { return rule; }

		//{WildcardDefinition} 'wildcard'
		public Group getGroup() { return cGroup; }

		//{WildcardDefinition}
		public Action getWildcardDefinitionAction_0() { return cWildcardDefinitionAction_0; }

		//'wildcard'
		public Keyword getWildcardKeyword_1() { return cWildcardKeyword_1; }
	}

	public class VariableDefinitionElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.VariableDefinition");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cVariableDefinitionAction_0 = (Action)cGroup.eContents().get(0);
		private final Assignment cVariableNameAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cVariableNameIDTerminalRuleCall_1_0 = (RuleCall)cVariableNameAssignment_1.eContents().get(0);
		
		//VariableDefinition:
		//	{VariableDefinition} variableName=ID;
		@Override public ParserRule getRule() { return rule; }

		//{VariableDefinition} variableName=ID
		public Group getGroup() { return cGroup; }

		//{VariableDefinition}
		public Action getVariableDefinitionAction_0() { return cVariableDefinitionAction_0; }

		//variableName=ID
		public Assignment getVariableNameAssignment_1() { return cVariableNameAssignment_1; }

		//ID
		public RuleCall getVariableNameIDTerminalRuleCall_1_0() { return cVariableNameIDTerminalRuleCall_1_0; }
	}

	public class ACIDavoidableElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.ACIDavoidable");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cAAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cAAavoidableEnumRuleCall_0_0 = (RuleCall)cAAssignment_0.eContents().get(0);
		private final Keyword cFullStopKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cCAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cCCavoidableEnumRuleCall_2_0 = (RuleCall)cCAssignment_2.eContents().get(0);
		private final Keyword cFullStopKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Assignment cIAssignment_4 = (Assignment)cGroup.eContents().get(4);
		private final RuleCall cIIavoidableEnumRuleCall_4_0 = (RuleCall)cIAssignment_4.eContents().get(0);
		private final Keyword cFullStopKeyword_5 = (Keyword)cGroup.eContents().get(5);
		private final Assignment cDAssignment_6 = (Assignment)cGroup.eContents().get(6);
		private final RuleCall cDDavoidableEnumRuleCall_6_0 = (RuleCall)cDAssignment_6.eContents().get(0);
		
		//ACIDavoidable:
		//	a=Aavoidable '.' c=Cavoidable '.' i=Iavoidable '.' d=Davoidable;
		@Override public ParserRule getRule() { return rule; }

		//a=Aavoidable '.' c=Cavoidable '.' i=Iavoidable '.' d=Davoidable
		public Group getGroup() { return cGroup; }

		//a=Aavoidable
		public Assignment getAAssignment_0() { return cAAssignment_0; }

		//Aavoidable
		public RuleCall getAAavoidableEnumRuleCall_0_0() { return cAAavoidableEnumRuleCall_0_0; }

		//'.'
		public Keyword getFullStopKeyword_1() { return cFullStopKeyword_1; }

		//c=Cavoidable
		public Assignment getCAssignment_2() { return cCAssignment_2; }

		//Cavoidable
		public RuleCall getCCavoidableEnumRuleCall_2_0() { return cCCavoidableEnumRuleCall_2_0; }

		//'.'
		public Keyword getFullStopKeyword_3() { return cFullStopKeyword_3; }

		//i=Iavoidable
		public Assignment getIAssignment_4() { return cIAssignment_4; }

		//Iavoidable
		public RuleCall getIIavoidableEnumRuleCall_4_0() { return cIIavoidableEnumRuleCall_4_0; }

		//'.'
		public Keyword getFullStopKeyword_5() { return cFullStopKeyword_5; }

		//d=Davoidable
		public Assignment getDAssignment_6() { return cDAssignment_6; }

		//Davoidable
		public RuleCall getDDavoidableEnumRuleCall_6_0() { return cDDavoidableEnumRuleCall_6_0; }
	}

	public class ACIDMitigationElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.ACIDMitigation");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cAAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cAAmitigationEnumRuleCall_0_0 = (RuleCall)cAAssignment_0.eContents().get(0);
		private final Keyword cFullStopKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cCAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cCCmitigationEnumRuleCall_2_0 = (RuleCall)cCAssignment_2.eContents().get(0);
		private final Keyword cFullStopKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Assignment cIAssignment_4 = (Assignment)cGroup.eContents().get(4);
		private final RuleCall cIImitigationEnumRuleCall_4_0 = (RuleCall)cIAssignment_4.eContents().get(0);
		private final Keyword cFullStopKeyword_5 = (Keyword)cGroup.eContents().get(5);
		private final Assignment cDAssignment_6 = (Assignment)cGroup.eContents().get(6);
		private final RuleCall cDDmitigationEnumRuleCall_6_0 = (RuleCall)cDAssignment_6.eContents().get(0);
		
		//ACIDMitigation:
		//	a=Amitigation '.' c=Cmitigation '.' i=Imitigation '.' d=Dmitigation;
		@Override public ParserRule getRule() { return rule; }

		//a=Amitigation '.' c=Cmitigation '.' i=Imitigation '.' d=Dmitigation
		public Group getGroup() { return cGroup; }

		//a=Amitigation
		public Assignment getAAssignment_0() { return cAAssignment_0; }

		//Amitigation
		public RuleCall getAAmitigationEnumRuleCall_0_0() { return cAAmitigationEnumRuleCall_0_0; }

		//'.'
		public Keyword getFullStopKeyword_1() { return cFullStopKeyword_1; }

		//c=Cmitigation
		public Assignment getCAssignment_2() { return cCAssignment_2; }

		//Cmitigation
		public RuleCall getCCmitigationEnumRuleCall_2_0() { return cCCmitigationEnumRuleCall_2_0; }

		//'.'
		public Keyword getFullStopKeyword_3() { return cFullStopKeyword_3; }

		//i=Imitigation
		public Assignment getIAssignment_4() { return cIAssignment_4; }

		//Imitigation
		public RuleCall getIImitigationEnumRuleCall_4_0() { return cIImitigationEnumRuleCall_4_0; }

		//'.'
		public Keyword getFullStopKeyword_5() { return cFullStopKeyword_5; }

		//d=Dmitigation
		public Assignment getDAssignment_6() { return cDAssignment_6; }

		//Dmitigation
		public RuleCall getDDmitigationEnumRuleCall_6_0() { return cDDmitigationEnumRuleCall_6_0; }
	}

	public class FQNElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.FQN");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final RuleCall cIDTerminalRuleCall_0 = (RuleCall)cGroup.eContents().get(0);
		private final Group cGroup_1 = (Group)cGroup.eContents().get(1);
		private final Keyword cColonColonKeyword_1_0 = (Keyword)cGroup_1.eContents().get(0);
		private final RuleCall cIDTerminalRuleCall_1_1 = (RuleCall)cGroup_1.eContents().get(1);
		
		///*
		// * Additional rule to refer UML elements in a Model
		// */ FQN:
		//	ID ('::' ID)*;
		@Override public ParserRule getRule() { return rule; }

		//ID ('::' ID)*
		public Group getGroup() { return cGroup; }

		//ID
		public RuleCall getIDTerminalRuleCall_0() { return cIDTerminalRuleCall_0; }

		//('::' ID)*
		public Group getGroup_1() { return cGroup_1; }

		//'::'
		public Keyword getColonColonKeyword_1_0() { return cColonColonKeyword_1_0; }

		//ID
		public RuleCall getIDTerminalRuleCall_1_1() { return cIDTerminalRuleCall_1_1; }
	}
	
	
	public class FailureTypeElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.FailureType");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cNO_FAILUREEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cNO_FAILURENoFailureKeyword_0_0 = (Keyword)cNO_FAILUREEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cEARLYEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cEARLYEarlyKeyword_1_0 = (Keyword)cEARLYEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cLATEEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cLATELateKeyword_2_0 = (Keyword)cLATEEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cCOMMISSIONEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cCOMMISSIONCommissionKeyword_3_0 = (Keyword)cCOMMISSIONEnumLiteralDeclaration_3.eContents().get(0);
		private final EnumLiteralDeclaration cOMISSIONEnumLiteralDeclaration_4 = (EnumLiteralDeclaration)cAlternatives.eContents().get(4);
		private final Keyword cOMISSIONOmissionKeyword_4_0 = (Keyword)cOMISSIONEnumLiteralDeclaration_4.eContents().get(0);
		private final EnumLiteralDeclaration cVALUE_SUBTLEEnumLiteralDeclaration_5 = (EnumLiteralDeclaration)cAlternatives.eContents().get(5);
		private final Keyword cVALUE_SUBTLEValueSubtleKeyword_5_0 = (Keyword)cVALUE_SUBTLEEnumLiteralDeclaration_5.eContents().get(0);
		private final EnumLiteralDeclaration cVALUE_COARSEEnumLiteralDeclaration_6 = (EnumLiteralDeclaration)cAlternatives.eContents().get(6);
		private final Keyword cVALUE_COARSEValueCoarseKeyword_6_0 = (Keyword)cVALUE_COARSEEnumLiteralDeclaration_6.eContents().get(0);
		private final EnumLiteralDeclaration cWILDCARDEnumLiteralDeclaration_7 = (EnumLiteralDeclaration)cAlternatives.eContents().get(7);
		private final Keyword cWILDCARDWildcardKeyword_7_0 = (Keyword)cWILDCARDEnumLiteralDeclaration_7.eContents().get(0);
		private final EnumLiteralDeclaration cVARIABLEEnumLiteralDeclaration_8 = (EnumLiteralDeclaration)cAlternatives.eContents().get(8);
		private final Keyword cVARIABLEVariableKeyword_8_0 = (Keyword)cVARIABLEEnumLiteralDeclaration_8.eContents().get(0);
		
		//enum FailureType:
		//	NO_FAILURE='noFailure' | EARLY='early' | LATE='late' | COMMISSION='commission' | OMISSION='omission' |
		//	VALUE_SUBTLE='valueSubtle' | VALUE_COARSE='valueCoarse' | WILDCARD="wildcard" | VARIABLE='variable';
		public EnumRule getRule() { return rule; }

		//NO_FAILURE='noFailure' | EARLY='early' | LATE='late' | COMMISSION='commission' | OMISSION='omission' |
		//VALUE_SUBTLE='valueSubtle' | VALUE_COARSE='valueCoarse' | WILDCARD="wildcard" | VARIABLE='variable'
		public Alternatives getAlternatives() { return cAlternatives; }

		//NO_FAILURE='noFailure'
		public EnumLiteralDeclaration getNO_FAILUREEnumLiteralDeclaration_0() { return cNO_FAILUREEnumLiteralDeclaration_0; }

		//'noFailure'
		public Keyword getNO_FAILURENoFailureKeyword_0_0() { return cNO_FAILURENoFailureKeyword_0_0; }

		//EARLY='early'
		public EnumLiteralDeclaration getEARLYEnumLiteralDeclaration_1() { return cEARLYEnumLiteralDeclaration_1; }

		//'early'
		public Keyword getEARLYEarlyKeyword_1_0() { return cEARLYEarlyKeyword_1_0; }

		//LATE='late'
		public EnumLiteralDeclaration getLATEEnumLiteralDeclaration_2() { return cLATEEnumLiteralDeclaration_2; }

		//'late'
		public Keyword getLATELateKeyword_2_0() { return cLATELateKeyword_2_0; }

		//COMMISSION='commission'
		public EnumLiteralDeclaration getCOMMISSIONEnumLiteralDeclaration_3() { return cCOMMISSIONEnumLiteralDeclaration_3; }

		//'commission'
		public Keyword getCOMMISSIONCommissionKeyword_3_0() { return cCOMMISSIONCommissionKeyword_3_0; }

		//OMISSION='omission'
		public EnumLiteralDeclaration getOMISSIONEnumLiteralDeclaration_4() { return cOMISSIONEnumLiteralDeclaration_4; }

		//'omission'
		public Keyword getOMISSIONOmissionKeyword_4_0() { return cOMISSIONOmissionKeyword_4_0; }

		//VALUE_SUBTLE='valueSubtle'
		public EnumLiteralDeclaration getVALUE_SUBTLEEnumLiteralDeclaration_5() { return cVALUE_SUBTLEEnumLiteralDeclaration_5; }

		//'valueSubtle'
		public Keyword getVALUE_SUBTLEValueSubtleKeyword_5_0() { return cVALUE_SUBTLEValueSubtleKeyword_5_0; }

		//VALUE_COARSE='valueCoarse'
		public EnumLiteralDeclaration getVALUE_COARSEEnumLiteralDeclaration_6() { return cVALUE_COARSEEnumLiteralDeclaration_6; }

		//'valueCoarse'
		public Keyword getVALUE_COARSEValueCoarseKeyword_6_0() { return cVALUE_COARSEValueCoarseKeyword_6_0; }

		//WILDCARD="wildcard"
		public EnumLiteralDeclaration getWILDCARDEnumLiteralDeclaration_7() { return cWILDCARDEnumLiteralDeclaration_7; }

		//"wildcard"
		public Keyword getWILDCARDWildcardKeyword_7_0() { return cWILDCARDWildcardKeyword_7_0; }

		//VARIABLE='variable'
		public EnumLiteralDeclaration getVARIABLEEnumLiteralDeclaration_8() { return cVARIABLEEnumLiteralDeclaration_8; }

		//'variable'
		public Keyword getVARIABLEVariableKeyword_8_0() { return cVARIABLEVariableKeyword_8_0; }
	}

	public class ActualFailureTypeElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.ActualFailureType");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cEARLYEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cEARLYEarlyKeyword_0_0 = (Keyword)cEARLYEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cLATEEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cLATELateKeyword_1_0 = (Keyword)cLATEEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cCOMMISSIONEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cCOMMISSIONCommissionKeyword_2_0 = (Keyword)cCOMMISSIONEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cOMISSIONEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cOMISSIONOmissionKeyword_3_0 = (Keyword)cOMISSIONEnumLiteralDeclaration_3.eContents().get(0);
		private final EnumLiteralDeclaration cVALUE_SUBTLEEnumLiteralDeclaration_4 = (EnumLiteralDeclaration)cAlternatives.eContents().get(4);
		private final Keyword cVALUE_SUBTLEValueSubtleKeyword_4_0 = (Keyword)cVALUE_SUBTLEEnumLiteralDeclaration_4.eContents().get(0);
		private final EnumLiteralDeclaration cVALUE_COARSEEnumLiteralDeclaration_5 = (EnumLiteralDeclaration)cAlternatives.eContents().get(5);
		private final Keyword cVALUE_COARSEValueCoarseKeyword_5_0 = (Keyword)cVALUE_COARSEEnumLiteralDeclaration_5.eContents().get(0);
		
		//enum ActualFailureType returns FailureType:
		//	EARLY="early" | LATE="late" | COMMISSION="commission" | OMISSION="omission" | VALUE_SUBTLE="valueSubtle" |
		//	VALUE_COARSE="valueCoarse";
		public EnumRule getRule() { return rule; }

		//EARLY="early" | LATE="late" | COMMISSION="commission" | OMISSION="omission" | VALUE_SUBTLE="valueSubtle" |
		//VALUE_COARSE="valueCoarse"
		public Alternatives getAlternatives() { return cAlternatives; }

		//EARLY="early"
		public EnumLiteralDeclaration getEARLYEnumLiteralDeclaration_0() { return cEARLYEnumLiteralDeclaration_0; }

		//"early"
		public Keyword getEARLYEarlyKeyword_0_0() { return cEARLYEarlyKeyword_0_0; }

		//LATE="late"
		public EnumLiteralDeclaration getLATEEnumLiteralDeclaration_1() { return cLATEEnumLiteralDeclaration_1; }

		//"late"
		public Keyword getLATELateKeyword_1_0() { return cLATELateKeyword_1_0; }

		//COMMISSION="commission"
		public EnumLiteralDeclaration getCOMMISSIONEnumLiteralDeclaration_2() { return cCOMMISSIONEnumLiteralDeclaration_2; }

		//"commission"
		public Keyword getCOMMISSIONCommissionKeyword_2_0() { return cCOMMISSIONCommissionKeyword_2_0; }

		//OMISSION="omission"
		public EnumLiteralDeclaration getOMISSIONEnumLiteralDeclaration_3() { return cOMISSIONEnumLiteralDeclaration_3; }

		//"omission"
		public Keyword getOMISSIONOmissionKeyword_3_0() { return cOMISSIONOmissionKeyword_3_0; }

		//VALUE_SUBTLE="valueSubtle"
		public EnumLiteralDeclaration getVALUE_SUBTLEEnumLiteralDeclaration_4() { return cVALUE_SUBTLEEnumLiteralDeclaration_4; }

		//"valueSubtle"
		public Keyword getVALUE_SUBTLEValueSubtleKeyword_4_0() { return cVALUE_SUBTLEValueSubtleKeyword_4_0; }

		//VALUE_COARSE="valueCoarse"
		public EnumLiteralDeclaration getVALUE_COARSEEnumLiteralDeclaration_5() { return cVALUE_COARSEEnumLiteralDeclaration_5; }

		//"valueCoarse"
		public Keyword getVALUE_COARSEValueCoarseKeyword_5_0() { return cVALUE_COARSEValueCoarseKeyword_5_0; }
	}

	public class NoFailureTypeElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.NoFailureType");
		private final EnumLiteralDeclaration cNO_FAILUREEnumLiteralDeclaration = (EnumLiteralDeclaration)rule.eContents().get(1);
		private final Keyword cNO_FAILURENoFailureKeyword_0 = (Keyword)cNO_FAILUREEnumLiteralDeclaration.eContents().get(0);
		
		//enum NoFailureType returns FailureType:
		//	NO_FAILURE="noFailure";
		public EnumRule getRule() { return rule; }

		//NO_FAILURE="noFailure"
		public EnumLiteralDeclaration getNO_FAILUREEnumLiteralDeclaration() { return cNO_FAILUREEnumLiteralDeclaration; }

		//"noFailure"
		public Keyword getNO_FAILURENoFailureKeyword_0() { return cNO_FAILURENoFailureKeyword_0; }
	}

	public class WildcardElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Wildcard");
		private final EnumLiteralDeclaration cWILDCARDEnumLiteralDeclaration = (EnumLiteralDeclaration)rule.eContents().get(1);
		private final Keyword cWILDCARDWildcardKeyword_0 = (Keyword)cWILDCARDEnumLiteralDeclaration.eContents().get(0);
		
		//enum Wildcard returns FailureType:
		//	WILDCARD="wildcard";
		public EnumRule getRule() { return rule; }

		//WILDCARD="wildcard"
		public EnumLiteralDeclaration getWILDCARDEnumLiteralDeclaration() { return cWILDCARDEnumLiteralDeclaration; }

		//"wildcard"
		public Keyword getWILDCARDWildcardKeyword_0() { return cWILDCARDWildcardKeyword_0; }
	}

	public class AavoidableElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Aavoidable");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cINCOMPLETIONEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cINCOMPLETIONIncompletionKeyword_0_0 = (Keyword)cINCOMPLETIONEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cNONENoneKeyword_1_0 = (Keyword)cNONEEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_2_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_2.eContents().get(0);
		
		//enum Aavoidable:
		//	INCOMPLETION='incompletion' | NONE='none' | UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//INCOMPLETION='incompletion' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//INCOMPLETION='incompletion'
		public EnumLiteralDeclaration getINCOMPLETIONEnumLiteralDeclaration_0() { return cINCOMPLETIONEnumLiteralDeclaration_0; }

		//'incompletion'
		public Keyword getINCOMPLETIONIncompletionKeyword_0_0() { return cINCOMPLETIONIncompletionKeyword_0_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_1() { return cNONEEnumLiteralDeclaration_1; }

		//'none'
		public Keyword getNONENoneKeyword_1_0() { return cNONENoneKeyword_1_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_2() { return cUNSPECIFIEDEnumLiteralDeclaration_2; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_2_0() { return cUNSPECIFIEDUnspecifiedKeyword_2_0; }
	}

	public class CavoidableElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Cavoidable");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cINCONSISTENCYEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cINCONSISTENCYInconsistencyKeyword_0_0 = (Keyword)cINCONSISTENCYEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cNONENoneKeyword_1_0 = (Keyword)cNONEEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_2_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_2.eContents().get(0);
		
		//enum Cavoidable:
		//	INCONSISTENCY='inconsistency' | NONE='none' | UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//INCONSISTENCY='inconsistency' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//INCONSISTENCY='inconsistency'
		public EnumLiteralDeclaration getINCONSISTENCYEnumLiteralDeclaration_0() { return cINCONSISTENCYEnumLiteralDeclaration_0; }

		//'inconsistency'
		public Keyword getINCONSISTENCYInconsistencyKeyword_0_0() { return cINCONSISTENCYInconsistencyKeyword_0_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_1() { return cNONEEnumLiteralDeclaration_1; }

		//'none'
		public Keyword getNONENoneKeyword_1_0() { return cNONENoneKeyword_1_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_2() { return cUNSPECIFIEDEnumLiteralDeclaration_2; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_2_0() { return cUNSPECIFIEDUnspecifiedKeyword_2_0; }
	}

	public class IavoidableElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Iavoidable");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cINTERFERENCEEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cINTERFERENCEInterferenceKeyword_0_0 = (Keyword)cINTERFERENCEEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cNONENoneKeyword_1_0 = (Keyword)cNONEEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_2_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_2.eContents().get(0);
		
		//enum Iavoidable:
		//	INTERFERENCE='interference' | NONE='none' | UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//INTERFERENCE='interference' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//INTERFERENCE='interference'
		public EnumLiteralDeclaration getINTERFERENCEEnumLiteralDeclaration_0() { return cINTERFERENCEEnumLiteralDeclaration_0; }

		//'interference'
		public Keyword getINTERFERENCEInterferenceKeyword_0_0() { return cINTERFERENCEInterferenceKeyword_0_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_1() { return cNONEEnumLiteralDeclaration_1; }

		//'none'
		public Keyword getNONENoneKeyword_1_0() { return cNONENoneKeyword_1_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_2() { return cUNSPECIFIEDEnumLiteralDeclaration_2; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_2_0() { return cUNSPECIFIEDUnspecifiedKeyword_2_0; }
	}

	public class DavoidableElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Davoidable");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cIMPERMANENCEEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cIMPERMANENCEImpermanenceKeyword_0_0 = (Keyword)cIMPERMANENCEEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cNONENoneKeyword_1_0 = (Keyword)cNONEEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_2_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_2.eContents().get(0);
		
		//enum Davoidable:
		//	IMPERMANENCE='impermanence' | NONE='none' | UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//IMPERMANENCE='impermanence' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//IMPERMANENCE='impermanence'
		public EnumLiteralDeclaration getIMPERMANENCEEnumLiteralDeclaration_0() { return cIMPERMANENCEEnumLiteralDeclaration_0; }

		//'impermanence'
		public Keyword getIMPERMANENCEImpermanenceKeyword_0_0() { return cIMPERMANENCEImpermanenceKeyword_0_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_1() { return cNONEEnumLiteralDeclaration_1; }

		//'none'
		public Keyword getNONENoneKeyword_1_0() { return cNONENoneKeyword_1_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_2() { return cUNSPECIFIEDEnumLiteralDeclaration_2; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_2_0() { return cUNSPECIFIEDUnspecifiedKeyword_2_0; }
	}

	public class AmitigationElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Amitigation");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cALL_OR_NOTHINGEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cALL_OR_NOTHINGAll_or_nothingKeyword_0_0 = (Keyword)cALL_OR_NOTHINGEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cALL_OR_COMPENSATIONEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cALL_OR_COMPENSATIONAll_or_compensationKeyword_1_0 = (Keyword)cALL_OR_COMPENSATIONEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cNONENoneKeyword_2_0 = (Keyword)cNONEEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_3_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_3.eContents().get(0);
		
		//enum Amitigation:
		//	ALL_OR_NOTHING='all_or_nothing' | ALL_OR_COMPENSATION='all_or_compensation' | NONE='none' |
		//	UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//ALL_OR_NOTHING='all_or_nothing' | ALL_OR_COMPENSATION='all_or_compensation' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//ALL_OR_NOTHING='all_or_nothing'
		public EnumLiteralDeclaration getALL_OR_NOTHINGEnumLiteralDeclaration_0() { return cALL_OR_NOTHINGEnumLiteralDeclaration_0; }

		//'all_or_nothing'
		public Keyword getALL_OR_NOTHINGAll_or_nothingKeyword_0_0() { return cALL_OR_NOTHINGAll_or_nothingKeyword_0_0; }

		//ALL_OR_COMPENSATION='all_or_compensation'
		public EnumLiteralDeclaration getALL_OR_COMPENSATIONEnumLiteralDeclaration_1() { return cALL_OR_COMPENSATIONEnumLiteralDeclaration_1; }

		//'all_or_compensation'
		public Keyword getALL_OR_COMPENSATIONAll_or_compensationKeyword_1_0() { return cALL_OR_COMPENSATIONAll_or_compensationKeyword_1_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_2() { return cNONEEnumLiteralDeclaration_2; }

		//'none'
		public Keyword getNONENoneKeyword_2_0() { return cNONENoneKeyword_2_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_3() { return cUNSPECIFIEDEnumLiteralDeclaration_3; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_3_0() { return cUNSPECIFIEDUnspecifiedKeyword_3_0; }
	}

	public class CmitigationElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Cmitigation");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cFULL_CONSISTENCYEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cFULL_CONSISTENCYFull_consistencyKeyword_0_0 = (Keyword)cFULL_CONSISTENCYEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cRANGE_VIOLATION_ALLOWEDEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cRANGE_VIOLATION_ALLOWEDRange_violation_allowedKeyword_1_0 = (Keyword)cRANGE_VIOLATION_ALLOWEDEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cNONENoneKeyword_2_0 = (Keyword)cNONEEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_3_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_3.eContents().get(0);
		
		//enum Cmitigation:
		//	FULL_CONSISTENCY='full_consistency' | RANGE_VIOLATION_ALLOWED='range_violation_allowed' | NONE='none' |
		//	UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//FULL_CONSISTENCY='full_consistency' | RANGE_VIOLATION_ALLOWED='range_violation_allowed' | NONE='none' |
		//UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//FULL_CONSISTENCY='full_consistency'
		public EnumLiteralDeclaration getFULL_CONSISTENCYEnumLiteralDeclaration_0() { return cFULL_CONSISTENCYEnumLiteralDeclaration_0; }

		//'full_consistency'
		public Keyword getFULL_CONSISTENCYFull_consistencyKeyword_0_0() { return cFULL_CONSISTENCYFull_consistencyKeyword_0_0; }

		//RANGE_VIOLATION_ALLOWED='range_violation_allowed'
		public EnumLiteralDeclaration getRANGE_VIOLATION_ALLOWEDEnumLiteralDeclaration_1() { return cRANGE_VIOLATION_ALLOWEDEnumLiteralDeclaration_1; }

		//'range_violation_allowed'
		public Keyword getRANGE_VIOLATION_ALLOWEDRange_violation_allowedKeyword_1_0() { return cRANGE_VIOLATION_ALLOWEDRange_violation_allowedKeyword_1_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_2() { return cNONEEnumLiteralDeclaration_2; }

		//'none'
		public Keyword getNONENoneKeyword_2_0() { return cNONENoneKeyword_2_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_3() { return cUNSPECIFIEDEnumLiteralDeclaration_3; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_3_0() { return cUNSPECIFIEDUnspecifiedKeyword_3_0; }
	}

	public class ImitigationElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Imitigation");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cSERIALIZABLEEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cSERIALIZABLESerializableKeyword_0_0 = (Keyword)cSERIALIZABLEEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cPORTABLE_LEVELEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cPORTABLE_LEVELPortable_levelKeyword_1_0 = (Keyword)cPORTABLE_LEVELEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cNONENoneKeyword_2_0 = (Keyword)cNONEEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_3_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_3.eContents().get(0);
		
		//enum Imitigation:
		//	SERIALIZABLE='serializable' | PORTABLE_LEVEL='portable_level' | NONE='none' | UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//SERIALIZABLE='serializable' | PORTABLE_LEVEL='portable_level' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//SERIALIZABLE='serializable'
		public EnumLiteralDeclaration getSERIALIZABLEEnumLiteralDeclaration_0() { return cSERIALIZABLEEnumLiteralDeclaration_0; }

		//'serializable'
		public Keyword getSERIALIZABLESerializableKeyword_0_0() { return cSERIALIZABLESerializableKeyword_0_0; }

		//PORTABLE_LEVEL='portable_level'
		public EnumLiteralDeclaration getPORTABLE_LEVELEnumLiteralDeclaration_1() { return cPORTABLE_LEVELEnumLiteralDeclaration_1; }

		//'portable_level'
		public Keyword getPORTABLE_LEVELPortable_levelKeyword_1_0() { return cPORTABLE_LEVELPortable_levelKeyword_1_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_2() { return cNONEEnumLiteralDeclaration_2; }

		//'none'
		public Keyword getNONENoneKeyword_2_0() { return cNONENoneKeyword_2_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_3() { return cUNSPECIFIEDEnumLiteralDeclaration_3; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_3_0() { return cUNSPECIFIEDUnspecifiedKeyword_3_0; }
	}

	public class DmitigationElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.polarsys.chess.xtext.FlaDsl.Dmitigation");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cNO_LOSSEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cNO_LOSSNo_lossKeyword_0_0 = (Keyword)cNO_LOSSEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cPARTIAL_LOSS_ALLOWEDEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cPARTIAL_LOSS_ALLOWEDPartial_loss_allowedKeyword_1_0 = (Keyword)cPARTIAL_LOSS_ALLOWEDEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cNONEEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cNONENoneKeyword_2_0 = (Keyword)cNONEEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cUNSPECIFIEDEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cUNSPECIFIEDUnspecifiedKeyword_3_0 = (Keyword)cUNSPECIFIEDEnumLiteralDeclaration_3.eContents().get(0);
		
		//enum Dmitigation:
		//	NO_LOSS='no_loss' | PARTIAL_LOSS_ALLOWED='partial_loss_allowed' | NONE='none' | UNSPECIFIED='unspecified';
		public EnumRule getRule() { return rule; }

		//NO_LOSS='no_loss' | PARTIAL_LOSS_ALLOWED='partial_loss_allowed' | NONE='none' | UNSPECIFIED='unspecified'
		public Alternatives getAlternatives() { return cAlternatives; }

		//NO_LOSS='no_loss'
		public EnumLiteralDeclaration getNO_LOSSEnumLiteralDeclaration_0() { return cNO_LOSSEnumLiteralDeclaration_0; }

		//'no_loss'
		public Keyword getNO_LOSSNo_lossKeyword_0_0() { return cNO_LOSSNo_lossKeyword_0_0; }

		//PARTIAL_LOSS_ALLOWED='partial_loss_allowed'
		public EnumLiteralDeclaration getPARTIAL_LOSS_ALLOWEDEnumLiteralDeclaration_1() { return cPARTIAL_LOSS_ALLOWEDEnumLiteralDeclaration_1; }

		//'partial_loss_allowed'
		public Keyword getPARTIAL_LOSS_ALLOWEDPartial_loss_allowedKeyword_1_0() { return cPARTIAL_LOSS_ALLOWEDPartial_loss_allowedKeyword_1_0; }

		//NONE='none'
		public EnumLiteralDeclaration getNONEEnumLiteralDeclaration_2() { return cNONEEnumLiteralDeclaration_2; }

		//'none'
		public Keyword getNONENoneKeyword_2_0() { return cNONENoneKeyword_2_0; }

		//UNSPECIFIED='unspecified'
		public EnumLiteralDeclaration getUNSPECIFIEDEnumLiteralDeclaration_3() { return cUNSPECIFIEDEnumLiteralDeclaration_3; }

		//'unspecified'
		public Keyword getUNSPECIFIEDUnspecifiedKeyword_3_0() { return cUNSPECIFIEDUnspecifiedKeyword_3_0; }
	}
	
	private final BehaviourElements pBehaviour;
	private final ExpressionElements pExpression;
	private final LhsElements pLhs;
	private final RhsElements pRhs;
	private final InputExpressionElements pInputExpression;
	private final OutputExpressionElements pOutputExpression;
	private final InFailureExprElements pInFailureExpr;
	private final OutFailureExprElements pOutFailureExpr;
	private final DefinitionsElements pDefinitions;
	private final FailureDefinitionElements pFailureDefinition;
	private final NoFailureDefinitionElements pNoFailureDefinition;
	private final ComplexNofailureDefinitionElements pComplexNofailureDefinition;
	private final WildcardDefinitionElements pWildcardDefinition;
	private final VariableDefinitionElements pVariableDefinition;
	private final FailureTypeElements eFailureType;
	private final ActualFailureTypeElements eActualFailureType;
	private final NoFailureTypeElements eNoFailureType;
	private final WildcardElements eWildcard;
	private final ACIDavoidableElements pACIDavoidable;
	private final AavoidableElements eAavoidable;
	private final CavoidableElements eCavoidable;
	private final IavoidableElements eIavoidable;
	private final DavoidableElements eDavoidable;
	private final ACIDMitigationElements pACIDMitigation;
	private final AmitigationElements eAmitigation;
	private final CmitigationElements eCmitigation;
	private final ImitigationElements eImitigation;
	private final DmitigationElements eDmitigation;
	private final FQNElements pFQN;
	
	private final Grammar grammar;

	private final TerminalsGrammarAccess gaTerminals;

	@Inject
	public FlaDslGrammarAccess(GrammarProvider grammarProvider,
		TerminalsGrammarAccess gaTerminals) {
		this.grammar = internalFindGrammar(grammarProvider);
		this.gaTerminals = gaTerminals;
		this.pBehaviour = new BehaviourElements();
		this.pExpression = new ExpressionElements();
		this.pLhs = new LhsElements();
		this.pRhs = new RhsElements();
		this.pInputExpression = new InputExpressionElements();
		this.pOutputExpression = new OutputExpressionElements();
		this.pInFailureExpr = new InFailureExprElements();
		this.pOutFailureExpr = new OutFailureExprElements();
		this.pDefinitions = new DefinitionsElements();
		this.pFailureDefinition = new FailureDefinitionElements();
		this.pNoFailureDefinition = new NoFailureDefinitionElements();
		this.pComplexNofailureDefinition = new ComplexNofailureDefinitionElements();
		this.pWildcardDefinition = new WildcardDefinitionElements();
		this.pVariableDefinition = new VariableDefinitionElements();
		this.eFailureType = new FailureTypeElements();
		this.eActualFailureType = new ActualFailureTypeElements();
		this.eNoFailureType = new NoFailureTypeElements();
		this.eWildcard = new WildcardElements();
		this.pACIDavoidable = new ACIDavoidableElements();
		this.eAavoidable = new AavoidableElements();
		this.eCavoidable = new CavoidableElements();
		this.eIavoidable = new IavoidableElements();
		this.eDavoidable = new DavoidableElements();
		this.pACIDMitigation = new ACIDMitigationElements();
		this.eAmitigation = new AmitigationElements();
		this.eCmitigation = new CmitigationElements();
		this.eImitigation = new ImitigationElements();
		this.eDmitigation = new DmitigationElements();
		this.pFQN = new FQNElements();
	}
	
	protected Grammar internalFindGrammar(GrammarProvider grammarProvider) {
		Grammar grammar = grammarProvider.getGrammar(this);
		while (grammar != null) {
			if ("org.polarsys.chess.xtext.FlaDsl".equals(grammar.getName())) {
				return grammar;
			}
			List<Grammar> grammars = grammar.getUsedGrammars();
			if (!grammars.isEmpty()) {
				grammar = grammars.iterator().next();
			} else {
				return null;
			}
		}
		return grammar;
	}
	
	@Override
	public Grammar getGrammar() {
		return grammar;
	}
	

	public TerminalsGrammarAccess getTerminalsGrammarAccess() {
		return gaTerminals;
	}

	
	///*
	// * FLA Grammar
	// */ Behaviour:
	//	rules+=Expression+;
	public BehaviourElements getBehaviourAccess() {
		return pBehaviour;
	}
	
	public ParserRule getBehaviourRule() {
		return getBehaviourAccess().getRule();
	}

	//Expression:
	//	'FLA:' lhs=Lhs '->' rhs=Rhs ';';
	public ExpressionElements getExpressionAccess() {
		return pExpression;
	}
	
	public ParserRule getExpressionRule() {
		return getExpressionAccess().getRule();
	}

	//Lhs:
	//	failures+=InputExpression (',' failures+=InputExpression)*;
	public LhsElements getLhsAccess() {
		return pLhs;
	}
	
	public ParserRule getLhsRule() {
		return getLhsAccess().getRule();
	}

	//Rhs:
	//	failures+=OutputExpression (',' failures+=OutputExpression)*;
	public RhsElements getRhsAccess() {
		return pRhs;
	}
	
	public ParserRule getRhsRule() {
		return getRhsAccess().getRule();
	}

	//InputExpression:
	//	(ref=[uml::Port] | "undefined") '.' failureExpr=InFailureExpr;
	public InputExpressionElements getInputExpressionAccess() {
		return pInputExpression;
	}
	
	public ParserRule getInputExpressionRule() {
		return getInputExpressionAccess().getRule();
	}

	//OutputExpression:
	//	(ref=[uml::Port] | "undefined") '.' failureExpr=OutFailureExpr;
	public OutputExpressionElements getOutputExpressionAccess() {
		return pOutputExpression;
	}
	
	public ParserRule getOutputExpressionRule() {
		return getOutputExpressionAccess().getRule();
	}

	//InFailureExpr:
	//	failures+=WildcardDefinition | failures+=NoFailureDefinition | failures+=FailureDefinition |
	//	'{' failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}' | failures+=VariableDefinition;
	public InFailureExprElements getInFailureExprAccess() {
		return pInFailureExpr;
	}
	
	public ParserRule getInFailureExprRule() {
		return getInFailureExprAccess().getRule();
	}

	//OutFailureExpr:
	//	failures+=NoFailureDefinition | failures+=ComplexNofailureDefinition | failures+=FailureDefinition |
	//	'{' failures+=FailureDefinition (',' failures+=FailureDefinition)+ '}' | failures+=VariableDefinition;
	public OutFailureExprElements getOutFailureExprAccess() {
		return pOutFailureExpr;
	}
	
	public ParserRule getOutFailureExprRule() {
		return getOutFailureExprAccess().getRule();
	}

	//Definitions:
	//	FailureDefinition | NoFailureDefinition | ComplexNofailureDefinition | WildcardDefinition | VariableDefinition;
	public DefinitionsElements getDefinitionsAccess() {
		return pDefinitions;
	}
	
	public ParserRule getDefinitionsRule() {
		return getDefinitionsAccess().getRule();
	}

	//FailureDefinition:
	//	{FailureDefinition} type=ActualFailureType ('.' acidAvoidable=ACIDavoidable)?;
	public FailureDefinitionElements getFailureDefinitionAccess() {
		return pFailureDefinition;
	}
	
	public ParserRule getFailureDefinitionRule() {
		return getFailureDefinitionAccess().getRule();
	}

	//NoFailureDefinition:
	//	{NoFailureDefinition} 'noFailure';
	public NoFailureDefinitionElements getNoFailureDefinitionAccess() {
		return pNoFailureDefinition;
	}
	
	public ParserRule getNoFailureDefinitionRule() {
		return getNoFailureDefinitionAccess().getRule();
	}

	//ComplexNofailureDefinition:
	//	{NoFailureDefinition} 'noFailure' '.' acidMitigation=ACIDMitigation;
	public ComplexNofailureDefinitionElements getComplexNofailureDefinitionAccess() {
		return pComplexNofailureDefinition;
	}
	
	public ParserRule getComplexNofailureDefinitionRule() {
		return getComplexNofailureDefinitionAccess().getRule();
	}

	//WildcardDefinition:
	//	{WildcardDefinition} 'wildcard';
	public WildcardDefinitionElements getWildcardDefinitionAccess() {
		return pWildcardDefinition;
	}
	
	public ParserRule getWildcardDefinitionRule() {
		return getWildcardDefinitionAccess().getRule();
	}

	//VariableDefinition:
	//	{VariableDefinition} variableName=ID;
	public VariableDefinitionElements getVariableDefinitionAccess() {
		return pVariableDefinition;
	}
	
	public ParserRule getVariableDefinitionRule() {
		return getVariableDefinitionAccess().getRule();
	}

	//enum FailureType:
	//	NO_FAILURE='noFailure' | EARLY='early' | LATE='late' | COMMISSION='commission' | OMISSION='omission' |
	//	VALUE_SUBTLE='valueSubtle' | VALUE_COARSE='valueCoarse' | WILDCARD="wildcard" | VARIABLE='variable';
	public FailureTypeElements getFailureTypeAccess() {
		return eFailureType;
	}
	
	public EnumRule getFailureTypeRule() {
		return getFailureTypeAccess().getRule();
	}

	//enum ActualFailureType returns FailureType:
	//	EARLY="early" | LATE="late" | COMMISSION="commission" | OMISSION="omission" | VALUE_SUBTLE="valueSubtle" |
	//	VALUE_COARSE="valueCoarse";
	public ActualFailureTypeElements getActualFailureTypeAccess() {
		return eActualFailureType;
	}
	
	public EnumRule getActualFailureTypeRule() {
		return getActualFailureTypeAccess().getRule();
	}

	//enum NoFailureType returns FailureType:
	//	NO_FAILURE="noFailure";
	public NoFailureTypeElements getNoFailureTypeAccess() {
		return eNoFailureType;
	}
	
	public EnumRule getNoFailureTypeRule() {
		return getNoFailureTypeAccess().getRule();
	}

	//enum Wildcard returns FailureType:
	//	WILDCARD="wildcard";
	public WildcardElements getWildcardAccess() {
		return eWildcard;
	}
	
	public EnumRule getWildcardRule() {
		return getWildcardAccess().getRule();
	}

	//ACIDavoidable:
	//	a=Aavoidable '.' c=Cavoidable '.' i=Iavoidable '.' d=Davoidable;
	public ACIDavoidableElements getACIDavoidableAccess() {
		return pACIDavoidable;
	}
	
	public ParserRule getACIDavoidableRule() {
		return getACIDavoidableAccess().getRule();
	}

	//enum Aavoidable:
	//	INCOMPLETION='incompletion' | NONE='none' | UNSPECIFIED='unspecified';
	public AavoidableElements getAavoidableAccess() {
		return eAavoidable;
	}
	
	public EnumRule getAavoidableRule() {
		return getAavoidableAccess().getRule();
	}

	//enum Cavoidable:
	//	INCONSISTENCY='inconsistency' | NONE='none' | UNSPECIFIED='unspecified';
	public CavoidableElements getCavoidableAccess() {
		return eCavoidable;
	}
	
	public EnumRule getCavoidableRule() {
		return getCavoidableAccess().getRule();
	}

	//enum Iavoidable:
	//	INTERFERENCE='interference' | NONE='none' | UNSPECIFIED='unspecified';
	public IavoidableElements getIavoidableAccess() {
		return eIavoidable;
	}
	
	public EnumRule getIavoidableRule() {
		return getIavoidableAccess().getRule();
	}

	//enum Davoidable:
	//	IMPERMANENCE='impermanence' | NONE='none' | UNSPECIFIED='unspecified';
	public DavoidableElements getDavoidableAccess() {
		return eDavoidable;
	}
	
	public EnumRule getDavoidableRule() {
		return getDavoidableAccess().getRule();
	}

	//ACIDMitigation:
	//	a=Amitigation '.' c=Cmitigation '.' i=Imitigation '.' d=Dmitigation;
	public ACIDMitigationElements getACIDMitigationAccess() {
		return pACIDMitigation;
	}
	
	public ParserRule getACIDMitigationRule() {
		return getACIDMitigationAccess().getRule();
	}

	//enum Amitigation:
	//	ALL_OR_NOTHING='all_or_nothing' | ALL_OR_COMPENSATION='all_or_compensation' | NONE='none' |
	//	UNSPECIFIED='unspecified';
	public AmitigationElements getAmitigationAccess() {
		return eAmitigation;
	}
	
	public EnumRule getAmitigationRule() {
		return getAmitigationAccess().getRule();
	}

	//enum Cmitigation:
	//	FULL_CONSISTENCY='full_consistency' | RANGE_VIOLATION_ALLOWED='range_violation_allowed' | NONE='none' |
	//	UNSPECIFIED='unspecified';
	public CmitigationElements getCmitigationAccess() {
		return eCmitigation;
	}
	
	public EnumRule getCmitigationRule() {
		return getCmitigationAccess().getRule();
	}

	//enum Imitigation:
	//	SERIALIZABLE='serializable' | PORTABLE_LEVEL='portable_level' | NONE='none' | UNSPECIFIED='unspecified';
	public ImitigationElements getImitigationAccess() {
		return eImitigation;
	}
	
	public EnumRule getImitigationRule() {
		return getImitigationAccess().getRule();
	}

	//enum Dmitigation:
	//	NO_LOSS='no_loss' | PARTIAL_LOSS_ALLOWED='partial_loss_allowed' | NONE='none' | UNSPECIFIED='unspecified';
	public DmitigationElements getDmitigationAccess() {
		return eDmitigation;
	}
	
	public EnumRule getDmitigationRule() {
		return getDmitigationAccess().getRule();
	}

	///*
	// * Additional rule to refer UML elements in a Model
	// */ FQN:
	//	ID ('::' ID)*;
	public FQNElements getFQNAccess() {
		return pFQN;
	}
	
	public ParserRule getFQNRule() {
		return getFQNAccess().getRule();
	}

	//terminal ID:
	//	'^'? ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*;
	public TerminalRule getIDRule() {
		return gaTerminals.getIDRule();
	} 

	//terminal INT returns ecore::EInt:
	//	'0'..'9'+;
	public TerminalRule getINTRule() {
		return gaTerminals.getINTRule();
	} 

	//terminal STRING:
	//	'"' ('\\' . | !('\\' | '"'))* '"' | "'" ('\\' . | !('\\' | "'"))* "'";
	public TerminalRule getSTRINGRule() {
		return gaTerminals.getSTRINGRule();
	} 

	//terminal ML_COMMENT:
	//	'/*'->'*/';
	public TerminalRule getML_COMMENTRule() {
		return gaTerminals.getML_COMMENTRule();
	} 

	//terminal SL_COMMENT:
	//	'//' !('\n' | '\r')* ('\r'? '\n')?;
	public TerminalRule getSL_COMMENTRule() {
		return gaTerminals.getSL_COMMENTRule();
	} 

	//terminal WS:
	//	' ' | '\t' | '\r' | '\n'+;
	public TerminalRule getWSRule() {
		return gaTerminals.getWSRule();
	} 

	//terminal ANY_OTHER:
	//	.;
	public TerminalRule getANY_OTHERRule() {
		return gaTerminals.getANY_OTHERRule();
	} 
}
