Add FindOptionByLongName and FindOptionByShortName
diff --git a/command.go b/command.go
index 5e63ecb..df6bf71 100644
--- a/command.go
+++ b/command.go
@@ -112,6 +112,32 @@
 	return nil
 }
 
+// Find an option that is part of the command, or any of its
+// parent commands, by matching its long name
+// (including the option namespace).
+func (c *Command) FindOptionByLongName(longName string) (option *Option) {
+	for option == nil && c != nil {
+		option = c.Group.FindOptionByLongName(longName)
+
+		c, _ = c.parent.(*Command)
+	}
+
+	return option
+}
+
+// Find an option that is part of the command, or any of its
+// parent commands, by matching its long name
+// (including the option namespace).
+func (c *Command) FindOptionByShortName(shortName rune) (option *Option) {
+	for option == nil && c != nil {
+		option = c.Group.FindOptionByShortName(shortName)
+
+		c, _ = c.parent.(*Command)
+	}
+
+	return option
+}
+
 // Args returns a list of positional arguments associated with this command.
 func (c *Command) Args() []*Arg {
 	ret := make([]*Arg, len(c.args))
diff --git a/command_test.go b/command_test.go
index e64ac45..72d397d 100644
--- a/command_test.go
+++ b/command_test.go
@@ -480,3 +480,65 @@
 		t.Errorf("Expected G to be true")
 	}
 }
+
+func TestSubCommandFindOptionByLongFlag(t *testing.T) {
+	var opts struct {
+		Testing bool `long:"testing" description:"Testing"`
+	}
+
+	var cmd struct {
+		Other bool `long:"other" description:"Other"`
+	}
+
+	p := NewParser(&opts, Default)
+	c, _ := p.AddCommand("command", "Short", "Long", &cmd)
+
+	opt := c.FindOptionByLongName("other")
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	assertString(t, opt.LongName, "other")
+
+	opt = c.FindOptionByLongName("testing")
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	assertString(t, opt.LongName, "testing")
+}
+
+func TestSubCommandFindOptionByShortFlag(t *testing.T) {
+	var opts struct {
+		Testing bool `short:"t" description:"Testing"`
+	}
+
+	var cmd struct {
+		Other bool `short:"o" description:"Other"`
+	}
+
+	p := NewParser(&opts, Default)
+	c, _ := p.AddCommand("command", "Short", "Long", &cmd)
+
+	opt := c.FindOptionByShortName('o')
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	if opt.ShortName != 'o' {
+		t.Errorf("Expected 'o', but got %v", opt.ShortName)
+	}
+
+	opt = c.FindOptionByShortName('t')
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	if opt.ShortName != 't' {
+		t.Errorf("Expected 'o', but got %v", opt.ShortName)
+	}
+}
diff --git a/group.go b/group.go
index 8ab809e..0a40b39 100644
--- a/group.go
+++ b/group.go
@@ -98,6 +98,34 @@
 	return ret
 }
 
+func (g *Group) findOption(matcher func(*Option) bool) (option *Option) {
+	g.eachGroup(func(g *Group) {
+		for _, opt := range g.options {
+			if option == nil && matcher(opt) {
+				option = opt
+			}
+		}
+	})
+
+	return option
+}
+
+// Find an option that is part of the group, or any of its subgroups,
+// by matching its long name (including the option namespace).
+func (g *Group) FindOptionByLongName(longName string) *Option {
+	return g.findOption(func(option *Option) bool {
+		return option.LongNameWithNamespace() == longName
+	})
+}
+
+// Find an option that is part of the group, or any of its subgroups,
+// by matching its short name.
+func (g *Group) FindOptionByShortName(shortName rune) *Option {
+	return g.findOption(func(option *Option) bool {
+		return option.ShortName == shortName
+	})
+}
+
 func newGroup(shortDescription string, longDescription string, data interface{}) *Group {
 	return &Group{
 		ShortDescription: shortDescription,
diff --git a/group_test.go b/group_test.go
index b5ed9d4..18cd6c1 100644
--- a/group_test.go
+++ b/group_test.go
@@ -185,3 +185,71 @@
 		}
 	}
 }
+
+func TestFindOptionByLongFlag(t *testing.T) {
+	var opts struct {
+		Testing bool `long:"testing" description:"Testing"`
+	}
+
+	p := NewParser(&opts, Default)
+	opt := p.FindOptionByLongName("testing")
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	assertString(t, opt.LongName, "testing")
+}
+
+func TestFindOptionByShortFlag(t *testing.T) {
+	var opts struct {
+		Testing bool `short:"t" description:"Testing"`
+	}
+
+	p := NewParser(&opts, Default)
+	opt := p.FindOptionByShortName('t')
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	if opt.ShortName != 't' {
+		t.Errorf("Expected 't', but got %v", opt.ShortName)
+	}
+}
+
+func TestFindOptionByLongFlagInSubGroup(t *testing.T) {
+	var opts struct {
+		Group struct {
+			Testing bool `long:"testing" description:"Testing"`
+		} `group:"sub-group"`
+	}
+
+	p := NewParser(&opts, Default)
+	opt := p.FindOptionByLongName("testing")
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	assertString(t, opt.LongName, "testing")
+}
+
+func TestFindOptionByShortFlagInSubGroup(t *testing.T) {
+	var opts struct {
+		Group struct {
+			Testing bool `short:"t" description:"Testing"`
+		} `group:"sub-group"`
+	}
+
+	p := NewParser(&opts, Default)
+	opt := p.FindOptionByShortName('t')
+
+	if opt == nil {
+		t.Errorf("Expected option, but found none")
+	}
+
+	if opt.ShortName != 't' {
+		t.Errorf("Expected 't', but got %v", opt.ShortName)
+	}
+}