<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -14,21 +14,35 @@ sub _build_builder {
 
 sub start {
     my $self = shift;
-    $self-&gt;on( '' =&gt; shift, shift);
+    $self-&gt;on( '' =&gt; always_run =&gt; 1, @_ );
 }
 
 sub on {
     my $self = shift;
     my $path = shift;
-    my $argument_schema = shift;
-    my $run = shift;
-    my %given = @_;
+
+    my ( @argument_schema, $run, @given );
+    while ( @_ ) {
+
+        local $_ = shift;
+        if ( ref eq 'ARRAY' ) {
+            push @argument_schema, @$_;
+        }
+        elsif ( ref eq 'CODE' ) {
+            $run = $_;
+        }
+        elsif ( ! defined ) {   
+        }
+        else {
+            push @given, $_ =&gt; shift;
+        }
+    }
+    my %given = @given;
 
     my %control = (
-        map { $_ =&gt; $given{$_} } grep { exists $given{$_} } qw/always_run/
+        map { $_ =&gt; $given{$_} } grep { exists $given{$_} } qw/always_run terminator/
     );
     
-    
     my $matcher;
     if (ref $path eq 'ARRAY') {
         $matcher = $path;
@@ -37,30 +51,34 @@ sub on {
         $matcher = $path;
     }
     elsif (! ref $path) {
-        # Also, check for '*', '$', etc. Ignore if literal =&gt; 1
-        if ($path eq '') { # The start rule, special case
-            $control{always_run} = 1 unless exists $given{always_run};
-            $matcher = [];
-        }
-        elsif ($path =~ s/\s+\*\s*$//) {
+        if ( $path =~ s/\s+\*\s*$// ) { # &quot;xyzzy *&quot;
             $matcher = qr/$path\b(.*)/;
             $control{arguments_from_1} = 1;
         }
-        elsif ($path =~ m/^\s*\*\s*$/) {
+        elsif ( $path =~ m/^\s*\*\s*$/ ) { # &quot;*&quot;
             $matcher = qr/(.*)/;
             $control{arguments_from_1} = 1;
         }
+        elsif ( $path =~ s/\s+--\s*$// ) { # &quot;xyzzy --&quot;
+            $matcher = [ split m/\s+/, $path ];
+            $control{terminator} = 1;
+        }
+        elsif ( $path =~ m/^\s*--\s*$/ ) { # &quot;--&quot;
+            $matcher = [];
+            $control{terminator} = 1;
+        }
         else {
             $matcher = [ split m/\s+/, $path ];
         }
-    
     }
     else {
         croak &quot;Don't recogonize matcher ($path)&quot;;
     }
     $self-&gt;builder-&gt;on( $matcher, sub { # The builder should do the split for us!
         my $context = shift;
-        return $context-&gt;run_step( $argument_schema, $run, { %control } );
+        my $dollar1;
+        $dollar1 = $1 if $control{arguments_from_1};
+        return $context-&gt;run_step( \@argument_schema, $run, { %control }, dollar1 =&gt; $dollar1 );
     } );
 }
 </diff>
      <filename>lib/Getopt/Chain/Builder.pm</filename>
    </modified>
    <modified>
      <diff>@@ -150,17 +150,6 @@ sub consume_arguments($$) { # Will modify arguments, reflecting consumption
     };
     croak &quot;There was an error option-processing arguments: $@&quot; if $@;
 
-    if (@$arguments &amp;&amp; is_option_like $arguments-&gt;[0]) {
-        if (0) {
-            croak &quot;Have remainder arguments after option-processing: &quot;, $arguments-&gt;[0];
-        }
-        else {
-            my @discard;
-            push @discard, shift @$arguments while $arguments-&gt;[0] &amp;&amp; is_option_like $arguments-&gt;[0];
-            warn &quot;Unknown option-like argument@{[ @discard == 1 ? '' : 's' ]} (discarding): @discard&quot;, &quot;\n&quot; if DEBUG;
-        }
-    }
-
     return ( \%options );
 }
 
@@ -182,15 +171,15 @@ sub stash {
 }
 
 # The original arguments from the commandline (or wherever)... read only!
-has arguments =&gt; qw/metaclass Collection::Array reader _arguments required 1 lazy 1 isa ArrayRef/, default =&gt; sub { [] }, provides =&gt; {qw/
-    elements    arguments
+has starting_arguments =&gt; qw/metaclass Collection::Array reader _arguments init_arg arguments required 1 lazy 1 isa ArrayRef/, default =&gt; sub { [] }, provides =&gt; {qw/
+    elements    starting_arguments
 /};
 
 # The arguments remaining after each step does argument consuming... written by the step!
-has remaining_arguments =&gt; qw/metaclass Collection::Array accessor _remaining_arguments isa ArrayRef/, provides =&gt; {qw/
-    elements    remaining_arguments
-    shift       shift_remaining_argument
-    first       first_remaining_argument
+has parsing_arguments =&gt; qw/metaclass Collection::Array accessor _parsing_arguments isa ArrayRef/, provides =&gt; {qw/
+    elements    parsing_arguments
+    shift       shift_parsing_argument
+    first       first_parsing_argument
 /};
 
 has steps =&gt; qw/metaclass Collection::Array reader _steps required 1 lazy 1 isa ArrayRef/, default =&gt; sub { [] }, provides =&gt; {qw/
@@ -208,7 +197,7 @@ has _path =&gt; qw/metaclass Collection::Array is ro required 1 lazy 1 isa ArrayRef
 
 sub initialize_run {
     my $self = shift;
-    $self-&gt;_remaining_arguments( [ $self-&gt;arguments ] );
+    $self-&gt;_parsing_arguments( [ $self-&gt;starting_arguments ] );
 }
 
 sub run {
@@ -221,14 +210,13 @@ sub run {
 sub next {
     my $self = shift;
 
-    unless (defined $self-&gt;_remaining_arguments) { # Haven't been run yet
+    unless (defined $self-&gt;_parsing_arguments) { # Haven't been run yet
         $self-&gt;initialize_run;
     }
 
     my $run_path = join ' ', $self-&gt;path;
     warn &quot;Context::next &quot;, $self-&gt;path_as_string, &quot; ($run_path)\n&quot;  if $DEBUG;
 
-    
     {
         # $self-&gt;dispatcher-&gt;run( $run_path, $self ); # This will (indirectly) call -&gt;run_step( ... ) below
         my $dispatch = $self-&gt;dispatcher-&gt;dispatch( $run_path );
@@ -239,31 +227,23 @@ sub next {
             }
         }
     }
-    my $next_path_part;
-    $self-&gt;push_path( $next_path_part ) if $next_path_part = $self-&gt;next_path_part;
-    return $next_path_part;
+
+    my $next;
+    $self-&gt;push_path( $next ) if $next = $self-&gt;next_path_part;
+    return $next;
 }
 
 sub next_path_part {
     my $self = shift;
 
-    return unless defined (my $argument = $self-&gt;first_remaining_argument);
-    if (0) {
-        croak &quot;Had remainder arguments after option-processing: &quot;, $argument, &quot; @ &quot;, $self-&gt;path_as_string, &quot; [&quot;, join ' ', $self-&gt;remaining_arguments, &quot;]&quot; if is_option_like $argument;
-    }
-    else {
-        while ( defined $argument &amp;&amp; is_option_like $argument ) {
-            warn &quot;Discarding option-like argument: &quot;, $argument, &quot;\n&quot; if DEBUG;
-            $self-&gt;shift_remaining_argument;
-            return unless defined ($argument = $self-&gt;first_remaining_argument);
-        }
-    }
-    return $self-&gt;shift_remaining_argument; # Same as $argument, really
+    return unless defined (my $argument = $self-&gt;first_parsing_argument);
+    croak &quot;Have option-like element at head of parsing arguments: &quot;, $argument, &quot; @ &quot;, $self-&gt;path_as_string, &quot; [&quot;, join ' ', $self-&gt;parsing_arguments, &quot;]&quot; if is_option_like $argument;
+    return $self-&gt;shift_parsing_argument; # Same as $argument, really
 }
 
 sub last {
     my $self = shift;
-    return ! defined $self-&gt;first_remaining_argument;
+    return ! defined $self-&gt;first_parsing_argument;
 }
 
 sub path_as_string {
@@ -279,8 +259,8 @@ sub run_step { # Called from within the Path::Dispatcher rule
 
     $argument_schema = [] unless defined $argument_schema;
     
-    my $step = $self-&gt;add_step( argument_schema =&gt; $argument_schema, run =&gt; $run ); 
-    return 1 if $step-&gt;run( $control ); # We consumed and ran, so we need to rollback
+    my $step = $self-&gt;add_step( argument_schema =&gt; $argument_schema, run =&gt; $run, @_ ); 
+    return 1 if $step-&gt;run( $control ); # We consumed and ran, so we don't need to rollback
     $self-&gt;pop_step; # Rollback, since we didn't actually run
     return 0;
 }
@@ -290,7 +270,7 @@ sub add_step {
     my %given = @_; # Should be: argument_schema, run
 
     my $parent = $self-&gt;last_step; # Could be undef
-    my $step = Getopt::Chain::Context::Step-&gt;new( context =&gt; $self, parent =&gt; $parent, path =&gt; [ $self-&gt;path ], arguments =&gt; [ $self-&gt;remaining_arguments ], %given );
+    my $step = Getopt::Chain::Context::Step-&gt;new( context =&gt; $self, parent =&gt; $parent, path =&gt; [ $self-&gt;path ], arguments =&gt; [ $self-&gt;parsing_arguments ], %given );
     $self-&gt;push_step( $step );
     return $step;
 }
@@ -333,10 +313,15 @@ sub _build__options {
     return Hash::Param-&gt;new( params =&gt; {} );
 }
 
-has arguments =&gt; qw/metaclass Collection::Array accessor _arguments required 1 isa ArrayRef/, provides =&gt; {qw/
-    elements arguments
+has starting_arguments =&gt; qw/metaclass Collection::Array init_arg arguments accessor _starting_arguments required 1 isa ArrayRef/, provides =&gt; {qw/
+    elements starting_arguments
 /};
 
+has remaining_arguments =&gt; qw/metaclass Collection::Array accessor _remaining_arguments isa ArrayRef lazy 1/, provides =&gt; {qw/
+    elements remaining_arguments
+    elements arguments
+/}, default =&gt; sub { [] };
+
 has argument_schema =&gt; qw/metaclass Collection::Array accessor _argument_schema required 1 isa ArrayRef/, provides =&gt; {qw/
     elements argument_schema
 /};
@@ -351,47 +336,69 @@ has _path =&gt; qw/metaclass Collection::Array is ro required 1 lazy 1 isa ArrayRef
 
 has parent =&gt; qw/is ro isa Maybe[Getopt::Chain::Context::Step]/;
 
+has dollar1 =&gt; qw/is ro/;
+
 sub run {
     my $self = shift;
     my $control = shift;
 
-    my @arguments;
-    if ($control-&gt;{arguments_from_1} &amp;&amp; defined $1) {
-        push @arguments, grep { length } split m/\s+/, $1;
-    }
-
     my $options = {};
-    my $arguments = [ $self-&gt;arguments ];
+    my $arguments = [ $self-&gt;starting_arguments ];
     my $argument_schema = [ $self-&gt;argument_schema ];
+    my ( $last );
 
     warn &quot;Context::Step::run &quot;, $self-&gt;context-&gt;path_as_string, &quot; [@$arguments] {@$argument_schema}\n&quot; if $DEBUG;
 
     eval {
         $options = Getopt::Chain::Context::consume_arguments $argument_schema, $arguments;
+        unless ( $control-&gt;{terminator} ) {
+            if ( @$arguments &amp;&amp; Getopt::Chain::Context::is_option_like $arguments-&gt;[0] ) {
+                die &quot;Unknown option-like argument: $arguments-&gt;[0]&quot;, &quot;\n&quot;;
+            }
+        }
     };
-    if ($@) {
-        chomp( my $error = $@ );
-        croak &quot;At &quot;, join( '/', $self-&gt;path ), &quot; with arguments [@$arguments]: $@&quot;;
-    }
-
-    $self-&gt;context-&gt;_remaining_arguments( $arguments );
+    die &quot;Exception at \&quot;&quot;, join( '/', $self-&gt;path ), &quot;\&quot; with arguments [ @$arguments ]: $@&quot; if $@;
 
     while (my ($key, $value) = each %$options) {
         $self-&gt;option( $key =&gt; $value );
         $self-&gt;context-&gt;option( $key =&gt; $value ); # TODO Better way to do this...
     }
 
-    my $last = ! @$arguments;
-
-    unless ($last || $control-&gt;{always_run}) {
+    $self-&gt;_remaining_arguments( $arguments );
+    if ( $control-&gt;{terminator} ) {
+        $self-&gt;context-&gt;_parsing_arguments( [] );
+        $last = 1;
+    }
+    else {
+        $self-&gt;context-&gt;_parsing_arguments( [ @$arguments ] );
+        $last = @$arguments ? 0 : 1; # Same as $ctx-&gt;last, really
+    }
+    
+    unless ( $last || $control-&gt;{always_run} ) {
         warn &quot;Context::Step::run &quot;, $self-&gt;context-&gt;path_as_string, &quot; SKIP\n&quot; if DEBUG;
         return;
     }
 
-    push @arguments, @$arguments; # TODO: Test this
-
-    my $run = $self-&gt;_run;
-    $run-&gt;( $self-&gt;context, @arguments ) if $run;
+    {
+        # on 'A *'
+
+        # A b -x c (Although this is an error condition)
+        # A b -x c      $1 = ''     [ b -x c ]
+        # A/b -x c      $1 = 'b'    [ -x c ] # Error, -x wasn't parsed!
+        # A/b/c         $1 = 'b c'  [ ]
+
+        # A b c d
+        # A b c d       $1 = ''         [ b c d ]
+        # A/b c d       $1 = 'b'        [ c d ]
+        # A/b/c d       $1 = 'b c'      [ d ]
+        # A/b/c/d       $1 = 'b c d'    [ ]
+
+        my @arguments;
+        push @arguments, grep { length } split m/\s+/, $self-&gt;dollar1 if defined $self-&gt;dollar1;
+        push @arguments, @$arguments;
+        my $run = $self-&gt;_run;
+        $run-&gt;( $self-&gt;context, @arguments ) if $run;
+    }
 
     return 1;
 }</diff>
      <filename>lib/Getopt/Chain/Context.pm</filename>
    </modified>
    <modified>
      <diff>@@ -18,33 +18,52 @@ rewrite qr/^\?(.*)/ =&gt; sub { &quot;help &quot;.($1||'') };
 rewrite [ ['about', 'copying'] ] =&gt; sub { &quot;help $1&quot; };
 
 start [qw//], sub {
-    my $context = shift;
-#    push @did, [ $context-&gt;command ]; # always_run is back, so we'll disable this for now
+    my $ctx = shift;
+#    push @did, [ $ctx-&gt;command ]; # always_run is back, so we'll disable this for now
 };
 
 #on 'apple' =&gt; undef, sub {
-#    my $context = shift;
-#    push @did, [ $context-&gt;command ];
+#    my $ctx = shift;
+#    push @did, [ $ctx-&gt;command ];
 #};
 
 on 'apple banana' =&gt; undef, sub {
-    my $context = shift;
+    my $ctx = shift;
     push @did, [ 'apple banana' ];
 };
 
 on 'apple *' =&gt; undef, sub {
-    my $context = shift;
+    my $ctx = shift;
     push @did, [ 'apple' ];
 };
 
+on 'banana cherry' =&gt; sub {
+    my $ctx = shift;
+    warn &quot;@_&quot;;
+};
+
+on 'banana --' =&gt; sub {
+    my $ctx = shift;
+    warn &quot;@_&quot;;
+};
+
+under 'cherry' =&gt; sub {
+
+    on '--' =&gt; sub {
+        my $ctx = shift;
+        warn &quot;@_&quot;;
+    };
+
+};
+
 on help =&gt; undef, sub {
-    my $context = shift;
+    my $ctx = shift;
 
     # Do help stuff ...
     # First argument is undef because help
     # doesn't take any options
     
-    push @did, [ $context-&gt;command, ];
+    push @did, [ $ctx-&gt;command, ];
 };
 
 under help =&gt; sub {
@@ -52,42 +71,42 @@ under help =&gt; sub {
     # my-command help create
     # my-command help initialize
     on [ [ qw/create initialize/ ] ] =&gt; undef, sub {
-        my $context = shift;
+        my $ctx = shift;
 
         # Do help for create/initialize
         # Both: &quot;help create&quot; and &quot;help initialize&quot; go here
 
-        push @did, [ 'help', $context-&gt;command, ];
+        push @did, [ 'help', $ctx-&gt;command, ];
     };
 
     # my-command help about
     on 'about' =&gt; undef, sub {
-        my $context = shift;
+        my $ctx = shift;
 
         # Help for about...
 
-        push @did, [ 'help', $context-&gt;command, ];
+        push @did, [ 'help', $ctx-&gt;command, ];
     };
 
     # my-command help copying
     on 'copying' =&gt; undef, sub {
-        my $context = shift;
+        my $ctx = shift;
 
         # Help for copying...
 
-        push @did, [ 'help', $context-&gt;command, ];
+        push @did, [ 'help', $ctx-&gt;command, ];
     };
 
     # my-command help ...
     # Also, on '*' will sort of work...
     on '*' =&gt; undef, sub {
 #    on qr/^(\S+)$/ =&gt; undef, sub {
-       my $context = shift;
+       my $ctx = shift;
        my $topic = $1;
 
         # Catch-all for anything not fitting into the above...
         
-        push @did, [ 'help', $context-&gt;command, &quot;I don't know about \&quot;$topic\&quot;&quot; ]
+        push @did, [ 'help', $ctx-&gt;command, &quot;I don't know about \&quot;$topic\&quot;&quot; ]
     };
 };
 
@@ -96,21 +115,21 @@ on qr/.*/ =&gt; undef, sub {
 };
 
 #on apple =&gt; [qw/ c3 /], sub {
-#    my $context = shift;
+#    my $ctx = shift;
 #
-#    $context-&gt;option( apple =&gt; 1 );
+#    $ctx-&gt;option( apple =&gt; 1 );
 #};
 #
 #on help =&gt; undef, sub {
-#    my $context = shift;
+#    my $ctx = shift;
 #
-#    $context-&gt;option( help =&gt; 1 );
+#    $ctx-&gt;option( help =&gt; 1 );
 #};
 
 #on 'help xyzzy' =&gt; undef, sub {
-#    my $context = shift;
+#    my $ctx = shift;
 
-#    $context-&gt;option( help_xyzzy =&gt; 1 );
+#    $ctx-&gt;option( help_xyzzy =&gt; 1 );
 #};
 
 no Getopt::Chain::Declare;
@@ -151,3 +170,15 @@ cmp_deeply( \@did, [ [ 'help', 'xyzzy', 'I don\'t know about &quot;xyzzy&quot;'  ] ] );
 
 run qw/about/;
 cmp_deeply( \@did, [ [ 'help', 'about'  ] ] );
+
+# TODO Moar better
+eval {
+    run qw/apple argument --option/;
+};
+ok( $@ );
+
+run qw/banana argument --option/;
+
+run qw/banana cherry argument --option/;
+
+run qw/cherry argument --option/;</diff>
      <filename>t/05-declare-with-argument.t</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>8f108bb920625d4ba3cf7ba4cb79aceac6bf98a7</id>
    </parent>
  </parents>
  <author>
    <name>robertkrimen</name>
    <email>robertkrimen@gmail.com</email>
  </author>
  <url>http://github.com/robertkrimen/Getopt-Chain/commit/c876e1838df74743309955dfe28e5fcf14ac845f</url>
  <id>c876e1838df74743309955dfe28e5fcf14ac845f</id>
  <committed-date>2009-06-07T00:11:38-07:00</committed-date>
  <authored-date>2009-06-07T00:11:38-07:00</authored-date>
  <message>Added '--' path conditional and better builder parsing

Made ::Context and ::Context::Step more explicit with starting_arguments
::Context now uses parsing_arguments (instead of remaining_arguments)
Reinstituted unparsed option-like arguments as a fatal error (except
during --)</message>
  <tree>247616bead9c6656acd264a004fb621975d35c3a</tree>
  <committer>
    <name>robertkrimen</name>
    <email>robertkrimen@gmail.com</email>
  </committer>
</commit>
