<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1 +1 @@
-Dir[File.dirname(__FILE__) + '/am_extensions/*.rb'].each{|g| require g}
+Dir[File.dirname(__FILE__) + '/am_extensions/*.rb'].each{|g| require g}</diff>
      <filename>recurring_billing/lib/am_extensions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,14 +1,14 @@
-require 'rubygems'
-
-gem 'activemerchant'
-require 'active_merchant'
-
-#TODO: Autodiscover new libs from vendor and add them to load path
-$: &lt;&lt; File.dirname(__FILE__) + &quot;/../../vendor/money-1.7.1/lib&quot;
-require &quot;money&quot;
-
-gem 'activesupport'
-require 'active_support/core_ext/string/inflections'
-class String # :nodoc:
-  include ActiveSupport::CoreExtensions::String::Inflections
-end
+require 'rubygems'
+
+gem 'activemerchant'
+require 'active_merchant'
+
+#TODO: Autodiscover new libs from vendor and add them to load path
+$: &lt;&lt; File.dirname(__FILE__) + &quot;/../../vendor/money-1.7.1/lib&quot;
+require &quot;money&quot;
+
+gem 'activesupport'
+require 'active_support/core_ext/string/inflections'
+class String # :nodoc:
+  include ActiveSupport::CoreExtensions::String::Inflections
+end</diff>
      <filename>recurring_billing/lib/dependencies.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
-require File.dirname(__FILE__) + '/utils'
-require File.dirname(__FILE__) + '/recurring_billing'
-require File.dirname(__FILE__) + '/am_extensions'
-
-Dir[File.dirname(__FILE__) + '/gateways/*.rb'].each{|g| require g}
+require File.dirname(__FILE__) + '/utils'
+require File.dirname(__FILE__) + '/recurring_billing'
+require File.dirname(__FILE__) + '/am_extensions'
+
+Dir[File.dirname(__FILE__) + '/gateways/*.rb'].each{|g| require g}</diff>
      <filename>recurring_billing/lib/gateways.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,87 +1,87 @@
-This class provides unified API to access remote payment gateways.
-
-== Quick overview
-=== Creating a gateway accessor
-There are two options to get an instance of an accessor for required gateway. First is to use get_instance method:
- options = {:gateway =&gt; :authorize_net, :login =&gt; 'MyLogin', :password =&gt; 'MyPassword'}
- gateway = RecurringBilling::RecurringBillingGateway.get_instance(options)
-which basically is an alias for the second method, directly calling
-the constructor of RecurringBilling::AuthorizeNetGateway (or any other RecurringBillingGateway descendant):
- gateway = RecurringBilling::AuthorizeNetGateway({:login =&gt; 'MyLogin', :password =&gt; 'MyPassword'})
-First method is recommended to be used for more flexibility.
-
-=== Common options for RecurringBilling methods
-It should be self-explanatory that every recurring payment itself has many parameters - those parameters have to be specified
-when the payment is created and updated on remote gateway as well. Within the API, these are grouped for convenience into four groups
-that have become the input parameters for create and update methods:
- - Amount
- - Card
- - Payment Options
- - Recurring Options
-
-&lt;b&gt;Amount&lt;/b&gt;(amount) is the object of Money class, which includes both amount and currency of the payment.
-
-&lt;b&gt;Card&lt;/b&gt;(card) is the object of ActiveMerchant::Billing::CreditCard representing the credit card that is charged during recurring payments
-
-&lt;b&gt;Payment Options&lt;/b&gt;(payment_options) are a hash of:
-- :subscription_name - +string+ containing the reference name for the subscription
-- :billing_address - +hash+ containing subscriber's billing address (see ActiveMerchant for more info on structure)
-- :order - +hash+ containing merchant's info about order, like invoice ID (see ActiveMerchant for more info on structure)
-- :taxes_amount_included - +boolean+ declaring if taxes are included in payment amount or not
-This set of options contains information of merchant.
-
-&lt;b&gt;Recurring Options&lt;/b&gt;(payment_options) are a hash of:
-- :start_date - +Date+ object, date of the first billing occurrence
-- :interval - +string+ of &lt;tt&gt;(0.5|d+)\s*(d|w|m|y)/&lt;/tt&gt; template that shows time between two consecutive billing occurrences
-- :end_date -  +Date+ object representing date after which there are no more billing occurrences
-- :occurrences - positive +integer+ showing number of billing occurrences. Either this or :end_date should be specified
-- :trial_days - positive +integer+ showing number of days of free trial
-This set of options declares settings of payment recurring occurrences.
-
-=== Creating a remote payment
-Once gateway is created, payments could be made. The whole idea is very simple - prepare parameters and use the
-create method of an instance:
- amount = Money.us_dollar(100) # $1 USD
- card =   ActiveMerchant::Billing::CreditCard.new({
-   :number =&gt; '4242424242424242',
-   :month =&gt; 9,
-   :year =&gt; Time.now.year + 1,
-   :first_name =&gt; 'Name',
-   :last_name =&gt; 'Lastname',
-   :verification_value =&gt; '123',
-   :type =&gt; 'visa'
- }) # Some random credit card
- payment_options = {
-         :subscription_name =&gt; 'Random subscription',
-         :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
-         }
- recurring_options = {
-         :start_date =&gt; Date.today,
-         :occurrences =&gt; 10,
-         :interval =&gt; '10d'
-         }
- billing_id = gateway.create(amount, card, payment_options, recurring_options)
-You may then check the result of recurring payment creation by accessing last_response:
- response = gateway.last_response
- print response.inspect
-Exact structure of last_response return value is defined in respective ActiveMerchant module. Most common
-uses of last_response query are:
- unless response.success? # succeed-failed check
-    print response.message # get message retrieved from remote gateway
- ...
-Last response is changed whenever create, update, inquiry or delete methods are called.
-
-=== Updating and canceling a remote payment
-To update the settings of recurring payment on  gateway, just call the update method of an instance.
- new_amount = Money.us_dollar(150) # $1.5 USD
- success = gateway.update(billing_id, new_amount, nil, {}, {}) # or just gateway.update(new_amount)
-Please note that acceptable update parameters vary with gateway. Correctness of parameters for update is
-checked via protected correct_update? method.
-
-Recurring payment may be cancelled via delete method:
- success = gateway.delete(billing_id)
-
-=== Inquiring gateway on payment status
-In order to inquire remote gateway on status of given subscription, inquiry method of an instance should be used:
- result = gateway.inquiry(billing_id)
-The result structure varies from gateway to gateway.
+This class provides unified API to access remote payment gateways.
+
+== Quick overview
+=== Creating a gateway accessor
+There are two options to get an instance of an accessor for required gateway. First is to use get_instance method:
+ options = {:gateway =&gt; :authorize_net, :login =&gt; 'MyLogin', :password =&gt; 'MyPassword'}
+ gateway = RecurringBilling::RecurringBillingGateway.get_instance(options)
+which basically is an alias for the second method, directly calling
+the constructor of RecurringBilling::AuthorizeNetGateway (or any other RecurringBillingGateway descendant):
+ gateway = RecurringBilling::AuthorizeNetGateway({:login =&gt; 'MyLogin', :password =&gt; 'MyPassword'})
+First method is recommended to be used for more flexibility.
+
+=== Common options for RecurringBilling methods
+It should be self-explanatory that every recurring payment itself has many parameters - those parameters have to be specified
+when the payment is created and updated on remote gateway as well. Within the API, these are grouped for convenience into four groups
+that have become the input parameters for create and update methods:
+ - Amount
+ - Card
+ - Payment Options
+ - Recurring Options
+
+&lt;b&gt;Amount&lt;/b&gt;(amount) is the object of Money class, which includes both amount and currency of the payment.
+
+&lt;b&gt;Card&lt;/b&gt;(card) is the object of ActiveMerchant::Billing::CreditCard representing the credit card that is charged during recurring payments
+
+&lt;b&gt;Payment Options&lt;/b&gt;(payment_options) are a hash of:
+- :subscription_name - +string+ containing the reference name for the subscription
+- :billing_address - +hash+ containing subscriber's billing address (see ActiveMerchant for more info on structure)
+- :order - +hash+ containing merchant's info about order, like invoice ID (see ActiveMerchant for more info on structure)
+- :taxes_amount_included - +boolean+ declaring if taxes are included in payment amount or not
+This set of options contains information of merchant.
+
+&lt;b&gt;Recurring Options&lt;/b&gt;(payment_options) are a hash of:
+- :start_date - +Date+ object, date of the first billing occurrence
+- :interval - +string+ of &lt;tt&gt;(0.5|d+)\s*(d|w|m|y)/&lt;/tt&gt; template that shows time between two consecutive billing occurrences
+- :end_date -  +Date+ object representing date after which there are no more billing occurrences
+- :occurrences - positive +integer+ showing number of billing occurrences. Either this or :end_date should be specified
+- :trial_days - positive +integer+ showing number of days of free trial
+This set of options declares settings of payment recurring occurrences.
+
+=== Creating a remote payment
+Once gateway is created, payments could be made. The whole idea is very simple - prepare parameters and use the
+create method of an instance:
+ amount = Money.us_dollar(100) # $1 USD
+ card =   ActiveMerchant::Billing::CreditCard.new({
+   :number =&gt; '4242424242424242',
+   :month =&gt; 9,
+   :year =&gt; Time.now.year + 1,
+   :first_name =&gt; 'Name',
+   :last_name =&gt; 'Lastname',
+   :verification_value =&gt; '123',
+   :type =&gt; 'visa'
+ }) # Some random credit card
+ payment_options = {
+         :subscription_name =&gt; 'Random subscription',
+         :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
+         }
+ recurring_options = {
+         :start_date =&gt; Date.today,
+         :occurrences =&gt; 10,
+         :interval =&gt; '10d'
+         }
+ billing_id = gateway.create(amount, card, payment_options, recurring_options)
+You may then check the result of recurring payment creation by accessing last_response:
+ response = gateway.last_response
+ print response.inspect
+Exact structure of last_response return value is defined in respective ActiveMerchant module. Most common
+uses of last_response query are:
+ unless response.success? # succeed-failed check
+    print response.message # get message retrieved from remote gateway
+ ...
+Last response is changed whenever create, update, inquiry or delete methods are called.
+
+=== Updating and canceling a remote payment
+To update the settings of recurring payment on  gateway, just call the update method of an instance.
+ new_amount = Money.us_dollar(150) # $1.5 USD
+ success = gateway.update(billing_id, new_amount, nil, {}, {}) # or just gateway.update(new_amount)
+Please note that acceptable update parameters vary with gateway. Correctness of parameters for update is
+checked via protected correct_update? method.
+
+Recurring payment may be cancelled via delete method:
+ success = gateway.delete(billing_id)
+
+=== Inquiring gateway on payment status
+In order to inquire remote gateway on status of given subscription, inquiry method of an instance should be used:
+ result = gateway.inquiry(billing_id)
+The result structure varies from gateway to gateway.</diff>
      <filename>recurring_billing/lib/recurring_billing.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -1,36 +1,36 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class AuthorizeNetGatewayRemoteTest &lt; Test::Unit::TestCase
-  
-  def setup
-    credentials = fixtures(:authorize_net)
-    assert @gw = RecurringBilling::AuthorizeNetGateway.new(credentials.update({:is_test =&gt; true}))
-    assert_equal @gw.name, 'Authorize.net'
-    @card = credit_card()
-  end
-  
-  def test_crud_recurring_payment
-    payment_options = {
-          :subscription_name =&gt; 'Test Subscription 1337',
-          :order =&gt; {:invoice_number =&gt; '407933'}
-          }    
-    recurring_options = {
-          :start_date =&gt; Date.today + 1,
-          :end_date =&gt; Date.today + 290,
-          :interval =&gt; '1m'
-          }    
-
-    billing_id = @gw.create(Money.us_dollar(15), @card, payment_options, recurring_options)
-    print &quot;Create:\n&quot;
-    print @gw.last_response.inspect
-    payment_options[:order] = {:invoice_number =&gt; '407934'}
-    @gw.update(billing_id, Money.us_dollar(16), @card, payment_options, nil)
-    print &quot;\nUpdate:\n&quot;
-    print @gw.last_response.inspect
-    @gw.delete(billing_id)
-    print &quot;\nDelete:\n&quot;
-    print @gw.last_response.inspect
-    assert true
-  end
-  
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class AuthorizeNetGatewayRemoteTest &lt; Test::Unit::TestCase
+  
+  def setup
+    credentials = fixtures(:authorize_net)
+    assert @gw = RecurringBilling::AuthorizeNetGateway.new(credentials.update({:is_test =&gt; true}))
+    assert_equal @gw.name, 'Authorize.net'
+    @card = credit_card()
+  end
+  
+  def test_crud_recurring_payment
+    payment_options = {
+          :subscription_name =&gt; 'Test Subscription 1337',
+          :order =&gt; {:invoice_number =&gt; '407933'}
+          }    
+    recurring_options = {
+          :start_date =&gt; Date.today + 1,
+          :end_date =&gt; Date.today + 290,
+          :interval =&gt; '1m'
+          }    
+
+    billing_id = @gw.create(Money.us_dollar(15), @card, payment_options, recurring_options)
+    print &quot;Create:\n&quot;
+    print @gw.last_response.inspect
+    payment_options[:order] = {:invoice_number =&gt; '407934'}
+    @gw.update(billing_id, Money.us_dollar(16), @card, payment_options, nil)
+    print &quot;\nUpdate:\n&quot;
+    print @gw.last_response.inspect
+    @gw.delete(billing_id)
+    print &quot;\nDelete:\n&quot;
+    print @gw.last_response.inspect
+    assert true
+  end
+  
+end</diff>
      <filename>recurring_billing/test/remote/authorize_net_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,46 +1,46 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class PaypalGatewayRemoteTest &lt; Test::Unit::TestCase
-
-  def setup
-    cred = fixtures(:paypal)
-    assert @gw = RecurringBilling::PaypalGateway.new(cred.update({:is_test=&gt;true}))
-    assert_equal @gw.name, 'PayPal Website Payments Pro (US)'
-    @card = credit_card()
-  end
-
-  def test_crud_recurring_payment
-    payment_options = {
-          :subscription_name =&gt; 'Test Subscription 1337',
-          :order =&gt; {:invoice_number =&gt; '407933'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today + 1,
-          :end_date =&gt; Date.today + 290,
-          :interval =&gt; '1m'
-          }
-
-    print &quot;\nCreate:\n&quot;
-    billing_id = @gw.create(Money.us_dollar(15), @card, payment_options=payment_options, recurring_options=recurring_options)
-    print @gw.last_response.inspect
-    payment_options[:order] = {:invoice_number =&gt; '407934'}
-    assert @gw.last_response.success?
-
-    print &quot;\n\nUpdate:\n&quot;
-    @gw.update(billing_id, Money.us_dollar(16), @card, payment_options=payment_options)
-    print @gw.last_response.inspect
-    assert @gw.last_response.success?
-
-    print &quot;\n\nInquiry:\n&quot;
-    result = @gw.inquiry(billing_id)
-    print @gw.last_response.inspect
-    print &quot;\n\n&quot;, result.inspect
-    assert @gw.last_response.success?
-
-    print &quot;\n\nDelete:\n&quot;
-    @gw.delete(billing_id)
-    print @gw.last_response.inspect
-    assert @gw.last_response.success?
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PaypalGatewayRemoteTest &lt; Test::Unit::TestCase
+
+  def setup
+    cred = fixtures(:paypal)
+    assert @gw = RecurringBilling::PaypalGateway.new(cred.update({:is_test=&gt;true}))
+    assert_equal @gw.name, 'PayPal Website Payments Pro (US)'
+    @card = credit_card()
+  end
+
+  def test_crud_recurring_payment
+    payment_options = {
+          :subscription_name =&gt; 'Test Subscription 1337',
+          :order =&gt; {:invoice_number =&gt; '407933'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today + 1,
+          :end_date =&gt; Date.today + 290,
+          :interval =&gt; '1m'
+          }
+
+    print &quot;\nCreate:\n&quot;
+    billing_id = @gw.create(Money.us_dollar(15), @card, payment_options=payment_options, recurring_options=recurring_options)
+    print @gw.last_response.inspect
+    payment_options[:order] = {:invoice_number =&gt; '407934'}
+    assert @gw.last_response.success?
+
+    print &quot;\n\nUpdate:\n&quot;
+    @gw.update(billing_id, Money.us_dollar(16), @card, payment_options=payment_options)
+    print @gw.last_response.inspect
+    assert @gw.last_response.success?
+
+    print &quot;\n\nInquiry:\n&quot;
+    result = @gw.inquiry(billing_id)
+    print @gw.last_response.inspect
+    print &quot;\n\n&quot;, result.inspect
+    assert @gw.last_response.success?
+
+    print &quot;\n\nDelete:\n&quot;
+    @gw.delete(billing_id)
+    print @gw.last_response.inspect
+    assert @gw.last_response.success?
+  end
+
+end</diff>
      <filename>recurring_billing/test/remote/paypal_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,41 +1,41 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class RecurringBillingRemoteTest &lt; Test::Unit::TestCase
-
-  def setup
-    @card = credit_card()
-  end
-
-  def perform_generic_test(gateway)
-    random_invoice = &quot;%06d&quot; % rand(999999)
-    payment_options = {
-          :subscription_name =&gt; 'Test Subscription 1337',
-          :order =&gt; {:invoice_number =&gt; random_invoice}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today + 1,
-          :end_date =&gt; Date.today + 290,
-          :interval =&gt; '1m'
-          }
-    credentials = fixtures(gateway)
-    assert gw = RecurringBilling::RecurringBillingGateway.get_instance(credentials)
-
-    billing_id = gw.create(Money.us_dollar(15), @card, payment_options, recurring_options)
-    assert gw.last_response.success?
-    new_random_invoice = &quot;%06d&quot; % rand(999999)
-    payment_options[:order] = {:invoice_number =&gt; new_random_invoice}
-    gw.update(billing_id, Money.us_dollar(16), @card, payment_options, {})
-    assert gw.last_response.success?
-    gw.delete(billing_id)
-    assert gw.last_response.success?
-  end
-
-  def test_paypal
-    perform_generic_test(:paypal)
-  end
-
-  def test_authorize_net
-    perform_generic_test(:authorize_net)
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class RecurringBillingRemoteTest &lt; Test::Unit::TestCase
+
+  def setup
+    @card = credit_card()
+  end
+
+  def perform_generic_test(gateway)
+    random_invoice = &quot;%06d&quot; % rand(999999)
+    payment_options = {
+          :subscription_name =&gt; 'Test Subscription 1337',
+          :order =&gt; {:invoice_number =&gt; random_invoice}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today + 1,
+          :end_date =&gt; Date.today + 290,
+          :interval =&gt; '1m'
+          }
+    credentials = fixtures(gateway)
+    assert gw = RecurringBilling::RecurringBillingGateway.get_instance(credentials)
+
+    billing_id = gw.create(Money.us_dollar(15), @card, payment_options, recurring_options)
+    assert gw.last_response.success?
+    new_random_invoice = &quot;%06d&quot; % rand(999999)
+    payment_options[:order] = {:invoice_number =&gt; new_random_invoice}
+    gw.update(billing_id, Money.us_dollar(16), @card, payment_options, {})
+    assert gw.last_response.success?
+    gw.delete(billing_id)
+    assert gw.last_response.success?
+  end
+
+  def test_paypal
+    perform_generic_test(:paypal)
+  end
+
+  def test_authorize_net
+    perform_generic_test(:authorize_net)
+  end
+
+end</diff>
      <filename>recurring_billing/test/remote/recurring_billing_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,42 +1,42 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class AuthorizeNetGatewayTest &lt; Test::Unit::TestCase
-  
-  def setup
-    credentials = fixtures(:authorize_net)
-    assert @gw = RecurringBilling::AuthorizeNetGateway.new(credentials.update({:is_test =&gt; true}))
-    assert_equal @gw.name, 'Authorize.net'
-    @card = credit_card()
-  end
-
-  def test_correct_update?
-    #def correct_update?(billing_id, amount, card, payment_options, recurring_options)
-    subscr_id = 'SOMERANDOMID'
-    assert_raise StandardError do; @gw.correct_update?(subscr_id, nil, @card, nil, {:start_date =&gt; Date.today + 1}); end
-    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 1, @card, nil, nil);end
-    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 100, @card, nil, {});end
-    
-  end
-  
-  def test_transform_dates
-    def d(string);return Date.parse(string);end
-    def h(a,b,c,d);return {:interval=&gt;{:length=&gt;a, :unit=&gt;b}, :duration=&gt;{:start_date=&gt;c, :occurrences=&gt;d}};end
-    
-    #syntax is: transform_dates(start_date, interval, occurrences, end_date)
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', nil, nil); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', 5, d('2009/01/01')); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), 'm', 1, nil); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '0.5m', 1, nil); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '1 year', 1, nil); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '8', 1, nil); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', -1, nil); end
-    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', nil, d('2007/12/31')); end
-    
-    assert_equal @gw.transform_dates(d('2008/01/01'), '5m', 7, nil), h(5,:months,d('2008/01/01'),7)
-    assert_equal @gw.transform_dates(d('2008/01/01'), '3 d', nil, d('2008/01/19')), h(3,:days,d('2008/01/01'),7)
-    assert_equal @gw.transform_dates(d('2008/01/01'), '3d', nil, d('2008/01/21')), h(3,:days,d('2008/01/01'),7)
-    assert_equal @gw.transform_dates(d('2008/01/01'), '8w', 13, nil), h(56,:days,d('2008/01/01'),13)
-    assert_equal @gw.transform_dates(d('2008/01/01'), '1y', nil, d('2010/12/01')), h(12,:months,d('2008/01/01'),3)
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class AuthorizeNetGatewayTest &lt; Test::Unit::TestCase
+  
+  def setup
+    credentials = fixtures(:authorize_net)
+    assert @gw = RecurringBilling::AuthorizeNetGateway.new(credentials.update({:is_test =&gt; true}))
+    assert_equal @gw.name, 'Authorize.net'
+    @card = credit_card()
+  end
+
+  def test_correct_update?
+    #def correct_update?(billing_id, amount, card, payment_options, recurring_options)
+    subscr_id = 'SOMERANDOMID'
+    assert_raise StandardError do; @gw.correct_update?(subscr_id, nil, @card, nil, {:start_date =&gt; Date.today + 1}); end
+    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 1, @card, nil, nil);end
+    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 100, @card, nil, {});end
+    
+  end
+  
+  def test_transform_dates
+    def d(string);return Date.parse(string);end
+    def h(a,b,c,d);return {:interval=&gt;{:length=&gt;a, :unit=&gt;b}, :duration=&gt;{:start_date=&gt;c, :occurrences=&gt;d}};end
+    
+    #syntax is: transform_dates(start_date, interval, occurrences, end_date)
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', nil, nil); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', 5, d('2009/01/01')); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), 'm', 1, nil); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '0.5m', 1, nil); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '1 year', 1, nil); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '8', 1, nil); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', -1, nil); end
+    assert_raise ArgumentError do; @gw.transform_dates(d('2008/01/01'), '5m', nil, d('2007/12/31')); end
+    
+    assert_equal @gw.transform_dates(d('2008/01/01'), '5m', 7, nil), h(5,:months,d('2008/01/01'),7)
+    assert_equal @gw.transform_dates(d('2008/01/01'), '3 d', nil, d('2008/01/19')), h(3,:days,d('2008/01/01'),7)
+    assert_equal @gw.transform_dates(d('2008/01/01'), '3d', nil, d('2008/01/21')), h(3,:days,d('2008/01/01'),7)
+    assert_equal @gw.transform_dates(d('2008/01/01'), '8w', 13, nil), h(56,:days,d('2008/01/01'),13)
+    assert_equal @gw.transform_dates(d('2008/01/01'), '1y', nil, d('2010/12/01')), h(12,:months,d('2008/01/01'),3)
+  end
+
+end</diff>
      <filename>recurring_billing/test/unit/authorize_net_gateway_class_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,23 +1,23 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class PaypalGatewayTest &lt; Test::Unit::TestCase
-
-  def setup
-    cred = fixtures(:paypal)
-    assert @gw = RecurringBilling::PaypalGateway.new(cred.update({:is_test=&gt;true}))
-    assert_equal @gw.name, 'PayPal Website Payments Pro (US)'
-    @card = credit_card()
-  end
-
-  def test_true
-  end
-
-#  def test_correct_update?
-#    #def correct_update?(billing_id, amount, card, payment_options, recurring_options)
-#    subscr_id = 'SOMERANDOMID'
-#    assert_raise StandardError do; @gw.correct_update?(subscr_id, nil, @card, nil, {:start_date =&gt; Date.today + 1}); end
-#    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 1, @card, nil, nil);end
-#    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 100, @card, nil, {});end
-#  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class PaypalGatewayTest &lt; Test::Unit::TestCase
+
+  def setup
+    cred = fixtures(:paypal)
+    assert @gw = RecurringBilling::PaypalGateway.new(cred.update({:is_test=&gt;true}))
+    assert_equal @gw.name, 'PayPal Website Payments Pro (US)'
+    @card = credit_card()
+  end
+
+  def test_true
+  end
+
+#  def test_correct_update?
+#    #def correct_update?(billing_id, amount, card, payment_options, recurring_options)
+#    subscr_id = 'SOMERANDOMID'
+#    assert_raise StandardError do; @gw.correct_update?(subscr_id, nil, @card, nil, {:start_date =&gt; Date.today + 1}); end
+#    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 1, @card, nil, nil);end
+#    assert_nothing_thrown do;@gw.correct_update?(subscr_id, 100, @card, nil, {});end
+#  end
+
+end</diff>
      <filename>recurring_billing/test/unit/paypal_gateway_class_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,35 +1,35 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class RecurringBillingGatewayTest &lt; Test::Unit::TestCase
-
-  def perform_generic_test(gateway)
-    credentials = fixtures(gateway)
-    assert gw = RecurringBilling::RecurringBillingGateway.get_instance(credentials)
-  end
-
-  # Checking separate_create_update_params_from_options method  
-  def test_separate_create_update_params_from_options
-    cc = credit_card()
-    payment_options = {
-          :subscription_name =&gt; 'Test Subscription 1337',
-          :order =&gt; {:invoice_number =&gt; '000000'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today + 1,
-          :end_date =&gt; Date.today + 290,
-          :interval =&gt; '1m'
-          }
-    all_options = {}.update({:card =&gt; cc}).update(payment_options).update(recurring_options)
-    separate_options = RecurringBilling::RecurringBillingGateway.separate_create_update_params_from_options(all_options)
-    assert_equal separate_options, {:amount =&gt; nil, :card =&gt; cc, :payment_options =&gt; payment_options, :recurring_options =&gt; recurring_options}
-  end
-
-  def test_paypal
-    perform_generic_test(:paypal)
-  end
-
-  def test_authorize_net
-    perform_generic_test(:authorize_net)
-  end
-  
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class RecurringBillingGatewayTest &lt; Test::Unit::TestCase
+
+  def perform_generic_test(gateway)
+    credentials = fixtures(gateway)
+    assert gw = RecurringBilling::RecurringBillingGateway.get_instance(credentials)
+  end
+
+  # Checking separate_create_update_params_from_options method  
+  def test_separate_create_update_params_from_options
+    cc = credit_card()
+    payment_options = {
+          :subscription_name =&gt; 'Test Subscription 1337',
+          :order =&gt; {:invoice_number =&gt; '000000'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today + 1,
+          :end_date =&gt; Date.today + 290,
+          :interval =&gt; '1m'
+          }
+    all_options = {}.update({:card =&gt; cc}).update(payment_options).update(recurring_options)
+    separate_options = RecurringBilling::RecurringBillingGateway.separate_create_update_params_from_options(all_options)
+    assert_equal separate_options, {:amount =&gt; nil, :card =&gt; cc, :payment_options =&gt; payment_options, :recurring_options =&gt; recurring_options}
+  end
+
+  def test_paypal
+    perform_generic_test(:paypal)
+  end
+
+  def test_authorize_net
+    perform_generic_test(:authorize_net)
+  end
+  
+end</diff>
      <filename>recurring_billing/test/unit/recurring_billing_gateway_class_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,17 +1,17 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-class UtilsTest &lt; Test::Unit::TestCase
-  def test_months_between
-    def d(string);return Date.parse(string);end
-    
-    assert months_between(d(&quot;2008/10/01&quot;), d(&quot;2008/10/01&quot;)), 0
-    assert months_between(d(&quot;2008/10/02&quot;), d(&quot;2008/10/01&quot;)), 0
-    assert months_between(d(&quot;2008/11/01&quot;), d(&quot;2008/10/02&quot;)), 0
-    assert months_between(d(&quot;2008/01/01&quot;), d(&quot;2007/12/31&quot;)), 0
-    assert months_between(d(&quot;2008/11/01&quot;), d(&quot;2008/10/01&quot;)), 1
-    assert months_between(d(&quot;2008/02/01&quot;), d(&quot;2007/05/01&quot;)), 9
-    assert months_between(d(&quot;2008/02/14&quot;), d(&quot;2007/05/01&quot;)), 9
-    assert months_between(d(&quot;2008/02/02&quot;), d(&quot;2007/05/13&quot;)), 8
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+class UtilsTest &lt; Test::Unit::TestCase
+  def test_months_between
+    def d(string);return Date.parse(string);end
+    
+    assert months_between(d(&quot;2008/10/01&quot;), d(&quot;2008/10/01&quot;)), 0
+    assert months_between(d(&quot;2008/10/02&quot;), d(&quot;2008/10/01&quot;)), 0
+    assert months_between(d(&quot;2008/11/01&quot;), d(&quot;2008/10/02&quot;)), 0
+    assert months_between(d(&quot;2008/01/01&quot;), d(&quot;2007/12/31&quot;)), 0
+    assert months_between(d(&quot;2008/11/01&quot;), d(&quot;2008/10/01&quot;)), 1
+    assert months_between(d(&quot;2008/02/01&quot;), d(&quot;2007/05/01&quot;)), 9
+    assert months_between(d(&quot;2008/02/14&quot;), d(&quot;2007/05/01&quot;)), 9
+    assert months_between(d(&quot;2008/02/02&quot;), d(&quot;2007/05/13&quot;)), 8
+  end
+
+end</diff>
      <filename>recurring_billing/test/unit/utils_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,41 +1,41 @@
-&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot;&gt;
-&lt;tr&gt;
-  &lt;th rowspan=&quot;2&quot;&gt;Reference #&lt;/th&gt;
-  &lt;th rowspan=&quot;2&quot;&gt;Gateway&lt;/th&gt;
-  &lt;th rowspan=&quot;2&quot;&gt;Balance&lt;/th&gt;
-  &lt;th colspan=&quot;4&quot;&gt;Payments&lt;/th&gt;
-  &lt;th colspan=&quot;5&quot;&gt;Billing Info&lt;/th&gt;
-  &lt;th rowspan=&quot;2&quot;&gt;Status&lt;/th&gt;
-&lt;/tr&gt;
-&lt;tr&gt;
-  &lt;th&gt;Total&lt;/th&gt;
-  &lt;th&gt;Complete&lt;/th&gt;
-  &lt;th&gt;Failed&lt;/th&gt;
-  &lt;th&gt;Remaining&lt;/th&gt;
-  &lt;th&gt;Amount&lt;/th&gt;
-  &lt;th&gt;Periodicity&lt;/th&gt;
-  &lt;th&gt;Start Date&lt;/th&gt;
-  &lt;th&gt;Trial Days&lt;/th&gt;
-  &lt;th&gt;Credit Card&lt;/th&gt;
-&lt;/tr&gt;
-
-&lt;% for profile in profiles %&gt;
-    &lt;td&gt;&lt;%= profile.gateway_reference %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= profile.gateway %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= (profile.outstanding_balance) ? profile.outstanding_balance : &quot;n/a&quot; %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= (profile.total_payments_count &amp;&amp; profile.total_payments_count &gt;= 0) ? profile.total_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= (profile.complete_payments_count &amp;&amp; profile.complete_payments_count &gt;= 0) ? profile.complete_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= (profile.failed_payments_count &amp;&amp; profile.failed_payments_count &gt;= 0) ? profile.failed_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= (profile.remaining_payments_count &amp;&amp; profile.remaining_payments_count &gt;= 0) ? profile.remaining_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= profile.money_formatted %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= SubscriptionManagement.format_periodicity(profile.periodicity).capitalize %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= Date.new(profile.created_at.year, profile.created_at.month, profile.created_at.mday) %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= (profile.trial_days &gt; 0) ? profile.trial_days : &quot;--&quot; %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= profile.card_owner_memo %&gt;&lt;/td&gt;
-    &lt;td&gt;&lt;%= profile.status.capitalize %&gt;&lt;% if !profile.problem_status.empty? %&gt;&lt;br /&gt;
-          payment problem: &lt;%= profile.problem_status %&gt;
-        &lt;% end %&gt;
-    &lt;/td&gt;
-  &lt;/tr&gt;
-&lt;% end %&gt;
-&lt;/table&gt;
+&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot;&gt;
+&lt;tr&gt;
+  &lt;th rowspan=&quot;2&quot;&gt;Reference #&lt;/th&gt;
+  &lt;th rowspan=&quot;2&quot;&gt;Gateway&lt;/th&gt;
+  &lt;th rowspan=&quot;2&quot;&gt;Balance&lt;/th&gt;
+  &lt;th colspan=&quot;4&quot;&gt;Payments&lt;/th&gt;
+  &lt;th colspan=&quot;5&quot;&gt;Billing Info&lt;/th&gt;
+  &lt;th rowspan=&quot;2&quot;&gt;Status&lt;/th&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+  &lt;th&gt;Total&lt;/th&gt;
+  &lt;th&gt;Complete&lt;/th&gt;
+  &lt;th&gt;Failed&lt;/th&gt;
+  &lt;th&gt;Remaining&lt;/th&gt;
+  &lt;th&gt;Amount&lt;/th&gt;
+  &lt;th&gt;Periodicity&lt;/th&gt;
+  &lt;th&gt;Start Date&lt;/th&gt;
+  &lt;th&gt;Trial Days&lt;/th&gt;
+  &lt;th&gt;Credit Card&lt;/th&gt;
+&lt;/tr&gt;
+
+&lt;% for profile in profiles %&gt;
+    &lt;td&gt;&lt;%= profile.gateway_reference %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= profile.gateway %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= (profile.outstanding_balance) ? profile.outstanding_balance : &quot;n/a&quot; %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= (profile.total_payments_count &amp;&amp; profile.total_payments_count &gt;= 0) ? profile.total_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= (profile.complete_payments_count &amp;&amp; profile.complete_payments_count &gt;= 0) ? profile.complete_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= (profile.failed_payments_count &amp;&amp; profile.failed_payments_count &gt;= 0) ? profile.failed_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= (profile.remaining_payments_count &amp;&amp; profile.remaining_payments_count &gt;= 0) ? profile.remaining_payments_count : &quot;n/a&quot; %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= profile.money_formatted %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= SubscriptionManagement.format_periodicity(profile.periodicity).capitalize %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= Date.new(profile.created_at.year, profile.created_at.month, profile.created_at.mday) %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= (profile.trial_days &gt; 0) ? profile.trial_days : &quot;--&quot; %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= profile.card_owner_memo %&gt;&lt;/td&gt;
+    &lt;td&gt;&lt;%= profile.status.capitalize %&gt;&lt;% if !profile.problem_status.empty? %&gt;&lt;br /&gt;
+          payment problem: &lt;%= profile.problem_status %&gt;
+        &lt;% end %&gt;
+    &lt;/td&gt;
+  &lt;/tr&gt;
+&lt;% end %&gt;
+&lt;/table&gt;</diff>
      <filename>sample_app/app/views/subscription/_recurring_payment_profile.rhtml</filename>
    </modified>
    <modified>
      <diff>@@ -1,25 +1,25 @@
-&lt;!--
-&lt;tr&gt;&lt;th&gt;Service&lt;/th&gt;&lt;td&gt;&lt;%= tariff_plan['service']['name'] %&gt;&lt;/td&gt;&lt;/tr&gt;
---&gt;
-&lt;tr&gt;&lt;th&gt;Features&lt;/th&gt;
-  &lt;td&gt;
-    &lt;ul style='padding: 0 0 0 1em; margin: 0;'&gt;
-    &lt;% for feature in tariff_plan['service']['features'] %&gt;
-      &lt;li&gt;&lt;%= SubscriptionManagement.format_feature(feature) %&gt;&lt;/li&gt;
-    &lt;% end %&gt;
-    &lt;/ul&gt;
-  &lt;/td&gt;
-&lt;/tr&gt;
-&lt;tr&gt;&lt;th&gt;Billing (w/o tax):&lt;/th&gt;
-  &lt;td&gt;&lt;%= tariff_plan['currency'] %&gt; &lt;%= sprintf(&quot;%.2f&quot;, tariff_plan['price'] / 100.00) %&gt;
-  &lt;%= SubscriptionManagement.format_periodicity(tariff_plan['payment_term']['periodicity']) %&gt;&lt;/td&gt;
-&lt;/tr&gt;
-
-&lt;tr&gt;&lt;th&gt;Trial&lt;/th&gt;&lt;td&gt;
-&lt;% if !tariff_plan['payment_term']['trial_days'].nil? %&gt;
-&lt;%= tariff_plan['payment_term']['trial_days'] %&gt; days
-&lt;% else %&gt;
-no
-&lt;% end %&gt;
-&lt;/td&gt;&lt;/tr&gt;
-
+&lt;!--
+&lt;tr&gt;&lt;th&gt;Service&lt;/th&gt;&lt;td&gt;&lt;%= tariff_plan['service']['name'] %&gt;&lt;/td&gt;&lt;/tr&gt;
+--&gt;
+&lt;tr&gt;&lt;th&gt;Features&lt;/th&gt;
+  &lt;td&gt;
+    &lt;ul style='padding: 0 0 0 1em; margin: 0;'&gt;
+    &lt;% for feature in tariff_plan['service']['features'] %&gt;
+      &lt;li&gt;&lt;%= SubscriptionManagement.format_feature(feature) %&gt;&lt;/li&gt;
+    &lt;% end %&gt;
+    &lt;/ul&gt;
+  &lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;&lt;th&gt;Billing (w/o tax):&lt;/th&gt;
+  &lt;td&gt;&lt;%= tariff_plan['currency'] %&gt; &lt;%= sprintf(&quot;%.2f&quot;, tariff_plan['price'] / 100.00) %&gt;
+  &lt;%= SubscriptionManagement.format_periodicity(tariff_plan['payment_term']['periodicity']) %&gt;&lt;/td&gt;
+&lt;/tr&gt;
+
+&lt;tr&gt;&lt;th&gt;Trial&lt;/th&gt;&lt;td&gt;
+&lt;% if !tariff_plan['payment_term']['trial_days'].nil? %&gt;
+&lt;%= tariff_plan['payment_term']['trial_days'] %&gt; days
+&lt;% else %&gt;
+no
+&lt;% end %&gt;
+&lt;/td&gt;&lt;/tr&gt;
+</diff>
      <filename>sample_app/app/views/subscription/_tariff_plan.rhtml</filename>
    </modified>
    <modified>
      <diff>@@ -1,101 +1,101 @@
-# Tariff configuration for backpack
-# http://www.backpackit.com/signup
-#
-
-backpack:
-  features:
-    user: &amp;user
-      name: User Accounts
-      description: &quot;User accounts available within application&quot;
-    storage: &amp;storage
-      name: &quot;File Storage&quot;
-      unit: Gigabyte
-      description: &quot;File storage maximum disk quota&quot;
-    page: &amp;page
-      name: Pages
-      description: &quot;Backpack Pages are the core of Backpack. You can add any combination of notes, to-dos, files, photos, and dividers to a Backpack Page.&quot;
-    group_calendar: &amp;group_calendar
-      name: Group calendar
-      description: &quot;Shared calendar for all users&quot;
-    message_boards: &amp;message_boards
-      name: Message Boards
-      description: &quot;Backpack's Message Boards allow you to centralize your communications and discussions online.&quot;
-    ssl: &amp;ssl
-      name: SSL Security
-      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
-    free_campfire_premium: &amp;free_campfire_premium
-      name: Free Campfire Premium
-      description: &quot;Free Premium Campfire membership. Campfire is real-time group chat tool for businesses.&quot;
-  payment_terms:
-    monthly: &amp;monthly
-      name: Monthly payments
-      periodicity: 1m
-      trial_days: 30
-  services:
-    solo: &amp;solo
-      name: Solo
-      features:
-       - feature: *user
-         quantity: 1
-       - feature: *storage
-         quantity: 1
-       - feature: *page
-         quantity: 0
-       - feature: *ssl
-    basic: &amp;basic
-      name: Basic
-      features:
-       - feature: *user
-         quantity: 6
-       - feature: *storage
-         quantity: 4
-       - feature: *page
-         quantity: 1000
-       - feature: *group_calendar
-       - feature: *message_boards
-    plus: &amp;plus
-      name: Plus
-      features:
-       - feature: *user
-         quantity: 15
-       - feature: *storage
-         quantity: 10
-       - feature: *page
-         quantity: 2500
-       - feature: *group_calendar
-       - feature: *message_boards
-       - feature: *ssl
-    pro: &amp;pro
-      name: Pro
-      features:
-       - feature: *user
-         quantity: 40
-       - feature: *storage
-         quantity: 20
-       - feature: *page
-         quantity: 5000
-       - feature: *group_calendar
-       - feature: *message_boards
-       - feature: *ssl
-       - feature: *free_campfire_premium
-  tariff_plans:
-    solo_monthly:
-      service: *solo
-      payment_term: *monthly
-      currency: USD
-      price: 700
-    basic_monthly:
-      service: *basic
-      payment_term: *monthly
-      currency: USD
-      price: 2400
-    plus_monthly:
-      service: *plus
-      payment_term: *monthly
-      currency: USD
-      price: 4900
-    pro_monthly:
-      service: *pro
-      payment_term: *monthly
-      currency: USD
-      price: 9900
+# Tariff configuration for backpack
+# http://www.backpackit.com/signup
+#
+
+backpack:
+  features:
+    user: &amp;user
+      name: User Accounts
+      description: &quot;User accounts available within application&quot;
+    storage: &amp;storage
+      name: &quot;File Storage&quot;
+      unit: Gigabyte
+      description: &quot;File storage maximum disk quota&quot;
+    page: &amp;page
+      name: Pages
+      description: &quot;Backpack Pages are the core of Backpack. You can add any combination of notes, to-dos, files, photos, and dividers to a Backpack Page.&quot;
+    group_calendar: &amp;group_calendar
+      name: Group calendar
+      description: &quot;Shared calendar for all users&quot;
+    message_boards: &amp;message_boards
+      name: Message Boards
+      description: &quot;Backpack's Message Boards allow you to centralize your communications and discussions online.&quot;
+    ssl: &amp;ssl
+      name: SSL Security
+      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
+    free_campfire_premium: &amp;free_campfire_premium
+      name: Free Campfire Premium
+      description: &quot;Free Premium Campfire membership. Campfire is real-time group chat tool for businesses.&quot;
+  payment_terms:
+    monthly: &amp;monthly
+      name: Monthly payments
+      periodicity: 1m
+      trial_days: 30
+  services:
+    solo: &amp;solo
+      name: Solo
+      features:
+       - feature: *user
+         quantity: 1
+       - feature: *storage
+         quantity: 1
+       - feature: *page
+         quantity: 0
+       - feature: *ssl
+    basic: &amp;basic
+      name: Basic
+      features:
+       - feature: *user
+         quantity: 6
+       - feature: *storage
+         quantity: 4
+       - feature: *page
+         quantity: 1000
+       - feature: *group_calendar
+       - feature: *message_boards
+    plus: &amp;plus
+      name: Plus
+      features:
+       - feature: *user
+         quantity: 15
+       - feature: *storage
+         quantity: 10
+       - feature: *page
+         quantity: 2500
+       - feature: *group_calendar
+       - feature: *message_boards
+       - feature: *ssl
+    pro: &amp;pro
+      name: Pro
+      features:
+       - feature: *user
+         quantity: 40
+       - feature: *storage
+         quantity: 20
+       - feature: *page
+         quantity: 5000
+       - feature: *group_calendar
+       - feature: *message_boards
+       - feature: *ssl
+       - feature: *free_campfire_premium
+  tariff_plans:
+    solo_monthly:
+      service: *solo
+      payment_term: *monthly
+      currency: USD
+      price: 700
+    basic_monthly:
+      service: *basic
+      payment_term: *monthly
+      currency: USD
+      price: 2400
+    plus_monthly:
+      service: *plus
+      payment_term: *monthly
+      currency: USD
+      price: 4900
+    pro_monthly:
+      service: *pro
+      payment_term: *monthly
+      currency: USD
+      price: 9900</diff>
      <filename>subscription_management/samples/backpack.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,71 +1,71 @@
-# Tariff configuration for basecamp
-# http://www.basecamphq.com/signup
-#
-
-basecamp:
-  features:
-    user: &amp;project
-      name: Projects
-      unit: project
-      description: &quot;Basecamp project&quot;
-    storage: &amp;storage
-      name: &quot;File Storage&quot;
-      unit: Gigabyte
-      description: &quot;File storage maximum disk quota &quot;
-    time_tracking: &amp;time_tracking
-      name: Time Tracking
-      description: &quot;Basecamp Time Tracking allows you to keep track of how much time your group is spending on tasks. You can run reports on individual people, date ranges, or total aggregate time across all projects.&quot;
-    ssl: &amp;ssl
-      name: SSL Security
-      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
-    free_campfire_premium: &amp;free_campfire_premium
-      name: Free Campfire Premium
-      description: &quot;Free Premium Campfire membership. Campfire is real-time group chat tool for businesses.&quot;
-  payment_terms:
-    monthly: &amp;monthly
-      name: Monthly payments
-      periodicity: 1m
-      trial_days: 30
-  services:
-    basic: &amp;basic
-      name: Basic
-      features:
-       - feature: *project
-         quantity: 15
-       - feature: *storage
-         quantity: 3
-    plus: &amp;plus
-      name: Plus
-      features:
-       - feature: *project
-         quantity: 35
-       - feature: *storage
-         quantity: 10
-       - feature: *time_tracking
-       - feature: *ssl
-    max: &amp;max
-      name: Max
-      features:
-       - feature: *project
-         quantity: 0
-       - feature: *storage
-         quantity: 50
-       - feature: *time_tracking
-       - feature: *ssl
-       - feature: *free_campfire_premium
-  tariff_plans:
-    basic_monthly:
-      service: *basic
-      payment_term: *monthly
-      currency: USD
-      price: 2400
-    plus_monthly:
-      service: *plus
-      payment_term: *monthly
-      currency: USD
-      price: 4900
-    max_monthly:
-      service: *max
-      payment_term: *monthly
-      currency: USD
-      price: 14900
+# Tariff configuration for basecamp
+# http://www.basecamphq.com/signup
+#
+
+basecamp:
+  features:
+    user: &amp;project
+      name: Projects
+      unit: project
+      description: &quot;Basecamp project&quot;
+    storage: &amp;storage
+      name: &quot;File Storage&quot;
+      unit: Gigabyte
+      description: &quot;File storage maximum disk quota &quot;
+    time_tracking: &amp;time_tracking
+      name: Time Tracking
+      description: &quot;Basecamp Time Tracking allows you to keep track of how much time your group is spending on tasks. You can run reports on individual people, date ranges, or total aggregate time across all projects.&quot;
+    ssl: &amp;ssl
+      name: SSL Security
+      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
+    free_campfire_premium: &amp;free_campfire_premium
+      name: Free Campfire Premium
+      description: &quot;Free Premium Campfire membership. Campfire is real-time group chat tool for businesses.&quot;
+  payment_terms:
+    monthly: &amp;monthly
+      name: Monthly payments
+      periodicity: 1m
+      trial_days: 30
+  services:
+    basic: &amp;basic
+      name: Basic
+      features:
+       - feature: *project
+         quantity: 15
+       - feature: *storage
+         quantity: 3
+    plus: &amp;plus
+      name: Plus
+      features:
+       - feature: *project
+         quantity: 35
+       - feature: *storage
+         quantity: 10
+       - feature: *time_tracking
+       - feature: *ssl
+    max: &amp;max
+      name: Max
+      features:
+       - feature: *project
+         quantity: 0
+       - feature: *storage
+         quantity: 50
+       - feature: *time_tracking
+       - feature: *ssl
+       - feature: *free_campfire_premium
+  tariff_plans:
+    basic_monthly:
+      service: *basic
+      payment_term: *monthly
+      currency: USD
+      price: 2400
+    plus_monthly:
+      service: *plus
+      payment_term: *monthly
+      currency: USD
+      price: 4900
+    max_monthly:
+      service: *max
+      payment_term: *monthly
+      currency: USD
+      price: 14900</diff>
      <filename>subscription_management/samples/basecamp.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,74 +1,74 @@
-# Tariff configuration for campfire
-# http://www.campfirenow.com/signup
-#
-
-campfire:
-  features:
-    chatter: &amp;chatter
-      name: Simultaneous Chatters
-      description: &quot;Simultaneous chatters are the total number of people chatting across your account in all your rooms at one time.&quot;
-    storage: &amp;storage
-      name: &quot;File Storage&quot;
-      unit: Gigabyte
-      description: &quot;File storage maximum disk quota &quot;
-    ssl: &amp;ssl
-      name: SSL Security
-      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
-  payment_terms:
-    monthly: &amp;monthly
-      name: Monthly payments
-      periodicity: 1m
-      trial_days: 30
-  services:
-    basic: &amp;basic
-      name: Basic
-      features:
-       - feature: *chatter
-         quantity: 12
-       - feature: *storage
-         quantity: 1
-    plus: &amp;plus
-      name: Plus
-      features:
-       - feature: *chatter
-         quantity: 25
-       - feature: *storage
-         quantity: 3
-       - feature: *ssl
-    premium: &amp;premium
-      name: premium
-      features:
-       - feature: *chatter
-         quantity: 60
-       - feature: *storage
-         quantity: 10
-       - feature: *ssl
-    max: &amp;max
-      name: Max
-      features:
-       - feature: *chatter
-         quantity: 100
-       - feature: *storage
-         quantity: 25
-       - feature: *ssl
-  tariff_plans:
-    basic_monthly:
-      service: *basic
-      payment_term: *monthly
-      currency: USD
-      price: 1200
-    plus_monthly:
-      service: *plus
-      payment_term: *monthly
-      currency: USD
-      price: 2400
-    premium_monthly:
-      service: *premium
-      payment_term: *monthly
-      currency: USD
-      price: 4900
-    max_monthly:
-      service: *solo
-      payment_term: *monthly
-      currency: USD
-      price: 9900
+# Tariff configuration for campfire
+# http://www.campfirenow.com/signup
+#
+
+campfire:
+  features:
+    chatter: &amp;chatter
+      name: Simultaneous Chatters
+      description: &quot;Simultaneous chatters are the total number of people chatting across your account in all your rooms at one time.&quot;
+    storage: &amp;storage
+      name: &quot;File Storage&quot;
+      unit: Gigabyte
+      description: &quot;File storage maximum disk quota &quot;
+    ssl: &amp;ssl
+      name: SSL Security
+      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
+  payment_terms:
+    monthly: &amp;monthly
+      name: Monthly payments
+      periodicity: 1m
+      trial_days: 30
+  services:
+    basic: &amp;basic
+      name: Basic
+      features:
+       - feature: *chatter
+         quantity: 12
+       - feature: *storage
+         quantity: 1
+    plus: &amp;plus
+      name: Plus
+      features:
+       - feature: *chatter
+         quantity: 25
+       - feature: *storage
+         quantity: 3
+       - feature: *ssl
+    premium: &amp;premium
+      name: premium
+      features:
+       - feature: *chatter
+         quantity: 60
+       - feature: *storage
+         quantity: 10
+       - feature: *ssl
+    max: &amp;max
+      name: Max
+      features:
+       - feature: *chatter
+         quantity: 100
+       - feature: *storage
+         quantity: 25
+       - feature: *ssl
+  tariff_plans:
+    basic_monthly:
+      service: *basic
+      payment_term: *monthly
+      currency: USD
+      price: 1200
+    plus_monthly:
+      service: *plus
+      payment_term: *monthly
+      currency: USD
+      price: 2400
+    premium_monthly:
+      service: *premium
+      payment_term: *monthly
+      currency: USD
+      price: 4900
+    max_monthly:
+      service: *solo
+      payment_term: *monthly
+      currency: USD
+      price: 9900</diff>
      <filename>subscription_management/samples/campfire.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,174 +1,174 @@
-# Tariff configuration for e-lm
-# http://www.e-lm.com/subscribe.php?theme=normal&amp;textsize=small&amp;lang=us
-#
-
-elm:
-  features:
-    add_programs: &amp;add_programs
-      name: &quot;Add programs&quot;
-      description: &quot;Add programs&quot;
-    add_projects_and_subprojects: &amp;add_projects_and_subprojects
-      name: &quot;Add projects and sub-projects&quot;
-      description: &quot;Add projects and sub-projects&quot;
-    manage_budget: &amp;manage_budget
-      name: &quot;Manage budget&quot;
-      description: &quot;Manage budget&quot;
-    manage_milestones: &amp;manage_milestones
-      name: &quot;Manage milestones&quot;
-      description: &quot;Manage milestones&quot;
-    manage_risks: &amp;manage_risks
-      name: &quot;Manage risks&quot;
-      description: &quot;Manage risks&quot;
-    manage_issues: &amp;manage_issues
-      name: &quot;Manage issues&quot;
-      description: &quot;Manage issues&quot;
-    manage_change_requests: &amp;manage_change_requests
-      name: &quot;Manage change requests&quot;
-      description: &quot;Manage change requests&quot;
-    manage_requirements: &amp;manage_requirements
-      name: &quot;Manage requirements&quot;
-      description: &quot;Manage requirements&quot;
-    manage_traceability: &amp;manage_traceability
-      name: &quot;Manage traceability&quot;
-      description: &quot;Manage traceability&quot;
-    manage_testcases: &amp;manage_testcases
-      name: &quot;Manage test-cases&quot;
-      description: &quot;Manage test-cases&quot;
-    manage_test_results: &amp;manage_test_results
-      name: &quot;Manage test results&quot;
-      description: &quot;Manage test results&quot;
-    manage_defects: &amp;manage_defects
-      name: &quot;Manage defects&quot;
-      description: &quot;Manage defects&quot;
-    manage_products: &amp;manage_products
-      name: &quot;Manage products&quot;
-      description: &quot;Manage products&quot;
-    manage_releases_roadmap: &amp;manage_releases_roadmap
-      name: &quot;Manage releases (roadmap)&quot;
-      description: &quot;Manage releases (roadmap)&quot;
-    manage_features: &amp;manage_features
-      name: &quot;Manage features&quot;
-      description: &quot;Manage features&quot;
-    manage_release_notes: &amp;manage_release_notes
-      name: &quot;Manage release notes&quot;
-      description: &quot;Manage release notes&quot;
-    add_edit_or_delete_users: &amp;add_edit_or_delete_users
-      name: &quot;Add, edit or delete users&quot;
-      description: &quot;Add, edit or delete users&quot;
-    set_the_licenses_a_user_has_accees_to: &amp;set_the_licenses_a_user_has_accees_to
-      name: &quot;Set the licenses a user has accees to&quot;
-      description: &quot;Set the licenses a user has accees to&quot;
-    add_users_to_access_control_groups: &amp;add_users_to_access_control_groups
-      name: &quot;Add users to access control groups&quot;
-      description: &quot;Add users to access control groups&quot;
-    define_report_templates: &amp;define_report_templates
-      name: &quot;Define report templates&quot;
-      description: &quot;Define report templates&quot;
-    define_lifecycles_workflow: &amp;define_lifecycles_workflow
-      name: &quot;Define lifecycles (workflow)&quot;
-      description: &quot;Define lifecycles (workflow)&quot;
-    define_access_control_groups: &amp;define_access_control_groups
-      name: &quot;Define access control groups&quot;
-      description: &quot;Define access control groups&quot;
-  services:
-    program_project: &amp;program_project
-      name: &quot;Program &amp; Project Management&quot;
-      features:
-       - feature: *add_programs
-       - feature: *add_projects_and_subprojects
-       - feature: *manage_budget
-       - feature: *manage_milestones
-       - feature: *manage_risks
-       - feature: *manage_issues
-       - feature: *manage_change_requests
-    scope: &amp;scope
-      name: Scope Management
-      features:
-       - feature: *add_programs
-       - feature: *add_projects_and_subprojects
-       - feature: *manage_change_requests
-       - feature: *manage_requirements
-       - feature: *manage_traceability
-    test: &amp;test
-      name: Test Management
-      features:
-       - feature: *add_programs
-       - feature: *add_projects_and_subprojects
-       - feature: *manage_traceability
-       - feature: *manage_testcases
-       - feature: *manage_test_results
-       - feature: *manage_defects
-       - feature: *manage_products
-    product: &amp;product
-      name: Product Management
-      features:
-       - feature: *add_programs
-       - feature: *manage_issues
-       - feature: *manage_change_requests
-       - feature: *manage_defects
-       - feature: *manage_products
-       - feature: *manage_releases_roadmap
-       - feature: *manage_features
-       - feature: *manage_release_notes
-    account: &amp;account
-      name: Account Management
-      features:
-       - feature: *add_edit_or_delete_users
-       - feature: *set_the_licenses_a_user_has_accees_to
-       - feature: *add_users_to_access_control_groups
-    system: &amp;system
-      name: System Administration
-      features:
-       - feature: *add_programs
-       - feature: *add_projects_and_subprojects
-       - feature: *manage_budget
-       - feature: *manage_milestones
-       - feature: *manage_risks
-       - feature: *manage_issues
-       - feature: *manage_change_requests
-       - feature: *manage_requirements
-       - feature: *manage_traceability
-       - feature: *manage_testcases
-       - feature: *manage_test_results
-       - feature: *manage_defects
-       - feature: *manage_products
-       - feature: *manage_releases_roadmap
-       - feature: *manage_features
-       - feature: *manage_release_notes
-       - feature: *add_edit_or_delete_users
-       - feature: *set_the_licenses_a_user_has_accees_to
-       - feature: *add_users_to_access_control_groups
-       - feature: *define_report_templates
-       - feature: *define_lifecycles_workflow
-       - feature: *define_access_control_groups
-  tariff_plans:
-    program_project_monthly:
-      service: *program_project
-      payment_term: *monthly
-      currency: USD
-      price: 1400
-    scope_monthly:
-      service: *scope
-      payment_term: *monthly
-      currency: USD
-      price: 2700
-    test_monthly:
-      service: *test
-      payment_term: *monthly
-      currency: USD
-      price: 3900
-    product_monthly:
-      service: *product
-      payment_term: *monthly
-      currency: USD
-      price: 8900
-    account_monthly:
-      service: *account
-      payment_term: *monthly
-      currency: USD
-      price: 14900
-    system_monthly:
-      service: *system
-      payment_term: *monthly
-      currency: USD
-      price: 14900
+# Tariff configuration for e-lm
+# http://www.e-lm.com/subscribe.php?theme=normal&amp;textsize=small&amp;lang=us
+#
+
+elm:
+  features:
+    add_programs: &amp;add_programs
+      name: &quot;Add programs&quot;
+      description: &quot;Add programs&quot;
+    add_projects_and_subprojects: &amp;add_projects_and_subprojects
+      name: &quot;Add projects and sub-projects&quot;
+      description: &quot;Add projects and sub-projects&quot;
+    manage_budget: &amp;manage_budget
+      name: &quot;Manage budget&quot;
+      description: &quot;Manage budget&quot;
+    manage_milestones: &amp;manage_milestones
+      name: &quot;Manage milestones&quot;
+      description: &quot;Manage milestones&quot;
+    manage_risks: &amp;manage_risks
+      name: &quot;Manage risks&quot;
+      description: &quot;Manage risks&quot;
+    manage_issues: &amp;manage_issues
+      name: &quot;Manage issues&quot;
+      description: &quot;Manage issues&quot;
+    manage_change_requests: &amp;manage_change_requests
+      name: &quot;Manage change requests&quot;
+      description: &quot;Manage change requests&quot;
+    manage_requirements: &amp;manage_requirements
+      name: &quot;Manage requirements&quot;
+      description: &quot;Manage requirements&quot;
+    manage_traceability: &amp;manage_traceability
+      name: &quot;Manage traceability&quot;
+      description: &quot;Manage traceability&quot;
+    manage_testcases: &amp;manage_testcases
+      name: &quot;Manage test-cases&quot;
+      description: &quot;Manage test-cases&quot;
+    manage_test_results: &amp;manage_test_results
+      name: &quot;Manage test results&quot;
+      description: &quot;Manage test results&quot;
+    manage_defects: &amp;manage_defects
+      name: &quot;Manage defects&quot;
+      description: &quot;Manage defects&quot;
+    manage_products: &amp;manage_products
+      name: &quot;Manage products&quot;
+      description: &quot;Manage products&quot;
+    manage_releases_roadmap: &amp;manage_releases_roadmap
+      name: &quot;Manage releases (roadmap)&quot;
+      description: &quot;Manage releases (roadmap)&quot;
+    manage_features: &amp;manage_features
+      name: &quot;Manage features&quot;
+      description: &quot;Manage features&quot;
+    manage_release_notes: &amp;manage_release_notes
+      name: &quot;Manage release notes&quot;
+      description: &quot;Manage release notes&quot;
+    add_edit_or_delete_users: &amp;add_edit_or_delete_users
+      name: &quot;Add, edit or delete users&quot;
+      description: &quot;Add, edit or delete users&quot;
+    set_the_licenses_a_user_has_accees_to: &amp;set_the_licenses_a_user_has_accees_to
+      name: &quot;Set the licenses a user has accees to&quot;
+      description: &quot;Set the licenses a user has accees to&quot;
+    add_users_to_access_control_groups: &amp;add_users_to_access_control_groups
+      name: &quot;Add users to access control groups&quot;
+      description: &quot;Add users to access control groups&quot;
+    define_report_templates: &amp;define_report_templates
+      name: &quot;Define report templates&quot;
+      description: &quot;Define report templates&quot;
+    define_lifecycles_workflow: &amp;define_lifecycles_workflow
+      name: &quot;Define lifecycles (workflow)&quot;
+      description: &quot;Define lifecycles (workflow)&quot;
+    define_access_control_groups: &amp;define_access_control_groups
+      name: &quot;Define access control groups&quot;
+      description: &quot;Define access control groups&quot;
+  services:
+    program_project: &amp;program_project
+      name: &quot;Program &amp; Project Management&quot;
+      features:
+       - feature: *add_programs
+       - feature: *add_projects_and_subprojects
+       - feature: *manage_budget
+       - feature: *manage_milestones
+       - feature: *manage_risks
+       - feature: *manage_issues
+       - feature: *manage_change_requests
+    scope: &amp;scope
+      name: Scope Management
+      features:
+       - feature: *add_programs
+       - feature: *add_projects_and_subprojects
+       - feature: *manage_change_requests
+       - feature: *manage_requirements
+       - feature: *manage_traceability
+    test: &amp;test
+      name: Test Management
+      features:
+       - feature: *add_programs
+       - feature: *add_projects_and_subprojects
+       - feature: *manage_traceability
+       - feature: *manage_testcases
+       - feature: *manage_test_results
+       - feature: *manage_defects
+       - feature: *manage_products
+    product: &amp;product
+      name: Product Management
+      features:
+       - feature: *add_programs
+       - feature: *manage_issues
+       - feature: *manage_change_requests
+       - feature: *manage_defects
+       - feature: *manage_products
+       - feature: *manage_releases_roadmap
+       - feature: *manage_features
+       - feature: *manage_release_notes
+    account: &amp;account
+      name: Account Management
+      features:
+       - feature: *add_edit_or_delete_users
+       - feature: *set_the_licenses_a_user_has_accees_to
+       - feature: *add_users_to_access_control_groups
+    system: &amp;system
+      name: System Administration
+      features:
+       - feature: *add_programs
+       - feature: *add_projects_and_subprojects
+       - feature: *manage_budget
+       - feature: *manage_milestones
+       - feature: *manage_risks
+       - feature: *manage_issues
+       - feature: *manage_change_requests
+       - feature: *manage_requirements
+       - feature: *manage_traceability
+       - feature: *manage_testcases
+       - feature: *manage_test_results
+       - feature: *manage_defects
+       - feature: *manage_products
+       - feature: *manage_releases_roadmap
+       - feature: *manage_features
+       - feature: *manage_release_notes
+       - feature: *add_edit_or_delete_users
+       - feature: *set_the_licenses_a_user_has_accees_to
+       - feature: *add_users_to_access_control_groups
+       - feature: *define_report_templates
+       - feature: *define_lifecycles_workflow
+       - feature: *define_access_control_groups
+  tariff_plans:
+    program_project_monthly:
+      service: *program_project
+      payment_term: *monthly
+      currency: USD
+      price: 1400
+    scope_monthly:
+      service: *scope
+      payment_term: *monthly
+      currency: USD
+      price: 2700
+    test_monthly:
+      service: *test
+      payment_term: *monthly
+      currency: USD
+      price: 3900
+    product_monthly:
+      service: *product
+      payment_term: *monthly
+      currency: USD
+      price: 8900
+    account_monthly:
+      service: *account
+      payment_term: *monthly
+      currency: USD
+      price: 14900
+    system_monthly:
+      service: *system
+      payment_term: *monthly
+      currency: USD
+      price: 14900</diff>
      <filename>subscription_management/samples/elm.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,78 +1,78 @@
-# Tariff configuration for freshbooks
-# http://www.freshbooks.com/pricing.php
-#
-
-freshbooks:
-  features:
-    clients: &amp;clients
-      name: Active Clients
-      description: &quot;Number of clients available for management&quot;
-    staff: &amp;staff
-      name: Staff Members
-      description: &quot;Number of staff members who can access an account&quot;
-  payment_terms:
-    monthly: &amp;monthly
-      name: Monthly payments
-      periodicity: 1m
-  services:
-    shuttle_bus: &amp;shuttle_bus
-      name: Shuttle Bus
-      features:
-       - feature: *clients
-         quantity: 25
-       - feature: *staff
-         quantity: 1
-    limousine: &amp;limousine
-      name: Limousine
-      features:
-       - feature: *clients
-         quantity: 100
-       - feature: *staff
-         quantity: 2
-    private_jet: &amp;private_jet
-      name: Private Jet
-      features:
-       - feature: *clients
-         quantity: 500
-       - feature: *staff
-         quantity: 3
-    starship: &amp;starship
-      name: Starship
-      features:
-       - feature: *clients
-         quantity: 2000
-       - feature: *staff
-         quantity: 10
-    time_machine: &amp;time_machine
-      name: Time Machine
-      features:
-       - feature: *clients
-         quantity: 5000
-       - feature: *staff
-         quantity: 20
-  tariff_plans:
-    shuttle_bus_monthly:
-      service: *shuttle_bus
-      payment_term: *monthly
-      currency: USD
-      price: 1400
-    limousine_monthly:
-      service: *limousine
-      payment_term: *monthly
-      currency: USD
-      price: 2700
-    private_jet_monthly:
-      service: *private_jet
-      payment_term: *monthly
-      currency: USD
-      price: 3900
-    starship_monthly:
-      service: *starship
-      payment_term: *monthly
-      currency: USD
-      price: 8900
-    time_machine_monthly:
-      service: *time_machine
-      payment_term: *monthly
-      currency: USD
-      price: 14900
+# Tariff configuration for freshbooks
+# http://www.freshbooks.com/pricing.php
+#
+
+freshbooks:
+  features:
+    clients: &amp;clients
+      name: Active Clients
+      description: &quot;Number of clients available for management&quot;
+    staff: &amp;staff
+      name: Staff Members
+      description: &quot;Number of staff members who can access an account&quot;
+  payment_terms:
+    monthly: &amp;monthly
+      name: Monthly payments
+      periodicity: 1m
+  services:
+    shuttle_bus: &amp;shuttle_bus
+      name: Shuttle Bus
+      features:
+       - feature: *clients
+         quantity: 25
+       - feature: *staff
+         quantity: 1
+    limousine: &amp;limousine
+      name: Limousine
+      features:
+       - feature: *clients
+         quantity: 100
+       - feature: *staff
+         quantity: 2
+    private_jet: &amp;private_jet
+      name: Private Jet
+      features:
+       - feature: *clients
+         quantity: 500
+       - feature: *staff
+         quantity: 3
+    starship: &amp;starship
+      name: Starship
+      features:
+       - feature: *clients
+         quantity: 2000
+       - feature: *staff
+         quantity: 10
+    time_machine: &amp;time_machine
+      name: Time Machine
+      features:
+       - feature: *clients
+         quantity: 5000
+       - feature: *staff
+         quantity: 20
+  tariff_plans:
+    shuttle_bus_monthly:
+      service: *shuttle_bus
+      payment_term: *monthly
+      currency: USD
+      price: 1400
+    limousine_monthly:
+      service: *limousine
+      payment_term: *monthly
+      currency: USD
+      price: 2700
+    private_jet_monthly:
+      service: *private_jet
+      payment_term: *monthly
+      currency: USD
+      price: 3900
+    starship_monthly:
+      service: *starship
+      payment_term: *monthly
+      currency: USD
+      price: 8900
+    time_machine_monthly:
+      service: *time_machine
+      payment_term: *monthly
+      currency: USD
+      price: 14900</diff>
      <filename>subscription_management/samples/freshbooks.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,100 +1,100 @@
-# Tariff configuration for highrise
-# http://www.highrisehq.com/signup
-#
-
-highrise:
-  features:
-    user: &amp;user
-      name: User Accounts
-      description: &quot;User accounts available within application&quot;
-    storage: &amp;storage
-      name: &quot;File Storage&quot;
-      unit: Gigabyte
-      description: &quot;File storage maximum disk quota&quot;
-    case: &amp;case
-      name: Cases
-      description: &quot;Cases let you keep related people, companies, notes, files, and images together on a convenient single page.&quot;
-    contact: &amp;contact
-      name: Contacts
-      descrption: &quot;Contacts for an account&quot;
-    ssl: &amp;ssl
-      name: SSL Security
-      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
-    free_campfire_premium: &amp;free_campfire_premium
-      name: Free Campfore Premium
-      description: &quot;Free Premium Campfire membership. Campfire is real-time group chat tool for businesses.&quot;
-  payment_terms:
-    monthly: &amp;monthly
-      name: Monthly payments
-      periodicity: 1m
-      trial_days: 30
-  services:
-    solo: &amp;solo
-      name: Solo
-      features:
-       - feature: *user
-         quantity: 1
-       - feature: *storage
-         quantity: 3
-       - feature: *contact
-         quantity: 20000
-       - feature: *case
-         quantity: 0
-       - feature: *ssl
-    basic: &amp;basic
-      name: Basic
-      features:
-       - feature: *user
-         quantity: 6
-       - feature: *storage
-         quantity: 3
-       - feature: *contact
-         quantity: 5000
-       - feature: *case
-         quantity: 5
-    plus: &amp;plus
-      name: Plus
-      features:
-       - feature: *user
-         quantity: 15
-       - feature: *storage
-         quantity: 10
-       - feature: *contact
-         quantity: 20000
-       - feature: *case
-         quantity: 0
-       - feature: *ssl
-    pro: &amp;pro
-      name: Pro
-      features:
-       - feature: *user
-         quantity: 40
-       - feature: *storage
-         quantity: 20
-       - feature: *contact
-         quantity: 30000
-       - feature: *case
-         quantity: 0
-       - feature: *ssl
-       - feature: *free_campfire_premium
-  tariff_plans:
-    solo_monthly:
-      service: *solo
-      payment_term: *monthly
-      currency: USD
-      price: 2900
-    basic_monthly:
-      service: *basic
-      payment_term: *monthly
-      currency: USD
-      price: 2400
-    plus_monthly:
-      service: *plus
-      payment_term: *monthly
-      currency: USD
-      price: 4900
-    pro_monthly:
-      service: *pro
-      payment_term: *monthly
-      currency: USD
-      price: 9900
+# Tariff configuration for highrise
+# http://www.highrisehq.com/signup
+#
+
+highrise:
+  features:
+    user: &amp;user
+      name: User Accounts
+      description: &quot;User accounts available within application&quot;
+    storage: &amp;storage
+      name: &quot;File Storage&quot;
+      unit: Gigabyte
+      description: &quot;File storage maximum disk quota&quot;
+    case: &amp;case
+      name: Cases
+      description: &quot;Cases let you keep related people, companies, notes, files, and images together on a convenient single page.&quot;
+    contact: &amp;contact
+      name: Contacts
+      descrption: &quot;Contacts for an account&quot;
+    ssl: &amp;ssl
+      name: SSL Security
+      description: &quot;Whether SSL encryption for online sessions is available or not&quot;
+    free_campfire_premium: &amp;free_campfire_premium
+      name: Free Campfore Premium
+      description: &quot;Free Premium Campfire membership. Campfire is real-time group chat tool for businesses.&quot;
+  payment_terms:
+    monthly: &amp;monthly
+      name: Monthly payments
+      periodicity: 1m
+      trial_days: 30
+  services:
+    solo: &amp;solo
+      name: Solo
+      features:
+       - feature: *user
+         quantity: 1
+       - feature: *storage
+         quantity: 3
+       - feature: *contact
+         quantity: 20000
+       - feature: *case
+         quantity: 0
+       - feature: *ssl
+    basic: &amp;basic
+      name: Basic
+      features:
+       - feature: *user
+         quantity: 6
+       - feature: *storage
+         quantity: 3
+       - feature: *contact
+         quantity: 5000
+       - feature: *case
+         quantity: 5
+    plus: &amp;plus
+      name: Plus
+      features:
+       - feature: *user
+         quantity: 15
+       - feature: *storage
+         quantity: 10
+       - feature: *contact
+         quantity: 20000
+       - feature: *case
+         quantity: 0
+       - feature: *ssl
+    pro: &amp;pro
+      name: Pro
+      features:
+       - feature: *user
+         quantity: 40
+       - feature: *storage
+         quantity: 20
+       - feature: *contact
+         quantity: 30000
+       - feature: *case
+         quantity: 0
+       - feature: *ssl
+       - feature: *free_campfire_premium
+  tariff_plans:
+    solo_monthly:
+      service: *solo
+      payment_term: *monthly
+      currency: USD
+      price: 2900
+    basic_monthly:
+      service: *basic
+      payment_term: *monthly
+      currency: USD
+      price: 2400
+    plus_monthly:
+      service: *plus
+      payment_term: *monthly
+      currency: USD
+      price: 4900
+    pro_monthly:
+      service: *pro
+      payment_term: *monthly
+      currency: USD
+      price: 9900</diff>
      <filename>subscription_management/samples/highrise.yml</filename>
    </modified>
    <modified>
      <diff>@@ -1,112 +1,112 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-require 'money'
-
-class SubscriptionManagementRemoteTest &lt; Test::Unit::TestCase
-
-  def setup
-    @sm = ::SubscriptionManagement.new(
-                  :tariff_plans_config =&gt; File.dirname(__FILE__) + '/../../samples/backpack.yml',
-                  :taxes_config =&gt; File.dirname(__FILE__) + '/../../samples/taxes.yml',
-                  :gateways_config =&gt; File.dirname(__FILE__) + '/../../../recurring_billing/test/fixtures.yml',
-                  :gateway =&gt; :paypal
-                  )
-  end
-
-  # Checks if there are no exceptions while manipulating class with legit data; based on demo.rb
-  def test_crud_is_working
-    options = {
-              :account_id =&gt; 'test_acc_id',
-              :account_country =&gt; 'US',
-              :account_state =&gt; 'CA',
-              :tariff_plan =&gt; 'solo_monthly',
-              :start_date =&gt; (Date.today + 1),
-              :quantity =&gt; 1,
-              :end_date =&gt; DateTime.new(2010, 12, 11)
-              }
-    credit_card = credit_card()
-    credit_card_2 = credit_card(4929838635250031, {:year =&gt; Time.now.year + 5})
-    credit_card_3 = credit_card(4929273971564532, {:year =&gt; Time.now.year + 3})
-
-    assert_raise StandardError do; @sm.get_active_profile(-1); end
-
-    subscription_id = @sm.subscribe(options)
-    assert_equal 'pending', Subscription.find_by_id(subscription_id).status
-    assert_raise StandardError do; @sm.get_active_profile(subscription_id); end
-    @sm.pay_for_subscription(subscription_id, credit_card, {})
-    subscription = Subscription.find_by_id(subscription_id)
-    assert_equal 'ok', subscription.status
-    assert_equal 700, subscription.net_amount
-    assert_equal 140, subscription.taxes_amount
-    assert_equal 840, subscription.billing_amount
-
-    assert_equal 1, subscription.recurring_payment_profiles.length
-    profile = subscription.recurring_payment_profiles[0]
-    assert_equal 700, profile.net_amount
-    assert_equal 140, profile.taxes_amount
-    assert_equal 840, profile.amount
-
-    # create payment and check invoice
-    time = DateTime.now
-    transaction = Transaction.new({
-        :recurring_payment_profile_id =&gt; profile.id,
-        :gateway_reference =&gt; 'ABC0123456789XYZ',
-        :currency =&gt; 'USD',
-        :amount =&gt; 840,
-        :created_at =&gt; time
-        })
-    transaction.save!
-
-    invoice_data = @sm.get_invoice_data(transaction.id)
-    invoice_data[:date] = invoice_data[:date].strftime('%Y-%m-%d')
-
-    assert_equal({:taxes_comment    =&gt;&quot;resident, CA&quot;,
-                 :net_amount        =&gt;&quot;7.00 USD&quot;,
-                 :billing_account   =&gt;&quot;test_acc_id&quot;,
-                 :transaction_gateway=&gt;&quot;PAYPAL&quot;,
-                 :taxes_amount      =&gt;&quot;1.40 USD&quot;,
-                 :transaction_id    =&gt;&quot;ABC0123456789XYZ&quot;,
-                 :number            =&gt; transaction.id,
-                 :date              =&gt; time.strftime('%Y-%m-%d'),
-                 :transaction_amount=&gt;&quot;8.40 USD&quot;,
-                 :total_amount      =&gt;&quot;8.40 USD&quot;,
-                 :service_name      =&gt;&quot;Solo (per month)&quot;
-                 },
-                invoice_data
-                )
-
-    transaction = Transaction.new({
-        :recurring_payment_profile_id =&gt; profile.id,
-        :gateway_reference =&gt; 'CAB0123456789ZYX',
-        :currency =&gt; 'CAD',
-        :amount =&gt; 840,
-        :created_at =&gt; Date.today
-        })
-    transaction.save!
-    assert_raises NotImplementedError do; @sm.get_invoice_data(transaction.id); end
-
-    transaction = Transaction.new({
-        :recurring_payment_profile_id =&gt; profile.id,
-        :gateway_reference =&gt; 'CAB0123456789ZYX',
-        :currency =&gt; 'USD',
-        :amount =&gt; 839,
-        :created_at =&gt; Date.today
-        })
-    transaction.save!
-    assert_raises NotImplementedError do; @sm.get_invoice_data(transaction.id); end
-
-    features = @sm.get_features(subscription_id)
-
-    options = {:card=&gt;credit_card_2}
-    assert @sm.update_possible?(subscription_id, options)
-    @sm.update_subscription(subscription_id, options)
-
-    options = {:card=&gt;credit_card_3, :start_date =&gt; Date.today + 42}
-    assert !@sm.update_possible?(subscription_id, options)
-    @sm.update_subscription(subscription_id, options)
-
-    @sm.unsubscribe(subscription_id)
-    assert_equal 'canceled', Subscription.find_by_id(subscription_id).status
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+require 'money'
+
+class SubscriptionManagementRemoteTest &lt; Test::Unit::TestCase
+
+  def setup
+    @sm = ::SubscriptionManagement.new(
+                  :tariff_plans_config =&gt; File.dirname(__FILE__) + '/../../samples/backpack.yml',
+                  :taxes_config =&gt; File.dirname(__FILE__) + '/../../samples/taxes.yml',
+                  :gateways_config =&gt; File.dirname(__FILE__) + '/../../../recurring_billing/test/fixtures.yml',
+                  :gateway =&gt; :paypal
+                  )
+  end
+
+  # Checks if there are no exceptions while manipulating class with legit data; based on demo.rb
+  def test_crud_is_working
+    options = {
+              :account_id =&gt; 'test_acc_id',
+              :account_country =&gt; 'US',
+              :account_state =&gt; 'CA',
+              :tariff_plan =&gt; 'solo_monthly',
+              :start_date =&gt; (Date.today + 1),
+              :quantity =&gt; 1,
+              :end_date =&gt; DateTime.new(2010, 12, 11)
+              }
+    credit_card = credit_card()
+    credit_card_2 = credit_card(4929838635250031, {:year =&gt; Time.now.year + 5})
+    credit_card_3 = credit_card(4929273971564532, {:year =&gt; Time.now.year + 3})
+
+    assert_raise StandardError do; @sm.get_active_profile(-1); end
+
+    subscription_id = @sm.subscribe(options)
+    assert_equal 'pending', Subscription.find_by_id(subscription_id).status
+    assert_raise StandardError do; @sm.get_active_profile(subscription_id); end
+    @sm.pay_for_subscription(subscription_id, credit_card, {})
+    subscription = Subscription.find_by_id(subscription_id)
+    assert_equal 'ok', subscription.status
+    assert_equal 700, subscription.net_amount
+    assert_equal 140, subscription.taxes_amount
+    assert_equal 840, subscription.billing_amount
+
+    assert_equal 1, subscription.recurring_payment_profiles.length
+    profile = subscription.recurring_payment_profiles[0]
+    assert_equal 700, profile.net_amount
+    assert_equal 140, profile.taxes_amount
+    assert_equal 840, profile.amount
+
+    # create payment and check invoice
+    time = DateTime.now
+    transaction = Transaction.new({
+        :recurring_payment_profile_id =&gt; profile.id,
+        :gateway_reference =&gt; 'ABC0123456789XYZ',
+        :currency =&gt; 'USD',
+        :amount =&gt; 840,
+        :created_at =&gt; time
+        })
+    transaction.save!
+
+    invoice_data = @sm.get_invoice_data(transaction.id)
+    invoice_data[:date] = invoice_data[:date].strftime('%Y-%m-%d')
+
+    assert_equal({:taxes_comment    =&gt;&quot;resident, CA&quot;,
+                 :net_amount        =&gt;&quot;7.00 USD&quot;,
+                 :billing_account   =&gt;&quot;test_acc_id&quot;,
+                 :transaction_gateway=&gt;&quot;PAYPAL&quot;,
+                 :taxes_amount      =&gt;&quot;1.40 USD&quot;,
+                 :transaction_id    =&gt;&quot;ABC0123456789XYZ&quot;,
+                 :number            =&gt; transaction.id,
+                 :date              =&gt; time.strftime('%Y-%m-%d'),
+                 :transaction_amount=&gt;&quot;8.40 USD&quot;,
+                 :total_amount      =&gt;&quot;8.40 USD&quot;,
+                 :service_name      =&gt;&quot;Solo (per month)&quot;
+                 },
+                invoice_data
+                )
+
+    transaction = Transaction.new({
+        :recurring_payment_profile_id =&gt; profile.id,
+        :gateway_reference =&gt; 'CAB0123456789ZYX',
+        :currency =&gt; 'CAD',
+        :amount =&gt; 840,
+        :created_at =&gt; Date.today
+        })
+    transaction.save!
+    assert_raises NotImplementedError do; @sm.get_invoice_data(transaction.id); end
+
+    transaction = Transaction.new({
+        :recurring_payment_profile_id =&gt; profile.id,
+        :gateway_reference =&gt; 'CAB0123456789ZYX',
+        :currency =&gt; 'USD',
+        :amount =&gt; 839,
+        :created_at =&gt; Date.today
+        })
+    transaction.save!
+    assert_raises NotImplementedError do; @sm.get_invoice_data(transaction.id); end
+
+    features = @sm.get_features(subscription_id)
+
+    options = {:card=&gt;credit_card_2}
+    assert @sm.update_possible?(subscription_id, options)
+    @sm.update_subscription(subscription_id, options)
+
+    options = {:card=&gt;credit_card_3, :start_date =&gt; Date.today + 42}
+    assert !@sm.update_possible?(subscription_id, options)
+    @sm.update_subscription(subscription_id, options)
+
+    @sm.unsubscribe(subscription_id)
+    assert_equal 'canceled', Subscription.find_by_id(subscription_id).status
+  end
+
+end</diff>
      <filename>subscription_management/test/remote/subscription_management_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,40 +1,40 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-require 'money'
-
-class SubscriptionManagementTest &lt; Test::Unit::TestCase
-
-  def setup
-    @smc = SubscriptionManagement
-  end
-
-  def test_format_feature
-    feature = {'quantity' =&gt; 5, 'feature' =&gt; {'name'=&gt; 'Quota', 'unit'=&gt; 'Gigabyte'}}
-    assert_equal 'Quota: 5 Gigabytes', @smc.format_feature(feature)
-    feature = {'quantity' =&gt; 1, 'feature' =&gt; {'name'=&gt; 'Quota', 'unit'=&gt; 'Gigabyte'}}
-    assert_equal 'Quota: 1 Gigabyte', @smc.format_feature(feature)
-    feature = {'quantity' =&gt; 0, 'feature' =&gt; {'name'=&gt; 'Quota', 'unit'=&gt; 'Gigabyte'}}
-    assert_equal 'Quota: Unlimited', @smc.format_feature(feature)
-    feature = {'quantity' =&gt; 2, 'feature' =&gt; {'name'=&gt; 'Users'}}
-    assert_equal 'Users: 2', @smc.format_feature(feature)
-    feature = {'feature' =&gt; {'name'=&gt; 'SSL Encryption'}}
-    assert_equal 'SSL Encryption', @smc.format_feature(feature)
-  end
-
-  def test_format_periodicity
-    assert_equal 'twice a week', @smc.format_periodicity('0.5 w') 
-    assert_equal 'each month', @smc.format_periodicity('1 m')
-    assert_equal 'each 2 years', @smc.format_periodicity('2 y')
-    assert_equal 'each 42 days', @smc.format_periodicity('42 d')
-    assert_raise ArgumentError do; x = @smc.format_periodicity('random'); end;
-  end
-  
-  def test_get_taxes_id
-    taxes = {&quot;ca&quot;=&gt;{&quot;country&quot;=&gt;&quot;CA&quot;, &quot;taxes&quot;=&gt;[{&quot;tax&quot;=&gt;{&quot;name&quot;=&gt;&quot;Goods and Services Tax&quot;}, &quot;rate&quot;=&gt;0.05}], &quot;state&quot;=&gt;&quot;*&quot;},
-             &quot;us_ca&quot;=&gt;{&quot;country&quot;=&gt;&quot;US&quot;, &quot;taxes&quot;=&gt;[{&quot;tax&quot;=&gt;{&quot;name&quot;=&gt;&quot;Sample tax&quot;}, &quot;rate&quot;=&gt;0.2}], &quot;state&quot;=&gt;&quot;CA&quot;}}
-    assert_equal 'ca', @smc.get_taxes_id(taxes, 'CA', 'ON')
-    assert_equal 'us_ca', @smc.get_taxes_id(taxes, 'US', 'CA')
-    assert_raise StandardError do; x = @smc.get_taxes_id(taxes, 'US', 'NY'); end
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+require 'money'
+
+class SubscriptionManagementTest &lt; Test::Unit::TestCase
+
+  def setup
+    @smc = SubscriptionManagement
+  end
+
+  def test_format_feature
+    feature = {'quantity' =&gt; 5, 'feature' =&gt; {'name'=&gt; 'Quota', 'unit'=&gt; 'Gigabyte'}}
+    assert_equal 'Quota: 5 Gigabytes', @smc.format_feature(feature)
+    feature = {'quantity' =&gt; 1, 'feature' =&gt; {'name'=&gt; 'Quota', 'unit'=&gt; 'Gigabyte'}}
+    assert_equal 'Quota: 1 Gigabyte', @smc.format_feature(feature)
+    feature = {'quantity' =&gt; 0, 'feature' =&gt; {'name'=&gt; 'Quota', 'unit'=&gt; 'Gigabyte'}}
+    assert_equal 'Quota: Unlimited', @smc.format_feature(feature)
+    feature = {'quantity' =&gt; 2, 'feature' =&gt; {'name'=&gt; 'Users'}}
+    assert_equal 'Users: 2', @smc.format_feature(feature)
+    feature = {'feature' =&gt; {'name'=&gt; 'SSL Encryption'}}
+    assert_equal 'SSL Encryption', @smc.format_feature(feature)
+  end
+
+  def test_format_periodicity
+    assert_equal 'twice a week', @smc.format_periodicity('0.5 w') 
+    assert_equal 'each month', @smc.format_periodicity('1 m')
+    assert_equal 'each 2 years', @smc.format_periodicity('2 y')
+    assert_equal 'each 42 days', @smc.format_periodicity('42 d')
+    assert_raise ArgumentError do; x = @smc.format_periodicity('random'); end;
+  end
+  
+  def test_get_taxes_id
+    taxes = {&quot;ca&quot;=&gt;{&quot;country&quot;=&gt;&quot;CA&quot;, &quot;taxes&quot;=&gt;[{&quot;tax&quot;=&gt;{&quot;name&quot;=&gt;&quot;Goods and Services Tax&quot;}, &quot;rate&quot;=&gt;0.05}], &quot;state&quot;=&gt;&quot;*&quot;},
+             &quot;us_ca&quot;=&gt;{&quot;country&quot;=&gt;&quot;US&quot;, &quot;taxes&quot;=&gt;[{&quot;tax&quot;=&gt;{&quot;name&quot;=&gt;&quot;Sample tax&quot;}, &quot;rate&quot;=&gt;0.2}], &quot;state&quot;=&gt;&quot;CA&quot;}}
+    assert_equal 'ca', @smc.get_taxes_id(taxes, 'CA', 'ON')
+    assert_equal 'us_ca', @smc.get_taxes_id(taxes, 'US', 'CA')
+    assert_raise StandardError do; x = @smc.get_taxes_id(taxes, 'US', 'NY'); end
+  end
+
+end</diff>
      <filename>subscription_management/test/unit/subscription_management_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,34 +1,34 @@
-
-== Tracker module methods
-Tracker module provides payment profiles local storage capability for simple CRUD
-API RecurringBilling is. As a result, every RecurringBilling action is accompanied by number of Tracker database operations.
-Tracker auto-includes RecurringBilling
-and replaces its create, update, inquiry and delete methods with its own extended implementations while re-aliasing old ones as
-XXX_without_persist. The usual behavior of replacement methods is to execute corresponding old RecurringBilling method and,
-on success, to store given or returned parameters into database. Extending the methods doesn't change the syntax. Also, several
-new methods are added to RecurringBilling class.
-
-=== Updating exising remote payment
-The update method of RecurringBilling is limited by design: if updating payment information on remote gateway is impossible
-with given set of options, update raises Exception (and quits). Given that the main reason of such behavior is that RecurringBilling
-instance methods are isolated from each other payment-wise, Tracker combination of storage and gateway interaction provides an additional
-option to handle such situations. If RecurringBilling returns an Exception (meaning update is impossible), the recurring payment on
-gateway is cancelled and another, with updated options is created instead. For example, that way limitations on changing
-:recurring_options could be overcame.
-
-Two related methods are available for this feature. Both use payment gateway reference ID (+billing_id+) and combined options
-hash (+options+) as parameters. Second parameter may be obtained from usual quad-element structure something like this:
- options = {}
- options[:amount] = amount
- options[:card] = card
- options.update(payment_options)
- options.update(recurring_options)
-To check if recurring payment could be updated by usual RecurringBilling means, can_update? method is used. This check is integrated into
-update_or_recreate method that calls can_update? and then performs traditional update, or deletes and then re-creates the payment via gateway.
-For example:
- ...
- options = {:start_date =&gt; Date + 1337}
- print 'Warning! The billing profile will be re-created} if gateway.can_update?(billing_id, options)
- gateway.update_or_recreate(billing_id, options)
- ...
-Please note that missing but required options for payment re-creation are calculated from database.
+
+== Tracker module methods
+Tracker module provides payment profiles local storage capability for simple CRUD
+API RecurringBilling is. As a result, every RecurringBilling action is accompanied by number of Tracker database operations.
+Tracker auto-includes RecurringBilling
+and replaces its create, update, inquiry and delete methods with its own extended implementations while re-aliasing old ones as
+XXX_without_persist. The usual behavior of replacement methods is to execute corresponding old RecurringBilling method and,
+on success, to store given or returned parameters into database. Extending the methods doesn't change the syntax. Also, several
+new methods are added to RecurringBilling class.
+
+=== Updating exising remote payment
+The update method of RecurringBilling is limited by design: if updating payment information on remote gateway is impossible
+with given set of options, update raises Exception (and quits). Given that the main reason of such behavior is that RecurringBilling
+instance methods are isolated from each other payment-wise, Tracker combination of storage and gateway interaction provides an additional
+option to handle such situations. If RecurringBilling returns an Exception (meaning update is impossible), the recurring payment on
+gateway is cancelled and another, with updated options is created instead. For example, that way limitations on changing
+:recurring_options could be overcame.
+
+Two related methods are available for this feature. Both use payment gateway reference ID (+billing_id+) and combined options
+hash (+options+) as parameters. Second parameter may be obtained from usual quad-element structure something like this:
+ options = {}
+ options[:amount] = amount
+ options[:card] = card
+ options.update(payment_options)
+ options.update(recurring_options)
+To check if recurring payment could be updated by usual RecurringBilling means, can_update? method is used. This check is integrated into
+update_or_recreate method that calls can_update? and then performs traditional update, or deletes and then re-creates the payment via gateway.
+For example:
+ ...
+ options = {:start_date =&gt; Date + 1337}
+ print 'Warning! The billing profile will be re-created} if gateway.can_update?(billing_id, options)
+ gateway.update_or_recreate(billing_id, options)
+ ...
+Please note that missing but required options for payment re-creation are calculated from database.</diff>
      <filename>tracker/lib/recurring_billing_extension.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -1,35 +1,35 @@
-require File.dirname(__FILE__) + '/test_helper'
-
-class RandomRecurringProfileTest &lt; Test::Unit::TestCase
-
-  def setup
-    cred = fixtures(:paypal)
-    assert @gw = RecurringBilling::PaypalGateway.new(cred)
-    @card = credit_card(number='4532130086825928')
-  end
-
-  def test_crud_recurring_payment
-    payment_options = {
-          :subscription_name =&gt; 'Test Subscription 1337',
-          :order =&gt; {:invoice_number =&gt; '407933'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today + 1,
-          :end_date =&gt; Date.today + 290,
-          :interval =&gt; '1m'
-          }
-
-    billing_id = @gw.create_with_persist(Money.us_dollar(15), @card, payment_options=payment_options, recurring_options=recurring_options)
-    print &quot;\n\nCreate:\n&quot;
-    print @gw.last_response.inspect
-    payment_options[:order] = {:invoice_number =&gt; '407934'}
-    @gw.update_with_persist(billing_id, Money.us_dollar(16), @card, payment_options=payment_options)
-    print &quot;\n\nUpdate:\n&quot;
-    print @gw.last_response.inspect
-    @gw.delete_with_persist(billing_id)
-    print &quot;\n\nDelete:\n&quot;
-    print @gw.last_response.inspect
-  end
-
-end
-
+require File.dirname(__FILE__) + '/test_helper'
+
+class RandomRecurringProfileTest &lt; Test::Unit::TestCase
+
+  def setup
+    cred = fixtures(:paypal)
+    assert @gw = RecurringBilling::PaypalGateway.new(cred)
+    @card = credit_card(number='4532130086825928')
+  end
+
+  def test_crud_recurring_payment
+    payment_options = {
+          :subscription_name =&gt; 'Test Subscription 1337',
+          :order =&gt; {:invoice_number =&gt; '407933'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today + 1,
+          :end_date =&gt; Date.today + 290,
+          :interval =&gt; '1m'
+          }
+
+    billing_id = @gw.create_with_persist(Money.us_dollar(15), @card, payment_options=payment_options, recurring_options=recurring_options)
+    print &quot;\n\nCreate:\n&quot;
+    print @gw.last_response.inspect
+    payment_options[:order] = {:invoice_number =&gt; '407934'}
+    @gw.update_with_persist(billing_id, Money.us_dollar(16), @card, payment_options=payment_options)
+    print &quot;\n\nUpdate:\n&quot;
+    print @gw.last_response.inspect
+    @gw.delete_with_persist(billing_id)
+    print &quot;\n\nDelete:\n&quot;
+    print @gw.last_response.inspect
+  end
+
+end
+</diff>
      <filename>tracker/test/recurring_payment_profile.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,68 +1,68 @@
-require File.dirname(__FILE__) + '/../test_helper'
-require &quot;tracker&quot;
-
-class AuthorizeNetGatewayRemoteTest &lt; Test::Unit::TestCase
-
-  def setup
-    credentials = fixtures(:authorize_net)
-    assert @gw = RecurringBilling::AuthorizeNetGateway.new(credentials)
-    @card = credit_card()
-  end
-
-  def test_crud_recurring_payment
-    payment_options = {
-          :subscription_name =&gt; 'Random subscription',
-          :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today,
-          :occurrences =&gt; 10,
-          :interval =&gt; '10d'
-          }
-
-    sum = rand(50000)+120
-    billing_id = @gw.create(Money.us_dollar(sum), @card, payment_options, recurring_options)
-    assert @gw.last_response.success?
-
-    payment_options[:order] = {:invoice_number =&gt; 'ODMX17532'}
-
-    another_sum = rand(50000)+120
-    @gw.update(billing_id, Money.us_dollar(another_sum), @card, payment_options, {})
-    assert @gw.last_response.success?
-
-    assert_raise NotImplementedError do; @gw.inquiry(billing_id); end
-
-    @gw.delete(billing_id)
-    assert @gw.last_response.success?
-    profile = RecurringPaymentProfile.find_by_gateway_reference(billing_id)
-    assert_equal 'deleted', profile.status
-    
-    assert_raise StandardError do;@gw.update(billing_id, Money.us_dollar(another_sum), @card, payment_options, {});end;
-  end
-
-  def test_update_or_recreate
-    payment_options = {
-          :subscription_name =&gt; 'Random subscription',
-          :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today,
-          :occurrences =&gt; 10,
-          :interval =&gt; '10d'
-          }
-
-    sum = rand(50000)+120
-    billing_id = @gw.create(Money.us_dollar(sum), @card, payment_options, recurring_options)
-    assert @gw.last_response.success?
-
-    payment_options[:order] = {:invoice_number =&gt; 'ODMX17532'}
-
-    another_sum = rand(50000)+120
-    @gw.update_or_recreate(billing_id, {:amount =&gt; Money.us_dollar(another_sum)})
-    assert @gw.last_response.success?
-
-    @gw.update_or_recreate(billing_id, {:card =&gt; @card, :start_date =&gt; Date.new(2009, 7, 8)})
-    assert @gw.last_response.success?
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+require &quot;tracker&quot;
+
+class AuthorizeNetGatewayRemoteTest &lt; Test::Unit::TestCase
+
+  def setup
+    credentials = fixtures(:authorize_net)
+    assert @gw = RecurringBilling::AuthorizeNetGateway.new(credentials)
+    @card = credit_card()
+  end
+
+  def test_crud_recurring_payment
+    payment_options = {
+          :subscription_name =&gt; 'Random subscription',
+          :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today,
+          :occurrences =&gt; 10,
+          :interval =&gt; '10d'
+          }
+
+    sum = rand(50000)+120
+    billing_id = @gw.create(Money.us_dollar(sum), @card, payment_options, recurring_options)
+    assert @gw.last_response.success?
+
+    payment_options[:order] = {:invoice_number =&gt; 'ODMX17532'}
+
+    another_sum = rand(50000)+120
+    @gw.update(billing_id, Money.us_dollar(another_sum), @card, payment_options, {})
+    assert @gw.last_response.success?
+
+    assert_raise NotImplementedError do; @gw.inquiry(billing_id); end
+
+    @gw.delete(billing_id)
+    assert @gw.last_response.success?
+    profile = RecurringPaymentProfile.find_by_gateway_reference(billing_id)
+    assert_equal 'deleted', profile.status
+    
+    assert_raise StandardError do;@gw.update(billing_id, Money.us_dollar(another_sum), @card, payment_options, {});end;
+  end
+
+  def test_update_or_recreate
+    payment_options = {
+          :subscription_name =&gt; 'Random subscription',
+          :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today,
+          :occurrences =&gt; 10,
+          :interval =&gt; '10d'
+          }
+
+    sum = rand(50000)+120
+    billing_id = @gw.create(Money.us_dollar(sum), @card, payment_options, recurring_options)
+    assert @gw.last_response.success?
+
+    payment_options[:order] = {:invoice_number =&gt; 'ODMX17532'}
+
+    another_sum = rand(50000)+120
+    @gw.update_or_recreate(billing_id, {:amount =&gt; Money.us_dollar(another_sum)})
+    assert @gw.last_response.success?
+
+    @gw.update_or_recreate(billing_id, {:card =&gt; @card, :start_date =&gt; Date.new(2009, 7, 8)})
+    assert @gw.last_response.success?
+  end
+
+end</diff>
      <filename>tracker/test/remote/authorize_net_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,115 +1,115 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-require &quot;mocha&quot;
-require &quot;tracker&quot;
-
-class PaypalRemoteTest &lt; Test::Unit::TestCase
-
-  def setup
-    cred = fixtures(:paypal)
-    assert @gw = RecurringBilling::PaypalGateway.new(cred)
-    @card = credit_card()
-    @card2 = credit_card('4929838635250031', {:first_name =&gt; 'James', :last_name =&gt; 'Lueser'})
-    @card_bogus = credit_card(&quot;ISMELLLIKEBOGUS&quot;)
-  end
-
-  def test_inquiry_updates_tracker
-    payment_options = {
-          :subscription_name =&gt; 'Test Subscription 1337',
-          :order =&gt; {:invoice_number =&gt; '407933'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today + 1,
-          :end_date =&gt; Date.today + 290,
-          :interval =&gt; '1m'
-          }
-
-    billing_id = @gw.create(Money.us_dollar(15), @card, payment_options=payment_options, recurring_options=recurring_options)
-    assert @gw.last_response.success?
-
-    profile = RecurringPaymentProfile.find_by_gateway_reference(billing_id)
-    assert_equal 'active', profile.status
-    assert_not_equal -1, profile.outstanding_balance
-    assert_not_equal -1, profile.complete_payments_count
-    assert_not_equal -1, profile.failed_payments_count
-    assert_not_equal -1, profile.remaining_payments_count
-
-    # Mock result of original inquire methods
-    result_mock = {'profile_status'         =&gt; 'verified',
-                'outstanding_balance'    =&gt; ::Money.new(-100),
-                'number_cycles_completed'=&gt; -1,
-                'failed_payment_count'   =&gt; -1,
-                'number_cycles_remaining'=&gt; -1}
-
-    @gw.methods.include? :inquiry_without_persist
-    @gw.expects(:inquiry_without_persist).returns(result_mock)
-    result = @gw.inquiry(billing_id)
-    assert @gw.last_response.success?
-
-    assert_equal result_mock, result
-
-    # Get profile and check whether data is updated
-    profile = RecurringPaymentProfile.find_by_gateway_reference(billing_id)
-    assert_equal 'verified', profile.status
-    assert_equal -100, profile.outstanding_balance
-    assert_equal -1, profile.complete_payments_count
-    assert_equal -1, profile.failed_payments_count
-    assert_equal -1, profile.remaining_payments_count
-  end
-
-  def test_create_update_failure
-      payment_options = {
-            :subscription_name =&gt; 'Unsuccessful payment',
-            :order =&gt; {:invoice_number =&gt; '032895'}
-            }
-      recurring_options = {
-            :start_date =&gt; Date.today + 1,
-            :occurrences =&gt; 402,
-            :interval =&gt; '1w'
-            }
-
-      new_recurring_options = {
-            :pay_on_day_x =&gt; 3
-            }
-
-      token_sum = rand(50000)+120
-      @gw.create(Money.us_dollar(token_sum), @card_bogus, payment_options=payment_options, recurring_options=recurring_options)
-      assert !@gw.last_response.success?
-      assert RecurringPaymentProfile.find_by_net_amount(Money.us_dollar(token_sum).cents).nil?
-
-      new_token_sum = rand(50000)+120
-      billing_id = @gw.create(Money.us_dollar(new_token_sum), @card, payment_options=payment_options, recurring_options=recurring_options)
-      assert @gw.last_response.success?
-      assert_equal profile = RecurringPaymentProfile.find_by_net_amount(Money.us_dollar(new_token_sum).cents), RecurringPaymentProfile.find_by_gateway_reference(billing_id)
-
-      another_token_sum = rand(50000)+120
-      @gw.update(billing_id, Money.us_dollar(another_token_sum), @card, {}, new_recurring_options)
-      assert_not_equal profile.updated_at, (profile2 = RecurringPaymentProfile.find_by_gateway_reference(billing_id)).updated_at #meaning the profile hadn't been updated
-      assert_equal profile2.amount, Money.us_dollar(another_token_sum).cents
-
-
-      @gw.update(billing_id, Money.us_dollar(new_token_sum), @card_bogus, {}, {})
-      assert_equal profile2.updated_at, RecurringPaymentProfile.find_by_gateway_reference(billing_id).updated_at #meaning the profile hadn't been updated
-  end
-
-  def test_update_or_create
-    payment_options = {
-          :subscription_name =&gt; 'Random subscription',
-          :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
-          }
-    recurring_options = {
-          :start_date =&gt; Date.today,
-          :occurrences =&gt; 10,
-          :interval =&gt; '10 w'
-          }
-
-    sum = rand(50000)+120
-    billing_id = @gw.create(Money.us_dollar(sum), @card, payment_options, recurring_options)
-    assert @gw.last_response.success?
-
-    another_sum = rand(50000)+120
-    @gw.update_or_recreate(billing_id, {:card =&gt; @card2, :occurrences =&gt; 20})
-    assert @gw.last_response.success?
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+require &quot;mocha&quot;
+require &quot;tracker&quot;
+
+class PaypalRemoteTest &lt; Test::Unit::TestCase
+
+  def setup
+    cred = fixtures(:paypal)
+    assert @gw = RecurringBilling::PaypalGateway.new(cred)
+    @card = credit_card()
+    @card2 = credit_card('4929838635250031', {:first_name =&gt; 'James', :last_name =&gt; 'Lueser'})
+    @card_bogus = credit_card(&quot;ISMELLLIKEBOGUS&quot;)
+  end
+
+  def test_inquiry_updates_tracker
+    payment_options = {
+          :subscription_name =&gt; 'Test Subscription 1337',
+          :order =&gt; {:invoice_number =&gt; '407933'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today + 1,
+          :end_date =&gt; Date.today + 290,
+          :interval =&gt; '1m'
+          }
+
+    billing_id = @gw.create(Money.us_dollar(15), @card, payment_options=payment_options, recurring_options=recurring_options)
+    assert @gw.last_response.success?
+
+    profile = RecurringPaymentProfile.find_by_gateway_reference(billing_id)
+    assert_equal 'active', profile.status
+    assert_not_equal -1, profile.outstanding_balance
+    assert_not_equal -1, profile.complete_payments_count
+    assert_not_equal -1, profile.failed_payments_count
+    assert_not_equal -1, profile.remaining_payments_count
+
+    # Mock result of original inquire methods
+    result_mock = {'profile_status'         =&gt; 'verified',
+                'outstanding_balance'    =&gt; ::Money.new(-100),
+                'number_cycles_completed'=&gt; -1,
+                'failed_payment_count'   =&gt; -1,
+                'number_cycles_remaining'=&gt; -1}
+
+    @gw.methods.include? :inquiry_without_persist
+    @gw.expects(:inquiry_without_persist).returns(result_mock)
+    result = @gw.inquiry(billing_id)
+    assert @gw.last_response.success?
+
+    assert_equal result_mock, result
+
+    # Get profile and check whether data is updated
+    profile = RecurringPaymentProfile.find_by_gateway_reference(billing_id)
+    assert_equal 'verified', profile.status
+    assert_equal -100, profile.outstanding_balance
+    assert_equal -1, profile.complete_payments_count
+    assert_equal -1, profile.failed_payments_count
+    assert_equal -1, profile.remaining_payments_count
+  end
+
+  def test_create_update_failure
+      payment_options = {
+            :subscription_name =&gt; 'Unsuccessful payment',
+            :order =&gt; {:invoice_number =&gt; '032895'}
+            }
+      recurring_options = {
+            :start_date =&gt; Date.today + 1,
+            :occurrences =&gt; 402,
+            :interval =&gt; '1w'
+            }
+
+      new_recurring_options = {
+            :pay_on_day_x =&gt; 3
+            }
+
+      token_sum = rand(50000)+120
+      @gw.create(Money.us_dollar(token_sum), @card_bogus, payment_options=payment_options, recurring_options=recurring_options)
+      assert !@gw.last_response.success?
+      assert RecurringPaymentProfile.find_by_net_amount(Money.us_dollar(token_sum).cents).nil?
+
+      new_token_sum = rand(50000)+120
+      billing_id = @gw.create(Money.us_dollar(new_token_sum), @card, payment_options=payment_options, recurring_options=recurring_options)
+      assert @gw.last_response.success?
+      assert_equal profile = RecurringPaymentProfile.find_by_net_amount(Money.us_dollar(new_token_sum).cents), RecurringPaymentProfile.find_by_gateway_reference(billing_id)
+
+      another_token_sum = rand(50000)+120
+      @gw.update(billing_id, Money.us_dollar(another_token_sum), @card, {}, new_recurring_options)
+      assert_not_equal profile.updated_at, (profile2 = RecurringPaymentProfile.find_by_gateway_reference(billing_id)).updated_at #meaning the profile hadn't been updated
+      assert_equal profile2.amount, Money.us_dollar(another_token_sum).cents
+
+
+      @gw.update(billing_id, Money.us_dollar(new_token_sum), @card_bogus, {}, {})
+      assert_equal profile2.updated_at, RecurringPaymentProfile.find_by_gateway_reference(billing_id).updated_at #meaning the profile hadn't been updated
+  end
+
+  def test_update_or_create
+    payment_options = {
+          :subscription_name =&gt; 'Random subscription',
+          :order =&gt; {:invoice_number =&gt; 'ODMX31337'}
+          }
+    recurring_options = {
+          :start_date =&gt; Date.today,
+          :occurrences =&gt; 10,
+          :interval =&gt; '10 w'
+          }
+
+    sum = rand(50000)+120
+    billing_id = @gw.create(Money.us_dollar(sum), @card, payment_options, recurring_options)
+    assert @gw.last_response.success?
+
+    another_sum = rand(50000)+120
+    @gw.update_or_recreate(billing_id, {:card =&gt; @card2, :occurrences =&gt; 20})
+    assert @gw.last_response.success?
+  end
+
+end</diff>
      <filename>tracker/test/remote/paypal_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,62 +1,62 @@
-require File.dirname(__FILE__) + '/../test_helper'
-
-require 'money'
-
-class RecurringPaymentProfileTest &lt; Test::Unit::TestCase
-
-  def setup
-    @profile = ::RecurringPaymentProfile.new
-  end
-
-  def test_net_money_assigns
-    @profile.net_money=Money.new(333, currency='CAD')
-    assert_equal 333, @profile.net_amount
-    assert_equal 'CAD', @profile.currency
-  end
-
-  def test_taxes_money_assigns
-    @profile.taxes_money=Money.new(444, currency='RUR')
-    assert_equal 444, @profile.taxes_amount
-    assert_equal 'RUR', @profile.currency
-  end
-
-  def test_net_money_fails
-    @profile.taxes_money=Money.new(333, currency='CAD')
-    assert_raise ArgumentError do; @profile.net_money=Money.new(444, currency='RUR'); end
-  end
-
-  def test_taxes_money_fails
-    @profile.net_money=Money.new(333, currency='CAD')
-    assert_raise ArgumentError do; @profile.taxes_money=Money.new(444, currency='RUR'); end
-  end
-
-  def test_mask_card_number
-    assert_equal 'abba', @profile.mask_card_number('abba')
-    assert_equal 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXched', @profile.mask_card_number('whatisthethingthatcannotbetouched')
-  end
-
-  def test_parse_and_set_card
-    card = credit_card(number='1111111111', options={:type =&gt; 'master', :year =&gt; 2003, :month =&gt; 3, :first_name =&gt; 'Name', :last_name =&gt; 'Surname'})
-    @profile.parse_and_set_card(card)
-    assert_equal 'master', @profile.card_type
-    assert_equal 'Name Surname, MASTER, XXXXXX1111, exp. 2003-03', @profile.card_owner_memo
-  end
-
-  def test_parse_and_set_card_with_hint
-    card = credit_card(number='1111111111', options={:type =&gt; 'master'})
-    @profile.parse_and_set_card(card, 'this is my hint')
-    assert_equal 'master', @profile.card_type
-    assert_equal 'this is my hint', @profile.card_owner_memo
-  end
-
-  def test_card_exp_date
-    card = credit_card(number='4242424242424242', options={:year =&gt; 2001, :month =&gt; 1})
-    assert_equal '2001-01', @profile.card_exp_date(card)
-  end
-
-  def test_no_obsolete_fields
-    assert_raise NoMethodError do; @profile.payment_offset = 0; end
-    assert_raise NoMethodError do; @profile.payments_start_on = Date.today; end
-  end
-
-end
+require File.dirname(__FILE__) + '/../test_helper'
+
+require 'money'
+
+class RecurringPaymentProfileTest &lt; Test::Unit::TestCase
+
+  def setup
+    @profile = ::RecurringPaymentProfile.new
+  end
+
+  def test_net_money_assigns
+    @profile.net_money=Money.new(333, currency='CAD')
+    assert_equal 333, @profile.net_amount
+    assert_equal 'CAD', @profile.currency
+  end
+
+  def test_taxes_money_assigns
+    @profile.taxes_money=Money.new(444, currency='RUR')
+    assert_equal 444, @profile.taxes_amount
+    assert_equal 'RUR', @profile.currency
+  end
+
+  def test_net_money_fails
+    @profile.taxes_money=Money.new(333, currency='CAD')
+    assert_raise ArgumentError do; @profile.net_money=Money.new(444, currency='RUR'); end
+  end
+
+  def test_taxes_money_fails
+    @profile.net_money=Money.new(333, currency='CAD')
+    assert_raise ArgumentError do; @profile.taxes_money=Money.new(444, currency='RUR'); end
+  end
+
+  def test_mask_card_number
+    assert_equal 'abba', @profile.mask_card_number('abba')
+    assert_equal 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXched', @profile.mask_card_number('whatisthethingthatcannotbetouched')
+  end
+
+  def test_parse_and_set_card
+    card = credit_card(number='1111111111', options={:type =&gt; 'master', :year =&gt; 2003, :month =&gt; 3, :first_name =&gt; 'Name', :last_name =&gt; 'Surname'})
+    @profile.parse_and_set_card(card)
+    assert_equal 'master', @profile.card_type
+    assert_equal 'Name Surname, MASTER, XXXXXX1111, exp. 2003-03', @profile.card_owner_memo
+  end
+
+  def test_parse_and_set_card_with_hint
+    card = credit_card(number='1111111111', options={:type =&gt; 'master'})
+    @profile.parse_and_set_card(card, 'this is my hint')
+    assert_equal 'master', @profile.card_type
+    assert_equal 'this is my hint', @profile.card_owner_memo
+  end
+
+  def test_card_exp_date
+    card = credit_card(number='4242424242424242', options={:year =&gt; 2001, :month =&gt; 1})
+    assert_equal '2001-01', @profile.card_exp_date(card)
+  end
+
+  def test_no_obsolete_fields
+    assert_raise NoMethodError do; @profile.payment_offset = 0; end
+    assert_raise NoMethodError do; @profile.payments_start_on = Date.today; end
+  end
+
+end</diff>
      <filename>tracker/test/unit/recurring_payment_profile_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a5380aaa8d534cd61554e41abccd6a71338a354d</id>
    </parent>
  </parents>
  <author>
    <name>unknown</name>
    <email>me@alexlebedev.com</email>
  </author>
  <url>http://github.com/itteco/service_merchant/commit/9dad2a30565c5e7fdb6844058c1e6be539931496</url>
  <id>9dad2a30565c5e7fdb6844058c1e6be539931496</id>
  <committed-date>2008-10-16T06:17:33-07:00</committed-date>
  <authored-date>2008-10-16T06:17:18-07:00</authored-date>
  <message>[Test] Fixed all line endings</message>
  <tree>a6e3eff09042f90b0d7411df52801f47bc128c36</tree>
  <committer>
    <name>unknown</name>
    <email>me@alexlebedev.com</email>
  </committer>
</commit>
