    import ceylon.language {
        makeSpan=span,
        makeMeasure=measure
    }

    "A range of adjacent [[Enumerable]] values. Two values of an
     enumerable type are considered _adjacent_ if their
     [[offset|Enumerable.offset]] is of unit or zero magnitude.
     Thus, a `Range` is a list of values where for every integer
     `index` where both `index` and `index+1` fall within the
     indices of the range:

         range[index+1].offset(range[index]).magnitude <= 1

     A range is always nonempty, containing at least one value.
     Thus, it is a [[Sequence]].

     A sequence of adjacent values may be represented very
     efficiently in memory, either:

     - via its endpoints, `first..last`, or
     - via an endpoint and length, `first:size`.

     Furthermore, certain operations are much more efficient
     than for other lists, assuming that the enumerable type has
     efficient [[neighbour|Enumerable.neighbour]] and
     [[offset|Enumerable.offset]] functions.

     The functions [[ceylon.language::span]] and
     [[ceylon.language::measure]], and corresponding operators
     `..` and `:` are used to create new instances of `Range`."
    see (`function makeSpan`,
         `function makeMeasure`)
    shared sealed abstract class Range<Element>()
            of Span<Element> | Measure<Element>
            extends Object()
            satisfies [Element+]
            given Element satisfies Enumerable<Element> {

    	"Determines if this range includes the given value."
        shared formal Boolean containsElement(Element element);

    	"Determines if this range includes the given range."
        shared formal Boolean includesRange(Range<Element> range);

    	"Returns a range of the same length and type as this
    	 range, with its endpoints shifted by the given number
    	 of elements, where:

    	 - a negative [[shift]] measures
    	   [[decrements|Ordinal.predecessor]], and
    	 - a positive `shift` measures
    	   [[increments|Ordinal.successor]]."
        shared formal Range<Element> shifted(Integer shift);

        "Determines if the range is increasing, that is, if
         successors occur after predecessors."
        shared formal Boolean increasing;

        "Determines if the range is decreasing, that is, if
         predecessors occur after successors."
        shared formal Boolean decreasing;

        "Returns the range itself, since a range cannot contain
         null elements."
        shared actual Range<Element> coalesced => this;

    }