def restrict(declarer, opts={})
      rtype = opts[:type] || @type
      rinv = opts[:inverse] || inverse
      unless declarer < @declarer then
        raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self} to an incompatible declarer type #{declarer.qp}")
      end
      unless rtype <= @type then
        raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self}({@type.qp}) to an incompatible return type #{rtype.qp}")
      end
      # Copy this attribute and its instance variables minus the restrictions and make a deep copy of the flags.
      rst = deep_copy
      # specialize the copy declarer
      rst.set_restricted_declarer(declarer)
      # Capture the restriction to propagate modifications to this metadata, esp. adding an inverse.
      @restrictions ||= []
      @restrictions << rst
      # Set the restriction type
      rst.type = rtype
      # Specialize the inverse to the restricted type attribute, if necessary.
      rst.inverse = rinv
      rst
    end
def restrict(declarer, opts={})
      rtype = opts[:type] || @type
      rinv = opts[:inverse] || inverse
      unless declarer < @declarer then
        raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self} to an incompatible declarer type #{declarer.qp}")
      end
      unless rtype <= @type then
        raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self}({@type.qp}) to an incompatible return type #{rtype.qp}")
      end
      # Copy this attribute and its instance variables minus the restrictions and make a deep copy of the flags.
      rst = deep_copy
      # specialize the copy declarer
      rst.set_restricted_declarer(declarer)
      # Capture the restriction to propagate modifications to this metadata, esp. adding an inverse.
      @restrictions ||= []
      @restrictions << rst
      # Set the restriction type
      rst.type = rtype
      # Specialize the inverse to the restricted type attribute, if necessary.
      rst.inverse = rinv
      rst
    end
Creates a new declarer attribute which restricts this attribute.
 This method should only be called by a {Resource} class, since the class is responsible
 for resetting the attribute symbol => meta-data association to point to the new restricted
 attribute.

 If this attribute has an inverse, then the restriction inverse is set to the attribute
 declared by the restriction declarer'. For example, if:
 * +AbstractProtocol.coordinator+ has inverse +Administrator.protocol+
 * +AbstractProtocol+ has subclass +StudyProtocol+
 * +StudyProtocol.coordinator+ returns a +StudyCoordinator+
 * +AbstractProtocol.coordinator+ is restricted to +StudyProtocol+
 then calling this method on the +StudyProtocol.coordinator+ restriction
 sets the +StudyProtocol.coordinator+ inverse to +StudyCoordinator.coordinator+.

 @param [Class] declarer the subclass which declares the new restricted attribute
 @param [Hash, nil] opts the restriction options
 @option opts [Class] type the restriction return type (default this attribute's return type)
 @option opts [Symbol] type the restriction inverse (default this attribute's inverse)
 @return [Property] the new restricted attribute
 @raise [ArgumentError] if the restricted declarer is not a subclass of this attribute's declarer
 @raise [ArgumentError] if there is a restricted return type and it is not a subclass of this
   attribute's return type
 @raise [MetadataError] if this attribute has an inverse that is not independently declared by
   the restricted declarer subclass