Do not parse commands after seeing a non-option non-command arg

Fixes #170.
diff --git a/command_test.go b/command_test.go
index e7e3089..dc04b66 100644
--- a/command_test.go
+++ b/command_test.go
@@ -441,6 +441,20 @@
 	}
 }
 
+func TestAfterNonCommand(t *testing.T) {
+	var opts = struct {
+		Value bool `short:"v"`
+
+		Cmd1 struct {
+		} `command:"remove"`
+
+		Cmd2 struct {
+		} `command:"add"`
+	}{}
+
+	assertParseFail(t, ErrUnknownCommand, "Unknown command `nocmd'. Please specify one command of: add or remove", &opts, "nocmd", "remove")
+}
+
 func TestSubcommandsOptional(t *testing.T) {
 	var opts = struct {
 		Value bool `short:"v"`
@@ -467,6 +481,30 @@
 	}
 }
 
+func TestSubcommandsOptionalAfterNonCommand(t *testing.T) {
+	var opts = struct {
+		Value bool `short:"v"`
+
+		Cmd1 struct {
+		} `command:"remove"`
+
+		Cmd2 struct {
+		} `command:"add"`
+	}{}
+
+	p := NewParser(&opts, None)
+	p.SubcommandsOptional = true
+
+	retargs, err := p.ParseArgs([]string{"nocmd", "remove"})
+
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+		return
+	}
+
+	assertStringArray(t, retargs, []string{"nocmd", "remove"})
+}
+
 func TestCommandAlias(t *testing.T) {
 	var opts = struct {
 		Command struct {
diff --git a/parser.go b/parser.go
index 2290941..a52647c 100644
--- a/parser.go
+++ b/parser.go
@@ -620,10 +620,19 @@
 		return s.addArgs(s.arg)
 	}
 
-	if cmd := s.lookup.commands[s.arg]; cmd != nil {
-		s.command.Active = cmd
-		cmd.fillParseState(s)
-	} else if (p.Options & PassAfterNonOption) != None {
+	if len(s.command.commands) > 0 && len(s.retargs) == 0 {
+		if cmd := s.lookup.commands[s.arg]; cmd != nil {
+			s.command.Active = cmd
+			cmd.fillParseState(s)
+
+			return nil
+		} else if !s.command.SubcommandsOptional {
+			s.addArgs(s.arg)
+			return newErrorf(ErrUnknownCommand, "Unknown command `%s'", s.arg)
+		}
+	}
+
+	if (p.Options & PassAfterNonOption) != None {
 		// If PassAfterNonOption is set then all remaining arguments
 		// are considered positional
 		if err := s.addArgs(s.arg); err != nil {