<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1 +1 @@
-ActiveRecord::Base.send :extend, PermalinkFu
\ No newline at end of file
+ActiveRecord::Base.send :include, PermalinkFu
\ No newline at end of file</diff>
      <filename>vendor/plugins/permalink_fu/init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,12 @@
 require 'iconv'
+require 'digest/sha1'
 module PermalinkFu
   class &lt;&lt; self
     attr_accessor :translation_to
     attr_accessor :translation_from
-
+    
     def escape(str)
-      s = Iconv.iconv(translation_to, translation_from, str).to_s
+      s = Iconv.iconv(translation_to + '//IGNORE', translation_from, str).to_s
       s.gsub!(/\W+/, ' ') # all non-word chars to spaces
       s.strip!            # ohh la la
       s.downcase!         #
@@ -13,27 +14,78 @@ module PermalinkFu
       s
     end
   end
+  
+  def self.included(base)
+    base.extend ClassMethods
+    class &lt;&lt; base
+      attr_accessor :permalink_options
+      attr_accessor :permalink_attributes
+      attr_accessor :permalink_field
+    end
+  end
+  
+  module ClassMethods
+    # Specifies the given field(s) as a permalink, meaning it is passed through PermalinkFu.escape and set to the permalink_field.  This
+    # is done
+    #
+    #   class Foo &lt; ActiveRecord::Base
+    #     # stores permalink form of #title to the #permalink attribute
+    #     has_permalink :title
+    #   
+    #     # stores a permalink form of &quot;#{category}-#{title}&quot; to the #permalink attribute
+    #   
+    #     has_permalink [:category, :title]
+    #   
+    #     # stores permalink form of #title to the #category_permalink attribute
+    #     has_permalink [:category, :title], :category_permalink
+    #
+    #     # add a scope
+    #     has_permalink :title, :scope =&gt; :blog_id
+    #
+    #     # add a scope and specify the permalink field name
+    #     has_permalink :title, :slug, :scope =&gt; :blog_id
+    #   end
+    #
+    def has_permalink(attr_names = [], permalink_field = nil, options = {})
+      if permalink_field.is_a?(Hash)
+        options = permalink_field
+        permalink_field = nil
+      end
+      self.permalink_attributes = Array(attr_names)
+      self.permalink_field      = permalink_field || :permalink
+      self.permalink_options    = options
+      before_validation :create_unique_permalink
+      evaluate_attribute_method permalink_field, &quot;def #{self.permalink_field}=(new_value);write_attribute(:#{self.permalink_field}, PermalinkFu.escape(new_value));end&quot;, &quot;#{self.permalink_field}=&quot;
+    end
+  end
+  
+protected
+  def create_unique_permalink
+    if send(self.class.permalink_field).to_s.empty?
+      send(&quot;#{self.class.permalink_field}=&quot;, create_permalink_for(self.class.permalink_attributes))
+    end
+    base       = send(self.class.permalink_field)
+    counter    = 1
+    # oh how i wish i could use a hash for conditions
+    conditions = [&quot;#{self.class.permalink_field} = ?&quot;, base]
+    unless new_record?
+      conditions.first &lt;&lt; &quot; and id != ?&quot;
+      conditions       &lt;&lt; id
+    end
+    if self.class.permalink_options[:scope]
+      conditions.first &lt;&lt; &quot; and #{self.class.permalink_options[:scope]} = ?&quot;
+      conditions       &lt;&lt; send(self.class.permalink_options[:scope])
+    end
+    while self.class.exists?(conditions)
+      conditions[1] = &quot;#{base}-#{counter += 1}&quot;
+      send(&quot;#{self.class.permalink_field}=&quot;, conditions[1])
+    end
+  end
 
-  # Specifies the given field(s) as a permalink, meaning it is passed through PermalinkFu.escape and set to the permalink_field.  This
-  # is done
-  #
-  # class Foo &lt; ActiveRecord::Base
-  #   # stores permalink form of #title to the #permalink attribute
-  #   has_permalink :title
-  #
-  #   # stores a permalink form of &quot;#{category}-#{title}&quot; to the #permalink attribute
-  #
-  #   has_permalink [:category, :title]
-  #
-  #   # stores permalink form of #title to the #category_permalink attribute
-  #   has_permalink [:category, :title], :category_permalink
-  # end
-  #
-  def has_permalink(attr_names = [], permalink_field = nil)
-    permalink_field ||= 'permalink'
-    before_validation { |record| record.send(&quot;#{permalink_field}=&quot;, Array(attr_names).collect { |attr_name| PermalinkFu.escape(record.send(attr_name).to_s) }.join('-')) if record.send(permalink_field).to_s.empty? }
+  def create_permalink_for(attr_names)
+    attr_names.collect { |attr_name| send(attr_name).to_s } * &quot; &quot;
   end
 end
 
 PermalinkFu.translation_to   = 'ascii//translit'
-PermalinkFu.translation_from = 'utf-8'
+PermalinkFu.translation_from = 'utf-8'
\ No newline at end of file</diff>
      <filename>vendor/plugins/permalink_fu/lib/permalink_fu.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,38 +1,97 @@
 require 'test/unit'
 require File.join(File.dirname(__FILE__), '../lib/permalink_fu')
 
-class MockModel
-  extend PermalinkFu
+class BaseModel
+  include PermalinkFu
+  attr_accessor :id
   attr_accessor :title
-  attr_accessor :permalink
+  attr_accessor :extra
+  attr_reader   :permalink
+  attr_accessor :foo
+
+  class &lt;&lt; self
+    attr_accessor :validation
+  end
   
-  def self.before_validation(&amp;block)
-    @@validation = block
+  def self.generated_methods
+    @generated_methods ||= []
   end
   
-  def validate
-    @@validation.call self
-    permalink
+  def self.primary_key
+    :id
   end
   
-  has_permalink :title
-end
+  def self.logger
+    nil
+  end
+  
+  # ripped from AR
+  def self.evaluate_attribute_method(attr_name, method_definition, method_name=attr_name)
 
-class MockModelExtra
-  extend PermalinkFu
-  attr_accessor :title
-  attr_accessor :extra
-  attr_accessor :permalink
+    unless method_name.to_s == primary_key.to_s
+      generated_methods &lt;&lt; method_name
+    end
+
+    begin
+      class_eval(method_definition, __FILE__, __LINE__)
+    rescue SyntaxError =&gt; err
+      generated_methods.delete(attr_name)
+      if logger
+        logger.warn &quot;Exception occurred during reader method compilation.&quot;
+        logger.warn &quot;Maybe #{attr_name} is not a valid Ruby identifier?&quot;
+        logger.warn &quot;#{err.message}&quot;
+      end
+    end
+  end
 
-  def self.before_validation(&amp;block)
-    @@validation = block
+  def self.exists?(*args)
+    false
+  end
+
+  def self.before_validation(method)
+    self.validation = method
   end
 
   def validate
-    @@validation.call self
+    send self.class.validation
     permalink
   end
+  
+  def new_record?
+    @id.nil?
+  end
+  
+  def write_attribute(key, value)
+    instance_variable_set &quot;@#{key}&quot;, value
+  end
+end
+
+class MockModel &lt; BaseModel
+  def self.exists?(conditions)
+    if conditions[1] == 'foo'   || conditions[1] == 'bar' || 
+      (conditions[1] == 'bar-2' &amp;&amp; conditions[2] != 2)
+      true
+    else
+      false
+    end
+  end
 
+  has_permalink :title
+end
+
+class ScopedModel &lt; BaseModel
+  def self.exists?(conditions)
+    if conditions[1] == 'foo' &amp;&amp; conditions[2] != 5
+      true
+    else
+      false
+    end
+  end
+
+  has_permalink :title, :scope =&gt; :foo
+end
+
+class MockModelExtra &lt; BaseModel
   has_permalink [:title, :extra]
 end
 
@@ -40,7 +99,8 @@ class PermalinkFuTest &lt; Test::Unit::TestCase
   @@samples = {
     'This IS a Tripped out title!!.!1  (well/ not really)' =&gt; 'this-is-a-tripped-out-title-1-well-not-really',
     '////// meph1sto r0x ! \\\\\\' =&gt; 'meph1sto-r0x',
-    '&#257;&#269;&#275;&#291;&#299;&#311;&#316;&#326;&#363;' =&gt; 'acegiklnu'
+    '&#257;&#269;&#275;&#291;&#299;&#311;&#316;&#326;&#363;' =&gt; 'acegiklnu',
+    '&#20013;&#25991;&#28204;&#35430; chinese text' =&gt; 'chinese-text'
   }
 
   @@extra = { 'some-)()()-ExtRa!/// .data==?&gt;    to \/\/test' =&gt; 'some-extra-data-to-test' }
@@ -68,4 +128,35 @@ class PermalinkFuTest &lt; Test::Unit::TestCase
       end
     end
   end
+  
+  def test_should_create_unique_permalink
+    @m = MockModel.new
+    @m.permalink = 'foo'
+    @m.validate
+    assert_equal 'foo-2', @m.permalink
+    
+    @m.permalink = 'bar'
+    @m.validate
+    assert_equal 'bar-3', @m.permalink
+  end
+  
+  def test_should_not_check_itself_for_unique_permalink
+    @m = MockModel.new
+    @m.id = 2
+    @m.permalink = 'bar-2'
+    @m.validate
+    assert_equal 'bar-2', @m.permalink
+  end
+  
+  def test_should_create_unique_scoped_permalink
+    @m = ScopedModel.new
+    @m.permalink = 'foo'
+    @m.validate
+    assert_equal 'foo-2', @m.permalink
+
+    @m.foo = 5
+    @m.permalink = 'foo'
+    @m.validate
+    assert_equal 'foo', @m.permalink
+  end
 end</diff>
      <filename>vendor/plugins/permalink_fu/test/permalink_fu_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>4d74fcfad278355a5d380c61231bca9409596f36</id>
    </parent>
  </parents>
  <author>
    <name>rick</name>
    <email>technoweenie@gmail.com</email>
  </author>
  <url>http://github.com/emk/mephisto/commit/86d5a4d33d898d3e4e1532af853587a7c4616147</url>
  <id>86d5a4d33d898d3e4e1532af853587a7c4616147</id>
  <committed-date>2008-02-02T15:30:22-08:00</committed-date>
  <authored-date>2008-02-02T15:30:22-08:00</authored-date>
  <message>update permalink_fu plugin</message>
  <tree>1af702ee651fb6b41dc53c686599fcec9e5e9230</tree>
  <committer>
    <name>rick</name>
    <email>technoweenie@gmail.com</email>
  </committer>
</commit>
