/*
 * generated by Xtext 2.11.0
 */
package org.eclipse.osbp.xtext.gridsource.services;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.List;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.Alternatives;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.EnumLiteralDeclaration;
import org.eclipse.xtext.EnumRule;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.TerminalRule;
import org.eclipse.xtext.service.AbstractElementFinder.AbstractEnumRuleElementFinder;
import org.eclipse.xtext.service.AbstractElementFinder.AbstractGrammarElementFinder;
import org.eclipse.xtext.service.GrammarProvider;
import org.eclipse.xtext.xbase.services.XtypeGrammarAccess;

@Singleton
public class GridSourceGrammarAccess extends AbstractGrammarElementFinder {
	
	public class SourceElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.Source");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cGridsourceKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cIdAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cIdQualifiedNameParserRuleCall_1_0 = (RuleCall)cIdAssignment_1.eContents().get(0);
		private final Keyword cForKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cRootTypeAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cRootTypeJvmTypeReferenceParserRuleCall_3_0 = (RuleCall)cRootTypeAssignment_3.eContents().get(0);
		private final Keyword cLeftCurlyBracketKeyword_4 = (Keyword)cGroup.eContents().get(4);
		private final Keyword cInputsKeyword_5 = (Keyword)cGroup.eContents().get(5);
		private final Keyword cLeftCurlyBracketKeyword_6 = (Keyword)cGroup.eContents().get(6);
		private final Assignment cInputsAssignment_7 = (Assignment)cGroup.eContents().get(7);
		private final RuleCall cInputsInputParserRuleCall_7_0 = (RuleCall)cInputsAssignment_7.eContents().get(0);
		private final Keyword cRightCurlyBracketKeyword_8 = (Keyword)cGroup.eContents().get(8);
		private final Assignment cPropertiesAssignment_9 = (Assignment)cGroup.eContents().get(9);
		private final RuleCall cPropertiesPropertyParserRuleCall_9_0 = (RuleCall)cPropertiesAssignment_9.eContents().get(0);
		private final Keyword cRightCurlyBracketKeyword_10 = (Keyword)cGroup.eContents().get(10);
		
		//Source CxGridSource:
		//	'gridsource' id=QualifiedName 'for' rootType=JvmTypeReference '{'
		//	'inputs' '{'
		//	inputs+=Input*
		//	'}'
		//	properties+=Property*
		//	'}';
		@Override public ParserRule getRule() { return rule; }
		
		//'gridsource' id=QualifiedName 'for' rootType=JvmTypeReference '{' 'inputs' '{' inputs+=Input* '}' properties+=Property*
		//'}'
		public Group getGroup() { return cGroup; }
		
		//'gridsource'
		public Keyword getGridsourceKeyword_0() { return cGridsourceKeyword_0; }
		
		//id=QualifiedName
		public Assignment getIdAssignment_1() { return cIdAssignment_1; }
		
		//QualifiedName
		public RuleCall getIdQualifiedNameParserRuleCall_1_0() { return cIdQualifiedNameParserRuleCall_1_0; }
		
		//'for'
		public Keyword getForKeyword_2() { return cForKeyword_2; }
		
		//rootType=JvmTypeReference
		public Assignment getRootTypeAssignment_3() { return cRootTypeAssignment_3; }
		
		//JvmTypeReference
		public RuleCall getRootTypeJvmTypeReferenceParserRuleCall_3_0() { return cRootTypeJvmTypeReferenceParserRuleCall_3_0; }
		
		//'{'
		public Keyword getLeftCurlyBracketKeyword_4() { return cLeftCurlyBracketKeyword_4; }
		
		//'inputs'
		public Keyword getInputsKeyword_5() { return cInputsKeyword_5; }
		
		//'{'
		public Keyword getLeftCurlyBracketKeyword_6() { return cLeftCurlyBracketKeyword_6; }
		
		//inputs+=Input*
		public Assignment getInputsAssignment_7() { return cInputsAssignment_7; }
		
		//Input
		public RuleCall getInputsInputParserRuleCall_7_0() { return cInputsInputParserRuleCall_7_0; }
		
		//'}'
		public Keyword getRightCurlyBracketKeyword_8() { return cRightCurlyBracketKeyword_8; }
		
		//properties+=Property*
		public Assignment getPropertiesAssignment_9() { return cPropertiesAssignment_9; }
		
		//Property
		public RuleCall getPropertiesPropertyParserRuleCall_9_0() { return cPropertiesPropertyParserRuleCall_9_0; }
		
		//'}'
		public Keyword getRightCurlyBracketKeyword_10() { return cRightCurlyBracketKeyword_10; }
	}
	public class InputElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.Input");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cInputTypeKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cInputTypeAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cInputTypeJvmTypeReferenceParserRuleCall_1_0 = (RuleCall)cInputTypeAssignment_1.eContents().get(0);
		private final Keyword cFiltersKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cFiltersAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cFiltersEQFilterParserRuleCall_3_0 = (RuleCall)cFiltersAssignment_3.eContents().get(0);
		private final Group cGroup_4 = (Group)cGroup.eContents().get(4);
		private final Keyword cAmpersandAmpersandKeyword_4_0 = (Keyword)cGroup_4.eContents().get(0);
		private final Assignment cFiltersAssignment_4_1 = (Assignment)cGroup_4.eContents().get(1);
		private final RuleCall cFiltersEQFilterParserRuleCall_4_1_0 = (RuleCall)cFiltersAssignment_4_1.eContents().get(0);
		
		//Input CxGridSourceInput:
		//	'inputType' inputType=JvmTypeReference
		//	'filters' filters+=EQFilter ('&&' filters+=EQFilter)*;
		@Override public ParserRule getRule() { return rule; }
		
		//'inputType' inputType=JvmTypeReference 'filters' filters+=EQFilter ('&&' filters+=EQFilter)*
		public Group getGroup() { return cGroup; }
		
		//'inputType'
		public Keyword getInputTypeKeyword_0() { return cInputTypeKeyword_0; }
		
		//inputType=JvmTypeReference
		public Assignment getInputTypeAssignment_1() { return cInputTypeAssignment_1; }
		
		//JvmTypeReference
		public RuleCall getInputTypeJvmTypeReferenceParserRuleCall_1_0() { return cInputTypeJvmTypeReferenceParserRuleCall_1_0; }
		
		//'filters'
		public Keyword getFiltersKeyword_2() { return cFiltersKeyword_2; }
		
		//filters+=EQFilter
		public Assignment getFiltersAssignment_3() { return cFiltersAssignment_3; }
		
		//EQFilter
		public RuleCall getFiltersEQFilterParserRuleCall_3_0() { return cFiltersEQFilterParserRuleCall_3_0; }
		
		//('&&' filters+=EQFilter)*
		public Group getGroup_4() { return cGroup_4; }
		
		//'&&'
		public Keyword getAmpersandAmpersandKeyword_4_0() { return cAmpersandAmpersandKeyword_4_0; }
		
		//filters+=EQFilter
		public Assignment getFiltersAssignment_4_1() { return cFiltersAssignment_4_1; }
		
		//EQFilter
		public RuleCall getFiltersEQFilterParserRuleCall_4_1_0() { return cFiltersEQFilterParserRuleCall_4_1_0; }
	}
	public class EQFilterElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.EQFilter");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridSourceEQFilterAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cRootKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cRootTypePropertyPathAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cRootTypePropertyPathNestedFieldParserRuleCall_2_0 = (RuleCall)cRootTypePropertyPathAssignment_2.eContents().get(0);
		private final Keyword cEqualsSignKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Keyword cInputKeyword_4 = (Keyword)cGroup.eContents().get(4);
		private final Assignment cInputTypePropertyPathAssignment_5 = (Assignment)cGroup.eContents().get(5);
		private final RuleCall cInputTypePropertyPathNestedFieldParserRuleCall_5_0 = (RuleCall)cInputTypePropertyPathAssignment_5.eContents().get(0);
		
		//EQFilter CxGridSourceEQFilter:
		//	{CxGridSourceEQFilter}
		//	'root:' rootTypePropertyPath=NestedField '=' 'input:' inputTypePropertyPath=NestedField;
		@Override public ParserRule getRule() { return rule; }
		
		//{CxGridSourceEQFilter} 'root:' rootTypePropertyPath=NestedField '=' 'input:' inputTypePropertyPath=NestedField
		public Group getGroup() { return cGroup; }
		
		//{CxGridSourceEQFilter}
		public Action getCxGridSourceEQFilterAction_0() { return cCxGridSourceEQFilterAction_0; }
		
		//'root:'
		public Keyword getRootKeyword_1() { return cRootKeyword_1; }
		
		//rootTypePropertyPath=NestedField
		public Assignment getRootTypePropertyPathAssignment_2() { return cRootTypePropertyPathAssignment_2; }
		
		//NestedField
		public RuleCall getRootTypePropertyPathNestedFieldParserRuleCall_2_0() { return cRootTypePropertyPathNestedFieldParserRuleCall_2_0; }
		
		//'='
		public Keyword getEqualsSignKeyword_3() { return cEqualsSignKeyword_3; }
		
		//'input:'
		public Keyword getInputKeyword_4() { return cInputKeyword_4; }
		
		//inputTypePropertyPath=NestedField
		public Assignment getInputTypePropertyPathAssignment_5() { return cInputTypePropertyPathAssignment_5; }
		
		//NestedField
		public RuleCall getInputTypePropertyPathNestedFieldParserRuleCall_5_0() { return cInputTypePropertyPathNestedFieldParserRuleCall_5_0; }
	}
	public class PropertyElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.Property");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cPropKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cPathAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cPathNestedFieldParserRuleCall_1_0 = (RuleCall)cPathAssignment_1.eContents().get(0);
		private final Keyword cStyleKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cStyleAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cStylePropertyStyleParserRuleCall_3_0 = (RuleCall)cStyleAssignment_3.eContents().get(0);
		
		//Property CxGridProperty:
		//	'prop' path=NestedField 'style' style=PropertyStyle;
		@Override public ParserRule getRule() { return rule; }
		
		//'prop' path=NestedField 'style' style=PropertyStyle
		public Group getGroup() { return cGroup; }
		
		//'prop'
		public Keyword getPropKeyword_0() { return cPropKeyword_0; }
		
		//path=NestedField
		public Assignment getPathAssignment_1() { return cPathAssignment_1; }
		
		//NestedField
		public RuleCall getPathNestedFieldParserRuleCall_1_0() { return cPathNestedFieldParserRuleCall_1_0; }
		
		//'style'
		public Keyword getStyleKeyword_2() { return cStyleKeyword_2; }
		
		//style=PropertyStyle
		public Assignment getStyleAssignment_3() { return cStyleAssignment_3; }
		
		//PropertyStyle
		public RuleCall getStylePropertyStyleParserRuleCall_3_0() { return cStylePropertyStyleParserRuleCall_3_0; }
	}
	public class NestedFieldElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.NestedField");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridNestedFieldAction_0 = (Action)cGroup.eContents().get(0);
		private final Assignment cFieldAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final CrossReference cFieldJvmOperationCrossReference_1_0 = (CrossReference)cFieldAssignment_1.eContents().get(0);
		private final RuleCall cFieldJvmOperationIDTerminalRuleCall_1_0_1 = (RuleCall)cFieldJvmOperationCrossReference_1_0.eContents().get(1);
		private final Assignment cPathAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cPathNestedPathParserRuleCall_2_0 = (RuleCall)cPathAssignment_2.eContents().get(0);
		
		//NestedField CxGridNestedField:
		//	{CxGridNestedField} field=[types::JvmOperation] path=NestedPath?;
		@Override public ParserRule getRule() { return rule; }
		
		//{CxGridNestedField} field=[types::JvmOperation] path=NestedPath?
		public Group getGroup() { return cGroup; }
		
		//{CxGridNestedField}
		public Action getCxGridNestedFieldAction_0() { return cCxGridNestedFieldAction_0; }
		
		//field=[types::JvmOperation]
		public Assignment getFieldAssignment_1() { return cFieldAssignment_1; }
		
		//[types::JvmOperation]
		public CrossReference getFieldJvmOperationCrossReference_1_0() { return cFieldJvmOperationCrossReference_1_0; }
		
		//ID
		public RuleCall getFieldJvmOperationIDTerminalRuleCall_1_0_1() { return cFieldJvmOperationIDTerminalRuleCall_1_0_1; }
		
		//path=NestedPath?
		public Assignment getPathAssignment_2() { return cPathAssignment_2; }
		
		//NestedPath
		public RuleCall getPathNestedPathParserRuleCall_2_0() { return cPathNestedPathParserRuleCall_2_0; }
	}
	public class NestedPathElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.NestedPath");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridNestedPathAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cFullStopKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cFieldAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final CrossReference cFieldJvmOperationCrossReference_2_0 = (CrossReference)cFieldAssignment_2.eContents().get(0);
		private final RuleCall cFieldJvmOperationIDTerminalRuleCall_2_0_1 = (RuleCall)cFieldJvmOperationCrossReference_2_0.eContents().get(1);
		private final Assignment cPathAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cPathNestedPathParserRuleCall_3_0 = (RuleCall)cPathAssignment_3.eContents().get(0);
		
		//NestedPath CxGridNestedPath:
		//	{CxGridNestedPath}
		//	'.' field=[types::JvmOperation] path=NestedPath?;
		@Override public ParserRule getRule() { return rule; }
		
		//{CxGridNestedPath} '.' field=[types::JvmOperation] path=NestedPath?
		public Group getGroup() { return cGroup; }
		
		//{CxGridNestedPath}
		public Action getCxGridNestedPathAction_0() { return cCxGridNestedPathAction_0; }
		
		//'.'
		public Keyword getFullStopKeyword_1() { return cFullStopKeyword_1; }
		
		//field=[types::JvmOperation]
		public Assignment getFieldAssignment_2() { return cFieldAssignment_2; }
		
		//[types::JvmOperation]
		public CrossReference getFieldJvmOperationCrossReference_2_0() { return cFieldJvmOperationCrossReference_2_0; }
		
		//ID
		public RuleCall getFieldJvmOperationIDTerminalRuleCall_2_0_1() { return cFieldJvmOperationIDTerminalRuleCall_2_0_1; }
		
		//path=NestedPath?
		public Assignment getPathAssignment_3() { return cPathAssignment_3; }
		
		//NestedPath
		public RuleCall getPathNestedPathParserRuleCall_3_0() { return cPathNestedPathParserRuleCall_3_0; }
	}
	public class PropertyStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyStyle");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final RuleCall cPropertyButtonStyleParserRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0);
		private final RuleCall cPropertyHtmlStyleParserRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1);
		private final RuleCall cPropertyProgressbarStyleParserRuleCall_2 = (RuleCall)cAlternatives.eContents().get(2);
		private final RuleCall cPropertyTextStyleParserRuleCall_3 = (RuleCall)cAlternatives.eContents().get(3);
		private final RuleCall cPropertyBooleanStyleParserRuleCall_4 = (RuleCall)cAlternatives.eContents().get(4);
		private final RuleCall cPropertyDateStyleParserRuleCall_5 = (RuleCall)cAlternatives.eContents().get(5);
		private final RuleCall cPropertyNumberStyleParserRuleCall_6 = (RuleCall)cAlternatives.eContents().get(6);
		private final RuleCall cPropertyImageStyleParserRuleCall_7 = (RuleCall)cAlternatives.eContents().get(7);
		private final RuleCall cPropertyQuantityStyleParserRuleCall_8 = (RuleCall)cAlternatives.eContents().get(8);
		private final RuleCall cPropertyPriceStyleParserRuleCall_9 = (RuleCall)cAlternatives.eContents().get(9);
		private final RuleCall cGridPropIndicatorStyleParserRuleCall_10 = (RuleCall)cAlternatives.eContents().get(10);
		
		//PropertyStyle style::CxGridPropStyle:
		//	PropertyButtonStyle | PropertyHtmlStyle | PropertyProgressbarStyle | PropertyTextStyle | PropertyBooleanStyle |
		//	PropertyDateStyle | PropertyNumberStyle | PropertyImageStyle | PropertyQuantityStyle | PropertyPriceStyle |
		//	GridPropIndicatorStyle;
		@Override public ParserRule getRule() { return rule; }
		
		//PropertyButtonStyle | PropertyHtmlStyle | PropertyProgressbarStyle | PropertyTextStyle | PropertyBooleanStyle |
		//PropertyDateStyle | PropertyNumberStyle | PropertyImageStyle | PropertyQuantityStyle | PropertyPriceStyle |
		//GridPropIndicatorStyle
		public Alternatives getAlternatives() { return cAlternatives; }
		
		//PropertyButtonStyle
		public RuleCall getPropertyButtonStyleParserRuleCall_0() { return cPropertyButtonStyleParserRuleCall_0; }
		
		//PropertyHtmlStyle
		public RuleCall getPropertyHtmlStyleParserRuleCall_1() { return cPropertyHtmlStyleParserRuleCall_1; }
		
		//PropertyProgressbarStyle
		public RuleCall getPropertyProgressbarStyleParserRuleCall_2() { return cPropertyProgressbarStyleParserRuleCall_2; }
		
		//PropertyTextStyle
		public RuleCall getPropertyTextStyleParserRuleCall_3() { return cPropertyTextStyleParserRuleCall_3; }
		
		//PropertyBooleanStyle
		public RuleCall getPropertyBooleanStyleParserRuleCall_4() { return cPropertyBooleanStyleParserRuleCall_4; }
		
		//PropertyDateStyle
		public RuleCall getPropertyDateStyleParserRuleCall_5() { return cPropertyDateStyleParserRuleCall_5; }
		
		//PropertyNumberStyle
		public RuleCall getPropertyNumberStyleParserRuleCall_6() { return cPropertyNumberStyleParserRuleCall_6; }
		
		//PropertyImageStyle
		public RuleCall getPropertyImageStyleParserRuleCall_7() { return cPropertyImageStyleParserRuleCall_7; }
		
		//PropertyQuantityStyle
		public RuleCall getPropertyQuantityStyleParserRuleCall_8() { return cPropertyQuantityStyleParserRuleCall_8; }
		
		//PropertyPriceStyle
		public RuleCall getPropertyPriceStyleParserRuleCall_9() { return cPropertyPriceStyleParserRuleCall_9; }
		
		//GridPropIndicatorStyle
		public RuleCall getGridPropIndicatorStyleParserRuleCall_10() { return cGridPropIndicatorStyleParserRuleCall_10; }
	}
	public class PropertyButtonStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyButtonStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropButtonStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cButtonStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Keyword cEventTopicKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cEventTopicAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cEventTopicSTRINGTerminalRuleCall_3_0 = (RuleCall)cEventTopicAssignment_3.eContents().get(0);
		
		//PropertyButtonStyle style::CxGridPropButtonStyle:
		//	{style::CxGridPropButtonStyle}
		//	'buttonStyle' 'eventTopic' eventTopic=STRING;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropButtonStyle} 'buttonStyle' 'eventTopic' eventTopic=STRING
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropButtonStyle}
		public Action getCxGridPropButtonStyleAction_0() { return cCxGridPropButtonStyleAction_0; }
		
		//'buttonStyle'
		public Keyword getButtonStyleKeyword_1() { return cButtonStyleKeyword_1; }
		
		//'eventTopic'
		public Keyword getEventTopicKeyword_2() { return cEventTopicKeyword_2; }
		
		//eventTopic=STRING
		public Assignment getEventTopicAssignment_3() { return cEventTopicAssignment_3; }
		
		//STRING
		public RuleCall getEventTopicSTRINGTerminalRuleCall_3_0() { return cEventTopicSTRINGTerminalRuleCall_3_0; }
	}
	public class PropertyHtmlStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyHtmlStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropHtmlStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cHtmlStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		
		//PropertyHtmlStyle style::CxGridPropHtmlStyle:
		//	{style::CxGridPropHtmlStyle}
		//	'htmlStyle';
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropHtmlStyle} 'htmlStyle'
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropHtmlStyle}
		public Action getCxGridPropHtmlStyleAction_0() { return cCxGridPropHtmlStyleAction_0; }
		
		//'htmlStyle'
		public Keyword getHtmlStyleKeyword_1() { return cHtmlStyleKeyword_1; }
	}
	public class PropertyBooleanStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyBooleanStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropBooleanStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cBoolStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		
		//PropertyBooleanStyle style::CxGridPropBooleanStyle:
		//	{style::CxGridPropBooleanStyle}
		//	'boolStyle';
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropBooleanStyle} 'boolStyle'
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropBooleanStyle}
		public Action getCxGridPropBooleanStyleAction_0() { return cCxGridPropBooleanStyleAction_0; }
		
		//'boolStyle'
		public Keyword getBoolStyleKeyword_1() { return cBoolStyleKeyword_1; }
	}
	public class PropertyDateStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyDateStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropDateStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cDateStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Keyword cFormatKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cDateFormatAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cDateFormatSTRINGTerminalRuleCall_3_0 = (RuleCall)cDateFormatAssignment_3.eContents().get(0);
		
		//PropertyDateStyle style::CxGridPropDateStyle:
		//	{style::CxGridPropDateStyle}
		//	'dateStyle' 'format' dateFormat=STRING;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropDateStyle} 'dateStyle' 'format' dateFormat=STRING
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropDateStyle}
		public Action getCxGridPropDateStyleAction_0() { return cCxGridPropDateStyleAction_0; }
		
		//'dateStyle'
		public Keyword getDateStyleKeyword_1() { return cDateStyleKeyword_1; }
		
		//'format'
		public Keyword getFormatKeyword_2() { return cFormatKeyword_2; }
		
		//dateFormat=STRING
		public Assignment getDateFormatAssignment_3() { return cDateFormatAssignment_3; }
		
		//STRING
		public RuleCall getDateFormatSTRINGTerminalRuleCall_3_0() { return cDateFormatSTRINGTerminalRuleCall_3_0; }
	}
	public class PropertyNumberStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyNumberStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropNumberStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cNumberStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Keyword cFormatKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cNumberFormatAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cNumberFormatSTRINGTerminalRuleCall_3_0 = (RuleCall)cNumberFormatAssignment_3.eContents().get(0);
		
		//PropertyNumberStyle style::CxGridPropNumberStyle:
		//	{style::CxGridPropNumberStyle}
		//	'numberStyle' 'format' numberFormat=STRING;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropNumberStyle} 'numberStyle' 'format' numberFormat=STRING
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropNumberStyle}
		public Action getCxGridPropNumberStyleAction_0() { return cCxGridPropNumberStyleAction_0; }
		
		//'numberStyle'
		public Keyword getNumberStyleKeyword_1() { return cNumberStyleKeyword_1; }
		
		//'format'
		public Keyword getFormatKeyword_2() { return cFormatKeyword_2; }
		
		//numberFormat=STRING
		public Assignment getNumberFormatAssignment_3() { return cNumberFormatAssignment_3; }
		
		//STRING
		public RuleCall getNumberFormatSTRINGTerminalRuleCall_3_0() { return cNumberFormatSTRINGTerminalRuleCall_3_0; }
	}
	public class PropertyProgressbarStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyProgressbarStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropProgressbarStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cProgressbarStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Keyword cMaxKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cMaxValueAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cMaxValueLDoubleParserRuleCall_3_0 = (RuleCall)cMaxValueAssignment_3.eContents().get(0);
		
		//PropertyProgressbarStyle style::CxGridPropProgressbarStyle:
		//	{style::CxGridPropProgressbarStyle}
		//	'progressbarStyle' 'max' maxValue=LDouble;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropProgressbarStyle} 'progressbarStyle' 'max' maxValue=LDouble
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropProgressbarStyle}
		public Action getCxGridPropProgressbarStyleAction_0() { return cCxGridPropProgressbarStyleAction_0; }
		
		//'progressbarStyle'
		public Keyword getProgressbarStyleKeyword_1() { return cProgressbarStyleKeyword_1; }
		
		//'max'
		public Keyword getMaxKeyword_2() { return cMaxKeyword_2; }
		
		//maxValue=LDouble
		public Assignment getMaxValueAssignment_3() { return cMaxValueAssignment_3; }
		
		//LDouble
		public RuleCall getMaxValueLDoubleParserRuleCall_3_0() { return cMaxValueLDoubleParserRuleCall_3_0; }
	}
	public class GridPropIndicatorStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.GridPropIndicatorStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropIndicatorStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cIndicatorStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Keyword cGreenFromKeyword_2 = (Keyword)cGroup.eContents().get(2);
		private final Assignment cGreenStartsAssignment_3 = (Assignment)cGroup.eContents().get(3);
		private final RuleCall cGreenStartsLDoubleParserRuleCall_3_0 = (RuleCall)cGreenStartsAssignment_3.eContents().get(0);
		private final Keyword cRedUntilKeyword_4 = (Keyword)cGroup.eContents().get(4);
		private final Assignment cRedEndsAssignment_5 = (Assignment)cGroup.eContents().get(5);
		private final RuleCall cRedEndsLDoubleParserRuleCall_5_0 = (RuleCall)cRedEndsAssignment_5.eContents().get(0);
		
		//GridPropIndicatorStyle style::CxGridPropIndicatorStyle:
		//	{style::CxGridPropIndicatorStyle}
		//	'indicatorStyle' 'greenFrom' greenStarts=LDouble 'redUntil' redEnds=LDouble;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropIndicatorStyle} 'indicatorStyle' 'greenFrom' greenStarts=LDouble 'redUntil' redEnds=LDouble
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropIndicatorStyle}
		public Action getCxGridPropIndicatorStyleAction_0() { return cCxGridPropIndicatorStyleAction_0; }
		
		//'indicatorStyle'
		public Keyword getIndicatorStyleKeyword_1() { return cIndicatorStyleKeyword_1; }
		
		//'greenFrom'
		public Keyword getGreenFromKeyword_2() { return cGreenFromKeyword_2; }
		
		//greenStarts=LDouble
		public Assignment getGreenStartsAssignment_3() { return cGreenStartsAssignment_3; }
		
		//LDouble
		public RuleCall getGreenStartsLDoubleParserRuleCall_3_0() { return cGreenStartsLDoubleParserRuleCall_3_0; }
		
		//'redUntil'
		public Keyword getRedUntilKeyword_4() { return cRedUntilKeyword_4; }
		
		//redEnds=LDouble
		public Assignment getRedEndsAssignment_5() { return cRedEndsAssignment_5; }
		
		//LDouble
		public RuleCall getRedEndsLDoubleParserRuleCall_5_0() { return cRedEndsLDoubleParserRuleCall_5_0; }
	}
	public class PropertyQuantityStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyQuantityStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropQuantityStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cQuantityStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cHtmlPatternAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cHtmlPatternSTRINGTerminalRuleCall_2_0 = (RuleCall)cHtmlPatternAssignment_2.eContents().get(0);
		private final Keyword cValueKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Keyword cEqualsSignKeyword_4 = (Keyword)cGroup.eContents().get(4);
		private final Assignment cValuePropertyPathAssignment_5 = (Assignment)cGroup.eContents().get(5);
		private final RuleCall cValuePropertyPathNestedFieldParserRuleCall_5_0 = (RuleCall)cValuePropertyPathAssignment_5.eContents().get(0);
		private final Group cGroup_6 = (Group)cGroup.eContents().get(6);
		private final Keyword cLeftParenthesisKeyword_6_0 = (Keyword)cGroup_6.eContents().get(0);
		private final Keyword cFormatKeyword_6_1 = (Keyword)cGroup_6.eContents().get(1);
		private final Assignment cValueNumberFormatAssignment_6_2 = (Assignment)cGroup_6.eContents().get(2);
		private final RuleCall cValueNumberFormatSTRINGTerminalRuleCall_6_2_0 = (RuleCall)cValueNumberFormatAssignment_6_2.eContents().get(0);
		private final Keyword cRightParenthesisKeyword_6_3 = (Keyword)cGroup_6.eContents().get(3);
		private final Keyword cUomKeyword_7 = (Keyword)cGroup.eContents().get(7);
		private final Keyword cEqualsSignKeyword_8 = (Keyword)cGroup.eContents().get(8);
		private final Assignment cUomPropertyPathAssignment_9 = (Assignment)cGroup.eContents().get(9);
		private final RuleCall cUomPropertyPathNestedFieldParserRuleCall_9_0 = (RuleCall)cUomPropertyPathAssignment_9.eContents().get(0);
		
		//PropertyQuantityStyle style::CxGridPropQuantityStyle:
		//	{style::CxGridPropQuantityStyle}
		//	'quantityStyle' htmlPattern=STRING? 'value' '=' valuePropertyPath=NestedField ('(' 'format' valueNumberFormat=STRING
		//	')')? 'uom' '='
		//	uomPropertyPath=NestedField;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropQuantityStyle} 'quantityStyle' htmlPattern=STRING? 'value' '=' valuePropertyPath=NestedField ('('
		//'format' valueNumberFormat=STRING ')')? 'uom' '=' uomPropertyPath=NestedField
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropQuantityStyle}
		public Action getCxGridPropQuantityStyleAction_0() { return cCxGridPropQuantityStyleAction_0; }
		
		//'quantityStyle'
		public Keyword getQuantityStyleKeyword_1() { return cQuantityStyleKeyword_1; }
		
		//htmlPattern=STRING?
		public Assignment getHtmlPatternAssignment_2() { return cHtmlPatternAssignment_2; }
		
		//STRING
		public RuleCall getHtmlPatternSTRINGTerminalRuleCall_2_0() { return cHtmlPatternSTRINGTerminalRuleCall_2_0; }
		
		//'value'
		public Keyword getValueKeyword_3() { return cValueKeyword_3; }
		
		//'='
		public Keyword getEqualsSignKeyword_4() { return cEqualsSignKeyword_4; }
		
		//valuePropertyPath=NestedField
		public Assignment getValuePropertyPathAssignment_5() { return cValuePropertyPathAssignment_5; }
		
		//NestedField
		public RuleCall getValuePropertyPathNestedFieldParserRuleCall_5_0() { return cValuePropertyPathNestedFieldParserRuleCall_5_0; }
		
		//('(' 'format' valueNumberFormat=STRING ')')?
		public Group getGroup_6() { return cGroup_6; }
		
		//'('
		public Keyword getLeftParenthesisKeyword_6_0() { return cLeftParenthesisKeyword_6_0; }
		
		//'format'
		public Keyword getFormatKeyword_6_1() { return cFormatKeyword_6_1; }
		
		//valueNumberFormat=STRING
		public Assignment getValueNumberFormatAssignment_6_2() { return cValueNumberFormatAssignment_6_2; }
		
		//STRING
		public RuleCall getValueNumberFormatSTRINGTerminalRuleCall_6_2_0() { return cValueNumberFormatSTRINGTerminalRuleCall_6_2_0; }
		
		//')'
		public Keyword getRightParenthesisKeyword_6_3() { return cRightParenthesisKeyword_6_3; }
		
		//'uom'
		public Keyword getUomKeyword_7() { return cUomKeyword_7; }
		
		//'='
		public Keyword getEqualsSignKeyword_8() { return cEqualsSignKeyword_8; }
		
		//uomPropertyPath=NestedField
		public Assignment getUomPropertyPathAssignment_9() { return cUomPropertyPathAssignment_9; }
		
		//NestedField
		public RuleCall getUomPropertyPathNestedFieldParserRuleCall_9_0() { return cUomPropertyPathNestedFieldParserRuleCall_9_0; }
	}
	public class PropertyPriceStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyPriceStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropPriceStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cPriceStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Assignment cHtmlPatternAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cHtmlPatternSTRINGTerminalRuleCall_2_0 = (RuleCall)cHtmlPatternAssignment_2.eContents().get(0);
		private final Keyword cValueKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Keyword cEqualsSignKeyword_4 = (Keyword)cGroup.eContents().get(4);
		private final Assignment cValuePropertyPathAssignment_5 = (Assignment)cGroup.eContents().get(5);
		private final RuleCall cValuePropertyPathNestedFieldParserRuleCall_5_0 = (RuleCall)cValuePropertyPathAssignment_5.eContents().get(0);
		private final Group cGroup_6 = (Group)cGroup.eContents().get(6);
		private final Keyword cLeftParenthesisKeyword_6_0 = (Keyword)cGroup_6.eContents().get(0);
		private final Keyword cFormatKeyword_6_1 = (Keyword)cGroup_6.eContents().get(1);
		private final Assignment cValueNumberFormatAssignment_6_2 = (Assignment)cGroup_6.eContents().get(2);
		private final RuleCall cValueNumberFormatSTRINGTerminalRuleCall_6_2_0 = (RuleCall)cValueNumberFormatAssignment_6_2.eContents().get(0);
		private final Keyword cRightParenthesisKeyword_6_3 = (Keyword)cGroup_6.eContents().get(3);
		private final Keyword cCurrencyKeyword_7 = (Keyword)cGroup.eContents().get(7);
		private final Keyword cEqualsSignKeyword_8 = (Keyword)cGroup.eContents().get(8);
		private final Assignment cCurrencyPropertyPathAssignment_9 = (Assignment)cGroup.eContents().get(9);
		private final RuleCall cCurrencyPropertyPathNestedFieldParserRuleCall_9_0 = (RuleCall)cCurrencyPropertyPathAssignment_9.eContents().get(0);
		
		//PropertyPriceStyle style::CxGridPropPriceStyle:
		//	{style::CxGridPropPriceStyle}
		//	'priceStyle' htmlPattern=STRING? 'value' '=' valuePropertyPath=NestedField ('(' 'format' valueNumberFormat=STRING
		//	')')? 'currency' '='
		//	currencyPropertyPath=NestedField;
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropPriceStyle} 'priceStyle' htmlPattern=STRING? 'value' '=' valuePropertyPath=NestedField ('(' 'format'
		//valueNumberFormat=STRING ')')? 'currency' '=' currencyPropertyPath=NestedField
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropPriceStyle}
		public Action getCxGridPropPriceStyleAction_0() { return cCxGridPropPriceStyleAction_0; }
		
		//'priceStyle'
		public Keyword getPriceStyleKeyword_1() { return cPriceStyleKeyword_1; }
		
		//htmlPattern=STRING?
		public Assignment getHtmlPatternAssignment_2() { return cHtmlPatternAssignment_2; }
		
		//STRING
		public RuleCall getHtmlPatternSTRINGTerminalRuleCall_2_0() { return cHtmlPatternSTRINGTerminalRuleCall_2_0; }
		
		//'value'
		public Keyword getValueKeyword_3() { return cValueKeyword_3; }
		
		//'='
		public Keyword getEqualsSignKeyword_4() { return cEqualsSignKeyword_4; }
		
		//valuePropertyPath=NestedField
		public Assignment getValuePropertyPathAssignment_5() { return cValuePropertyPathAssignment_5; }
		
		//NestedField
		public RuleCall getValuePropertyPathNestedFieldParserRuleCall_5_0() { return cValuePropertyPathNestedFieldParserRuleCall_5_0; }
		
		//('(' 'format' valueNumberFormat=STRING ')')?
		public Group getGroup_6() { return cGroup_6; }
		
		//'('
		public Keyword getLeftParenthesisKeyword_6_0() { return cLeftParenthesisKeyword_6_0; }
		
		//'format'
		public Keyword getFormatKeyword_6_1() { return cFormatKeyword_6_1; }
		
		//valueNumberFormat=STRING
		public Assignment getValueNumberFormatAssignment_6_2() { return cValueNumberFormatAssignment_6_2; }
		
		//STRING
		public RuleCall getValueNumberFormatSTRINGTerminalRuleCall_6_2_0() { return cValueNumberFormatSTRINGTerminalRuleCall_6_2_0; }
		
		//')'
		public Keyword getRightParenthesisKeyword_6_3() { return cRightParenthesisKeyword_6_3; }
		
		//'currency'
		public Keyword getCurrencyKeyword_7() { return cCurrencyKeyword_7; }
		
		//'='
		public Keyword getEqualsSignKeyword_8() { return cEqualsSignKeyword_8; }
		
		//currencyPropertyPath=NestedField
		public Assignment getCurrencyPropertyPathAssignment_9() { return cCurrencyPropertyPathAssignment_9; }
		
		//NestedField
		public RuleCall getCurrencyPropertyPathNestedFieldParserRuleCall_9_0() { return cCurrencyPropertyPathNestedFieldParserRuleCall_9_0; }
	}
	public class PropertyTextStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyTextStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropTextStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cTextStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		
		//PropertyTextStyle style::CxGridPropTextStyle:
		//	{style::CxGridPropTextStyle}
		//	'textStyle';
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropTextStyle} 'textStyle'
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropTextStyle}
		public Action getCxGridPropTextStyleAction_0() { return cCxGridPropTextStyleAction_0; }
		
		//'textStyle'
		public Keyword getTextStyleKeyword_1() { return cTextStyleKeyword_1; }
	}
	public class PropertyImageStyleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.PropertyImageStyle");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Action cCxGridPropImageStyleAction_0 = (Action)cGroup.eContents().get(0);
		private final Keyword cImageStyleKeyword_1 = (Keyword)cGroup.eContents().get(1);
		private final Group cGroup_2 = (Group)cGroup.eContents().get(2);
		private final Keyword cEventTopicKeyword_2_0 = (Keyword)cGroup_2.eContents().get(0);
		private final Assignment cEventTopicAssignment_2_1 = (Assignment)cGroup_2.eContents().get(1);
		private final RuleCall cEventTopicSTRINGTerminalRuleCall_2_1_0 = (RuleCall)cEventTopicAssignment_2_1.eContents().get(0);
		private final Keyword cLeftCurlyBracketKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Assignment cConfigsAssignment_4 = (Assignment)cGroup.eContents().get(4);
		private final RuleCall cConfigsStyleConfigParserRuleCall_4_0 = (RuleCall)cConfigsAssignment_4.eContents().get(0);
		private final Keyword cRightCurlyBracketKeyword_5 = (Keyword)cGroup.eContents().get(5);
		
		//PropertyImageStyle style::CxGridPropImageStyle:
		//	{style::CxGridPropImageStyle}
		//	'imageStyle' ('eventTopic' eventTopic=STRING)? '{'
		//	configs+=StyleConfig*
		//	'}';
		@Override public ParserRule getRule() { return rule; }
		
		//{style::CxGridPropImageStyle} 'imageStyle' ('eventTopic' eventTopic=STRING)? '{' configs+=StyleConfig* '}'
		public Group getGroup() { return cGroup; }
		
		//{style::CxGridPropImageStyle}
		public Action getCxGridPropImageStyleAction_0() { return cCxGridPropImageStyleAction_0; }
		
		//'imageStyle'
		public Keyword getImageStyleKeyword_1() { return cImageStyleKeyword_1; }
		
		//('eventTopic' eventTopic=STRING)?
		public Group getGroup_2() { return cGroup_2; }
		
		//'eventTopic'
		public Keyword getEventTopicKeyword_2_0() { return cEventTopicKeyword_2_0; }
		
		//eventTopic=STRING
		public Assignment getEventTopicAssignment_2_1() { return cEventTopicAssignment_2_1; }
		
		//STRING
		public RuleCall getEventTopicSTRINGTerminalRuleCall_2_1_0() { return cEventTopicSTRINGTerminalRuleCall_2_1_0; }
		
		//'{'
		public Keyword getLeftCurlyBracketKeyword_3() { return cLeftCurlyBracketKeyword_3; }
		
		//configs+=StyleConfig*
		public Assignment getConfigsAssignment_4() { return cConfigsAssignment_4; }
		
		//StyleConfig
		public RuleCall getConfigsStyleConfigParserRuleCall_4_0() { return cConfigsStyleConfigParserRuleCall_4_0; }
		
		//'}'
		public Keyword getRightCurlyBracketKeyword_5() { return cRightCurlyBracketKeyword_5; }
	}
	public class QualifiedNameElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.QualifiedName");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final RuleCall cValidIDParserRuleCall_0 = (RuleCall)cGroup.eContents().get(0);
		private final Group cGroup_1 = (Group)cGroup.eContents().get(1);
		private final Keyword cFullStopKeyword_1_0 = (Keyword)cGroup_1.eContents().get(0);
		private final RuleCall cValidIDParserRuleCall_1_1 = (RuleCall)cGroup_1.eContents().get(1);
		
		//@ Override QualifiedName:
		//	ValidID (=> '.' ValidID)*;
		@Override public ParserRule getRule() { return rule; }
		
		//ValidID (=> '.' ValidID)*
		public Group getGroup() { return cGroup; }
		
		//ValidID
		public RuleCall getValidIDParserRuleCall_0() { return cValidIDParserRuleCall_0; }
		
		//(=> '.' ValidID)*
		public Group getGroup_1() { return cGroup_1; }
		
		//=> '.'
		public Keyword getFullStopKeyword_1_0() { return cFullStopKeyword_1_0; }
		
		//ValidID
		public RuleCall getValidIDParserRuleCall_1_1() { return cValidIDParserRuleCall_1_1; }
	}
	public class ValidIDElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.ValidID");
		private final RuleCall cIDTerminalRuleCall = (RuleCall)rule.eContents().get(1);
		
		//@ Override ValidID:
		//	ID;
		@Override public ParserRule getRule() { return rule; }
		
		//ID
		public RuleCall getIDTerminalRuleCall() { return cIDTerminalRuleCall; }
	}
	public class StyleConfigElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.StyleConfig");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final RuleCall cNumericToResourceStyleConfigParserRuleCall_0 = (RuleCall)cAlternatives.eContents().get(0);
		private final RuleCall cStringToResourceStyleConfigParserRuleCall_1 = (RuleCall)cAlternatives.eContents().get(1);
		
		//StyleConfig style::CxGridStyleConfig:
		//	NumericToResourceStyleConfig | StringToResourceStyleConfig;
		@Override public ParserRule getRule() { return rule; }
		
		//NumericToResourceStyleConfig | StringToResourceStyleConfig
		public Alternatives getAlternatives() { return cAlternatives; }
		
		//NumericToResourceStyleConfig
		public RuleCall getNumericToResourceStyleConfigParserRuleCall_0() { return cNumericToResourceStyleConfigParserRuleCall_0; }
		
		//StringToResourceStyleConfig
		public RuleCall getStringToResourceStyleConfigParserRuleCall_1() { return cStringToResourceStyleConfigParserRuleCall_1; }
	}
	public class NumericToResourceStyleConfigElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.NumericToResourceStyleConfig");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cNumberKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cCompareAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cCompareStyleCompareEnumRuleCall_1_0 = (RuleCall)cCompareAssignment_1.eContents().get(0);
		private final Assignment cValueAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cValueLDoubleParserRuleCall_2_0 = (RuleCall)cValueAssignment_2.eContents().get(0);
		private final Keyword cThenKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Assignment cResourceThemePathAssignment_4 = (Assignment)cGroup.eContents().get(4);
		private final RuleCall cResourceThemePathTHEME_RESOURCETerminalRuleCall_4_0 = (RuleCall)cResourceThemePathAssignment_4.eContents().get(0);
		
		//NumericToResourceStyleConfig style::CxGridStyleConfigNumericToResource:
		//	'number' compare=StyleCompare value=LDouble 'then' resourceThemePath=THEME_RESOURCE;
		@Override public ParserRule getRule() { return rule; }
		
		//'number' compare=StyleCompare value=LDouble 'then' resourceThemePath=THEME_RESOURCE
		public Group getGroup() { return cGroup; }
		
		//'number'
		public Keyword getNumberKeyword_0() { return cNumberKeyword_0; }
		
		//compare=StyleCompare
		public Assignment getCompareAssignment_1() { return cCompareAssignment_1; }
		
		//StyleCompare
		public RuleCall getCompareStyleCompareEnumRuleCall_1_0() { return cCompareStyleCompareEnumRuleCall_1_0; }
		
		//value=LDouble
		public Assignment getValueAssignment_2() { return cValueAssignment_2; }
		
		//LDouble
		public RuleCall getValueLDoubleParserRuleCall_2_0() { return cValueLDoubleParserRuleCall_2_0; }
		
		//'then'
		public Keyword getThenKeyword_3() { return cThenKeyword_3; }
		
		//resourceThemePath=THEME_RESOURCE
		public Assignment getResourceThemePathAssignment_4() { return cResourceThemePathAssignment_4; }
		
		//THEME_RESOURCE
		public RuleCall getResourceThemePathTHEME_RESOURCETerminalRuleCall_4_0() { return cResourceThemePathTHEME_RESOURCETerminalRuleCall_4_0; }
	}
	public class StringToResourceStyleConfigElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.StringToResourceStyleConfig");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Keyword cStringKeyword_0 = (Keyword)cGroup.eContents().get(0);
		private final Assignment cCompareAssignment_1 = (Assignment)cGroup.eContents().get(1);
		private final RuleCall cCompareStyleCompareEnumRuleCall_1_0 = (RuleCall)cCompareAssignment_1.eContents().get(0);
		private final Assignment cValueAssignment_2 = (Assignment)cGroup.eContents().get(2);
		private final RuleCall cValueSTRINGTerminalRuleCall_2_0 = (RuleCall)cValueAssignment_2.eContents().get(0);
		private final Keyword cThenKeyword_3 = (Keyword)cGroup.eContents().get(3);
		private final Assignment cResourceThemePathAssignment_4 = (Assignment)cGroup.eContents().get(4);
		private final RuleCall cResourceThemePathTHEME_RESOURCETerminalRuleCall_4_0 = (RuleCall)cResourceThemePathAssignment_4.eContents().get(0);
		
		//StringToResourceStyleConfig style::CxGridStyleConfigStringToResource:
		//	'string' compare=StyleCompare value=STRING 'then' resourceThemePath=THEME_RESOURCE;
		@Override public ParserRule getRule() { return rule; }
		
		//'string' compare=StyleCompare value=STRING 'then' resourceThemePath=THEME_RESOURCE
		public Group getGroup() { return cGroup; }
		
		//'string'
		public Keyword getStringKeyword_0() { return cStringKeyword_0; }
		
		//compare=StyleCompare
		public Assignment getCompareAssignment_1() { return cCompareAssignment_1; }
		
		//StyleCompare
		public RuleCall getCompareStyleCompareEnumRuleCall_1_0() { return cCompareStyleCompareEnumRuleCall_1_0; }
		
		//value=STRING
		public Assignment getValueAssignment_2() { return cValueAssignment_2; }
		
		//STRING
		public RuleCall getValueSTRINGTerminalRuleCall_2_0() { return cValueSTRINGTerminalRuleCall_2_0; }
		
		//'then'
		public Keyword getThenKeyword_3() { return cThenKeyword_3; }
		
		//resourceThemePath=THEME_RESOURCE
		public Assignment getResourceThemePathAssignment_4() { return cResourceThemePathAssignment_4; }
		
		//THEME_RESOURCE
		public RuleCall getResourceThemePathTHEME_RESOURCETerminalRuleCall_4_0() { return cResourceThemePathTHEME_RESOURCETerminalRuleCall_4_0; }
	}
	public class LIntElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.LInt");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final Alternatives cAlternatives_0 = (Alternatives)cGroup.eContents().get(0);
		private final Keyword cPlusSignKeyword_0_0 = (Keyword)cAlternatives_0.eContents().get(0);
		private final Keyword cHyphenMinusKeyword_0_1 = (Keyword)cAlternatives_0.eContents().get(1);
		private final RuleCall cINTTerminalRuleCall_1 = (RuleCall)cGroup.eContents().get(1);
		
		//LInt ecore::EInt:
		//	('+' | '-')? INT;
		@Override public ParserRule getRule() { return rule; }
		
		//('+' | '-')? INT
		public Group getGroup() { return cGroup; }
		
		//('+' | '-')?
		public Alternatives getAlternatives_0() { return cAlternatives_0; }
		
		//'+'
		public Keyword getPlusSignKeyword_0_0() { return cPlusSignKeyword_0_0; }
		
		//'-'
		public Keyword getHyphenMinusKeyword_0_1() { return cHyphenMinusKeyword_0_1; }
		
		//INT
		public RuleCall getINTTerminalRuleCall_1() { return cINTTerminalRuleCall_1; }
	}
	public class LDoubleElements extends AbstractParserRuleElementFinder {
		private final ParserRule rule = (ParserRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.LDouble");
		private final Group cGroup = (Group)rule.eContents().get(1);
		private final RuleCall cLIntParserRuleCall_0 = (RuleCall)cGroup.eContents().get(0);
		private final Group cGroup_1 = (Group)cGroup.eContents().get(1);
		private final Keyword cFullStopKeyword_1_0 = (Keyword)cGroup_1.eContents().get(0);
		private final RuleCall cINTTerminalRuleCall_1_1 = (RuleCall)cGroup_1.eContents().get(1);
		
		//LDouble ecore::EDouble:
		//	LInt ('.' INT)?;
		@Override public ParserRule getRule() { return rule; }
		
		//LInt ('.' INT)?
		public Group getGroup() { return cGroup; }
		
		//LInt
		public RuleCall getLIntParserRuleCall_0() { return cLIntParserRuleCall_0; }
		
		//('.' INT)?
		public Group getGroup_1() { return cGroup_1; }
		
		//'.'
		public Keyword getFullStopKeyword_1_0() { return cFullStopKeyword_1_0; }
		
		//INT
		public RuleCall getINTTerminalRuleCall_1_1() { return cINTTerminalRuleCall_1_1; }
	}
	
	public class StyleCompareElements extends AbstractEnumRuleElementFinder {
		private final EnumRule rule = (EnumRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.StyleCompare");
		private final Alternatives cAlternatives = (Alternatives)rule.eContents().get(1);
		private final EnumLiteralDeclaration cEqualEnumLiteralDeclaration_0 = (EnumLiteralDeclaration)cAlternatives.eContents().get(0);
		private final Keyword cEqualEqualKeyword_0_0 = (Keyword)cEqualEnumLiteralDeclaration_0.eContents().get(0);
		private final EnumLiteralDeclaration cGreaterEqualEnumLiteralDeclaration_1 = (EnumLiteralDeclaration)cAlternatives.eContents().get(1);
		private final Keyword cGreaterEqualGreaterEqualKeyword_1_0 = (Keyword)cGreaterEqualEnumLiteralDeclaration_1.eContents().get(0);
		private final EnumLiteralDeclaration cGreaterThanEnumLiteralDeclaration_2 = (EnumLiteralDeclaration)cAlternatives.eContents().get(2);
		private final Keyword cGreaterThanGreaterThanKeyword_2_0 = (Keyword)cGreaterThanEnumLiteralDeclaration_2.eContents().get(0);
		private final EnumLiteralDeclaration cLowerEqualEnumLiteralDeclaration_3 = (EnumLiteralDeclaration)cAlternatives.eContents().get(3);
		private final Keyword cLowerEqualLowerEqualKeyword_3_0 = (Keyword)cLowerEqualEnumLiteralDeclaration_3.eContents().get(0);
		private final EnumLiteralDeclaration cLowerThanEnumLiteralDeclaration_4 = (EnumLiteralDeclaration)cAlternatives.eContents().get(4);
		private final Keyword cLowerThanLowerThanKeyword_4_0 = (Keyword)cLowerThanEnumLiteralDeclaration_4.eContents().get(0);
		private final EnumLiteralDeclaration cNotEqualEnumLiteralDeclaration_5 = (EnumLiteralDeclaration)cAlternatives.eContents().get(5);
		private final Keyword cNotEqualNotEqualKeyword_5_0 = (Keyword)cNotEqualEnumLiteralDeclaration_5.eContents().get(0);
		
		//enum StyleCompare returns style::CxGridCompare:
		//	Equal="equal" | GreaterEqual="greater equal" | GreaterThan="greater than" | LowerEqual="lower equal" |
		//	LowerThan="lower than" | NotEqual="not equal";
		public EnumRule getRule() { return rule; }
		
		//Equal="equal" | GreaterEqual="greater equal" | GreaterThan="greater than" | LowerEqual="lower equal" |
		//LowerThan="lower than" | NotEqual="not equal"
		public Alternatives getAlternatives() { return cAlternatives; }
		
		//Equal="equal"
		public EnumLiteralDeclaration getEqualEnumLiteralDeclaration_0() { return cEqualEnumLiteralDeclaration_0; }
		
		//"equal"
		public Keyword getEqualEqualKeyword_0_0() { return cEqualEqualKeyword_0_0; }
		
		//GreaterEqual="greater equal"
		public EnumLiteralDeclaration getGreaterEqualEnumLiteralDeclaration_1() { return cGreaterEqualEnumLiteralDeclaration_1; }
		
		//"greater equal"
		public Keyword getGreaterEqualGreaterEqualKeyword_1_0() { return cGreaterEqualGreaterEqualKeyword_1_0; }
		
		//GreaterThan="greater than"
		public EnumLiteralDeclaration getGreaterThanEnumLiteralDeclaration_2() { return cGreaterThanEnumLiteralDeclaration_2; }
		
		//"greater than"
		public Keyword getGreaterThanGreaterThanKeyword_2_0() { return cGreaterThanGreaterThanKeyword_2_0; }
		
		//LowerEqual="lower equal"
		public EnumLiteralDeclaration getLowerEqualEnumLiteralDeclaration_3() { return cLowerEqualEnumLiteralDeclaration_3; }
		
		//"lower equal"
		public Keyword getLowerEqualLowerEqualKeyword_3_0() { return cLowerEqualLowerEqualKeyword_3_0; }
		
		//LowerThan="lower than"
		public EnumLiteralDeclaration getLowerThanEnumLiteralDeclaration_4() { return cLowerThanEnumLiteralDeclaration_4; }
		
		//"lower than"
		public Keyword getLowerThanLowerThanKeyword_4_0() { return cLowerThanLowerThanKeyword_4_0; }
		
		//NotEqual="not equal"
		public EnumLiteralDeclaration getNotEqualEnumLiteralDeclaration_5() { return cNotEqualEnumLiteralDeclaration_5; }
		
		//"not equal"
		public Keyword getNotEqualNotEqualKeyword_5_0() { return cNotEqualNotEqualKeyword_5_0; }
	}
	
	private final SourceElements pSource;
	private final InputElements pInput;
	private final EQFilterElements pEQFilter;
	private final PropertyElements pProperty;
	private final NestedFieldElements pNestedField;
	private final NestedPathElements pNestedPath;
	private final PropertyStyleElements pPropertyStyle;
	private final PropertyButtonStyleElements pPropertyButtonStyle;
	private final PropertyHtmlStyleElements pPropertyHtmlStyle;
	private final PropertyBooleanStyleElements pPropertyBooleanStyle;
	private final PropertyDateStyleElements pPropertyDateStyle;
	private final PropertyNumberStyleElements pPropertyNumberStyle;
	private final PropertyProgressbarStyleElements pPropertyProgressbarStyle;
	private final GridPropIndicatorStyleElements pGridPropIndicatorStyle;
	private final PropertyQuantityStyleElements pPropertyQuantityStyle;
	private final PropertyPriceStyleElements pPropertyPriceStyle;
	private final PropertyTextStyleElements pPropertyTextStyle;
	private final PropertyImageStyleElements pPropertyImageStyle;
	private final QualifiedNameElements pQualifiedName;
	private final ValidIDElements pValidID;
	private final StyleConfigElements pStyleConfig;
	private final NumericToResourceStyleConfigElements pNumericToResourceStyleConfig;
	private final StringToResourceStyleConfigElements pStringToResourceStyleConfig;
	private final StyleCompareElements eStyleCompare;
	private final TerminalRule tID;
	private final TerminalRule tINT;
	private final TerminalRule tTHEME_RESOURCE;
	private final LIntElements pLInt;
	private final LDoubleElements pLDouble;
	private final TerminalRule tEVENT_TOPIC;
	
	private final Grammar grammar;
	
	private final XtypeGrammarAccess gaXtype;

	@Inject
	public GridSourceGrammarAccess(GrammarProvider grammarProvider,
			XtypeGrammarAccess gaXtype) {
		this.grammar = internalFindGrammar(grammarProvider);
		this.gaXtype = gaXtype;
		this.pSource = new SourceElements();
		this.pInput = new InputElements();
		this.pEQFilter = new EQFilterElements();
		this.pProperty = new PropertyElements();
		this.pNestedField = new NestedFieldElements();
		this.pNestedPath = new NestedPathElements();
		this.pPropertyStyle = new PropertyStyleElements();
		this.pPropertyButtonStyle = new PropertyButtonStyleElements();
		this.pPropertyHtmlStyle = new PropertyHtmlStyleElements();
		this.pPropertyBooleanStyle = new PropertyBooleanStyleElements();
		this.pPropertyDateStyle = new PropertyDateStyleElements();
		this.pPropertyNumberStyle = new PropertyNumberStyleElements();
		this.pPropertyProgressbarStyle = new PropertyProgressbarStyleElements();
		this.pGridPropIndicatorStyle = new GridPropIndicatorStyleElements();
		this.pPropertyQuantityStyle = new PropertyQuantityStyleElements();
		this.pPropertyPriceStyle = new PropertyPriceStyleElements();
		this.pPropertyTextStyle = new PropertyTextStyleElements();
		this.pPropertyImageStyle = new PropertyImageStyleElements();
		this.pQualifiedName = new QualifiedNameElements();
		this.pValidID = new ValidIDElements();
		this.pStyleConfig = new StyleConfigElements();
		this.pNumericToResourceStyleConfig = new NumericToResourceStyleConfigElements();
		this.pStringToResourceStyleConfig = new StringToResourceStyleConfigElements();
		this.eStyleCompare = new StyleCompareElements();
		this.tID = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.ID");
		this.tINT = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.INT");
		this.tTHEME_RESOURCE = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.THEME_RESOURCE");
		this.pLInt = new LIntElements();
		this.pLDouble = new LDoubleElements();
		this.tEVENT_TOPIC = (TerminalRule) GrammarUtil.findRuleForName(getGrammar(), "org.eclipse.osbp.xtext.gridsource.GridSource.EVENT_TOPIC");
	}
	
	protected Grammar internalFindGrammar(GrammarProvider grammarProvider) {
		Grammar grammar = grammarProvider.getGrammar(this);
		while (grammar != null) {
			if ("org.eclipse.osbp.xtext.gridsource.GridSource".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 XtypeGrammarAccess getXtypeGrammarAccess() {
		return gaXtype;
	}

	
	//Source CxGridSource:
	//	'gridsource' id=QualifiedName 'for' rootType=JvmTypeReference '{'
	//	'inputs' '{'
	//	inputs+=Input*
	//	'}'
	//	properties+=Property*
	//	'}';
	public SourceElements getSourceAccess() {
		return pSource;
	}
	
	public ParserRule getSourceRule() {
		return getSourceAccess().getRule();
	}
	
	//Input CxGridSourceInput:
	//	'inputType' inputType=JvmTypeReference
	//	'filters' filters+=EQFilter ('&&' filters+=EQFilter)*;
	public InputElements getInputAccess() {
		return pInput;
	}
	
	public ParserRule getInputRule() {
		return getInputAccess().getRule();
	}
	
	//EQFilter CxGridSourceEQFilter:
	//	{CxGridSourceEQFilter}
	//	'root:' rootTypePropertyPath=NestedField '=' 'input:' inputTypePropertyPath=NestedField;
	public EQFilterElements getEQFilterAccess() {
		return pEQFilter;
	}
	
	public ParserRule getEQFilterRule() {
		return getEQFilterAccess().getRule();
	}
	
	//Property CxGridProperty:
	//	'prop' path=NestedField 'style' style=PropertyStyle;
	public PropertyElements getPropertyAccess() {
		return pProperty;
	}
	
	public ParserRule getPropertyRule() {
		return getPropertyAccess().getRule();
	}
	
	//NestedField CxGridNestedField:
	//	{CxGridNestedField} field=[types::JvmOperation] path=NestedPath?;
	public NestedFieldElements getNestedFieldAccess() {
		return pNestedField;
	}
	
	public ParserRule getNestedFieldRule() {
		return getNestedFieldAccess().getRule();
	}
	
	//NestedPath CxGridNestedPath:
	//	{CxGridNestedPath}
	//	'.' field=[types::JvmOperation] path=NestedPath?;
	public NestedPathElements getNestedPathAccess() {
		return pNestedPath;
	}
	
	public ParserRule getNestedPathRule() {
		return getNestedPathAccess().getRule();
	}
	
	//PropertyStyle style::CxGridPropStyle:
	//	PropertyButtonStyle | PropertyHtmlStyle | PropertyProgressbarStyle | PropertyTextStyle | PropertyBooleanStyle |
	//	PropertyDateStyle | PropertyNumberStyle | PropertyImageStyle | PropertyQuantityStyle | PropertyPriceStyle |
	//	GridPropIndicatorStyle;
	public PropertyStyleElements getPropertyStyleAccess() {
		return pPropertyStyle;
	}
	
	public ParserRule getPropertyStyleRule() {
		return getPropertyStyleAccess().getRule();
	}
	
	//PropertyButtonStyle style::CxGridPropButtonStyle:
	//	{style::CxGridPropButtonStyle}
	//	'buttonStyle' 'eventTopic' eventTopic=STRING;
	public PropertyButtonStyleElements getPropertyButtonStyleAccess() {
		return pPropertyButtonStyle;
	}
	
	public ParserRule getPropertyButtonStyleRule() {
		return getPropertyButtonStyleAccess().getRule();
	}
	
	//PropertyHtmlStyle style::CxGridPropHtmlStyle:
	//	{style::CxGridPropHtmlStyle}
	//	'htmlStyle';
	public PropertyHtmlStyleElements getPropertyHtmlStyleAccess() {
		return pPropertyHtmlStyle;
	}
	
	public ParserRule getPropertyHtmlStyleRule() {
		return getPropertyHtmlStyleAccess().getRule();
	}
	
	//PropertyBooleanStyle style::CxGridPropBooleanStyle:
	//	{style::CxGridPropBooleanStyle}
	//	'boolStyle';
	public PropertyBooleanStyleElements getPropertyBooleanStyleAccess() {
		return pPropertyBooleanStyle;
	}
	
	public ParserRule getPropertyBooleanStyleRule() {
		return getPropertyBooleanStyleAccess().getRule();
	}
	
	//PropertyDateStyle style::CxGridPropDateStyle:
	//	{style::CxGridPropDateStyle}
	//	'dateStyle' 'format' dateFormat=STRING;
	public PropertyDateStyleElements getPropertyDateStyleAccess() {
		return pPropertyDateStyle;
	}
	
	public ParserRule getPropertyDateStyleRule() {
		return getPropertyDateStyleAccess().getRule();
	}
	
	//PropertyNumberStyle style::CxGridPropNumberStyle:
	//	{style::CxGridPropNumberStyle}
	//	'numberStyle' 'format' numberFormat=STRING;
	public PropertyNumberStyleElements getPropertyNumberStyleAccess() {
		return pPropertyNumberStyle;
	}
	
	public ParserRule getPropertyNumberStyleRule() {
		return getPropertyNumberStyleAccess().getRule();
	}
	
	//PropertyProgressbarStyle style::CxGridPropProgressbarStyle:
	//	{style::CxGridPropProgressbarStyle}
	//	'progressbarStyle' 'max' maxValue=LDouble;
	public PropertyProgressbarStyleElements getPropertyProgressbarStyleAccess() {
		return pPropertyProgressbarStyle;
	}
	
	public ParserRule getPropertyProgressbarStyleRule() {
		return getPropertyProgressbarStyleAccess().getRule();
	}
	
	//GridPropIndicatorStyle style::CxGridPropIndicatorStyle:
	//	{style::CxGridPropIndicatorStyle}
	//	'indicatorStyle' 'greenFrom' greenStarts=LDouble 'redUntil' redEnds=LDouble;
	public GridPropIndicatorStyleElements getGridPropIndicatorStyleAccess() {
		return pGridPropIndicatorStyle;
	}
	
	public ParserRule getGridPropIndicatorStyleRule() {
		return getGridPropIndicatorStyleAccess().getRule();
	}
	
	//PropertyQuantityStyle style::CxGridPropQuantityStyle:
	//	{style::CxGridPropQuantityStyle}
	//	'quantityStyle' htmlPattern=STRING? 'value' '=' valuePropertyPath=NestedField ('(' 'format' valueNumberFormat=STRING
	//	')')? 'uom' '='
	//	uomPropertyPath=NestedField;
	public PropertyQuantityStyleElements getPropertyQuantityStyleAccess() {
		return pPropertyQuantityStyle;
	}
	
	public ParserRule getPropertyQuantityStyleRule() {
		return getPropertyQuantityStyleAccess().getRule();
	}
	
	//PropertyPriceStyle style::CxGridPropPriceStyle:
	//	{style::CxGridPropPriceStyle}
	//	'priceStyle' htmlPattern=STRING? 'value' '=' valuePropertyPath=NestedField ('(' 'format' valueNumberFormat=STRING
	//	')')? 'currency' '='
	//	currencyPropertyPath=NestedField;
	public PropertyPriceStyleElements getPropertyPriceStyleAccess() {
		return pPropertyPriceStyle;
	}
	
	public ParserRule getPropertyPriceStyleRule() {
		return getPropertyPriceStyleAccess().getRule();
	}
	
	//PropertyTextStyle style::CxGridPropTextStyle:
	//	{style::CxGridPropTextStyle}
	//	'textStyle';
	public PropertyTextStyleElements getPropertyTextStyleAccess() {
		return pPropertyTextStyle;
	}
	
	public ParserRule getPropertyTextStyleRule() {
		return getPropertyTextStyleAccess().getRule();
	}
	
	//PropertyImageStyle style::CxGridPropImageStyle:
	//	{style::CxGridPropImageStyle}
	//	'imageStyle' ('eventTopic' eventTopic=STRING)? '{'
	//	configs+=StyleConfig*
	//	'}';
	public PropertyImageStyleElements getPropertyImageStyleAccess() {
		return pPropertyImageStyle;
	}
	
	public ParserRule getPropertyImageStyleRule() {
		return getPropertyImageStyleAccess().getRule();
	}
	
	//@ Override QualifiedName:
	//	ValidID (=> '.' ValidID)*;
	public QualifiedNameElements getQualifiedNameAccess() {
		return pQualifiedName;
	}
	
	public ParserRule getQualifiedNameRule() {
		return getQualifiedNameAccess().getRule();
	}
	
	//@ Override ValidID:
	//	ID;
	public ValidIDElements getValidIDAccess() {
		return pValidID;
	}
	
	public ParserRule getValidIDRule() {
		return getValidIDAccess().getRule();
	}
	
	//StyleConfig style::CxGridStyleConfig:
	//	NumericToResourceStyleConfig | StringToResourceStyleConfig;
	public StyleConfigElements getStyleConfigAccess() {
		return pStyleConfig;
	}
	
	public ParserRule getStyleConfigRule() {
		return getStyleConfigAccess().getRule();
	}
	
	//NumericToResourceStyleConfig style::CxGridStyleConfigNumericToResource:
	//	'number' compare=StyleCompare value=LDouble 'then' resourceThemePath=THEME_RESOURCE;
	public NumericToResourceStyleConfigElements getNumericToResourceStyleConfigAccess() {
		return pNumericToResourceStyleConfig;
	}
	
	public ParserRule getNumericToResourceStyleConfigRule() {
		return getNumericToResourceStyleConfigAccess().getRule();
	}
	
	//StringToResourceStyleConfig style::CxGridStyleConfigStringToResource:
	//	'string' compare=StyleCompare value=STRING 'then' resourceThemePath=THEME_RESOURCE;
	public StringToResourceStyleConfigElements getStringToResourceStyleConfigAccess() {
		return pStringToResourceStyleConfig;
	}
	
	public ParserRule getStringToResourceStyleConfigRule() {
		return getStringToResourceStyleConfigAccess().getRule();
	}
	
	//enum StyleCompare returns style::CxGridCompare:
	//	Equal="equal" | GreaterEqual="greater equal" | GreaterThan="greater than" | LowerEqual="lower equal" |
	//	LowerThan="lower than" | NotEqual="not equal";
	public StyleCompareElements getStyleCompareAccess() {
		return eStyleCompare;
	}
	
	public EnumRule getStyleCompareRule() {
		return getStyleCompareAccess().getRule();
	}
	
	//@ Override terminal ID:
	//	'^'? ('a'..'z' | 'A'..'Z' | '$' | '_') ('a'..'z' | 'A'..'Z' | '$' | '_' | '0'..'9')*;
	public TerminalRule getIDRule() {
		return tID;
	}
	
	//terminal INT returns ecore::EInt:
	//	'0'..'9' ('0'..'9' | '_')*;
	public TerminalRule getINTRule() {
		return tINT;
	}
	
	//terminal THEME_RESOURCE:
	//	'theme:/' ('a'..'z' | 'A'..'Z' | '$' | '_' | '.' | '/' | '0'..'9')*;
	public TerminalRule getTHEME_RESOURCERule() {
		return tTHEME_RESOURCE;
	}
	
	//LInt ecore::EInt:
	//	('+' | '-')? INT;
	public LIntElements getLIntAccess() {
		return pLInt;
	}
	
	public ParserRule getLIntRule() {
		return getLIntAccess().getRule();
	}
	
	//LDouble ecore::EDouble:
	//	LInt ('.' INT)?;
	public LDoubleElements getLDoubleAccess() {
		return pLDouble;
	}
	
	public ParserRule getLDoubleRule() {
		return getLDoubleAccess().getRule();
	}
	
	//terminal EVENT_TOPIC:
	//	"'" ID ('/' ID)* '/*'? "'";
	public TerminalRule getEVENT_TOPICRule() {
		return tEVENT_TOPIC;
	}
	
	//JvmTypeReference:
	//	JvmParameterizedTypeReference => ({JvmGenericArrayTypeReference.componentType=current} ArrayBrackets)*
	//	| XFunctionTypeRef;
	public XtypeGrammarAccess.JvmTypeReferenceElements getJvmTypeReferenceAccess() {
		return gaXtype.getJvmTypeReferenceAccess();
	}
	
	public ParserRule getJvmTypeReferenceRule() {
		return getJvmTypeReferenceAccess().getRule();
	}
	
	//ArrayBrackets:
	//	'[' ']';
	public XtypeGrammarAccess.ArrayBracketsElements getArrayBracketsAccess() {
		return gaXtype.getArrayBracketsAccess();
	}
	
	public ParserRule getArrayBracketsRule() {
		return getArrayBracketsAccess().getRule();
	}
	
	//XFunctionTypeRef:
	//	('(' (paramTypes+=JvmTypeReference (',' paramTypes+=JvmTypeReference)*)? ')')? '=>' returnType=JvmTypeReference;
	public XtypeGrammarAccess.XFunctionTypeRefElements getXFunctionTypeRefAccess() {
		return gaXtype.getXFunctionTypeRefAccess();
	}
	
	public ParserRule getXFunctionTypeRefRule() {
		return getXFunctionTypeRefAccess().getRule();
	}
	
	//JvmParameterizedTypeReference:
	//	type=[JvmType|super::QualifiedName] (=> '<' arguments+=JvmArgumentTypeReference (','
	//	arguments+=JvmArgumentTypeReference)* '>' (=> ({JvmInnerTypeReference.outer=current} '.')
	//	type=[JvmType|super::ValidID] (=> '<' arguments+=JvmArgumentTypeReference (',' arguments+=JvmArgumentTypeReference)*
	//	'>')?)*)?;
	public XtypeGrammarAccess.JvmParameterizedTypeReferenceElements getJvmParameterizedTypeReferenceAccess() {
		return gaXtype.getJvmParameterizedTypeReferenceAccess();
	}
	
	public ParserRule getJvmParameterizedTypeReferenceRule() {
		return getJvmParameterizedTypeReferenceAccess().getRule();
	}
	
	//JvmArgumentTypeReference JvmTypeReference:
	//	JvmTypeReference | JvmWildcardTypeReference;
	public XtypeGrammarAccess.JvmArgumentTypeReferenceElements getJvmArgumentTypeReferenceAccess() {
		return gaXtype.getJvmArgumentTypeReferenceAccess();
	}
	
	public ParserRule getJvmArgumentTypeReferenceRule() {
		return getJvmArgumentTypeReferenceAccess().getRule();
	}
	
	//JvmWildcardTypeReference:
	//	{JvmWildcardTypeReference} '?' (constraints+=JvmUpperBound constraints+=JvmUpperBoundAnded*
	//	| constraints+=JvmLowerBound constraints+=JvmLowerBoundAnded*)?;
	public XtypeGrammarAccess.JvmWildcardTypeReferenceElements getJvmWildcardTypeReferenceAccess() {
		return gaXtype.getJvmWildcardTypeReferenceAccess();
	}
	
	public ParserRule getJvmWildcardTypeReferenceRule() {
		return getJvmWildcardTypeReferenceAccess().getRule();
	}
	
	//JvmUpperBound:
	//	'extends' typeReference=JvmTypeReference;
	public XtypeGrammarAccess.JvmUpperBoundElements getJvmUpperBoundAccess() {
		return gaXtype.getJvmUpperBoundAccess();
	}
	
	public ParserRule getJvmUpperBoundRule() {
		return getJvmUpperBoundAccess().getRule();
	}
	
	//JvmUpperBoundAnded JvmUpperBound:
	//	'&' typeReference=JvmTypeReference;
	public XtypeGrammarAccess.JvmUpperBoundAndedElements getJvmUpperBoundAndedAccess() {
		return gaXtype.getJvmUpperBoundAndedAccess();
	}
	
	public ParserRule getJvmUpperBoundAndedRule() {
		return getJvmUpperBoundAndedAccess().getRule();
	}
	
	//JvmLowerBound:
	//	'super' typeReference=JvmTypeReference;
	public XtypeGrammarAccess.JvmLowerBoundElements getJvmLowerBoundAccess() {
		return gaXtype.getJvmLowerBoundAccess();
	}
	
	public ParserRule getJvmLowerBoundRule() {
		return getJvmLowerBoundAccess().getRule();
	}
	
	//JvmLowerBoundAnded JvmLowerBound:
	//	'&' typeReference=JvmTypeReference;
	public XtypeGrammarAccess.JvmLowerBoundAndedElements getJvmLowerBoundAndedAccess() {
		return gaXtype.getJvmLowerBoundAndedAccess();
	}
	
	public ParserRule getJvmLowerBoundAndedRule() {
		return getJvmLowerBoundAndedAccess().getRule();
	}
	
	//JvmTypeParameter:
	//	name=super::ValidID (constraints+=JvmUpperBound constraints+=JvmUpperBoundAnded*)?;
	public XtypeGrammarAccess.JvmTypeParameterElements getJvmTypeParameterAccess() {
		return gaXtype.getJvmTypeParameterAccess();
	}
	
	public ParserRule getJvmTypeParameterRule() {
		return getJvmTypeParameterAccess().getRule();
	}
	
	//QualifiedNameWithWildcard:
	//	super::QualifiedName '.' '*';
	public XtypeGrammarAccess.QualifiedNameWithWildcardElements getQualifiedNameWithWildcardAccess() {
		return gaXtype.getQualifiedNameWithWildcardAccess();
	}
	
	public ParserRule getQualifiedNameWithWildcardRule() {
		return getQualifiedNameWithWildcardAccess().getRule();
	}
	
	//XImportSection:
	//	importDeclarations+=XImportDeclaration+;
	public XtypeGrammarAccess.XImportSectionElements getXImportSectionAccess() {
		return gaXtype.getXImportSectionAccess();
	}
	
	public ParserRule getXImportSectionRule() {
		return getXImportSectionAccess().getRule();
	}
	
	//XImportDeclaration:
	//	'import' (static?='static' extension?='extension'? importedType=[JvmDeclaredType|QualifiedNameInStaticImport]
	//	(wildcard?='*' | memberName=super::ValidID) | importedType=[JvmDeclaredType|super::QualifiedName] |
	//	importedNamespace=QualifiedNameWithWildcard) ';'?;
	public XtypeGrammarAccess.XImportDeclarationElements getXImportDeclarationAccess() {
		return gaXtype.getXImportDeclarationAccess();
	}
	
	public ParserRule getXImportDeclarationRule() {
		return getXImportDeclarationAccess().getRule();
	}
	
	//QualifiedNameInStaticImport:
	//	(super::ValidID '.')+;
	public XtypeGrammarAccess.QualifiedNameInStaticImportElements getQualifiedNameInStaticImportAccess() {
		return gaXtype.getQualifiedNameInStaticImportAccess();
	}
	
	public ParserRule getQualifiedNameInStaticImportRule() {
		return getQualifiedNameInStaticImportAccess().getRule();
	}
	
	//terminal STRING:
	//	'"' ('\\' . | !('\\' | '"'))* '"'? |
	//	"'" ('\\' . | !('\\' | "'"))* "'"?;
	public TerminalRule getSTRINGRule() {
		return gaXtype.getSTRINGRule();
	}
	
	//terminal ML_COMMENT:
	//	'/*'->'*/';
	public TerminalRule getML_COMMENTRule() {
		return gaXtype.getML_COMMENTRule();
	}
	
	//terminal SL_COMMENT:
	//	'//' !('\n' | '\r')* ('\r'? '\n')?;
	public TerminalRule getSL_COMMENTRule() {
		return gaXtype.getSL_COMMENTRule();
	}
	
	//terminal WS:
	//	' ' | '\t' | '\r' | '\n'+;
	public TerminalRule getWSRule() {
		return gaXtype.getWSRule();
	}
	
	//terminal ANY_OTHER:
	//	.;
	public TerminalRule getANY_OTHERRule() {
		return gaXtype.getANY_OTHERRule();
	}
}
