    import ceylon.language.meta.model {
        Interface,
        MemberInterface,
        AppliedType = Type,
        IncompatibleTypeException,
        TypeApplicationException
    }

    """An interface declaration.

       <a name="toplevel-sample"></a>
       ### Usage sample for toplevel interfaces

       Because some interfaces have type parameters, getting a model requires applying type arguments to the
       interface declaration with [[interfaceApply]] in order to be able to get a closed type. For example, here is how you would
       obtain an interface model from a toplevel interface declaration:

           interface Foo<T> satisfies List<T> {
           }

           void test(){
               // We need to apply the Integer closed type to the Foo declaration in order to get the Foo<Integer> closed type
               Interface<Foo<Integer>> interfaceModel = `interface Foo`.interfaceApply<Foo<Integer>>(`Integer`);
               // This will print: ceylon.language::List<ceylon.language::Integer>
               for(satisfiedType in interfaceModel.satisfiedTypes){
                   print(satisfiedType);
               }
           }

       <a name="member-sample"></a>
       ### Usage sample for member interfaces

       For member interfaces it is a bit longer, because member interfaces need to be applied not only their type arguments but also
       the containing type, so you should use [[memberInterfaceApply]] and start by giving the containing closed type:

           class Outer(){
               shared interface Inner<T> satisfies List<T> {
               }
           }

           void test(){
               // apply the containing closed type `Outer` to the member class declaration `Outer.Inner`
               MemberInterface<Outer,Outer.Inner<Integer>> memberInterfaceModel = `interface Outer.Inner`.memberInterfaceApply<Outer,Outer.Inner<Integer>>(`Outer`, `Integer`);
               // This will print: ceylon.language::List<ceylon.language::Integer>
               for(satisfiedType in memberInterfaceModel.satisfiedTypes){
                   print(satisfiedType);
               }
           }
       """

    shared interface InterfaceDeclaration
            satisfies ClassOrInterfaceDeclaration {

        "Applies the given closed type arguments to this toplevel interface declaration in order to obtain an interface model.
         See [this code sample](#toplevel-sample) for an example on how to use this."
        throws(`class IncompatibleTypeException`, "If the specified `Type` type argument is not compatible with the actual result.")
        throws(`class TypeApplicationException`, "If the specified closed type argument values are not compatible with the actual result's type parameters.")
        shared formal Interface<Type> interfaceApply<Type=Anything>(AppliedType<Anything>* typeArguments);

        "Applies the given closed container type and type arguments to this member interface declaration in order to obtain a member interface model.
         See [this code sample](#member-sample) for an example on how to use this."
        throws(`class IncompatibleTypeException`, "If the specified `Container` or `Type` type arguments are not compatible with the actual result.")
        throws(`class TypeApplicationException`, "If the specified closed container type or type argument values are not compatible with the actual result's container type or type parameters.")
        shared formal MemberInterface<Container, Type> memberInterfaceApply<Container=Nothing, Type=Anything>(AppliedType<Container> containerType, AppliedType<Anything>* typeArguments);
    }