<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/ri_cal/component/non_standard.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,25 @@
+=== 0.8.0 - 11 August 2009
+
+  Minor Version Bump - There is a small potentially breaking change see section on treatment of X-properties below
+
+  * Unknown Components
+
+  Starting with version 0.8.0 RiCal will parse calendars and components which contain nonstandard components.
+
+  For example, there was a short-lived proposal to extend RFC2445 with a new VVENUE component which would hold structured information about the location of an event.  This proposal was never accepted and was withdrawn, but there is icalendar data in the wild which contains VVENUE components.
+
+  Prior to version 0.8.0, RiCal would raise an exception if unknown component types were encountered.  Starting with version 0.8.0 RiCal will 'parse' such components and create instances of NonStandard component to represent them.  Since the actual format of unknown components is not known by RiCal, the NonStandard component will simply save the data lines between the BEGIN:xxx and END:xxx lines, (where xxx is the non-standard component name, e.g. VVENUE).  If the calendar is re-exported the original lines will be replayed.
+
+  * Change to treatment of X-properties
+
+  RFC2445 allows 'non-standard' or experimental properties which property-names beginning with X.  RiCal always supported parsing these.
+
+  The standard properties are specified as to how many times they can occur within a particular component.  For singly occurring properties RiCal returns a single property object, while for properties which can occur multiple times RiCal returns an array of property objects.
+
+  While implementing NonStandard properties, I realized that X-properties were being assumed to be singly occurring. But this isn't necessarily true.  So starting with 0.8.0 the X-properties are represented by an array of property objects.
+
+  THIS MAY BREAK SOME APPLICATIONS, but the adaptation should be easy.
+
 === 0.7.7 - 6 August 2009
    - No changes other than a version number bump.  github seems to have failed to notice the commit of v0.7.6
      and didn't build the gem.  Hopefully it will notice this one.</diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -24,6 +24,7 @@ lib/ri_cal/component/calendar.rb
 lib/ri_cal/component/event.rb
 lib/ri_cal/component/freebusy.rb
 lib/ri_cal/component/journal.rb
+lib/ri_cal/component/non_standard.rb
 lib/ri_cal/component/t_z_info_timezone.rb
 lib/ri_cal/component/timezone.rb
 lib/ri_cal/component/timezone/daylight_period.rb</diff>
      <filename>Manifest.txt</filename>
    </modified>
    <modified>
      <diff>@@ -339,6 +339,24 @@ or another Enumerable method (RiCal::OccurrenceEnumerator includes Enumerable),
 	   #....
 	end
 
+=== Unknown Components
+
+Starting with version 0.8.0 RiCal will parse calendars and components which contain nonstandard components.
+
+For example, there was a short-lived proposal to extend RFC2445 with a new VVENUE component which would hold structured information about the location of an event.  This proposal was never accepted and was withdrawn, but there is icalendar data in the wild which contains VVENUE components.
+
+Prior to version 0.8.0, RiCal would raise an exception if unknown component types were encountered.  Starting with version 0.8.0 RiCal will 'parse' such components and create instances of NonStandard component to represent them.  Since the actual format of unknown components is not known by RiCal, the NonStandard component will simply save the data lines between the BEGIN:xxx and END:xxx lines, (where xxx is the non-standard component name, e.g. VVENUE).  If the calendar is re-exported the original lines will be replayed.
+
+=== Change to treatment of X-properties
+
+RFC2445 allows 'non-standard' or experimental properties which property-names beginning with X.  RiCal always supported parsing these.
+
+The standard properties are specified as to how many times they can occur within a particular component.  For singly occurring properties RiCal returns a single property object, while for properties which can occur multiple times RiCal returns an array of property objects.
+
+While implementing NonStandard properties, I realized that X-properties were being assumed to be singly occurring. But this isn't necessarily true.  So starting with 0.8.0 the X-properties are represented by an array of property objects.
+
+THIS MAY BREAK SOME APPLICATIONS, but the adaptation should be easy.
+
 == REQUIREMENTS:
 
 * RiCal requires that an implementation of TZInfo::Timezone. This requirement may be satisfied by either the TzInfo gem,</diff>
      <filename>README.txt</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,7 @@ module RiCal
   autoload :OccurrenceEnumerator, &quot;#{my_dir}/ri_cal/occurrence_enumerator.rb&quot;
   
   # :stopdoc:
-  VERSION = '0.7.7'
+  VERSION = '0.8.0'
   LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
   PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
 </diff>
      <filename>lib/ri_cal.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,7 @@ module RiCal
 
     attr_accessor :imported #:nodoc:
 
-    def initialize(parent=nil, &amp;init_block) #:nodoc:
+    def initialize(parent=nil, entity_name = nil, &amp;init_block) #:nodoc:
       @parent = parent
       if block_given?
         if init_block.arity == 1
@@ -81,8 +81,8 @@ module RiCal
       {}
     end
 
-    def self.from_parser(parser, parent) #:nodoc:
-      entity = self.new(parent)
+    def self.from_parser(parser, parent, entity_name) #:nodoc:
+      entity = self.new(parent, entity_name)
       entity.imported = true
       line = parser.next_separated_line
       while parser.still_in(entity_name, line)
@@ -142,12 +142,12 @@ module RiCal
     # return a hash of any extended properties, (i.e. those with a property name starting with &quot;X-&quot;
     # representing an extension to the RFC 2445 specification)
     def x_properties
-      @x_properties ||= {}
+      @x_properties ||= Hash.new {|h,k| h[k] = []}
     end
 
     # Add a n extended property
     def add_x_property(name, prop)
-      x_properties[name] = prop
+      x_properties[name] &lt;&lt; prop
     end
 
     def method_missing(selector, *args, &amp;b) #:nodoc:
@@ -200,8 +200,10 @@ module RiCal
     end
 
     def export_x_properties_to(export_stream) #:nodoc:
-      x_properties.each do |name, prop|
-        export_stream.puts(&quot;#{name}:#{prop}&quot;)
+      x_properties.each do |name, props|
+        props.each do | prop |
+          export_stream.puts(&quot;#{name}:#{prop}&quot;)
+        end
       end
     end
 </diff>
      <filename>lib/ri_cal/component.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,7 @@ module RiCal
       include RiCal::Properties::Calendar
       attr_reader :tz_source #:nodoc:
 
-      def initialize(parent=nil, &amp;init_block) #:nodoc:
+      def initialize(parent=nil,entity_name = nil, &amp;init_block) #:nodoc:
         @tz_source = 'TZINFO' # Until otherwise told
         super
       end
@@ -239,6 +239,11 @@ module RiCal
         export_subcomponent_to(export_stream, todos)
         export_subcomponent_to(export_stream, journals)
         export_subcomponent_to(export_stream, freebusys)
+        subcomponents.each do |key, value|
+          unless %{VEVENT VTODO VJOURNAL VFREEBUSYS}.include?(key)
+            export_subcomponent_to(export_stream, value)
+          end
+        end
         export_stream.puts(&quot;END:VCALENDAR&quot;)
         if to
           nil</diff>
      <filename>lib/ri_cal/component/calendar.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,7 @@ module RiCal
   #- All rights reserved. Refer to the file README.txt for the license
   #
   class Parser # :nodoc:
+    attr_reader :last_line_str #:nodoc:
     def next_line #:nodoc:
       result = nil
       begin
@@ -59,11 +60,12 @@ module RiCal
     def separate_line(string) #:nodoc:
       match = string.match(/^([^;:]*)(.*)$/)
       name = match[1]
+      @last_line_str = string
       params, value = *Parser.params_and_value(match[2])
       {
         :name =&gt; name,
         :params =&gt; params,
-        :value =&gt; value
+        :value =&gt; value,
       }
     end
 
@@ -97,7 +99,8 @@ module RiCal
       result = []
       while start_line = next_line
         @parent_stack = []
-        result &lt;&lt; parse_one(start_line, nil)
+        component = parse_one(start_line, nil)
+        result &lt;&lt; component if component
       end
       result
     end
@@ -112,27 +115,28 @@ module RiCal
         first_line = separate_line(start)
       end
       invalid unless first_line[:name] == &quot;BEGIN&quot;
-      result = case first_line[:value]
+      entity_name = first_line[:value]
+      result = case entity_name
       when &quot;VCALENDAR&quot;
-        RiCal::Component::Calendar.from_parser(self, parent_component)
+        RiCal::Component::Calendar.from_parser(self, parent_component, entity_name)
       when &quot;VEVENT&quot;
-        RiCal::Component::Event.from_parser(self, parent_component)
+        RiCal::Component::Event.from_parser(self, parent_component, entity_name)
       when &quot;VTODO&quot;
-        RiCal::Component::Todo.from_parser(self, parent_component)
+        RiCal::Component::Todo.from_parser(self, parent_component, entity_name)
       when &quot;VJOURNAL&quot;
-        RiCal::Component::Journal.from_parser(self, parent_component)
+        RiCal::Component::Journal.from_parser(self, parent_component, entity_name)
       when &quot;VFREEBUSY&quot;
-        RiCal::Component::Freebusy.from_parser(self, parent_component)
+        RiCal::Component::Freebusy.from_parser(self, parent_component, entity_name)
       when &quot;VTIMEZONE&quot;
-        RiCal::Component::Timezone.from_parser(self, parent_component)
+        RiCal::Component::Timezone.from_parser(self, parent_component, entity_name)
       when &quot;VALARM&quot;
-        RiCal::Component::Alarm.from_parser(self, parent_component)
+        RiCal::Component::Alarm.from_parser(self, parent_component, entity_name)
       when &quot;DAYLIGHT&quot;
-        RiCal::Component::Timezone::DaylightPeriod.from_parser(self, parent_component)
+        RiCal::Component::Timezone::DaylightPeriod.from_parser(self, parent_component, entity_name)
       when &quot;STANDARD&quot;
-        RiCal::Component::Timezone::StandardPeriod.from_parser(self, parent_component)
+        RiCal::Component::Timezone::StandardPeriod.from_parser(self, parent_component, entity_name)
       else
-        invalid
+        RiCal::Component::NonStandard.from_parser(self, parent_component, entity_name)
       end
       @parent_stack.pop
       result</diff>
      <filename>lib/ri_cal/parser.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,11 +2,11 @@
 
 Gem::Specification.new do |s|
   s.name = %q{ri_cal}
-  s.version = &quot;0.7.7&quot;
+  s.version = &quot;0.8.0&quot;
 
   s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
   s.authors = [&quot;author=Rick DeNatale&quot;]
-  s.date = %q{2009-08-06}
+  s.date = %q{2009-08-11}
   s.default_executable = %q{ri_cal}
   s.description = %q{A new Ruby implementation of RFC2445 iCalendar.
 
@@ -19,7 +19,7 @@ A Google group for discussion of this library has been set up http://groups.goog
   s.email = [&quot;rick.denatale@gmail.com&quot;]
   s.executables = [&quot;ri_cal&quot;]
   s.extra_rdoc_files = [&quot;History.txt&quot;, &quot;Manifest.txt&quot;, &quot;README.txt&quot;, &quot;copyrights.txt&quot;, &quot;docs/draft-ietf-calsify-2446bis-08.txt&quot;, &quot;docs/draft-ietf-calsify-rfc2445bis-09.txt&quot;, &quot;docs/incrementers.txt&quot;]
-  s.files = [&quot;History.txt&quot;, &quot;Manifest.txt&quot;, &quot;README.txt&quot;, &quot;Rakefile&quot;, &quot;bin/ri_cal&quot;, &quot;component_attributes/alarm.yml&quot;, &quot;component_attributes/calendar.yml&quot;, &quot;component_attributes/component_property_defs.yml&quot;, &quot;component_attributes/event.yml&quot;, &quot;component_attributes/freebusy.yml&quot;, &quot;component_attributes/journal.yml&quot;, &quot;component_attributes/timezone.yml&quot;, &quot;component_attributes/timezone_period.yml&quot;, &quot;component_attributes/todo.yml&quot;, &quot;copyrights.txt&quot;, &quot;docs/draft-ietf-calsify-2446bis-08.txt&quot;, &quot;docs/draft-ietf-calsify-rfc2445bis-09.txt&quot;, &quot;docs/incrementers.txt&quot;, &quot;docs/rfc2445.pdf&quot;, &quot;lib/ri_cal.rb&quot;, &quot;lib/ri_cal/component.rb&quot;, &quot;lib/ri_cal/component/alarm.rb&quot;, &quot;lib/ri_cal/component/calendar.rb&quot;, &quot;lib/ri_cal/component/event.rb&quot;, &quot;lib/ri_cal/component/freebusy.rb&quot;, &quot;lib/ri_cal/component/journal.rb&quot;, &quot;lib/ri_cal/component/t_z_info_timezone.rb&quot;, &quot;lib/ri_cal/component/timezone.rb&quot;, &quot;lib/ri_cal/component/timezone/daylight_period.rb&quot;, &quot;lib/ri_cal/component/timezone/standard_period.rb&quot;, &quot;lib/ri_cal/component/timezone/timezone_period.rb&quot;, &quot;lib/ri_cal/component/todo.rb&quot;, &quot;lib/ri_cal/core_extensions.rb&quot;, &quot;lib/ri_cal/core_extensions/array.rb&quot;, &quot;lib/ri_cal/core_extensions/array/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/date.rb&quot;, &quot;lib/ri_cal/core_extensions/date/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/date_time.rb&quot;, &quot;lib/ri_cal/core_extensions/date_time/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/object.rb&quot;, &quot;lib/ri_cal/core_extensions/object/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/string.rb&quot;, &quot;lib/ri_cal/core_extensions/string/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/time.rb&quot;, &quot;lib/ri_cal/core_extensions/time/calculations.rb&quot;, &quot;lib/ri_cal/core_extensions/time/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/time/tzid_access.rb&quot;, &quot;lib/ri_cal/core_extensions/time/week_day_predicates.rb&quot;, &quot;lib/ri_cal/fast_date_time.rb&quot;, &quot;lib/ri_cal/floating_timezone.rb&quot;, &quot;lib/ri_cal/invalid_property_value.rb&quot;, &quot;lib/ri_cal/invalid_timezone_identifer.rb&quot;, &quot;lib/ri_cal/occurrence_enumerator.rb&quot;, &quot;lib/ri_cal/occurrence_period.rb&quot;, &quot;lib/ri_cal/parser.rb&quot;, &quot;lib/ri_cal/properties/alarm.rb&quot;, &quot;lib/ri_cal/properties/calendar.rb&quot;, &quot;lib/ri_cal/properties/event.rb&quot;, &quot;lib/ri_cal/properties/freebusy.rb&quot;, &quot;lib/ri_cal/properties/journal.rb&quot;, &quot;lib/ri_cal/properties/timezone.rb&quot;, &quot;lib/ri_cal/properties/timezone_period.rb&quot;, &quot;lib/ri_cal/properties/todo.rb&quot;, &quot;lib/ri_cal/property_value.rb&quot;, &quot;lib/ri_cal/property_value/array.rb&quot;, &quot;lib/ri_cal/property_value/cal_address.rb&quot;, &quot;lib/ri_cal/property_value/date.rb&quot;, &quot;lib/ri_cal/property_value/date_time.rb&quot;, &quot;lib/ri_cal/property_value/date_time/additive_methods.rb&quot;, &quot;lib/ri_cal/property_value/date_time/time_machine.rb&quot;, &quot;lib/ri_cal/property_value/date_time/timezone_support.rb&quot;, &quot;lib/ri_cal/property_value/duration.rb&quot;, &quot;lib/ri_cal/property_value/geo.rb&quot;, &quot;lib/ri_cal/property_value/integer.rb&quot;, &quot;lib/ri_cal/property_value/occurrence_list.rb&quot;, &quot;lib/ri_cal/property_value/period.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/enumerator.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/numbered_span.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_day.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/validations.rb&quot;, &quot;lib/ri_cal/property_value/text.rb&quot;, &quot;lib/ri_cal/property_value/uri.rb&quot;, &quot;lib/ri_cal/property_value/utc_offset.rb&quot;, &quot;lib/ri_cal/required_timezones.rb&quot;, &quot;performance/paris_eastern/subject.rb&quot;, &quot;performance/penultimate_weekday/subject.rb&quot;, &quot;performance/psm_big_enum/ical.ics&quot;, &quot;performance/psm_big_enum/subject.rb&quot;, &quot;performance/utah_cycling/subject.rb&quot;, &quot;ri_cal.gemspec&quot;, &quot;sample_ical_files/from_ical_dot_app/test1.ics&quot;, &quot;script/benchmark_subject&quot;, &quot;script/console&quot;, &quot;script/destroy&quot;, &quot;script/generate&quot;, &quot;script/profile_subject&quot;, &quot;script/txt2html&quot;, &quot;spec/ri_cal/bugreports_spec.rb&quot;, &quot;spec/ri_cal/component/alarm_spec.rb&quot;, &quot;spec/ri_cal/component/calendar_spec.rb&quot;, &quot;spec/ri_cal/component/event_spec.rb&quot;, &quot;spec/ri_cal/component/freebusy_spec.rb&quot;, &quot;spec/ri_cal/component/journal_spec.rb&quot;, &quot;spec/ri_cal/component/t_z_info_timezone_spec.rb&quot;, &quot;spec/ri_cal/component/timezone_spec.rb&quot;, &quot;spec/ri_cal/component/todo_spec.rb&quot;, &quot;spec/ri_cal/component_spec.rb&quot;, &quot;spec/ri_cal/core_extensions/string/conversions_spec.rb&quot;, &quot;spec/ri_cal/core_extensions/time/calculations_spec.rb&quot;, &quot;spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb&quot;, &quot;spec/ri_cal/fast_date_time_spec.rb&quot;, &quot;spec/ri_cal/occurrence_enumerator_spec.rb&quot;, &quot;spec/ri_cal/parser_spec.rb&quot;, &quot;spec/ri_cal/property_value/date_spec.rb&quot;, &quot;spec/ri_cal/property_value/date_time_spec.rb&quot;, &quot;spec/ri_cal/property_value/duration_spec.rb&quot;, &quot;spec/ri_cal/property_value/occurrence_list_spec.rb&quot;, &quot;spec/ri_cal/property_value/period_spec.rb&quot;, &quot;spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb&quot;, &quot;spec/ri_cal/property_value/recurrence_rule_spec.rb&quot;, &quot;spec/ri_cal/property_value/text_spec.rb&quot;, &quot;spec/ri_cal/property_value/utc_offset_spec.rb&quot;, &quot;spec/ri_cal/property_value_spec.rb&quot;, &quot;spec/ri_cal/required_timezones_spec.rb&quot;, &quot;spec/ri_cal_spec.rb&quot;, &quot;spec/spec.opts&quot;, &quot;spec/spec_helper.rb&quot;, &quot;tasks/gem_loader/load_active_support.rb&quot;, &quot;tasks/gem_loader/load_tzinfo_gem.rb&quot;, &quot;tasks/ri_cal.rake&quot;, &quot;tasks/spec.rake&quot;]
+  s.files = [&quot;History.txt&quot;, &quot;Manifest.txt&quot;, &quot;README.txt&quot;, &quot;Rakefile&quot;, &quot;bin/ri_cal&quot;, &quot;component_attributes/alarm.yml&quot;, &quot;component_attributes/calendar.yml&quot;, &quot;component_attributes/component_property_defs.yml&quot;, &quot;component_attributes/event.yml&quot;, &quot;component_attributes/freebusy.yml&quot;, &quot;component_attributes/journal.yml&quot;, &quot;component_attributes/timezone.yml&quot;, &quot;component_attributes/timezone_period.yml&quot;, &quot;component_attributes/todo.yml&quot;, &quot;copyrights.txt&quot;, &quot;docs/draft-ietf-calsify-2446bis-08.txt&quot;, &quot;docs/draft-ietf-calsify-rfc2445bis-09.txt&quot;, &quot;docs/incrementers.txt&quot;, &quot;docs/rfc2445.pdf&quot;, &quot;lib/ri_cal.rb&quot;, &quot;lib/ri_cal/component.rb&quot;, &quot;lib/ri_cal/component/alarm.rb&quot;, &quot;lib/ri_cal/component/calendar.rb&quot;, &quot;lib/ri_cal/component/event.rb&quot;, &quot;lib/ri_cal/component/freebusy.rb&quot;, &quot;lib/ri_cal/component/journal.rb&quot;, &quot;lib/ri_cal/component/non_standard.rb&quot;, &quot;lib/ri_cal/component/t_z_info_timezone.rb&quot;, &quot;lib/ri_cal/component/timezone.rb&quot;, &quot;lib/ri_cal/component/timezone/daylight_period.rb&quot;, &quot;lib/ri_cal/component/timezone/standard_period.rb&quot;, &quot;lib/ri_cal/component/timezone/timezone_period.rb&quot;, &quot;lib/ri_cal/component/todo.rb&quot;, &quot;lib/ri_cal/core_extensions.rb&quot;, &quot;lib/ri_cal/core_extensions/array.rb&quot;, &quot;lib/ri_cal/core_extensions/array/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/date.rb&quot;, &quot;lib/ri_cal/core_extensions/date/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/date_time.rb&quot;, &quot;lib/ri_cal/core_extensions/date_time/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/object.rb&quot;, &quot;lib/ri_cal/core_extensions/object/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/string.rb&quot;, &quot;lib/ri_cal/core_extensions/string/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/time.rb&quot;, &quot;lib/ri_cal/core_extensions/time/calculations.rb&quot;, &quot;lib/ri_cal/core_extensions/time/conversions.rb&quot;, &quot;lib/ri_cal/core_extensions/time/tzid_access.rb&quot;, &quot;lib/ri_cal/core_extensions/time/week_day_predicates.rb&quot;, &quot;lib/ri_cal/fast_date_time.rb&quot;, &quot;lib/ri_cal/floating_timezone.rb&quot;, &quot;lib/ri_cal/invalid_property_value.rb&quot;, &quot;lib/ri_cal/invalid_timezone_identifer.rb&quot;, &quot;lib/ri_cal/occurrence_enumerator.rb&quot;, &quot;lib/ri_cal/occurrence_period.rb&quot;, &quot;lib/ri_cal/parser.rb&quot;, &quot;lib/ri_cal/properties/alarm.rb&quot;, &quot;lib/ri_cal/properties/calendar.rb&quot;, &quot;lib/ri_cal/properties/event.rb&quot;, &quot;lib/ri_cal/properties/freebusy.rb&quot;, &quot;lib/ri_cal/properties/journal.rb&quot;, &quot;lib/ri_cal/properties/timezone.rb&quot;, &quot;lib/ri_cal/properties/timezone_period.rb&quot;, &quot;lib/ri_cal/properties/todo.rb&quot;, &quot;lib/ri_cal/property_value.rb&quot;, &quot;lib/ri_cal/property_value/array.rb&quot;, &quot;lib/ri_cal/property_value/cal_address.rb&quot;, &quot;lib/ri_cal/property_value/date.rb&quot;, &quot;lib/ri_cal/property_value/date_time.rb&quot;, &quot;lib/ri_cal/property_value/date_time/additive_methods.rb&quot;, &quot;lib/ri_cal/property_value/date_time/time_machine.rb&quot;, &quot;lib/ri_cal/property_value/date_time/timezone_support.rb&quot;, &quot;lib/ri_cal/property_value/duration.rb&quot;, &quot;lib/ri_cal/property_value/geo.rb&quot;, &quot;lib/ri_cal/property_value/integer.rb&quot;, &quot;lib/ri_cal/property_value/occurrence_list.rb&quot;, &quot;lib/ri_cal/property_value/period.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/enumerator.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/numbered_span.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_day.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb&quot;, &quot;lib/ri_cal/property_value/recurrence_rule/validations.rb&quot;, &quot;lib/ri_cal/property_value/text.rb&quot;, &quot;lib/ri_cal/property_value/uri.rb&quot;, &quot;lib/ri_cal/property_value/utc_offset.rb&quot;, &quot;lib/ri_cal/required_timezones.rb&quot;, &quot;performance/paris_eastern/subject.rb&quot;, &quot;performance/penultimate_weekday/subject.rb&quot;, &quot;performance/psm_big_enum/ical.ics&quot;, &quot;performance/psm_big_enum/subject.rb&quot;, &quot;performance/utah_cycling/subject.rb&quot;, &quot;ri_cal.gemspec&quot;, &quot;sample_ical_files/from_ical_dot_app/test1.ics&quot;, &quot;script/benchmark_subject&quot;, &quot;script/console&quot;, &quot;script/destroy&quot;, &quot;script/generate&quot;, &quot;script/profile_subject&quot;, &quot;script/txt2html&quot;, &quot;spec/ri_cal/bugreports_spec.rb&quot;, &quot;spec/ri_cal/component/alarm_spec.rb&quot;, &quot;spec/ri_cal/component/calendar_spec.rb&quot;, &quot;spec/ri_cal/component/event_spec.rb&quot;, &quot;spec/ri_cal/component/freebusy_spec.rb&quot;, &quot;spec/ri_cal/component/journal_spec.rb&quot;, &quot;spec/ri_cal/component/t_z_info_timezone_spec.rb&quot;, &quot;spec/ri_cal/component/timezone_spec.rb&quot;, &quot;spec/ri_cal/component/todo_spec.rb&quot;, &quot;spec/ri_cal/component_spec.rb&quot;, &quot;spec/ri_cal/core_extensions/string/conversions_spec.rb&quot;, &quot;spec/ri_cal/core_extensions/time/calculations_spec.rb&quot;, &quot;spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb&quot;, &quot;spec/ri_cal/fast_date_time_spec.rb&quot;, &quot;spec/ri_cal/occurrence_enumerator_spec.rb&quot;, &quot;spec/ri_cal/parser_spec.rb&quot;, &quot;spec/ri_cal/property_value/date_spec.rb&quot;, &quot;spec/ri_cal/property_value/date_time_spec.rb&quot;, &quot;spec/ri_cal/property_value/duration_spec.rb&quot;, &quot;spec/ri_cal/property_value/occurrence_list_spec.rb&quot;, &quot;spec/ri_cal/property_value/period_spec.rb&quot;, &quot;spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb&quot;, &quot;spec/ri_cal/property_value/recurrence_rule_spec.rb&quot;, &quot;spec/ri_cal/property_value/text_spec.rb&quot;, &quot;spec/ri_cal/property_value/utc_offset_spec.rb&quot;, &quot;spec/ri_cal/property_value_spec.rb&quot;, &quot;spec/ri_cal/required_timezones_spec.rb&quot;, &quot;spec/ri_cal_spec.rb&quot;, &quot;spec/spec.opts&quot;, &quot;spec/spec_helper.rb&quot;, &quot;tasks/gem_loader/load_active_support.rb&quot;, &quot;tasks/gem_loader/load_tzinfo_gem.rb&quot;, &quot;tasks/ri_cal.rake&quot;, &quot;tasks/spec.rake&quot;]
   s.homepage = %q{http://ri-cal.rubyforge.org/}
   s.rdoc_options = [&quot;--main&quot;, &quot;README.txt&quot;]
   s.require_paths = [&quot;lib&quot;]</diff>
      <filename>ri_cal.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -16,7 +16,7 @@ X-WR-CALDESC:TO ADD EVENTS INVITE THIS ADDRESS\;\npf44opfb12hherild7h2pl11b
  4@group.calendar.google.com\n\nThis is a public calendar to know what's com
  ing up all around the country in the technology industry.\n\nIncludes digit
  al\, internet\, web\, enterprise\, software\, hardware\, and it's various f
- lavours. \n\nFeel free to add real events. Keep it real. 
+ lavours. \n\nFeel free to add real events. Keep it real.
 BEGIN:VTIMEZONE
 TZID:Australia/Perth
 X-LIC-LOCATION:Australia/Perth
@@ -90,7 +90,7 @@ describe &quot;http://rick_denatale.lighthouseapp.com/projects/30941/tickets/18&quot; do
         alarm.action = 'AUDIO'
       end
     end
-    
+
     lambda {event.export}.should_not raise_error
   end
 end
@@ -127,10 +127,10 @@ DESCRIPTION:Some event
 END:VEVENT
 END:VCALENDAR
 ENDCAL
-    
+
     @event = cals.first.events.first
   end
-  
+
   it &quot;not raise an error accessing DTSTART&quot; do
     lambda {@event.dtstart}.should_not raise_error
   end
@@ -154,13 +154,77 @@ FREEBUSY;FBTYPE=BUSY-TENTATIVE:20090711T050000Z/20090712T050000Z
 END:VFREEBUSY
 END:VCALENDAR
 ENDCAL
-  @free_busy = cal.first.freebusys.first    
+  @free_busy = cal.first.freebusys.first
   end
-  
+
   it &quot;should have two periods&quot; do
     @free_busy.freebusy.map {|fb| fb.to_s}.should == [
       &quot;;FBTYPE=BUSY:20090705T200417Z/20090707T050000Z&quot;,
       &quot;;FBTYPE=BUSY-TENTATIVE:20090711T050000Z/20090712T050000Z&quot;
       ]
-  end  
+  end
+end
+
+describe &quot;a calendar including vvenue&quot; do
+  before(:each) do
+    @cal_string = &lt;&lt;ENDCAL
+BEGIN:VCALENDAR
+VERSION:2.0
+X-WR-CALNAME:Upcoming Event: Film in the Park
+PRODID:-//Upcoming.org/Upcoming ICS//EN
+CALSCALE:GREGORIAN
+METHOD:PUBLISH
+BEGIN:VEVENT
+DTSTART:20090807T201500
+DTEND:20090807T220000
+RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090822T000000
+GEO:-104.997;39.546
+TRANSP:TRANSPARENT
+SUMMARY:Film in the Park
+DESCRIPTION: [Full details at http://upcoming.yahoo.com/event/3082410/ ] Plan to join the HRCA family summer tradition! Bring a blanket and enjoy great FREE family movies! Mark the dates now!
+URL;VALUE=URI:http://upcoming.yahoo.com/event/3082410/
+UID:http://upcoming.yahoo.com/event/3082410/
+DTSTAMP:20090716T103006
+LAST-UPDATED:20090716T103006
+CATEGORIES:Family
+ORGANIZER;CN=mepling95:X-ADDR:http://upcoming.yahoo.com/user/637615/
+LOCATION;VENUE-UID=&quot;http://upcoming.yahoo.com/venue/130821/&quot;:Civic Green Park @ 9370 Ridgeline Boulevard\, Highlands Ranch\, Colorado 80126 US
+END:VEVENT
+BEGIN:VVENUE
+X-VVENUE-INFO:http://evdb.com/docs/ical-venue/drft-norris-ical-venue.html
+NAME:Civic Green Park
+ADDRESS:9370 Ridgeline Boulevard
+CITY:Highlands Ranch
+REGION;X-ABBREV=co:Colorado
+COUNTRY;X-ABBREV=us:United States
+POSTALCODE:80126
+GEO:39.546;-104.997
+URL;X-LABEL=Venue Info:http://www.hrmafestival.org
+END:VVENUE
+END:VCALENDAR
+ENDCAL
+
+  @venue_str = &lt;&lt;ENDVENUE
+BEGIN:VVENUE
+X-VVENUE-INFO:http://evdb.com/docs/ical-venue/drft-norris-ical-venue.html
+NAME:Civic Green Park
+ADDRESS:9370 Ridgeline Boulevard
+CITY:Highlands Ranch
+REGION;X-ABBREV=co:Colorado
+COUNTRY;X-ABBREV=us:United States
+POSTALCODE:80126
+GEO:39.546;-104.997
+URL;X-LABEL=Venue Info:http://www.hrmafestival.org
+END:VVENUE
+ENDVENUE
+  end
+
+  it &quot;should parse without error&quot; do
+    lambda {RiCal.parse_string(@cal_string)}.should_not raise_error
+  end
+  
+  it &quot;should export correctly&quot; do
+    export = RiCal.parse_string(@cal_string).first.export
+    export.should include(@venue_str)
+  end
 end</diff>
      <filename>spec/ri_cal/bugreports_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -188,7 +188,7 @@ describe RiCal::Component do
       end
 
       it 'should have an x_wr_calname property with the value &quot;My Personal Calendar&quot;' do
-        @it.x_wr_calname.should == &quot;My Personal Calendar&quot;
+        @it.x_wr_calname.first.should == &quot;My Personal Calendar&quot;
       end
 
       context &quot;event with a long description and a dsl built recurence rule&quot; do</diff>
      <filename>spec/ri_cal/component_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -126,7 +126,7 @@ describe RiCal::Parser do
     describe &quot;parsing an event&quot; do
       it &quot;should parse an event&quot; do
         parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VEVENT&quot;))
-        RiCal::Component::Event.should_receive(:from_parser).with(parser, nil)
+        RiCal::Component::Event.should_receive(:from_parser).with(parser, nil, &quot;VEVENT&quot;)
         parser.parse
       end
 
@@ -249,7 +249,7 @@ describe RiCal::Parser do
 
       it &quot;should parse a calendar&quot; do
         parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VCALENDAR&quot;))
-        RiCal::Component::Calendar.should_receive(:from_parser).with(parser, nil)
+        RiCal::Component::Calendar.should_receive(:from_parser).with(parser, nil, &quot;VCALENDAR&quot;)
         parser.parse
       end
 
@@ -280,49 +280,54 @@ describe RiCal::Parser do
         before(:each) do
           @x_props = RiCal::Parser.parse(StringIO.new(&quot;BEGIN:VCALENDAR\nX-PROP;X-FOO=Y:BAR\nEND:VCALENDAR&quot;)).first.x_properties
           @x_prop = @x_props[&quot;X-PROP&quot;]
-        end 
+        end
+        
+        it &quot;should be an array of length 1&quot; do
+          @x_prop.should be_kind_of(Array)
+          @x_prop.length.should == 1
+        end
 
-        it &quot;should be a PropertyValue::Text&quot; do
-          @x_prop.should be_kind_of(RiCal::PropertyValue::Text)
+        it &quot;should have a PropertyValue::Text element&quot; do
+          @x_prop.first.should be_kind_of(RiCal::PropertyValue::Text)
         end
 
         it &quot;should have the right value&quot; do
-          @x_prop.value.should == &quot;BAR&quot;
+          @x_prop.first.value.should == &quot;BAR&quot;
         end
 
         it &quot;should have the right parameters&quot; do
-          @x_prop.params.should == {&quot;X-FOO&quot; =&gt; &quot;Y&quot;}
+          @x_prop.first.params.should == {&quot;X-FOO&quot; =&gt; &quot;Y&quot;}
         end
       end 
     end
 
     it &quot;should parse a to-do&quot; do
       parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VTODO&quot;))
-      RiCal::Component::Todo.should_receive(:from_parser).with(parser, nil)
+      RiCal::Component::Todo.should_receive(:from_parser).with(parser, nil, &quot;VTODO&quot;)
       parser.parse
     end
 
     it &quot;should parse a journal entry&quot; do
       parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VJOURNAL&quot;))
-      RiCal::Component::Journal.should_receive(:from_parser).with(parser, nil)
+      RiCal::Component::Journal.should_receive(:from_parser).with(parser, nil, &quot;VJOURNAL&quot;)
       parser.parse
     end
 
     it &quot;should parse a free/busy component&quot; do
       parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VFREEBUSY&quot;))
-      RiCal::Component::Freebusy.should_receive(:from_parser).with(parser, nil)
+      RiCal::Component::Freebusy.should_receive(:from_parser).with(parser, nil, &quot;VFREEBUSY&quot;)
       parser.parse
     end
 
     it &quot;should parse a timezone component&quot; do
       parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VTIMEZONE&quot;))
-      RiCal::Component::Timezone.should_receive(:from_parser).with(parser, nil)
+      RiCal::Component::Timezone.should_receive(:from_parser).with(parser, nil, &quot;VTIMEZONE&quot;)
       parser.parse
     end
 
     it &quot;should parse an alarm component&quot; do
       parser = RiCal::Parser.new(StringIO.new(&quot;BEGIN:VALARM&quot;))
-      RiCal::Component::Alarm.should_receive(:from_parser).with(parser, nil)
+      RiCal::Component::Alarm.should_receive(:from_parser).with(parser, nil, &quot;VALARM&quot;)
       parser.parse
     end
   end</diff>
      <filename>spec/ri_cal/parser_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,7 +34,7 @@
     &lt;div class=&quot;sidebar&quot;&gt;
       &lt;div id=&quot;version&quot; class=&quot;clickable&quot; onclick='document.location = &quot;http://rubyforge.org/projects/ri-cal&quot;; return false'&gt;
         &lt;p&gt;Get Version&lt;/p&gt;
-        &lt;a href=&quot;http://rubyforge.org/projects/ri-cal&quot; class=&quot;numbers&quot;&gt;0.7.6&lt;/a&gt;
+        &lt;a href=&quot;http://rubyforge.org/projects/ri-cal&quot; class=&quot;numbers&quot;&gt;0.8.0&lt;/a&gt;
         &lt;p&gt;
         &lt;a href='http://www.pledgie.com/campaigns/4360'&gt;&lt;img alt='Click here to lend your support to: ri_cal and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/4360.png?skin_name=chrome' border='0' /&gt;&lt;/a&gt;
         &lt;/p&gt;</diff>
      <filename>website/index.html</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>52efb38825f84b62ae1da2fd08a61e0f56000d4c</id>
    </parent>
  </parents>
  <author>
    <name>Rick DeNatale</name>
    <email>rick.denatale@gmail.com</email>
  </author>
  <url>http://github.com/rubyredrick/ri_cal/commit/128d820037b2a2fc3d5c0fdb545d6e00b916ce0d</url>
  <id>128d820037b2a2fc3d5c0fdb545d6e00b916ce0d</id>
  <committed-date>2009-08-11T16:14:40-07:00</committed-date>
  <authored-date>2009-08-11T16:14:40-07:00</authored-date>
  <message>0.8.0 - 11 August 2009 Minor Version Bump - There is a small potentially breaking change see section on treatment of X-properties below

  * Unknown Components

  Starting with version 0.8.0 RiCal will parse calendars and components which contain nonstandard components.

  For example, there was a short-lived proposal to extend RFC2445 with a new VVENUE component which would hold structured information about the location of an event.  This proposal was never accepted and was withdrawn, but there is icalendar data in the wild which contains VVENUE components.

  Prior to version 0.8.0, RiCal would raise an exception if unknown component types were encountered.  Starting with version 0.8.0 RiCal will 'parse' such components and create instances of NonStandard component to represent them.  Since the actual format of unknown components is not known by RiCal, the NonStandard component will simply save the data lines between the BEGIN:xxx and END:xxx lines, (where xxx is the non-standard component name, e.g. VVENUE).  If the calendar is re-exported the original lines will be replayed.

  * Change to treatment of X-properties

  RFC2445 allows 'non-standard' or experimental properties which property-names beginning with X.  RiCal always supported parsing these.

  The standard properties are specified as to how many times they can occur within a particular component.  For singly occurring properties RiCal returns a single property object, while for properties which can occur multiple times RiCal returns an array of property objects.

  While implementing NonStandard properties, I realized that X-properties were being assumed to be singly occurring. But this isn't necessarily true.  So starting with 0.8.0 the X-properties are represented by an array of property objects.

  THIS MAY BREAK SOME APPLICATIONS, but the adaptation should be easy.</message>
  <tree>e87ed652fd1c9a45bda15e5b50d15a9287437e3e</tree>
  <committer>
    <name>Rick DeNatale</name>
    <email>rick.denatale@gmail.com</email>
  </committer>
</commit>
