Ability to mark flags as deprecated

They will not show up in usage or help, but they will still work.
The usage message will print on os.Stderr any time the flag is set.
diff --git a/bool_test.go b/bool_test.go
index fe45b8d..2073590 100644
--- a/bool_test.go
+++ b/bool_test.go
@@ -156,7 +156,8 @@
 func TestInvalidValue(t *testing.T) {
 	var tristate triStateValue
 	f := setUpFlagSet(&tristate)
-	err := f.Parse([]string{"--tristate=invalid"})
+	args := []string{"--tristate=invalid"}
+	_, err := parseReturnStderr(t, f, args)
 	if err == nil {
 		t.Fatal("expected an error but did not get any, tristate has value", tristate)
 	}
diff --git a/flag.go b/flag.go
index 33db47c..ac14b81 100644
--- a/flag.go
+++ b/flag.go
@@ -152,6 +152,7 @@
 	Value       Value               // value as set
 	DefValue    string              // default value (as text); for usage message
 	Changed     bool                // If the user set the value (or if left to default)
+	Deprecated  string              // If this flag is deprecated, this string is the new or now thing to use
 	Annotations map[string][]string // used by cobra.Command  bash autocomple code
 }
 
@@ -243,6 +244,16 @@
 	return f.formal[name]
 }
 
+// Mark a flag deprecated in your program
+func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
+	flag := f.Lookup(name)
+	if flag == nil {
+		return fmt.Errorf("flag %q does not exist", name)
+	}
+	flag.Deprecated = usageMessage
+	return nil
+}
+
 // Lookup returns the Flag structure of the named command-line flag,
 // returning nil if none exists.
 func Lookup(name string) *Flag {
@@ -264,7 +275,10 @@
 		f.actual = make(map[normalizedName]*Flag)
 	}
 	f.actual[normalName] = flag
-	f.lookup(normalName).Changed = true
+	flag.Changed = true
+	if len(flag.Deprecated) > 0 {
+		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
+	}
 	return nil
 }
 
@@ -277,6 +291,9 @@
 // otherwise, the default values of all defined flags in the set.
 func (f *FlagSet) PrintDefaults() {
 	f.VisitAll(func(flag *Flag) {
+		if len(flag.Deprecated) > 0 {
+			return
+		}
 		format := "--%s=%s: %s\n"
 		if _, ok := flag.Value.(*stringValue); ok {
 			// put quotes on the value
@@ -295,6 +312,9 @@
 	x := new(bytes.Buffer)
 
 	f.VisitAll(func(flag *Flag) {
+		if len(flag.Deprecated) > 0 {
+			return
+		}
 		format := "--%s=%s: %s\n"
 		if _, ok := flag.Value.(*stringValue); ok {
 			// put quotes on the value
@@ -466,6 +486,9 @@
 	}
 	f.actual[f.normalizeFlagName(flag.Name)] = flag
 	flag.Changed = true
+	if len(flag.Deprecated) > 0 {
+		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
+	}
 	return nil
 }
 
diff --git a/flag_test.go b/flag_test.go
index c4055ed..a1478e2 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"sort"
@@ -445,3 +446,74 @@
 		t.Errorf("expected argument %q got %q", arg2, f.Args()[1])
 	}
 }
+
+func TestDeprecatedFlagInDocs(t *testing.T) {
+	f := NewFlagSet("bob", ContinueOnError)
+	f.Bool("badflag", true, "always true")
+	f.MarkDeprecated("badflag", "use --good-flag instead")
+
+	out := new(bytes.Buffer)
+	f.SetOutput(out)
+	f.PrintDefaults()
+
+	if strings.Contains(out.String(), "badflag") {
+		t.Errorf("found deprecated flag in usage!")
+	}
+}
+
+func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) {
+	oldStderr := os.Stderr
+	r, w, _ := os.Pipe()
+	os.Stderr = w
+
+	err := f.Parse(args)
+
+	outC := make(chan string)
+	// copy the output in a separate goroutine so printing can't block indefinitely
+	go func() {
+		var buf bytes.Buffer
+		io.Copy(&buf, r)
+		outC <- buf.String()
+	}()
+
+	w.Close()
+	os.Stderr = oldStderr
+	out := <-outC
+
+	return out, err
+}
+
+func TestDeprecatedFlagUsage(t *testing.T) {
+	f := NewFlagSet("bob", ContinueOnError)
+	f.Bool("badflag", true, "always true")
+	usageMsg := "use --good-flag instead"
+	f.MarkDeprecated("badflag", usageMsg)
+
+	args := []string{"--badflag"}
+	out, err := parseReturnStderr(t, f, args)
+	if err != nil {
+		t.Fatal("expected no error; got ", err)
+	}
+
+	if !strings.Contains(out, usageMsg) {
+		t.Errorf("usageMsg not printed when using a deprecated flag!")
+	}
+}
+
+func TestDeprecatedFlagUsageNormalized(t *testing.T) {
+	f := NewFlagSet("bob", ContinueOnError)
+	f.Bool("bad-double_flag", true, "always true")
+	f.SetWordSeparators([]string{"-", "_"})
+	usageMsg := "use --good-flag instead"
+	f.MarkDeprecated("bad_double-flag", usageMsg)
+
+	args := []string{"--bad_double_flag"}
+	out, err := parseReturnStderr(t, f, args)
+	if err != nil {
+		t.Fatal("expected no error; got ", err)
+	}
+
+	if !strings.Contains(out, usageMsg) {
+		t.Errorf("usageMsg not printed when using a deprecated flag!")
+	}
+}