<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>app/models/email_recipient/easy_build_recipient_extension.rb</filename>
    </added>
    <added>
      <filename>app/models/sender_email.rb</filename>
    </added>
    <added>
      <filename>db/migrate/002_add_email_recipients.rb</filename>
    </added>
    <added>
      <filename>lib/has_emails.rb</filename>
    </added>
    <added>
      <filename>test/app_root/app/models/department.rb</filename>
    </added>
    <added>
      <filename>test/app_root/app/models/user.rb</filename>
    </added>
    <added>
      <filename>test/app_root/config/environment.rb</filename>
    </added>
    <added>
      <filename>test/app_root/db/migrate/001_create_users.rb</filename>
    </added>
    <added>
      <filename>test/app_root/db/migrate/002_create_departments.rb</filename>
    </added>
    <added>
      <filename>test/app_root/test/fixtures/departments.yml</filename>
    </added>
    <added>
      <filename>test/app_root/test/fixtures/email_addresses.yml</filename>
    </added>
    <added>
      <filename>test/app_root/test/fixtures/message_recipients.yml</filename>
    </added>
    <added>
      <filename>test/app_root/test/fixtures/messages.yml</filename>
    </added>
    <added>
      <filename>test/app_root/test/fixtures/users.yml</filename>
    </added>
    <added>
      <filename>test/test_helper.rb</filename>
    </added>
    <added>
      <filename>test/unit/build_extension_test.rb</filename>
    </added>
    <added>
      <filename>test/unit/email_address_test.rb</filename>
    </added>
    <added>
      <filename>test/unit/email_recipient_test.rb</filename>
    </added>
    <added>
      <filename>test/unit/has_emails_test.rb</filename>
    </added>
    <added>
      <filename>test/unit/sender_email_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,12 +1,12 @@
-= acts_as_emailable
+= has_emails
 
-acts_as_emailable .
+has_emails .
 
 == Resources
 
 Wiki
 
-* http://wiki.pluginaweek.org/Acts_as_emailable
+* http://wiki.pluginaweek.org/Has_emails
 
 Announcement
 
@@ -14,11 +14,11 @@ Announcement
 
 Source
 
-* http://svn.pluginaweek.org/trunk/plugins/active_record/acts/acts_as_emailable
+* http://svn.pluginaweek.org/trunk/plugins/active_record/has/has_emails
 
 Development
 
-* http://dev.pluginaweek.org/browser/trunk/plugins/active_record/acts/acts_as_emailable
+* http://dev.pluginaweek.org/browser/trunk/plugins/active_record/has/has_emails
 
 == Description
 </diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ require 'rake/rdoctask'
 require 'rake/gempackagetask'
 require 'rake/contrib/sshpublisher'
 
-PKG_NAME           = 'acts_as_emailable'
+PKG_NAME           = 'has_emails'
 PKG_VERSION        = '0.0.1'
 PKG_FILE_NAME      = &quot;#{PKG_NAME}-#{PKG_VERSION}&quot;
 RUBY_FORGE_PROJECT = 'pluginaweek'
@@ -11,17 +11,17 @@ RUBY_FORGE_PROJECT = 'pluginaweek'
 desc 'Default: run unit tests.'
 task :default =&gt; :test
 
-desc 'Test the acts_as_emailable plugin.'
+desc 'Test the has_emails plugin.'
 Rake::TestTask.new(:test) do |t|
   t.libs &lt;&lt; 'lib'
   t.pattern = 'test/**/*_test.rb'
   t.verbose = true
 end
 
-desc 'Generate documentation for the acts_as_emailable plugin.'
+desc 'Generate documentation for the has_emails plugin.'
 Rake::RDocTask.new(:rdoc) do |rdoc|
   rdoc.rdoc_dir = 'rdoc'
-  rdoc.title    = 'ActsAsEmailable'
+  rdoc.title    = 'HasEmails'
   rdoc.options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source'
   rdoc.rdoc_files.include('README')
   rdoc.rdoc_files.include('lib/**/*.rb')
@@ -35,7 +35,7 @@ spec = Gem::Specification.new do |s|
   
   s.files           = FileList['{app,db,lib,tasks,test}/**/*'].to_a + %w(init.rb MIT-LICENSE Rakefile README)
   s.require_path    = 'lib'
-  s.autorequire     = 'acts_as_emailable'
+  s.autorequire     = 'has_emails'
   s.has_rdoc        = true
   s.test_files      = Dir['test/**/*_test.rb']
   </diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -44,7 +44,7 @@ class ApplicationMailer &lt; ActionMailer::Base
   def queue
     Email.transaction do
       # Create the main email
-      email = Email.create(
+      email = Email.create!(
         :from =&gt; from,
         :subject =&gt; subject,
         :body =&gt; body
@@ -54,10 +54,6 @@ class ApplicationMailer &lt; ActionMailer::Base
       email.to = to
       email.cc = cc
       email.bcc = bcc
-      puts email.valid?
-      puts email.errors.inspect
-      puts email.to.inspect
-      puts email.to.first.inspect
       email.queue!
     end
   end</diff>
      <filename>app/mailers/application_mailer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-# Represents a verified or unverified email address being used by a user
+# Represents a valid RFC822 email address
 class EmailAddress &lt; ActiveRecord::Base
   include TokenGenerator
   
@@ -25,67 +25,51 @@ class EmailAddress &lt; ActiveRecord::Base
     end
     
     # Determines if the email spec is a valid address using the RFC822 spec
-    def is_valid?(spec)
+    def valid?(spec)
       !RFC822::EmailAddress.match(spec).nil?
     end
-    
-    # Finds an email-address with the given spec
-    def find_by_spec(number, spec, *args)
-      if match = RFC822::EmailAddress.match(spec)
-        local_name = match.captures[0]
-        domain = match.captures[1]
-        
-        with_scope(:find =&gt; {:conditions =&gt; ['local_name = ? AND domain = ?', local_name, domain]}) do
-          find(number, *args)
-        end
-      end
-    end
   end
   
-  attr_protected            :local_name,
-                            :domain
-  
-  # Ensure the e-mail address has been verified
-  acts_as_state_machine     :initial =&gt; :unverified
+  # Support e-mail address verification
+  has_states    :initial =&gt; :unverified
   
   # Add messaging capabilities.  This will give us an email_box.
-  acts_as_messageable       :email,
-                              :class_name =&gt; 'Email'
-  
-  belongs_to                :emailable,
-                              :polymorphic =&gt; true
+  has_messages  :emails,
+                  :message_class =&gt; 'Email'
+  belongs_to    :emailable,
+                  :polymorphic =&gt; true
   
-  validates_presence_of     :spec
-  validates_confirmation_of :spec
-  validates_uniqueness_of   :local_name,
-                              :scope =&gt; :domain
-  validates_as_email        :spec
+  validates_presence_of       :spec
+  validates_uniqueness_of     :spec
+  validates_as_email_address  :spec
   
   # Ensure that the e-mail address has a verification code that can be sent
   # to the user
-  before_create             :create_verification_code
+  before_create :create_verification_code
   
-  state :unverified
-  state :verified
+  state :unverified, :verified
   
   # Verifies that the email address is valid
   event :verify do
-    transition_to :verified, :from =&gt; :verified
+    transition_to :verified, :from =&gt; :unverified
   end
   
   # Sets the full address
-  def spec=(value)
-    @spec = value
-    
-    if match = RFC822::EmailAddress.match(value)
-      self.local_name = match.captures[0]
-      self.domain = match.captures[1]
-    end
+  def spec=(new_spec)
+    @local_name = @domain = nil
+    write_attribute(:spec, new_spec)
   end
   
-  # Returns the full email address
-  def spec
-    @spec || (@spec = local_name + &quot;@&quot; + domain if local_name? &amp;&amp; domain?)
+  # The part of the e-mail address before the @
+  def local_name
+    parse_spec if !@local_name
+    @local_name
+  end
+  
+  # The part of the e-mail address after the @
+  def domain
+    parse_spec if !@domain
+    @domain
   end
   
   # Gets the name of the person whose email address this is.  Default is an
@@ -105,13 +89,20 @@ class EmailAddress &lt; ActiveRecord::Base
     spec
   end
   
-  protected
+  private
   # Creates the verification code that must be used when validating the email address
   def create_verification_code
-    self.verification_code = generate_token(40) do |token|
+    self.verification_code = generate_token(32) do |token|
       self.class.find_by_verification_code(token).nil?
     end
     
     self.code_expiry = 48.hour.from_now
   end
+  
+  def parse_spec
+    if !@local_name &amp;&amp; !@domain &amp;&amp; match = RFC822::EmailAddress.match(spec)
+      @local_name = match.captures[0]
+      @domain = match.captures[1]
+    end
+  end
 end
\ No newline at end of file</diff>
      <filename>app/models/email_address.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,16 @@
 class EmailRecipient &lt; MessageRecipient
+  validates_as_email_address  :messageable_spec,
+                                :allow_nil =&gt; true
+  validates_presence_of       :messageable_id,
+                                :if =&gt; :messageable_id_required?
+  
+  before_save :ensure_exclusive_references
+  
   # Included for support of recipients from emails sent by a string-based
   # sender
-  belongs_to                :message,
-                              :class_name =&gt; 'Email',
-                              :foreign_key =&gt; 'message_id'
-  alias_method              :email, :message
-  alias_method              :email=, :message=
-  alias_attribute           :email_id, :message_id
-  
-  validates_as_email        :messageable_spec,
-                              :allow_nil =&gt; true
-  validates_xor_presence_of :messageable_id,
-                            :messageable_spec
+  alias_method    :email, :message
+  alias_method    :email=, :message=
+  alias_attribute :email_id, :message_id
   
   # Returns the model that is messageable.
   def messageable_with_spec
@@ -56,6 +55,11 @@ class EmailRecipient &lt; MessageRecipient
     email_address.to_s
   end
   
+  # Actually delivers the email
+  def deliver
+    ApplicationMailer.deliver_email(self)
+  end
+  
   private
   def validate_on_create #:nodoc:
     begin
@@ -65,4 +69,24 @@ class EmailRecipient &lt; MessageRecipient
       errors.add 'messageable_id', 'must be a string, have a email_address attribute, or be a class that acts_as_emailable'
     end
   end
+  
+  # Strings are allowed to participate in messaging
+  def only_model_participants?
+    false
+  end
+  
+  # Does the messageable_id column need to be specified?
+  def messageable_id_required?
+    messageable_spec.nil?
+  end
+  
+  # Ensures that the country id/user region combo is not set at the same time as
+  # the region id
+  def ensure_exclusive_references
+    if messageable_id_required?
+      self.messageable_spec = nil
+    end
+    
+    true
+  end
 end
\ No newline at end of file</diff>
      <filename>app/models/email_recipient.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,4 @@
-&lt;%
-type = &lt;&lt;-EOV
-owner_type: 'EmailAddress'
-EOV
-%&gt;
-
 verify:
   id: 601
   name: verify
-  long_description: The email address has been verified
-  &lt;%= type %&gt;
\ No newline at end of file
+  owner_type: EmailAddress
\ No newline at end of file</diff>
      <filename>db/bootstrap/events.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,9 @@
-&lt;%
-type = &lt;&lt;-EOV
-owner_type: 'EmailAddress'
-EOV
-%&gt;
-
 unverified:
   id: 601
   name: unverified
-  long_description: The email address is unverified
-  &lt;%= type %&gt;
+  owner_type: EmailAddress
   
 verified:
   id: 602
   name: verified
-  long_description: The email adress has been verified
-  &lt;%= type %&gt;
\ No newline at end of file
+  owner_type: EmailAddress
\ No newline at end of file</diff>
      <filename>db/bootstrap/states.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,52 +1,23 @@
 class CreateEmailAddresses &lt; ActiveRecord::Migration
-  class EmailAddress &lt; ActiveRecord::Base; end
-  class StateChange &lt; ActiveRecord::Base; end
-  class StateDeadline &lt; ActiveRecord::Base; end
-  
-  class State &lt; ActiveRecord::Base
-    set_table_name 'states'
-    
-    has_many :email_addresses, :class_name =&gt; EmailAddress.to_s, :dependent =&gt; :destroy
-    has_many :from_changes, :class_name =&gt; StateChange.to_s, :foreign_key =&gt; 'from_state_id', :dependent =&gt; :destroy
-    has_many :to_changes, :class_name =&gt; StateChange.to_s, :foreign_key =&gt; 'to_state_id', :dependent =&gt; :destroy
-  end
-  
-  class Event &lt; ActiveRecord::Base
-    set_table_name 'events'
-    
-    has_many :state_changes, :class_name =&gt; StateChange.to_s, :foreign_key =&gt; 'event_id', :dependent =&gt; :destroy
-    has_many :state_deadlines, :class_name =&gt; StateDeadline.to_s, :foreign_key =&gt; 'event_id', :dependent =&gt; :destroy
-  end
-  
   def self.up
     create_table :email_addresses do |t|
-      t.column :emailable_id,       :integer,   :null =&gt; false, :unsigned =&gt; true, :references =&gt; nil
-      t.column :emailable_type,     :string,    :null =&gt; false
-      t.column :local_name,         :string,    :null =&gt; false, :limit =&gt; 382
-      t.column :domain,             :string,    :null =&gt; false, :limit =&gt; 382
-      t.column :verification_code,  :string,    :limit =&gt; 40
-      t.column :code_expiry,        :datetime
-      t.column :type,               :string,    :mull =&gt; false
-      t.column :created_at,         :timestamp, :null =&gt; false
-      t.column :updated_at,         :datetime,  :null =&gt; false
-      t.column :deleted_at,         :datetime
+      t.column :emailable_id, :integer, :null =&gt; false, :references =&gt; nil
+      t.column :emailable_type, :string, :null =&gt; false
+      t.column :spec, :string, :null =&gt; false, :limit =&gt; 382
+      t.column :verification_code, :string, :limit =&gt; 40
+      t.column :code_expiry, :datetime
+      t.column :created_at, :timestamp, :null =&gt; false
+      t.column :updated_at, :datetime, :null =&gt; false
     end
-    add_index :email_addresses, [:local_name, :domain], :unique =&gt; true
+    add_index :email_addresses, :spec, :unique =&gt; true
     add_index :email_addresses, :verification_code, :unique =&gt; true
     
-    PluginAWeek::Acts::StateMachine.migrate_up(:email_addresses)
+    PluginAWeek::Has::States.migrate_up(:email_addresses)
   end
   
   def self.down
-    PluginAWeek::Acts::StateMachine.migrate_down(:email_addresses)
+    PluginAWeek::Has::States.migrate_down(:email_addresses)
     
     drop_table :email_addresses
   end
-  
-  def self.bootstrap
-    {
-      'email_address/states' =&gt; {:class =&gt; State, :conditions =&gt; ['owner_type = ?', 'EmailAddress']},
-      'email_address/events' =&gt; {:class =&gt; Event, :conditions =&gt; ['owner_type = ?', 'EmailAddress']}
-    }
-  end
 end</diff>
      <filename>db/migrate/001_create_email_addresses.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1 @@
-require 'acts_as_emailable'
\ No newline at end of file
+require 'has_emails'
\ No newline at end of file</diff>
      <filename>init.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>app/models/email.rb</filename>
    </removed>
    <removed>
      <filename>app/models/email/easy_build_recipient_extension.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/002_add_emails.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/003_add_email_recipients.rb</filename>
    </removed>
    <removed>
      <filename>lib/acts_as_emailable.rb</filename>
    </removed>
    <removed>
      <filename>test/acts_as_emailable_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>3fd3cfb232802e7b78c90bc84307bc19ce134507</id>
    </parent>
  </parents>
  <author>
    <name>Aaron Pfeifer</name>
    <email>aaron.pfeifer@gmail.com</email>
  </author>
  <url>http://github.com/pluginaweek/has_emails/commit/5eaaa300ef342e68138161476e399e67c4abd22e</url>
  <id>5eaaa300ef342e68138161476e399e67c4abd22e</id>
  <committed-date>2007-07-30T11:42:09-07:00</committed-date>
  <authored-date>2007-07-30T11:42:09-07:00</authored-date>
  <message>Initial release</message>
  <tree>77cc9a640fa93a2308d3471b4d88a3d25501d95f</tree>
  <committer>
    <name>Aaron Pfeifer</name>
    <email>aaron.pfeifer@gmail.com</email>
  </committer>
</commit>
