def compose_property(property, other)
      if other.inverse.nil? then
        raise ArgumentError.new("Can't compose #{qp}.#{property} with inverseless #{other.declarer.qp}.#{other}")
      end
      # the source -> intermediary access methods
      sir, siw = property.accessors
      # the intermediary -> target access methods
      itr, itw = other.accessors
      # the target -> intermediary reader method
      tir = other.inverse
      # The reader composes the source -> intermediary -> target readers.
      define_method(itr) do
        ref = send(sir)
        ref.send(itr) if ref
      end
      # The writer sets the source intermediary to the target intermediary.
      define_method(itw) do |tgt|
        if tgt then
          ref = block_given? ? yield(tgt) : tgt.send(tir)
          raise ArgumentError.new("#{tgt} does not reference a #{other.inverse}") if ref.nil?
        end
        send(siw, ref)
      end
      prop = add_attribute(itr, other.type)
      logger.debug { "Created #{qp}.#{prop} which composes #{qp}.#{property} and #{other.declarer.qp}.#{other}." }
      prop.qualify(:collection) if other.collection?
      prop
    end
def compose_property(property, other)
      if other.inverse.nil? then
        raise ArgumentError.new("Can't compose #{qp}.#{property} with inverseless #{other.declarer.qp}.#{other}")
      end
      # the source -> intermediary access methods
      sir, siw = property.accessors
      # the intermediary -> target access methods
      itr, itw = other.accessors
      # the target -> intermediary reader method
      tir = other.inverse
      # The reader composes the source -> intermediary -> target readers.
      define_method(itr) do
        ref = send(sir)
        ref.send(itr) if ref
      end
      # The writer sets the source intermediary to the target intermediary.
      define_method(itw) do |tgt|
        if tgt then
          ref = block_given? ? yield(tgt) : tgt.send(tir)
          raise ArgumentError.new("#{tgt} does not reference a #{other.inverse}") if ref.nil?
        end
        send(siw, ref)
      end
      prop = add_attribute(itr, other.type)
      logger.debug { "Created #{qp}.#{prop} which composes #{qp}.#{property} and #{other.declarer.qp}.#{other}." }
      prop.qualify(:collection) if other.collection?
      prop
    end
Creates a new convenience property in this source class which composes
 the given property and the other property. The new property symbol is
 the same as the other property symbol. The new property reader and
 writer methods delegate to the respective composed property reader and
 writer methods.

 @param [Property] property the reference from the source to the intermediary
 @param [Property] other the reference from the intermediary to the target
 @yield [target] obtain the intermediary object from the target
 @yieldparam [Resource] target the target object
 @return [Property] the new property
 @raise [ArgumentError] if the other property does not have an inverse