Check required after parsing
diff --git a/command_private.go b/command_private.go
index bd97cc7..7c7c53c 100644
--- a/command_private.go
+++ b/command_private.go
@@ -11,7 +11,6 @@
 	shortNames map[string]*Option
 	longNames  map[string]*Option
 
-	required map[*Option]bool
 	commands map[string]*Command
 }
 
@@ -104,17 +103,11 @@
 	ret := lookup{
 		shortNames: make(map[string]*Option),
 		longNames:  make(map[string]*Option),
-
-		required: make(map[*Option]bool),
 		commands: make(map[string]*Command),
 	}
 
 	c.eachGroup(func(g *Group) {
 		for _, option := range g.options {
-			if option.Required && option.canCli() {
-				ret.required[option] = true
-			}
-
 			if option.ShortName != 0 {
 				ret.shortNames[string(option.ShortName)] = option
 			}
diff --git a/parser.go b/parser.go
index b6889cf..8fe4f78 100644
--- a/parser.go
+++ b/parser.go
@@ -162,15 +162,14 @@
 		}
 
 		var err error
-		var options []*Option
 
 		prefix, optname, islong := stripOptionPrefix(arg)
 		optname, argument := splitOption(prefix, optname, islong)
 
 		if islong {
-			options, err = p.parseLong(s, optname, argument)
+			err = p.parseLong(s, optname, argument)
 		} else {
-			options, err = p.parseShort(s, optname, argument)
+			err = p.parseShort(s, optname, argument)
 		}
 
 		if err != nil {
@@ -185,10 +184,6 @@
 			if ignoreUnknown {
 				s.retargs = append(s.retargs, arg)
 			}
-		} else {
-			for _, option := range options {
-				delete(s.lookup.required, option)
-			}
 		}
 	}
 
@@ -205,7 +200,7 @@
 			})
 		}, true)
 
-		s.checkRequired()
+		s.checkRequired(p)
 	}
 
 	var reterr error
diff --git a/parser_private.go b/parser_private.go
index 47fbd4e..23b0ee9 100644
--- a/parser_private.go
+++ b/parser_private.go
@@ -42,8 +42,22 @@
 	return p.args[0]
 }
 
-func (p *parseState) checkRequired() error {
-	required := p.lookup.required
+func (p *parseState) checkRequired(parser *Parser) error {
+	c := parser.Command
+
+	required := make([]*Option, 0)
+
+	for c != nil {
+		c.eachGroup(func (g *Group) {
+			for _, option := range g.options {
+				if !option.isSet && option.Required {
+					required = append(required, option)
+				}
+			}
+		})
+
+		c = c.Active
+	}
 
 	if len(required) == 0 {
 		return nil
@@ -51,7 +65,7 @@
 
 	names := make([]string, 0, len(required))
 
-	for k := range required {
+	for _, k := range required {
 		names = append(names, "`"+k.String()+"'")
 	}
 
@@ -155,20 +169,16 @@
 	return err
 }
 
-func (p *Parser) parseLong(s *parseState, name string, argument *string) (options []*Option, err error) {
+func (p *Parser) parseLong(s *parseState, name string, argument *string) error {
 	if option := s.lookup.longNames[name]; option != nil {
-		options = append(options, option)
-
 		// Only long options that are required can consume an argument
 		// from the argument list
 		canarg := !option.OptionalArgument
 
-		err := p.parseOption(s, name, option, canarg, argument)
-
-		return options, err
+		return p.parseOption(s, name, option, canarg, argument)
 	}
 
-	return nil, newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", name))
+	return newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", name))
 }
 
 func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) {
@@ -188,7 +198,7 @@
 	return optname, nil
 }
 
-func (p *Parser) parseShort(s *parseState, optname string, argument *string) (options []*Option, err error) {
+func (p *Parser) parseShort(s *parseState, optname string, argument *string) error {
 	if argument == nil {
 		optname, argument = p.splitShortConcatArg(s, optname)
 	}
@@ -197,17 +207,15 @@
 		shortname := string(c)
 
 		if option := s.lookup.shortNames[shortname]; option != nil {
-			options = append(options, option)
-
 			// Only the last short argument can consume an argument from
 			// the arguments list, and only if it's non optional
 			canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument
 
 			if err := p.parseOption(s, shortname, option, canarg, argument); err != nil {
-				return options, err
+				return err
 			}
 		} else {
-			return nil, newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", shortname))
+			return newError(ErrUnknownFlag, fmt.Sprintf("unknown flag `%s'", shortname))
 		}
 
 		// Only the first option can have a concatted argument, so just
@@ -215,15 +223,11 @@
 		argument = nil
 	}
 
-	return options, nil
+	return nil
 }
 
 func (p *Parser) parseNonOption(s *parseState) error {
 	if cmd := s.lookup.commands[s.arg]; cmd != nil {
-		if err := s.checkRequired(); err != nil {
-			return err
-		}
-
 		s.command.Active = cmd
 
 		s.command = cmd