ArtifactField:
	name='art-id' | name='art-type' | name='art-version-id' | name='art-mod-type' | name='tx-id' | name='art-url' |
	name='art-count';

AttributeField:
	name='id' | name='int-url' | name='ext-url' | name='version-id' | name='mod-type' | name='raw-value' |
	name='pretty-value' | name='count';
	//  the raw value of a date attribute is a ms as a long but its pretty value is date formatted string
RelationField:
	name='id' | SideId | name='rationale' | name='version-id' | name='mod-type' | name='count';

SideId:
	name='side-A-id' | name='side-B-id';

ModificationType:
	name='new' | name='modified' | name='deleted' | name='merged' | name='artifact_deleted' | name='introduced' |
	name='undeleted';

	// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIND CLAUSE
ObjectQuery:
	ArtifactQuery | MetaTypeQuery;

	// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIND TYPES
MetaTypeList:
	AllMetaTypes | MetaTypeIds;

AllMetaTypes:
	'{' name='*' '}';

MetaTypeIds:
	(type+=TypeId | '[' type+=TypeId (',' type+=TypeId)* ']');

MetaType:
	name='attribute' | name='artifact' | name='relation';

MetaTypeQuery:
	MetaTypeQueryAll | MetaTypeQueryByPredicate;

MetaTypeQueryAll:
	type=MetaType 'types' name='*';

MetaTypeQueryByPredicate:
	type=MetaType 'types' name='where' criteria+=MetaTypeCriteria ('and' criteria+=MetaTypeCriteria)*;

MetaTypeCriteria:
	name='super-type' op=EqualityOperator (type+=TypeId | '[' type+=TypeId (',' type+=TypeId)* ']');

	// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FIND ITEMS
ItemCriteria:
	ArtifactCriteria | AttributeCriteria | RelationCriteria;

ArtifactCriteria:
	 ArtifactModTypeCriteria;

ArtifactModTypeCriteria:
	name='art-mod-type' op=EqualityOperator (modType+=ModificationType | '[' modType+=ModificationType (','
	modType+=ModificationType)* ']');


AttributeCriteria:
   AttributeParameterCriteria;

AttributeParameterCriteria:
	specification=AttributeSpec op=Operator (ids+=AttributeId | '[' ids+=AttributeId (',' ids+=AttributeId)* ']');

RelationCriteria:
	RelationExistCriteria | RelationIdCriteria;

RelationIdCriteria:
	'relation' type=MetaTypeList '.' side=SideId op=EqualityOperator (ids+=RelationId | '[' ids+=RelationId (','
	ids+=RelationId)* ']');

	// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FOLLOW CLAUSE
FollowPredicate:
	//	 | FollowBranch | FollowTx | FollowAttribute;

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RelationType
//FollowBranch:
//	name='branch' 'to' type=FollowBranchType ('where' criteria+=BranchCriteria ('and' criteria+=BranchCriteria)*)?;
//
//FollowBranchType:
//	'parent' | 'children';
//FollowTx:
//	name='tx' 'to' type=FollowTxType;
//
//FollowTxType:
//	name='changed-artifacts' | name='branch-id' | name='parent-id';
//FollowAttribute:
//	name='attribute' (type+=TypeId | '[' type+=TypeId (',' type+=TypeId)* ']') 'to' predicate=FollowAttributePredicate;
//
//FollowAttributePredicate:
//	FollowAttributeToBranch | FollowAttributeToArtifact;
//
//FollowAttributeToBranch:
//	name='branch' ('where' criteria+=BranchCriteria ('and' criteria+=BranchCriteria)*)?;
//
//FollowAttributeToArtifact:
//	name='artifact' ('where' criteria+=ItemCriteria ('and' criteria+=ItemCriteria)*)?;
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


enum OsOrder:
	ASCENDING='ascending' | //
	DESCENDING='descending';

OsSortClause:
	name='sort' (fields+=OsFieldId | '[' fields+=OsFieldId (',' fields+=OsFieldId)* ']')* order=OsOrder;
	
OsCollectClause:
	name='collect' expression=OsCollectObjectExpression (limit=OsLimitClause)? (sort=OsSortClause)?;