<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/red_steak/copier.rb</filename>
    </added>
    <added>
      <filename>lib/red_steak/named_array.rb</filename>
    </added>
    <added>
      <filename>lib/red_steak/namespace.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -5,6 +5,7 @@
 ** Machine#state=(String|Array).
 ** Add :elapsed_time to history Hash - has performance implication.
 ** Support Statemachine#freeze to avoid accidental changes to a running Statemachine.
+** Support UML Pseudostates.
 
 * Jeremy's Comments:
 ** Builder#start_state and #end_state is confusing,</diff>
      <filename>TODO</filename>
    </modified>
    <modified>
      <diff>@@ -32,6 +32,7 @@ require 'red_steak/base'
 
 # UML Metamodel
 require 'red_steak/named_element'
+require 'red_steak/namespace'
 require 'red_steak/statemachine'
 require 'red_steak/vertex'
 require 'red_steak/state'</diff>
      <filename>lib/red_steak.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,40 +2,6 @@
 
 module RedSteak
 
-  # Copies object graphs with referential integrity.
-  class Copier
-    def self.copy x
-      self.new.copy(x)
-    end
-
-    attr_reader :map
-
-    def initialize
-      @map = { }
-    end
-
-    # Copies x deeply.
-    #
-    # 1) Dups x as xx
-    # 2) calls xx.deepen_copy! copier, x
-    #
-    def copy x
-      return x if ! x
-
-      if xx = @map[x]
-        return xx 
-      end
-
-      xx = @map[x] = (x.dup rescue x)
-      xx.deepen_copy!(self, x) if xx.respond_to?(:deepen_copy!)
-
-      xx
-    end
-
-    alias :[] :copy
-  end
-
-
   # Base class for RedSteak objects.
   class Base 
     # The name of this object.
@@ -157,83 +123,11 @@ module RedSteak
   end # class
 
 
-  # Simple Array proxy for looking up States and Transitions by name.
-  class NamedArray
-    def initialize a = [ ], axis = nil
-      @a = a
-      @axis = axis
-    end
-
-
-    def [] pattern
-      case pattern
-      when Integer
-        @a[pattern]
-      when Array
-        case pattern.size
-        when 0
-          nil
-        when 1
-          self[pattern.first]
-        else
-          x = self[pattern.first]
-          x = x.send(@axis) if @axis
-          x[pattern[1 .. -1]]
-        end
-      when String
-        self[pattern.split(SEP).map{|x| x.to_sym}]
-      else
-        @a.find { | e | e === pattern }
-      end
-    end
-
-
-    def []=(i, v)
-      case i
-      when Integer
-        if v
-          @a[i] = v
-        else
-          @a.delete(i)
-        end
-      else
-        @a.delete_if { | x | x === i }
-        @a &lt;&lt; v if v
-      end
-    end
-
-
-    def select &amp;blk
-      self.class.new(@a.select(&amp;blk), @axis)
-    end
-
-
-    def + x
-      @a + x.to_a
-    end
-
-
-    def method_missing sel, *args, &amp;blk
-      @a.send(sel, *args, &amp;blk)
-    end
-
-
-    # Deepens elements through a Copier.
-    def deepen_copy! copier, src
-      @a = @a.map { | x | copier[x] }
-    end
-
-
-    def to_a
-      @a
-    end
-
-
-    EMPTY = self.new([ ].freeze)
-  end # class
-
 end # module
 
 
+require 'red_steak/copier'
+require 'red_steak/named_array'
+
 ###############################################################################
 # EOF</diff>
      <filename>lib/red_steak/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -278,13 +278,18 @@ module RedSteak
     # Determine what object should own
     # a new State if one is created.
     def _owner
-      @context[:statemachine]
+      @context[:statemachine] ||
+        (raise Exception, &quot;statemachine is unknown&quot;)
     end
 
 
     # Locates a state by name or creates a new object.
-    def _find_state opts, create = true, owner = nil, namespaces = nil
-      # $stderr.puts &quot;_find_state #{opts.inspect}, #{create.inspect} from #{caller(1).first}&quot; if ! create
+    def _find_state opts, param = EMPTY_HASH
+      create = param[:create] != false
+      owner = param[:owner]
+      cls = param[:class] || State
+
+      _log &quot;_find_state #{opts.inspect}, #{param.inspect}&quot;
 
       # Parse opts.
       name = nil
@@ -300,12 +305,10 @@ module RedSteak
         raise ArgumentError, &quot;invalid opts, given #{opts.inspect}&quot;
       end
 
+      # Split Strings on &quot;::&quot;
       name = name.split(SEP) if String === name
  
-      # @logger = $stderr if name == :a
-
       # Determine owner.
-      owner ||= opts.delete(:_owner) if opts[:_owner]
       owner ||= _owner unless owner
       raise Exception, &quot;Cannot determine owner for new State #{name.inspect}&quot; unless owner
 
@@ -322,8 +325,7 @@ module RedSteak
         _log &quot;  looking for State #{name.inspect} in path #{path.inspect}&quot;
         path.each do | e |
           break unless owner
-          # $stderr.puts &quot;  owner = #{owner.inspect}&quot;
-          owner = _find_state(e.to_sym, create, owner)
+          owner = _find_state(e.to_sym, :owner =&gt; owner)
         end
         raise ArgumentError, &quot;Cannot locate State #{name.inspect} in #{owner.inspect}&quot; unless owner
 
@@ -345,7 +347,7 @@ module RedSteak
       _log &quot;  state = #{state.inspect} in #{owner.inspect}&quot;
 
 =begin
-      $stderr.puts &quot;owner = #{owner.inspect}&quot;
+      $stderr.puts &quot;  owner = #{owner.inspect}&quot;
       $stderr.puts &quot;caller = #{caller(0)[0 .. 4] * &quot;\n  &quot;}&quot;
       $stderr.puts &quot;state = #{state.inspect}&quot;
 =end
@@ -353,10 +355,13 @@ module RedSteak
       # Create a new one, if requested.
       if create &amp;&amp; ! state
         opts[:name] = name
-        opts[:statemachine] ||= @context[:statemachine]
-        state = State.new opts
+        _log &quot;  creating #{cls} #{opts.inspect} for #{owner.inspect}&quot;
+        state = cls.new opts
+        if State === owner
+          owner = owner.submachine
+        end
         owner.add_state! state
-        _log &quot;  created #{state.inspect}&quot;
+        _log &quot;  created #{state.inspect} for #{owner.inspect}&quot;
       else
         if state
           state.options = opts
@@ -373,10 +378,10 @@ module RedSteak
       blk = t[:block]
       opts = t[:opts]
 
-      _log &quot;\n\n_create_transition! #{opts.inspect}&quot;
+      _log &quot;\n\n_create_transition! #{t.inspect}&quot;
 
-      opts[:source] = _find_state opts[:source], :create, owner
-      opts[:target] = _find_state opts[:target], :create, owner
+      opts[:source] = _find_state opts[:source], :owner =&gt; owner
+      opts[:target] = _find_state opts[:target], :owner =&gt; owner
 
       _log &quot;  #{opts.inspect}&quot;
        </diff>
      <filename>lib/red_steak/builder.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,12 +3,16 @@ module RedSteak
 
   # Base class for all elements in a Statemachine.
   class NamedElement &lt; Base
+    # The Namespace of this NamedElement.
+    attr_accessor :namespace
+
     # The StateMachine that owns this object.
     attr_accessor :stateMachine # UML
     alias :statemachine :stateMachine # not UML
     alias :statemachine= :stateMachine= # not UML
     
     def intialize opts
+      @namespace = nil
       @stateMachine = nil
       super
     end
@@ -16,8 +20,18 @@ module RedSteak
     
     def deepen_copy! copier, src
       super
+      @namespace = copier[@namespace]
       @stateMachine = copier[@stateMachine]
     end
+
+
+    
+    def ownedMember_added! ns
+    end
+
+
+    def ownedMember_removed! ns
+    end
     
     
     # Called by subclasses to notify/query the context object for specific actions.</diff>
      <filename>lib/red_steak/named_element.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,17 @@ module RedSteak
 
   # 
   class Pseudostate &lt; Vertex
-    # See PseudostateKind
+    # See PseudostateKind.
+    # initial
+    # deepHistory
+    # shallowHistory
+    # join
+    # fork
+    # junction
+    # choice
+    # entryPoint
+    # exitPoint
+    # teminate
     attr_accessor :kind
 
     # The state associated with this Pseudostate.</diff>
      <filename>lib/red_steak/pseudostate.rb</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,9 @@ module RedSteak
     # This state's submachine, or nil.
     attr_accessor :submachine # UML
 
+    # List of Pseudostates.
+    attr_reader :connectionPoint # UML
+
 
     def initialize opts = { }
       @state_type = nil
@@ -26,6 +29,7 @@ module RedSteak
       @doActivity = nil
       @exit = nil
       @submachine = nil
+      @connectionPoint = NamedArray.new([ ])
       super
     end
 
@@ -34,6 +38,7 @@ module RedSteak
       super
 
       @submachine = copier[@submachine]
+      @connectionPoint = copier[@connectionPoint]
     end
 
 
@@ -124,7 +129,8 @@ module RedSteak
           if ss = superstate
             x.push(*ss.ancestors)
           end
-          x
+          
+          NamedArray.new(x.freeze, :state)
         end
     end
 
@@ -158,6 +164,40 @@ module RedSteak
     end
 
 
+    # Adds a Pseudostate to this State.
+    def add_connectionPoint! s
+      _log &quot;add_connectionPoint! #{s.inspect}&quot;
+
+      if @connectionPoint.find { | x | x.name == s.name }
+        raise ArgumentError, &quot;connectionPoint named #{s.name.inspect} already exists&quot;
+      end
+
+      @ownedMember &lt;&lt; s # ownedElement?!?!
+      @connectionPoint &lt;&lt; s
+      s.state = self
+
+      # Notify.
+      s.connectionPoint_added! self
+
+      s
+    end
+
+
+    # Removes a Pseudostate from this Statemachine.
+    def remove_connectionPoint! s
+      _log &quot;remove_Connection! #{s.inspect}&quot;
+
+      @ownedMember.delete(s) # ownedElement?!?!
+      @connectionPoint.delete(s)
+      s.state = nil
+
+      # Notify.
+      s.connectionPoint_removed! self
+
+      self
+    end
+
+
     def _validate errors
       errors &lt;&lt; :state_without_transitions unless transitionsize != 0
       case</diff>
      <filename>lib/red_steak/state.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,19 +2,21 @@
 module RedSteak
 
   # A Statemachine object.
-  class Statemachine &lt; Base
+  class Statemachine &lt; Namespace
 
-    # The list of all states.
+    # List of State objects.
+    # subsets ownedMember
     attr_reader :states # not UML
     alias :state :states # UML
 
-    # The list of all transitions.
+    # List of Pseudostate objects.
+    # subsets ownedMember
+    attr_reader :connectionPoint # UML
+
+    # List of Transition objects.
     attr_reader :transitions # not UML
     alias :transition :transitions # UML
 
-    # The list of Pseudostates.
-    attr_reader :connectionPoint # UML
-
     # The enclosing State if this is a submachine.
     attr_accessor :submachineState # UML
     alias :superstate :submachineState # not UML
@@ -52,10 +54,9 @@ module RedSteak
     def deepen_copy! copier, src
       super
 
-      @submachineState = copier[@submachineState]
-
       @states = copier[@states]
       @transitions = copier[@transitions]
+      @submachineState = copier[@submachineState]
 
       @start_state = copier[@start_state]
       @end_state   = copier[@end_state]
@@ -114,6 +115,7 @@ module RedSteak
         raise ArgumentError, &quot;state named #{s.name.inspect} already exists&quot;
       end
 
+      add_ownedMember!(s)
       @states &lt;&lt; s
       s.stateMachine = self
 
@@ -132,6 +134,7 @@ module RedSteak
 
       transitions = s.transitions
 
+      remove_ownedMember!(s)
       @states.delete(s)
       s.stateMachine = nil
 
@@ -154,6 +157,7 @@ module RedSteak
         raise ArgumentError, &quot;connectionPoint named #{s.name.inspect} already exists&quot;
       end
 
+      @ownedMember &lt;&lt; s
       @connectionPoint &lt;&lt; s
       s.stateMachine = self
 
@@ -168,6 +172,7 @@ module RedSteak
     def remove_connectionPoint! s
       _log &quot;remove_Connection! #{s.inspect}&quot;
 
+      @ownedMember.delete(s)
       @connectionPoint.delete(s)
       s.stateMachine = nil
 
@@ -274,11 +279,16 @@ module RedSteak
 
     ##################################################################
 
+    def inspect
+      &quot;#&lt;#{self.class} #{to_s}&gt;&quot;
+    end
+
+
 
     def _log *args
       case 
       when IO === @logger
-        @logger.puts &quot;#{self.to_a.inspect} #{(state &amp;&amp; state.to_a).inspect} #{args * &quot; &quot;}&quot;
+        @logger.puts &quot;#{self.to_s} #{args * &quot; &quot;}&quot;
       when defined?(::Log4r) &amp;&amp; (Log4r::Logger === @logger)
         @logger.send(log_level || :debug, *args)
       when (x = superstatemachine)</diff>
      <filename>lib/red_steak/statemachine.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 module RedSteak
 
   # Represents a transition from one state to another state in a statemachine.
-  class Transition &lt; NamedElement
+  class Transition &lt; Namespace
     # See TransitionKind.
     attr_accessor :kind
 
@@ -62,7 +62,7 @@ module RedSteak
 
 
     def inspect
-      &quot;#&lt;#{self.class} #{stateMachine.to_s} #{name} #{source.to_s} -&gt; #{target.to_s}&gt;&quot; 
+      &quot;#&lt;#{self.class} #{@stateMachine.to_s} #{name} #{source.to_s} -&gt; #{target.to_s}&gt;&quot; 
     end
 
   end # class</diff>
      <filename>lib/red_steak/transition.rb</filename>
    </modified>
    <modified>
      <diff>@@ -114,7 +114,7 @@ module RedSteak
     # Returns an Array representation of this State.
     # Includes superstates and substates.
     def to_a
-      if ss = @stateMachine.submachineState
+      if ss = @stateMachine &amp;&amp; @stateMachine.submachineState
         ss.to_a &lt;&lt; @name
       else
         [ @name ]</diff>
      <filename>lib/red_steak/vertex.rb</filename>
    </modified>
    <modified>
      <diff>@@ -105,11 +105,11 @@ describe RedSteak do
     # There can only one.
     return Thread.current[:statemachine] if Thread.current[:statemachine]
 
-    b = RedSteak::Builder.new
+    b = RedSteak::Builder.new(:logger =&gt; false &amp;&amp; $stderr)
     # breakpointer
     
     b.build do
-      statemachine :test do
+      statemachine :test, :logger =&gt; false &amp;&amp; $stderr do
         initial :a
         final :end
     
@@ -208,7 +208,7 @@ describe RedSteak do
     e.targets.to_a.should == [ ]
     e.sources.to_a.map{|s| s.to_s}.should == [ 'c', 'd', 'd::end' ]
 
-    sm.states.find{|s| s.name == :a}.options[:option_foo].should == :foo
+    sm.states[:a].options[:option_foo].should == :foo
 
     sm.validate.should == [ ]
 
@@ -527,9 +527,10 @@ describe RedSteak do
 
 
   it 'should handle transitions across substates and states' do
+    logger = nil &amp;&amp; $stderr
     sm = RedSteak::Statemachine.
-      new(:name =&gt; :test2).
-      build(:logger =&gt; false &amp;&amp; $stderr) do
+      new(:name =&gt; :test2, :logger =&gt; logger).
+      build(:logger =&gt; logger) do
       initial :a
       final :end
       </diff>
      <filename>test/red_steak.spec</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>1bdd51a3216fb5cc8e5d3403412d946674cba6b7</id>
    </parent>
  </parents>
  <author>
    <name>Kurt Stephens</name>
    <email>ks.github@kurtstephens.com</email>
  </author>
  <url>http://github.com/kstephens/red_steak/commit/2c87da86fc26f6aa65513c2ff297bd8a0e68bcf8</url>
  <id>2c87da86fc26f6aa65513c2ff297bd8a0e68bcf8</id>
  <committed-date>2008-12-31T01:40:03-08:00</committed-date>
  <authored-date>2008-12-31T01:40:03-08:00</authored-date>
  <message>Refactored Namespace and other support classes.</message>
  <tree>9ad84c9c16975203b611df904b33d479b300159d</tree>
  <committer>
    <name>Kurt Stephens</name>
    <email>ks.github@kurtstephens.com</email>
  </committer>
</commit>
