/*
 * generated by Xtext
 */
package org.eclipse.ocl.xtext.base.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.*;


@Singleton
public class BaseGrammarAccess extends AbstractGrammarElementFinder {
	
	
	public class MultiplicityBoundsCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "MultiplicityBoundsCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cLowerBoundAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cLowerBoundLOWERParserRuleCall_0_0 = (RuleCall)cLowerBoundAssignment_0.eContents().get(0);
		private final Group cGroup_1 = (Group)cGroup.eContents().get(1);
		private final Keyword cFullStopFullStopKeyword_1_0 = (Keyword)cGroup_1.eContents().get(0);
		private final Assignment cUpperBoundAssignment_1_1 = (Assignment)cGroup_1.eContents().get(1);
		private final RuleCall cUpperBoundUPPERParserRuleCall_1_1_0 = (RuleCall)cUpperBoundAssignment_1_1.eContents().get(0);
		
		//MultiplicityBoundsCS:
		//	lowerBound=LOWER (".." upperBound=UPPER)?;
		@Override public ParserRule getRule() { return rule; }

		//lowerBound=LOWER (".." upperBound=UPPER)?
		public Group getGroup() { return cGroup; }

		//lowerBound=LOWER
		public Assignment getLowerBoundAssignment_0() { return cLowerBoundAssignment_0; }

		//LOWER
		public RuleCall getLowerBoundLOWERParserRuleCall_0_0() { return cLowerBoundLOWERParserRuleCall_0_0; }

		//(".." upperBound=UPPER)?
		public Group getGroup_1() { return cGroup_1; }

		//".."
		public Keyword getFullStopFullStopKeyword_1_0() { return cFullStopFullStopKeyword_1_0; }

		//upperBound=UPPER
		public Assignment getUpperBoundAssignment_1_1() { return cUpperBoundAssignment_1_1; }

		//UPPER
		public RuleCall getUpperBoundUPPERParserRuleCall_1_1_0() { return cUpperBoundUPPERParserRuleCall_1_1_0; }
	}

	public class MultiplicityCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "MultiplicityCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cLeftSquareBracketKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1);
		private final RuleCall cMultiplicityBoundsCSParserRuleCall_1_0 = (RuleCall)cAlternatives_1.eContents().get(0);
		private final RuleCall cMultiplicityStringCSParserRuleCall_1_1 = (RuleCall)cAlternatives_1.eContents().get(1);
		private final Keyword cRightSquareBracketKeyword_2 = (Keyword)cGroup.eContents().get(2);
		
		//MultiplicityCS:
		//	"[" (MultiplicityBoundsCS | MultiplicityStringCS) "]";
		@Override public ParserRule getRule() { return rule; }

		//"[" (MultiplicityBoundsCS | MultiplicityStringCS) "]"
		public Group getGroup() { return cGroup; }

		//"["
		public Keyword getLeftSquareBracketKeyword_0() { return cLeftSquareBracketKeyword_0; }

		//MultiplicityBoundsCS | MultiplicityStringCS
		public Alternatives getAlternatives_1() { return cAlternatives_1; }

		//MultiplicityBoundsCS
		public RuleCall getMultiplicityBoundsCSParserRuleCall_1_0() { return cMultiplicityBoundsCSParserRuleCall_1_0; }

		//MultiplicityStringCS
		public RuleCall getMultiplicityStringCSParserRuleCall_1_1() { return cMultiplicityStringCSParserRuleCall_1_1; }

		//"]"
		public Keyword getRightSquareBracketKeyword_2() { return cRightSquareBracketKeyword_2; }
	}

	public class MultiplicityStringCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "MultiplicityStringCS");
		private final Assignment cStringBoundsAssignment = (Assignment)rule.eContents().get(1);
		private final Alternatives cStringBoundsAlternatives_0 = (Alternatives)cStringBoundsAssignment.eContents().get(0);
		private final Keyword cStringBoundsAsteriskKeyword_0_0 = (Keyword)cStringBoundsAlternatives_0.eContents().get(0);
		private final Keyword cStringBoundsPlusSignKeyword_0_1 = (Keyword)cStringBoundsAlternatives_0.eContents().get(1);
		private final Keyword cStringBoundsQuestionMarkKeyword_0_2 = (Keyword)cStringBoundsAlternatives_0.eContents().get(2);
		
		//MultiplicityStringCS:
		//	stringBounds=("*" | "+" | "?");
		@Override public ParserRule getRule() { return rule; }

		//stringBounds=("*" | "+" | "?")
		public Assignment getStringBoundsAssignment() { return cStringBoundsAssignment; }

		//"*" | "+" | "?"
		public Alternatives getStringBoundsAlternatives_0() { return cStringBoundsAlternatives_0; }

		//"*"
		public Keyword getStringBoundsAsteriskKeyword_0_0() { return cStringBoundsAsteriskKeyword_0_0; }

		//"+"
		public Keyword getStringBoundsPlusSignKeyword_0_1() { return cStringBoundsPlusSignKeyword_0_1; }

		//"?"
		public Keyword getStringBoundsQuestionMarkKeyword_0_2() { return cStringBoundsQuestionMarkKeyword_0_2; }
	}

	public class PathNameCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "PathNameCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cOwnedPathElementsAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cOwnedPathElementsFirstPathElementCSParserRuleCall_0_0 = (RuleCall)cOwnedPathElementsAssignment_0.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 Assignment cOwnedPathElementsAssignment_1_1 = (Assignment)cGroup_1.eContents().get(1);
		private final RuleCall cOwnedPathElementsNextPathElementCSParserRuleCall_1_1_0 = (RuleCall)cOwnedPathElementsAssignment_1_1.eContents().get(0);
		
		//PathNameCS:
		//	ownedPathElements+=FirstPathElementCS ("::" ownedPathElements+=NextPathElementCS)*;
		@Override public ParserRule getRule() { return rule; }

		//ownedPathElements+=FirstPathElementCS ("::" ownedPathElements+=NextPathElementCS)*
		public Group getGroup() { return cGroup; }

		//ownedPathElements+=FirstPathElementCS
		public Assignment getOwnedPathElementsAssignment_0() { return cOwnedPathElementsAssignment_0; }

		//FirstPathElementCS
		public RuleCall getOwnedPathElementsFirstPathElementCSParserRuleCall_0_0() { return cOwnedPathElementsFirstPathElementCSParserRuleCall_0_0; }

		//("::" ownedPathElements+=NextPathElementCS)*
		public Group getGroup_1() { return cGroup_1; }

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

		//ownedPathElements+=NextPathElementCS
		public Assignment getOwnedPathElementsAssignment_1_1() { return cOwnedPathElementsAssignment_1_1; }

		//NextPathElementCS
		public RuleCall getOwnedPathElementsNextPathElementCSParserRuleCall_1_1_0() { return cOwnedPathElementsNextPathElementCSParserRuleCall_1_1_0; }
	}

	public class FirstPathElementCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "FirstPathElementCS");
		private final Assignment cReferredElementAssignment = (Assignment)rule.eContents().get(1);
		private final CrossReference cReferredElementNamedElementCrossReference_0 = (CrossReference)cReferredElementAssignment.eContents().get(0);
		private final RuleCall cReferredElementNamedElementUnrestrictedNameParserRuleCall_0_1 = (RuleCall)cReferredElementNamedElementCrossReference_0.eContents().get(1);
		
		//FirstPathElementCS returns PathElementCS:
		//	referredElement=[pivot::NamedElement|UnrestrictedName];
		@Override public ParserRule getRule() { return rule; }

		//referredElement=[pivot::NamedElement|UnrestrictedName]
		public Assignment getReferredElementAssignment() { return cReferredElementAssignment; }

		//[pivot::NamedElement|UnrestrictedName]
		public CrossReference getReferredElementNamedElementCrossReference_0() { return cReferredElementNamedElementCrossReference_0; }

		//UnrestrictedName
		public RuleCall getReferredElementNamedElementUnrestrictedNameParserRuleCall_0_1() { return cReferredElementNamedElementUnrestrictedNameParserRuleCall_0_1; }
	}

	public class NextPathElementCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "NextPathElementCS");
		private final Assignment cReferredElementAssignment = (Assignment)rule.eContents().get(1);
		private final CrossReference cReferredElementNamedElementCrossReference_0 = (CrossReference)cReferredElementAssignment.eContents().get(0);
		private final RuleCall cReferredElementNamedElementUnreservedNameParserRuleCall_0_1 = (RuleCall)cReferredElementNamedElementCrossReference_0.eContents().get(1);
		
		//NextPathElementCS returns PathElementCS:
		//	referredElement=[pivot::NamedElement|UnreservedName];
		@Override public ParserRule getRule() { return rule; }

		//referredElement=[pivot::NamedElement|UnreservedName]
		public Assignment getReferredElementAssignment() { return cReferredElementAssignment; }

		//[pivot::NamedElement|UnreservedName]
		public CrossReference getReferredElementNamedElementCrossReference_0() { return cReferredElementNamedElementCrossReference_0; }

		//UnreservedName
		public RuleCall getReferredElementNamedElementUnreservedNameParserRuleCall_0_1() { return cReferredElementNamedElementUnreservedNameParserRuleCall_0_1; }
	}

	public class TemplateBindingCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TemplateBindingCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cLeftParenthesisKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cOwnedSubstitutionsAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cOwnedSubstitutionsTemplateParameterSubstitutionCSParserRuleCall_1_0 = (RuleCall)cOwnedSubstitutionsAssignment_1.eContents().get(0);
		private final Group cGroup_2 = (Group)cGroup.eContents().get(2);
		private final Keyword cCommaKeyword_2_0 = (Keyword)cGroup_2.eContents().get(0);
		private final Assignment cOwnedSubstitutionsAssignment_2_1 = (Assignment)cGroup_2.eContents().get(1);
		private final RuleCall cOwnedSubstitutionsTemplateParameterSubstitutionCSParserRuleCall_2_1_0 = (RuleCall)cOwnedSubstitutionsAssignment_2_1.eContents().get(0);
		private final Keyword cRightParenthesisKeyword_3 = (Keyword)cGroup.eContents().get(3);
		
		//TemplateBindingCS:
		//	"(" ownedSubstitutions+=TemplateParameterSubstitutionCS ("," ownedSubstitutions+=TemplateParameterSubstitutionCS)*
		//	")";
		@Override public ParserRule getRule() { return rule; }

		//"(" ownedSubstitutions+=TemplateParameterSubstitutionCS ("," ownedSubstitutions+=TemplateParameterSubstitutionCS)* ")"
		public Group getGroup() { return cGroup; }

		//"("
		public Keyword getLeftParenthesisKeyword_0() { return cLeftParenthesisKeyword_0; }

		//ownedSubstitutions+=TemplateParameterSubstitutionCS
		public Assignment getOwnedSubstitutionsAssignment_1() { return cOwnedSubstitutionsAssignment_1; }

		//TemplateParameterSubstitutionCS
		public RuleCall getOwnedSubstitutionsTemplateParameterSubstitutionCSParserRuleCall_1_0() { return cOwnedSubstitutionsTemplateParameterSubstitutionCSParserRuleCall_1_0; }

		//("," ownedSubstitutions+=TemplateParameterSubstitutionCS)*
		public Group getGroup_2() { return cGroup_2; }

		//","
		public Keyword getCommaKeyword_2_0() { return cCommaKeyword_2_0; }

		//ownedSubstitutions+=TemplateParameterSubstitutionCS
		public Assignment getOwnedSubstitutionsAssignment_2_1() { return cOwnedSubstitutionsAssignment_2_1; }

		//TemplateParameterSubstitutionCS
		public RuleCall getOwnedSubstitutionsTemplateParameterSubstitutionCSParserRuleCall_2_1_0() { return cOwnedSubstitutionsTemplateParameterSubstitutionCSParserRuleCall_2_1_0; }

		//")"
		public Keyword getRightParenthesisKeyword_3() { return cRightParenthesisKeyword_3; }
	}

	public class TemplateParameterSubstitutionCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TemplateParameterSubstitutionCS");
		private final Assignment cOwnedActualParameterAssignment = (Assignment)rule.eContents().get(1);
		private final RuleCall cOwnedActualParameterTypeRefCSParserRuleCall_0 = (RuleCall)cOwnedActualParameterAssignment.eContents().get(0);
		
		//TemplateParameterSubstitutionCS:
		//	ownedActualParameter=TypeRefCS;
		@Override public ParserRule getRule() { return rule; }

		//ownedActualParameter=TypeRefCS
		public Assignment getOwnedActualParameterAssignment() { return cOwnedActualParameterAssignment; }

		//TypeRefCS
		public RuleCall getOwnedActualParameterTypeRefCSParserRuleCall_0() { return cOwnedActualParameterTypeRefCSParserRuleCall_0; }
	}

	public class TemplateSignatureCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TemplateSignatureCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cLeftParenthesisKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cOwnedParametersAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cOwnedParametersTypeParameterCSParserRuleCall_1_0 = (RuleCall)cOwnedParametersAssignment_1.eContents().get(0);
		private final Group cGroup_2 = (Group)cGroup.eContents().get(2);
		private final Keyword cCommaKeyword_2_0 = (Keyword)cGroup_2.eContents().get(0);
		private final Assignment cOwnedParametersAssignment_2_1 = (Assignment)cGroup_2.eContents().get(1);
		private final RuleCall cOwnedParametersTypeParameterCSParserRuleCall_2_1_0 = (RuleCall)cOwnedParametersAssignment_2_1.eContents().get(0);
		private final Keyword cRightParenthesisKeyword_3 = (Keyword)cGroup.eContents().get(3);
		
		//TemplateSignatureCS:
		//	"(" ownedParameters+=TypeParameterCS ("," ownedParameters+=TypeParameterCS)* ")";
		@Override public ParserRule getRule() { return rule; }

		//"(" ownedParameters+=TypeParameterCS ("," ownedParameters+=TypeParameterCS)* ")"
		public Group getGroup() { return cGroup; }

		//"("
		public Keyword getLeftParenthesisKeyword_0() { return cLeftParenthesisKeyword_0; }

		//ownedParameters+=TypeParameterCS
		public Assignment getOwnedParametersAssignment_1() { return cOwnedParametersAssignment_1; }

		//TypeParameterCS
		public RuleCall getOwnedParametersTypeParameterCSParserRuleCall_1_0() { return cOwnedParametersTypeParameterCSParserRuleCall_1_0; }

		//("," ownedParameters+=TypeParameterCS)*
		public Group getGroup_2() { return cGroup_2; }

		//","
		public Keyword getCommaKeyword_2_0() { return cCommaKeyword_2_0; }

		//ownedParameters+=TypeParameterCS
		public Assignment getOwnedParametersAssignment_2_1() { return cOwnedParametersAssignment_2_1; }

		//TypeParameterCS
		public RuleCall getOwnedParametersTypeParameterCSParserRuleCall_2_1_0() { return cOwnedParametersTypeParameterCSParserRuleCall_2_1_0; }

		//")"
		public Keyword getRightParenthesisKeyword_3() { return cRightParenthesisKeyword_3; }
	}

	public class TypeParameterCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TypeParameterCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cNameAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cNameUnrestrictedNameParserRuleCall_0_0 = (RuleCall)cNameAssignment_0.eContents().get(0);
		private final Alternatives cAlternatives_1 = (Alternatives)cGroup.eContents().get(1);
		private final Group cGroup_1_0 = (Group)cAlternatives_1.eContents().get(0);
		private final Keyword cExtendsKeyword_1_0_0 = (Keyword)cGroup_1_0.eContents().get(0);
		private final Assignment cOwnedExtendsAssignment_1_0_1 = (Assignment)cGroup_1_0.eContents().get(1);
		private final RuleCall cOwnedExtendsTypedRefCSParserRuleCall_1_0_1_0 = (RuleCall)cOwnedExtendsAssignment_1_0_1.eContents().get(0);
		private final Group cGroup_1_0_2 = (Group)cGroup_1_0.eContents().get(2);
		private final Keyword cAmpersandAmpersandKeyword_1_0_2_0 = (Keyword)cGroup_1_0_2.eContents().get(0);
		private final Assignment cOwnedExtendsAssignment_1_0_2_1 = (Assignment)cGroup_1_0_2.eContents().get(1);
		private final RuleCall cOwnedExtendsTypedRefCSParserRuleCall_1_0_2_1_0 = (RuleCall)cOwnedExtendsAssignment_1_0_2_1.eContents().get(0);
		private final Group cGroup_1_1 = (Group)cAlternatives_1.eContents().get(1);
		private final Keyword cSuperKeyword_1_1_0 = (Keyword)cGroup_1_1.eContents().get(0);
		private final Assignment cOwnedSuperAssignment_1_1_1 = (Assignment)cGroup_1_1.eContents().get(1);
		private final RuleCall cOwnedSuperTypedRefCSParserRuleCall_1_1_1_0 = (RuleCall)cOwnedSuperAssignment_1_1_1.eContents().get(0);
		
		//TypeParameterCS:
		//	name=UnrestrictedName ("extends" ownedExtends+=TypedRefCS ("&&" ownedExtends+=TypedRefCS)* | "super"
		//	ownedSuper=TypedRefCS)?;
		@Override public ParserRule getRule() { return rule; }

		//name=UnrestrictedName ("extends" ownedExtends+=TypedRefCS ("&&" ownedExtends+=TypedRefCS)* | "super"
		//ownedSuper=TypedRefCS)?
		public Group getGroup() { return cGroup; }

		//name=UnrestrictedName
		public Assignment getNameAssignment_0() { return cNameAssignment_0; }

		//UnrestrictedName
		public RuleCall getNameUnrestrictedNameParserRuleCall_0_0() { return cNameUnrestrictedNameParserRuleCall_0_0; }

		//("extends" ownedExtends+=TypedRefCS ("&&" ownedExtends+=TypedRefCS)* | "super" ownedSuper=TypedRefCS)?
		public Alternatives getAlternatives_1() { return cAlternatives_1; }

		//"extends" ownedExtends+=TypedRefCS ("&&" ownedExtends+=TypedRefCS)*
		public Group getGroup_1_0() { return cGroup_1_0; }

		//"extends"
		public Keyword getExtendsKeyword_1_0_0() { return cExtendsKeyword_1_0_0; }

		//ownedExtends+=TypedRefCS
		public Assignment getOwnedExtendsAssignment_1_0_1() { return cOwnedExtendsAssignment_1_0_1; }

		//TypedRefCS
		public RuleCall getOwnedExtendsTypedRefCSParserRuleCall_1_0_1_0() { return cOwnedExtendsTypedRefCSParserRuleCall_1_0_1_0; }

		//("&&" ownedExtends+=TypedRefCS)*
		public Group getGroup_1_0_2() { return cGroup_1_0_2; }

		//"&&"
		public Keyword getAmpersandAmpersandKeyword_1_0_2_0() { return cAmpersandAmpersandKeyword_1_0_2_0; }

		//ownedExtends+=TypedRefCS
		public Assignment getOwnedExtendsAssignment_1_0_2_1() { return cOwnedExtendsAssignment_1_0_2_1; }

		//TypedRefCS
		public RuleCall getOwnedExtendsTypedRefCSParserRuleCall_1_0_2_1_0() { return cOwnedExtendsTypedRefCSParserRuleCall_1_0_2_1_0; }

		//"super" ownedSuper=TypedRefCS
		public Group getGroup_1_1() { return cGroup_1_1; }

		//"super"
		public Keyword getSuperKeyword_1_1_0() { return cSuperKeyword_1_1_0; }

		//ownedSuper=TypedRefCS
		public Assignment getOwnedSuperAssignment_1_1_1() { return cOwnedSuperAssignment_1_1_1; }

		//TypedRefCS
		public RuleCall getOwnedSuperTypedRefCSParserRuleCall_1_1_1_0() { return cOwnedSuperTypedRefCSParserRuleCall_1_1_1_0; }
	}

	public class TypeRefCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TypeRefCS");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final RuleCall cTypedRefCSParserRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0);
		private final RuleCall cWildcardTypeRefCSParserRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1);
		
		//TypeRefCS:
		//	TypedRefCS | WildcardTypeRefCS;
		@Override public ParserRule getRule() { return rule; }

		//TypedRefCS | WildcardTypeRefCS
		public Alternatives getAlternatives() { return cAlternatives; }

		//TypedRefCS
		public RuleCall getTypedRefCSParserRuleCall_0() { return cTypedRefCSParserRuleCall_0; }

		//WildcardTypeRefCS
		public RuleCall getWildcardTypeRefCSParserRuleCall_1() { return cWildcardTypeRefCSParserRuleCall_1; }
	}

	public class TypedRefCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TypedRefCS");
		private final RuleCall cTypedTypeRefCSParserRuleCall = (RuleCall)rule.eContents().get(1);
		
		//TypedRefCS:
		//	TypedTypeRefCS;
		@Override public ParserRule getRule() { return rule; }

		//TypedTypeRefCS
		public RuleCall getTypedTypeRefCSParserRuleCall() { return cTypedTypeRefCSParserRuleCall; }
	}

	public class TypedTypeRefCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "TypedTypeRefCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Assignment cOwnedPathNameAssignment_0 = (Assignment)cGroup.eContents().get(0);
		private final RuleCall cOwnedPathNamePathNameCSParserRuleCall_0_0 = (RuleCall)cOwnedPathNameAssignment_0.eContents().get(0);
		private final Assignment cOwnedBindingAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cOwnedBindingTemplateBindingCSParserRuleCall_1_0 = (RuleCall)cOwnedBindingAssignment_1.eContents().get(0);
		
		//TypedTypeRefCS:
		//	ownedPathName=PathNameCS ownedBinding=TemplateBindingCS?;
		@Override public ParserRule getRule() { return rule; }

		//ownedPathName=PathNameCS ownedBinding=TemplateBindingCS?
		public Group getGroup() { return cGroup; }

		//ownedPathName=PathNameCS
		public Assignment getOwnedPathNameAssignment_0() { return cOwnedPathNameAssignment_0; }

		//PathNameCS
		public RuleCall getOwnedPathNamePathNameCSParserRuleCall_0_0() { return cOwnedPathNamePathNameCSParserRuleCall_0_0; }

		//ownedBinding=TemplateBindingCS?
		public Assignment getOwnedBindingAssignment_1() { return cOwnedBindingAssignment_1; }

		//TemplateBindingCS
		public RuleCall getOwnedBindingTemplateBindingCSParserRuleCall_1_0() { return cOwnedBindingTemplateBindingCSParserRuleCall_1_0; }
	}

	public class UnreservedNameElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "UnreservedName");
		private final RuleCall cUnrestrictedNameParserRuleCall = (RuleCall)rule.eContents().get(1);
		
		//// Intended to be overridden
		// UnreservedName returns ecore::EString:
		//	UnrestrictedName;
		@Override public ParserRule getRule() { return rule; }

		//UnrestrictedName
		public RuleCall getUnrestrictedNameParserRuleCall() { return cUnrestrictedNameParserRuleCall; }
	}

	public class UnrestrictedNameElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "UnrestrictedName");
		private final RuleCall cIdentifierParserRuleCall = (RuleCall)rule.eContents().get(1);
		
		//// Intended to be overridden
		// UnrestrictedName returns ecore::EString:
		//	Identifier;
		@Override public ParserRule getRule() { return rule; }

		//Identifier
		public RuleCall getIdentifierParserRuleCall() { return cIdentifierParserRuleCall; }
	}

	public class WildcardTypeRefCSElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "WildcardTypeRefCS");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cWildcardTypeRefCSAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cQuestionMarkKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Alternatives cAlternatives_2 = (Alternatives)cGroup.eContents().get(2);
		private final Group cGroup_2_0 = (Group)cAlternatives_2.eContents().get(0);
		private final Keyword cExtendsKeyword_2_0_0 = (Keyword)cGroup_2_0.eContents().get(0);
		private final Assignment cOwnedExtendsAssignment_2_0_1 = (Assignment)cGroup_2_0.eContents().get(1);
		private final RuleCall cOwnedExtendsTypedRefCSParserRuleCall_2_0_1_0 = (RuleCall)cOwnedExtendsAssignment_2_0_1.eContents().get(0);
		private final Group cGroup_2_1 = (Group)cAlternatives_2.eContents().get(1);
		private final Keyword cSuperKeyword_2_1_0 = (Keyword)cGroup_2_1.eContents().get(0);
		private final Assignment cOwnedSuperAssignment_2_1_1 = (Assignment)cGroup_2_1.eContents().get(1);
		private final RuleCall cOwnedSuperTypedRefCSParserRuleCall_2_1_1_0 = (RuleCall)cOwnedSuperAssignment_2_1_1.eContents().get(0);
		
		//WildcardTypeRefCS:
		//	{WildcardTypeRefCS} "?" ("extends" ownedExtends=TypedRefCS | "super" ownedSuper=TypedRefCS)?;
		@Override public ParserRule getRule() { return rule; }

		//{WildcardTypeRefCS} "?" ("extends" ownedExtends=TypedRefCS | "super" ownedSuper=TypedRefCS)?
		public Group getGroup() { return cGroup; }

		//{WildcardTypeRefCS}
		public Action getWildcardTypeRefCSAction_0() { return cWildcardTypeRefCSAction_0; }

		//"?"
		public Keyword getQuestionMarkKeyword_1() { return cQuestionMarkKeyword_1; }

		//("extends" ownedExtends=TypedRefCS | "super" ownedSuper=TypedRefCS)?
		public Alternatives getAlternatives_2() { return cAlternatives_2; }

		//"extends" ownedExtends=TypedRefCS
		public Group getGroup_2_0() { return cGroup_2_0; }

		//"extends"
		public Keyword getExtendsKeyword_2_0_0() { return cExtendsKeyword_2_0_0; }

		//ownedExtends=TypedRefCS
		public Assignment getOwnedExtendsAssignment_2_0_1() { return cOwnedExtendsAssignment_2_0_1; }

		//TypedRefCS
		public RuleCall getOwnedExtendsTypedRefCSParserRuleCall_2_0_1_0() { return cOwnedExtendsTypedRefCSParserRuleCall_2_0_1_0; }

		//"super" ownedSuper=TypedRefCS
		public Group getGroup_2_1() { return cGroup_2_1; }

		//"super"
		public Keyword getSuperKeyword_2_1_0() { return cSuperKeyword_2_1_0; }

		//ownedSuper=TypedRefCS
		public Assignment getOwnedSuperAssignment_2_1_1() { return cOwnedSuperAssignment_2_1_1; }

		//TypedRefCS
		public RuleCall getOwnedSuperTypedRefCSParserRuleCall_2_1_1_0() { return cOwnedSuperTypedRefCSParserRuleCall_2_1_1_0; }
	}

	public class IDElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "ID");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final RuleCall cSIMPLE_IDTerminalRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0);
		private final RuleCall cESCAPED_IDTerminalRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1);
		
		//ID:
		//	SIMPLE_ID | ESCAPED_ID;
		@Override public ParserRule getRule() { return rule; }

		//SIMPLE_ID | ESCAPED_ID
		public Alternatives getAlternatives() { return cAlternatives; }

		//SIMPLE_ID
		public RuleCall getSIMPLE_IDTerminalRuleCall_0() { return cSIMPLE_IDTerminalRuleCall_0; }

		//ESCAPED_ID
		public RuleCall getESCAPED_IDTerminalRuleCall_1() { return cESCAPED_IDTerminalRuleCall_1; }
	}

	public class IdentifierElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "Identifier");
		private final RuleCall cIDParserRuleCall = (RuleCall)rule.eContents().get(1);
		
		//Identifier:
		//	ID;
		@Override public ParserRule getRule() { return rule; }

		//ID
		public RuleCall getIDParserRuleCall() { return cIDParserRuleCall; }
	}

	public class LOWERElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "LOWER");
		private final RuleCall cINTTerminalRuleCall = (RuleCall)rule.eContents().get(1);
		
		/// * A lowerbounded integer is used to define the lowerbound of a collection multiplicity. The value may not be the unlimited value. * /
		//LOWER returns ecore::EInt:
		//	INT;
		@Override public ParserRule getRule() { return rule; }

		//INT
		public RuleCall getINTTerminalRuleCall() { return cINTTerminalRuleCall; }
	}

	public class NUMBER_LITERALElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "NUMBER_LITERAL");
		private final RuleCall cINTTerminalRuleCall = (RuleCall)rule.eContents().get(1);
		
		/// * A number may be an integer or floating point value. The declaration here appears to be that for just an integer. This is to avoid
		// * lookahead conflicts in simple lexers between a dot within a floating point number and the dot-dot in a CollectionLiteralPartCS. A
		// * practical implementation should give high priority to a successful parse of INT ('.' INT)? (('e' | 'E') ('+' | '-')? INT)? than
		// * to the unsuccessful partial parse of INT '..'. The type of the INT terminal is String to allow the floating point syntax to be used.
		// * /
		//// Not terminal to allow parser backtracking to sort out "5..7"
		//
		//// EssentialOCLTokenSource pieces this together ('.' INT)? (('e' | 'E') ('+' | '-')? INT)?;
		// NUMBER_LITERAL returns
		//BigNumber:
		//	INT;
		@Override public ParserRule getRule() { return rule; }

		//INT
		public RuleCall getINTTerminalRuleCall() { return cINTTerminalRuleCall; }
	}

	public class StringLiteralElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "StringLiteral");
		private final RuleCall cSINGLE_QUOTED_STRINGTerminalRuleCall = (RuleCall)rule.eContents().get(1);
		
		//StringLiteral:
		//	SINGLE_QUOTED_STRING;
		@Override public ParserRule getRule() { return rule; }

		//SINGLE_QUOTED_STRING
		public RuleCall getSINGLE_QUOTED_STRINGTerminalRuleCall() { return cSINGLE_QUOTED_STRINGTerminalRuleCall; }
	}

	public class UPPERElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "UPPER");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final RuleCall cINTTerminalRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0);
		private final Keyword cAsteriskKeyword_1 = (Keyword)cAlternatives.eContents().get(1);
		
		/// * An upperbounded integer is used to define the upperbound of a collection multiplicity. The value may be the unlimited value. * /
		//UPPER returns ecore::EInt:
		//	INT | "*";
		@Override public ParserRule getRule() { return rule; }

		//INT | "*"
		public Alternatives getAlternatives() { return cAlternatives; }

		//INT
		public RuleCall getINTTerminalRuleCall_0() { return cINTTerminalRuleCall_0; }

		//"*"
		public Keyword getAsteriskKeyword_1() { return cAsteriskKeyword_1; }
	}

	public class URIElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "URI");
		private final RuleCall cSINGLE_QUOTED_STRINGTerminalRuleCall = (RuleCall)rule.eContents().get(1);
		
		//URI:
		//	SINGLE_QUOTED_STRING;
		@Override public ParserRule getRule() { return rule; }

		//SINGLE_QUOTED_STRING
		public RuleCall getSINGLE_QUOTED_STRINGTerminalRuleCall() { return cSINGLE_QUOTED_STRINGTerminalRuleCall; }
	}
	
	
	private final MultiplicityBoundsCSElements pMultiplicityBoundsCS;
	private final MultiplicityCSElements pMultiplicityCS;
	private final MultiplicityStringCSElements pMultiplicityStringCS;
	private final PathNameCSElements pPathNameCS;
	private final FirstPathElementCSElements pFirstPathElementCS;
	private final NextPathElementCSElements pNextPathElementCS;
	private final TemplateBindingCSElements pTemplateBindingCS;
	private final TemplateParameterSubstitutionCSElements pTemplateParameterSubstitutionCS;
	private final TemplateSignatureCSElements pTemplateSignatureCS;
	private final TypeParameterCSElements pTypeParameterCS;
	private final TypeRefCSElements pTypeRefCS;
	private final TypedRefCSElements pTypedRefCS;
	private final TypedTypeRefCSElements pTypedTypeRefCS;
	private final UnreservedNameElements pUnreservedName;
	private final UnrestrictedNameElements pUnrestrictedName;
	private final WildcardTypeRefCSElements pWildcardTypeRefCS;
	private final IDElements pID;
	private final IdentifierElements pIdentifier;
	private final LOWERElements pLOWER;
	private final NUMBER_LITERALElements pNUMBER_LITERAL;
	private final StringLiteralElements pStringLiteral;
	private final UPPERElements pUPPER;
	private final URIElements pURI;
	private final TerminalRule tESCAPED_CHARACTER;
	private final TerminalRule tLETTER_CHARACTER;
	private final TerminalRule tDOUBLE_QUOTED_STRING;
	private final TerminalRule tSINGLE_QUOTED_STRING;
	private final TerminalRule tML_SINGLE_QUOTED_STRING;
	private final TerminalRule tSIMPLE_ID;
	private final TerminalRule tESCAPED_ID;
	private final TerminalRule tINT;
	private final TerminalRule tML_COMMENT;
	private final TerminalRule tSL_COMMENT;
	private final TerminalRule tWS;
	private final TerminalRule tANY_OTHER;
	
	private final Grammar grammar;

	@Inject
	public BaseGrammarAccess(GrammarProvider grammarProvider) {
		this.grammar = internalFindGrammar(grammarProvider);
		this.pMultiplicityBoundsCS = new MultiplicityBoundsCSElements();
		this.pMultiplicityCS = new MultiplicityCSElements();
		this.pMultiplicityStringCS = new MultiplicityStringCSElements();
		this.pPathNameCS = new PathNameCSElements();
		this.pFirstPathElementCS = new FirstPathElementCSElements();
		this.pNextPathElementCS = new NextPathElementCSElements();
		this.pTemplateBindingCS = new TemplateBindingCSElements();
		this.pTemplateParameterSubstitutionCS = new TemplateParameterSubstitutionCSElements();
		this.pTemplateSignatureCS = new TemplateSignatureCSElements();
		this.pTypeParameterCS = new TypeParameterCSElements();
		this.pTypeRefCS = new TypeRefCSElements();
		this.pTypedRefCS = new TypedRefCSElements();
		this.pTypedTypeRefCS = new TypedTypeRefCSElements();
		this.pUnreservedName = new UnreservedNameElements();
		this.pUnrestrictedName = new UnrestrictedNameElements();
		this.pWildcardTypeRefCS = new WildcardTypeRefCSElements();
		this.pID = new IDElements();
		this.pIdentifier = new IdentifierElements();
		this.pLOWER = new LOWERElements();
		this.pNUMBER_LITERAL = new NUMBER_LITERALElements();
		this.pStringLiteral = new StringLiteralElements();
		this.pUPPER = new UPPERElements();
		this.pURI = new URIElements();
		this.tESCAPED_CHARACTER = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "ESCAPED_CHARACTER");
		this.tLETTER_CHARACTER = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "LETTER_CHARACTER");
		this.tDOUBLE_QUOTED_STRING = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "DOUBLE_QUOTED_STRING");
		this.tSINGLE_QUOTED_STRING = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "SINGLE_QUOTED_STRING");
		this.tML_SINGLE_QUOTED_STRING = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "ML_SINGLE_QUOTED_STRING");
		this.tSIMPLE_ID = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "SIMPLE_ID");
		this.tESCAPED_ID = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "ESCAPED_ID");
		this.tINT = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "INT");
		this.tML_COMMENT = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "ML_COMMENT");
		this.tSL_COMMENT = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "SL_COMMENT");
		this.tWS = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "WS");
		this.tANY_OTHER = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "ANY_OTHER");
	}
	
	protected Grammar internalFindGrammar(GrammarProvider grammarProvider) {
		Grammar grammar = grammarProvider.getGrammar(this);
		while (grammar != null) {
			if ("org.eclipse.ocl.xtext.base.Base".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;
	}
	

	
	//MultiplicityBoundsCS:
	//	lowerBound=LOWER (".." upperBound=UPPER)?;
	public MultiplicityBoundsCSElements getMultiplicityBoundsCSAccess() {
		return pMultiplicityBoundsCS;
	}
	
	public ParserRule getMultiplicityBoundsCSRule() {
		return getMultiplicityBoundsCSAccess().getRule();
	}

	//MultiplicityCS:
	//	"[" (MultiplicityBoundsCS | MultiplicityStringCS) "]";
	public MultiplicityCSElements getMultiplicityCSAccess() {
		return pMultiplicityCS;
	}
	
	public ParserRule getMultiplicityCSRule() {
		return getMultiplicityCSAccess().getRule();
	}

	//MultiplicityStringCS:
	//	stringBounds=("*" | "+" | "?");
	public MultiplicityStringCSElements getMultiplicityStringCSAccess() {
		return pMultiplicityStringCS;
	}
	
	public ParserRule getMultiplicityStringCSRule() {
		return getMultiplicityStringCSAccess().getRule();
	}

	//PathNameCS:
	//	ownedPathElements+=FirstPathElementCS ("::" ownedPathElements+=NextPathElementCS)*;
	public PathNameCSElements getPathNameCSAccess() {
		return pPathNameCS;
	}
	
	public ParserRule getPathNameCSRule() {
		return getPathNameCSAccess().getRule();
	}

	//FirstPathElementCS returns PathElementCS:
	//	referredElement=[pivot::NamedElement|UnrestrictedName];
	public FirstPathElementCSElements getFirstPathElementCSAccess() {
		return pFirstPathElementCS;
	}
	
	public ParserRule getFirstPathElementCSRule() {
		return getFirstPathElementCSAccess().getRule();
	}

	//NextPathElementCS returns PathElementCS:
	//	referredElement=[pivot::NamedElement|UnreservedName];
	public NextPathElementCSElements getNextPathElementCSAccess() {
		return pNextPathElementCS;
	}
	
	public ParserRule getNextPathElementCSRule() {
		return getNextPathElementCSAccess().getRule();
	}

	//TemplateBindingCS:
	//	"(" ownedSubstitutions+=TemplateParameterSubstitutionCS ("," ownedSubstitutions+=TemplateParameterSubstitutionCS)*
	//	")";
	public TemplateBindingCSElements getTemplateBindingCSAccess() {
		return pTemplateBindingCS;
	}
	
	public ParserRule getTemplateBindingCSRule() {
		return getTemplateBindingCSAccess().getRule();
	}

	//TemplateParameterSubstitutionCS:
	//	ownedActualParameter=TypeRefCS;
	public TemplateParameterSubstitutionCSElements getTemplateParameterSubstitutionCSAccess() {
		return pTemplateParameterSubstitutionCS;
	}
	
	public ParserRule getTemplateParameterSubstitutionCSRule() {
		return getTemplateParameterSubstitutionCSAccess().getRule();
	}

	//TemplateSignatureCS:
	//	"(" ownedParameters+=TypeParameterCS ("," ownedParameters+=TypeParameterCS)* ")";
	public TemplateSignatureCSElements getTemplateSignatureCSAccess() {
		return pTemplateSignatureCS;
	}
	
	public ParserRule getTemplateSignatureCSRule() {
		return getTemplateSignatureCSAccess().getRule();
	}

	//TypeParameterCS:
	//	name=UnrestrictedName ("extends" ownedExtends+=TypedRefCS ("&&" ownedExtends+=TypedRefCS)* | "super"
	//	ownedSuper=TypedRefCS)?;
	public TypeParameterCSElements getTypeParameterCSAccess() {
		return pTypeParameterCS;
	}
	
	public ParserRule getTypeParameterCSRule() {
		return getTypeParameterCSAccess().getRule();
	}

	//TypeRefCS:
	//	TypedRefCS | WildcardTypeRefCS;
	public TypeRefCSElements getTypeRefCSAccess() {
		return pTypeRefCS;
	}
	
	public ParserRule getTypeRefCSRule() {
		return getTypeRefCSAccess().getRule();
	}

	//TypedRefCS:
	//	TypedTypeRefCS;
	public TypedRefCSElements getTypedRefCSAccess() {
		return pTypedRefCS;
	}
	
	public ParserRule getTypedRefCSRule() {
		return getTypedRefCSAccess().getRule();
	}

	//TypedTypeRefCS:
	//	ownedPathName=PathNameCS ownedBinding=TemplateBindingCS?;
	public TypedTypeRefCSElements getTypedTypeRefCSAccess() {
		return pTypedTypeRefCS;
	}
	
	public ParserRule getTypedTypeRefCSRule() {
		return getTypedTypeRefCSAccess().getRule();
	}

	//// Intended to be overridden
	// UnreservedName returns ecore::EString:
	//	UnrestrictedName;
	public UnreservedNameElements getUnreservedNameAccess() {
		return pUnreservedName;
	}
	
	public ParserRule getUnreservedNameRule() {
		return getUnreservedNameAccess().getRule();
	}

	//// Intended to be overridden
	// UnrestrictedName returns ecore::EString:
	//	Identifier;
	public UnrestrictedNameElements getUnrestrictedNameAccess() {
		return pUnrestrictedName;
	}
	
	public ParserRule getUnrestrictedNameRule() {
		return getUnrestrictedNameAccess().getRule();
	}

	//WildcardTypeRefCS:
	//	{WildcardTypeRefCS} "?" ("extends" ownedExtends=TypedRefCS | "super" ownedSuper=TypedRefCS)?;
	public WildcardTypeRefCSElements getWildcardTypeRefCSAccess() {
		return pWildcardTypeRefCS;
	}
	
	public ParserRule getWildcardTypeRefCSRule() {
		return getWildcardTypeRefCSAccess().getRule();
	}

	//ID:
	//	SIMPLE_ID | ESCAPED_ID;
	public IDElements getIDAccess() {
		return pID;
	}
	
	public ParserRule getIDRule() {
		return getIDAccess().getRule();
	}

	//Identifier:
	//	ID;
	public IdentifierElements getIdentifierAccess() {
		return pIdentifier;
	}
	
	public ParserRule getIdentifierRule() {
		return getIdentifierAccess().getRule();
	}

	/// * A lowerbounded integer is used to define the lowerbound of a collection multiplicity. The value may not be the unlimited value. * /
	//LOWER returns ecore::EInt:
	//	INT;
	public LOWERElements getLOWERAccess() {
		return pLOWER;
	}
	
	public ParserRule getLOWERRule() {
		return getLOWERAccess().getRule();
	}

	/// * A number may be an integer or floating point value. The declaration here appears to be that for just an integer. This is to avoid
	// * lookahead conflicts in simple lexers between a dot within a floating point number and the dot-dot in a CollectionLiteralPartCS. A
	// * practical implementation should give high priority to a successful parse of INT ('.' INT)? (('e' | 'E') ('+' | '-')? INT)? than
	// * to the unsuccessful partial parse of INT '..'. The type of the INT terminal is String to allow the floating point syntax to be used.
	// * /
	//// Not terminal to allow parser backtracking to sort out "5..7"
	//
	//// EssentialOCLTokenSource pieces this together ('.' INT)? (('e' | 'E') ('+' | '-')? INT)?;
	// NUMBER_LITERAL returns
	//BigNumber:
	//	INT;
	public NUMBER_LITERALElements getNUMBER_LITERALAccess() {
		return pNUMBER_LITERAL;
	}
	
	public ParserRule getNUMBER_LITERALRule() {
		return getNUMBER_LITERALAccess().getRule();
	}

	//StringLiteral:
	//	SINGLE_QUOTED_STRING;
	public StringLiteralElements getStringLiteralAccess() {
		return pStringLiteral;
	}
	
	public ParserRule getStringLiteralRule() {
		return getStringLiteralAccess().getRule();
	}

	/// * An upperbounded integer is used to define the upperbound of a collection multiplicity. The value may be the unlimited value. * /
	//UPPER returns ecore::EInt:
	//	INT | "*";
	public UPPERElements getUPPERAccess() {
		return pUPPER;
	}
	
	public ParserRule getUPPERRule() {
		return getUPPERAccess().getRule();
	}

	//URI:
	//	SINGLE_QUOTED_STRING;
	public URIElements getURIAccess() {
		return pURI;
	}
	
	public ParserRule getURIRule() {
		return getURIAccess().getRule();
	}

	//terminal fragment ESCAPED_CHARACTER:
	//	"\\" ("b" | "t" | "n" | "f" | "r" | "u" | "\"" | "\'" | "\\");
	public TerminalRule getESCAPED_CHARACTERRule() {
		return tESCAPED_CHARACTER;
	} 

	//terminal fragment LETTER_CHARACTER:
	//	"a".."z" | "A".."Z" | "_";
	public TerminalRule getLETTER_CHARACTERRule() {
		return tLETTER_CHARACTER;
	} 

	//terminal DOUBLE_QUOTED_STRING:
	//	"\"" (ESCAPED_CHARACTER | !("\\" | "\""))* "\"";
	public TerminalRule getDOUBLE_QUOTED_STRINGRule() {
		return tDOUBLE_QUOTED_STRING;
	} 

	//terminal SINGLE_QUOTED_STRING:
	//	"\'" (ESCAPED_CHARACTER | !("\\" | "\'"))* "\'";
	public TerminalRule getSINGLE_QUOTED_STRINGRule() {
		return tSINGLE_QUOTED_STRING;
	} 

	//terminal ML_SINGLE_QUOTED_STRING:
	//	"/\'"->"\'/";
	public TerminalRule getML_SINGLE_QUOTED_STRINGRule() {
		return tML_SINGLE_QUOTED_STRING;
	} 

	//terminal SIMPLE_ID:
	//	LETTER_CHARACTER (LETTER_CHARACTER | "0".."9")*;
	public TerminalRule getSIMPLE_IDRule() {
		return tSIMPLE_ID;
	} 

	//terminal ESCAPED_ID:
	//	"_" SINGLE_QUOTED_STRING;
	public TerminalRule getESCAPED_IDRule() {
		return tESCAPED_ID;
	} 

	//// String to allow diverse re-use
	// // multiple leading zeroes occur as floating point fractional part
	// terminal INT:
	//	"0".."9"+;
	public TerminalRule getINTRule() {
		return tINT;
	} 

	/// * A multi-line comment supports a comment that may span more than one line using familiar slash-star...star-slash comment delimiters * /
	//terminal ML_COMMENT:
	//	"/ *"->"* /";
	public TerminalRule getML_COMMENTRule() {
		return tML_COMMENT;
	} 

	/// * A single-line comment supports a comment that terminates at the end of the line * / terminal SL_COMMENT:
	//	"--" !("\n" | "\r")* ("\r"? "\n")?;
	public TerminalRule getSL_COMMENTRule() {
		return tSL_COMMENT;
	} 

	/// * Whitespace may occur between any pair of tokens * / terminal WS:
	//	(" " | "\t" | "\r" | "\n")+;
	public TerminalRule getWSRule() {
		return tWS;
	} 

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