module ActiveFedora::NamedRelationships

def create_bidirectional_named_relationship_methods(name,outbound_name)

and will create members_remove which does same thing as members_outbound_remove
This method will create members_append which does same thing as members_outbound_append
Method members_outbound_append and members_outbound_remove added

has_bidirectional_relationship "members", :has_collection_member, :is_member_of_collection
====Example

Similar to +create_named_relationship_methods+ except we are merely creating an alias for outbound portion of bidirectional
** EXPERIMENTAL **
def create_bidirectional_named_relationship_methods(name,outbound_name)
  append_method_name = "#{name.to_s.downcase}_append"
  remove_method_name = "#{name.to_s.downcase}_remove"
  self.send(:define_method,:"#{append_method_name}") {|object| add_named_relationship(outbound_name,object)}
  self.send(:define_method,:"#{remove_method_name}") {|object| remove_named_relationship(outbound_name,object)}
end

def create_named_relationship_methods(name)

Boths methods take an object that is kind_of? ActiveFedora::Base as a parameter
Methods audio_records_append and audio_records_remove are created.

has_relationship "audio_records", :has_part, :type=>AudioRecord

For the following relationship
====Example
append and remove objects to and from a named relationship
Used in has_relationship call to create dynamic helper methods to

** EXPERIMENTAL **
def create_named_relationship_methods(name)
  append_method_name = "#{name.to_s.downcase}_append"
  remove_method_name = "#{name.to_s.downcase}_remove"
  self.send(:define_method,:"#{append_method_name}") {|object| add_named_relationship(name,object)}
  self.send(:define_method,:"#{remove_method_name}") {|object| remove_named_relationship(name,object)}
end 

def named_predicate_exists_with_different_name?(subject,name,predicate)

to predicate in RELS-EXT would be broken.
predicates cannot be reused across relationship names. Otherwise, the mapping of relationship name
This method is used to ensure conflicting has_relationship calls are not made because
with the same subject but different name.
Check to make sure a subject,name, and predicate triple does not already exist

** EXPERIMENTAL **
def named_predicate_exists_with_different_name?(subject,name,predicate)
  if named_relationships_desc.has_key?(subject)
    named_relationships_desc[subject].each_pair do |existing_name, args|
      return true if !args[:predicate].nil? && args[:predicate] == predicate && existing_name != name 
    end
  end
  return false
end

def named_relationships_desc

{:self=>{"audio_records"=>{:type=>AudioRecord, :singular=>nil, :predicate=>:has_part, :inbound=>false}}}
Results in the following returned by named_relationships_desc
has_relationship "audio_records", :has_part, :type=>AudioRecord

For the following relationship
====Example
Return hash that stores named relationship metadata defined by has_relationship calls

** EXPERIMENTAL **
def named_relationships_desc
  @class_named_relationships_desc ||= Hash[:self => {}]
  #class_named_relationships_desc
end

def register_named_relationship(subject, name, predicate, opts)

or inbound (:inbound) relationship types.
Internal method that adds relationship name and predicate pair to either an outbound (:self)

** EXPERIMENTAL **
def register_named_relationship(subject, name, predicate, opts)
  register_named_subject(subject)
  opts.merge!({:predicate=>predicate})
  named_relationships_desc[subject][name] = opts
end

def register_named_subject(subject)

exist within the named_relationships_desc hash tracking named relationships metadata.
Internal method that ensures a relationship subject such as :self and :inbound

** EXPERIMENTAL **
def register_named_subject(subject)
  unless named_relationships_desc.has_key?(subject) 
    named_relationships_desc[subject] = {} 
  end
end