<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>

	<!-- definition of root element -->
  <xsd:element name="calendarAlgSpec">
    <xsd:complexType>
    	<xsd:sequence minOccurs="0" maxOccurs="unbounded">
				<xsd:element ref="intermediateGranularity" minOccurs="0" maxOccurs="unbounded"/>
				<xsd:element ref="granularity" minOccurs="1"/>
			</xsd:sequence>
			<xsd:attribute name="underlyingGranularity" type="xsd:string" use="required"/>
    </xsd:complexType>
  </xsd:element>
  
  <!-- definition of root element's children (granularity/intermediateGranularity) -->
	<xsd:element name="intermediateGranularity">
		<xsd:complexType>
			<xsd:sequence minOccurs="1" maxOccurs="1">
				<xsd:group ref="allOperations"/>
			</xsd:sequence>
			<xsd:attribute name="name" type="xsd:string" use="required"/>
		</xsd:complexType>
	</xsd:element>		

	<xsd:element name="granularity">
		<xsd:complexType>
			<xsd:sequence minOccurs="1" maxOccurs="1">
				<xsd:group ref="allOperations"/>
			</xsd:sequence>
			<xsd:attribute name="name" type="xsd:string" use="required"/>
		</xsd:complexType>
	</xsd:element>	
	
	<!-- definition of layer 1 operations -->
		<!-- definition of basic operations (group, alter, shift) -->
	<xsd:group name="layerOneOperations">
		<xsd:choice>
			<xsd:element ref="group"/>
			<xsd:element ref="alter"/>
			<xsd:element ref="shift"/>
		</xsd:choice>
	</xsd:group>
	
	<xsd:element name="group">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="basicGranularityArgument"/>
			</xsd:sequence>
			<xsd:attribute name="groupBy" type="xsd:integer" use="required"/>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="alter">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="basicGranularityArgument"/>
				<xsd:group ref="basicGranularityArgument"/>
			</xsd:sequence>
			<xsd:attribute name="groupSize" type="xsd:integer" use="required"/>
			<xsd:attribute name="granuleToModify" type="xsd:integer" use="required"/>
			<xsd:attribute name="modifyBy" type="xsd:integer" use="required"/>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="shift">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="basicGranularityArgument"/>
			</xsd:sequence>
			<xsd:attribute name="shiftBy" type="xsd:integer" use="required"/>
		</xsd:complexType>
	</xsd:element>
	
	<!-- definition of layer 2 operations -->
		<!-- definition of subset, selecting, set operations -->
	<xsd:group name="layerTwoOperations">
		<xsd:choice>
			<xsd:element ref="subset"/>
			<xsd:element ref="select-down"/>
			<xsd:element ref="select-up"/>
			<xsd:element ref="select-by-intersect"/>
			<xsd:element ref="union"/>
			<xsd:element ref="intersection"/>
			<xsd:element ref="difference"/>
		</xsd:choice>
	</xsd:group>
	
	<xsd:element name="subset">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="layerTwoGranularityArgument"/>
			</xsd:sequence>
			<xsd:attribute name="lowerbound" type="xsd:integer" use="required"/>
			<xsd:attribute name="upperbound" type="xsd:integer" use="required"/>
		</xsd:complexType>
	</xsd:element>	
	
	<xsd:element name="select-down">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="basicGranularityArgument"/>
				<xsd:group ref="basicGranularityArgument"/>
			</xsd:sequence>
			<xsd:attribute name="startingGranule" type="xsd:integer" use="required"/>
			<xsd:attribute name="numGranules" type="xsd:integer" use="required"/>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="select-up">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="layerTwoGranularityArgument"/>
				<xsd:group ref="layerTwoGranularityArgument"/>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="select-by-intersect">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="layerTwoGranularityArgument"/>
				<xsd:group ref="layerTwoGranularityArgument"/>
			</xsd:sequence>
			<xsd:attribute name="startingGranule" type="xsd:integer" use="required"/>
			<xsd:attribute name="numGranules" type="xsd:integer" use="required"/>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="union">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:group ref="layerTwoGranularityArgument"/>
				<xsd:group ref="layerTwoGranularityArgument"/>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
	
		<xsd:element name="intersection">
			<xsd:complexType>
				<xsd:sequence>
					<xsd:group ref="layerTwoGranularityArgument"/>
					<xsd:group ref="layerTwoGranularityArgument"/>
				</xsd:sequence>
			</xsd:complexType>
	</xsd:element>
	
		<xsd:element name="difference">
			<xsd:complexType>
				<xsd:sequence>
					<xsd:group ref="layerTwoGranularityArgument"/>
					<xsd:group ref="layerTwoGranularityArgument"/>
				</xsd:sequence>
			</xsd:complexType>
	</xsd:element>
	
	<!-- definition of layer 3 operations -->
		<!-- definition of combining and anchored grouping operations) -->
	<xsd:group name="layerThreeOperations">
		<xsd:choice>
			<xsd:element ref="combine"/>
			<xsd:element ref="anchored-group"/>
		</xsd:choice>
	</xsd:group>
	
		<xsd:element name="combine">
			<xsd:complexType>
				<xsd:sequence>
					<xsd:group ref="layerThreeGranularityArgument"/>
					<xsd:group ref="layerThreeGranularityArgument"/>
				</xsd:sequence>
			</xsd:complexType>
	</xsd:element>
	
		<xsd:element name="anchored-group">
			<xsd:complexType>
				<xsd:sequence>
					<xsd:group ref="layerThreeGranularityArgument"/>
					<xsd:group ref="layerThreeGranularityArgument"/>
				</xsd:sequence>
			</xsd:complexType>
	</xsd:element>
	
	<!-- definition of arguments to operations -->
	
	<xsd:group name="basicGranularityArgument">
		<xsd:choice>
			<xsd:element ref="baseGranularity"/>
			<xsd:group ref="layerOneOperations"/>
		</xsd:choice>
	</xsd:group>

	<xsd:element name="baseGranularity">
		<xsd:complexType>
			<xsd:attribute name="name" type="xsd:string" use="required"/>
		</xsd:complexType>
	</xsd:element>

	<xsd:group name="layerOneAndTwoOperations">
		<xsd:choice>
			<xsd:group ref="layerOneOperations"/>
			<xsd:group ref="layerTwoOperations"/>
		</xsd:choice>
	</xsd:group>
	
	<xsd:group name="layerTwoGranularityArgument">
		<xsd:choice>
			<xsd:element ref="baseGranularity"/>
			<xsd:group ref="layerOneAndTwoOperations"/>
		</xsd:choice>
	</xsd:group>
	
	<xsd:group name="allOperations">
		<xsd:choice>
			<xsd:group ref="layerOneOperations"/>
			<xsd:group ref="layerTwoOperations"/>
			<xsd:group ref="layerThreeOperations"/>
		</xsd:choice>
	</xsd:group>
	
	<xsd:group name="layerThreeGranularityArgument">
		<xsd:choice>
			<xsd:element ref="baseGranularity"/>
			<xsd:group ref="allOperations"/>
		</xsd:choice>
	</xsd:group>

</xsd:schema>
