Merge pull request #8 from pascaldekloe/flag-binding

New flag integration
diff --git a/README.md b/README.md
index da3af46..b3b2e5c 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,10 @@
 ---------------
 
 ```go
-import "github.com/magiconair/properties"
+import (
+	"flag"
+	"github.com/magiconair/properties"
+)
 
 func main() {
 	p := properties.MustLoadFile("${HOME}/config.properties", properties.UTF8)
@@ -39,7 +42,7 @@
 	host := p.MustGetString("host")
 	port := p.GetInt("port", 8080)
 
-    // or via decode
+	// or via decode
 	type Config struct {
 		Host    string        `properties:"host"`
 		Port    int           `properties:"port,default=9000"`
@@ -50,6 +53,9 @@
 	if err := p.Decode(&cfg); err != nil {
 		log.Fatal(err)
 	}
+
+	// or via flags
+	p.MustFlag(flag.CommandLine)
 }
 
 ```
diff --git a/doc.go b/doc.go
index 6bca5cb..1d3fb86 100644
--- a/doc.go
+++ b/doc.go
@@ -102,6 +102,16 @@
 //   v = p.GetString("key", "def")
 //   v = p.GetDuration("key", 999)
 //
+// As an alterantive properties may be applied with the standard
+// library's flag implementation at any time.
+//
+//   # Standard configuration
+//   v = flag.Int("key", 999, "help message")
+//   flag.Parse()
+//
+//   # Merge p into the flag set
+//   p.MustFlag(flag.CommandLine)
+//
 // Properties provides several MustXXX() convenience functions
 // which will terminate the app if an error occurs. The behavior
 // of the failure is configurable and the default is to call
diff --git a/integrate.go b/integrate.go
new file mode 100644
index 0000000..1e97290
--- /dev/null
+++ b/integrate.go
@@ -0,0 +1,30 @@
+package properties
+
+import "flag"
+
+// MustFlag sets flags that are skipped by dst.Parse when p contains
+// the respective key for flag.Flag.Name.
+//
+// It's use is recommended with command line arguments as in:
+// 	flag.Parse()
+// 	p.MustFlag(flag.CommandLine)
+func (p *Properties) MustFlag(dst *flag.FlagSet) {
+	m := make(map[string]*flag.Flag)
+	dst.VisitAll(func(f *flag.Flag) {
+		m[f.Name] = f
+	})
+	dst.Visit(func(f *flag.Flag) {
+		delete(m, f.Name) // overridden
+	})
+
+	for name, f := range m {
+		v, ok := p.Get(name)
+		if !ok {
+			continue
+		}
+
+		if err := f.Value.Set(v); err != nil {
+			ErrorHandler(err)
+		}
+	}
+}
diff --git a/integrate_test.go b/integrate_test.go
new file mode 100644
index 0000000..90daaa2
--- /dev/null
+++ b/integrate_test.go
@@ -0,0 +1,70 @@
+package properties
+
+import (
+	"flag"
+	"fmt"
+	"testing"
+)
+
+// TestFlag verifies Properties.MustFlag without flag.FlagSet.Parse
+func TestFlag(t *testing.T) {
+	f := flag.NewFlagSet("src", flag.PanicOnError)
+	gotS := f.String("s", "?", "string flag")
+	gotI := f.Int("i", -1, "int flag")
+
+	p := NewProperties()
+	p.Set("s", "t")
+	p.Set("i", "9")
+	p.MustFlag(f)
+
+	if want := "t"; *gotS != want {
+		t.Errorf("Got string s=%q, want %q", *gotS, want)
+	}
+	if want := 9; *gotI != want {
+		t.Errorf("Got int i=%d, want %d", *gotI, want)
+	}
+}
+
+// TestFlagOverride verifies Properties.MustFlag with flag.FlagSet.Parse.
+func TestFlagOverride(t *testing.T) {
+	f := flag.NewFlagSet("src", flag.PanicOnError)
+	gotA := f.Int("a", 1, "remain default")
+	gotB := f.Int("b", 2, "customized")
+	gotC := f.Int("c", 3, "overridden")
+
+	f.Parse([]string{"-c", "4"})
+
+	p := NewProperties()
+	p.Set("b", "5")
+	p.Set("c", "6")
+	p.MustFlag(f)
+
+	if want := 1; *gotA != want {
+		t.Errorf("Got remain default a=%d, want %d", *gotA, want)
+	}
+	if want := 5; *gotB != want {
+		t.Errorf("Got customized b=%d, want %d", *gotB, want)
+	}
+	if want := 4; *gotC != want {
+		t.Errorf("Got overriden c=%d, want %d", *gotC, want)
+	}
+}
+
+func ExampleProperties_MustFlag() {
+	x := flag.Int("x", 0, "demo customize")
+	y := flag.Int("y", 0, "demo override")
+
+	// Demo alternative for flag.Parse():
+	flag.CommandLine.Parse([]string{"-y", "10"})
+	fmt.Printf("flagged as x=%d, y=%d\n", *x, *y)
+
+	p := NewProperties()
+	p.Set("x", "7")
+	p.Set("y", "42") // note discard
+	p.MustFlag(flag.CommandLine)
+	fmt.Printf("configured to x=%d, y=%d\n", *x, *y)
+
+	// Output:
+	// flagged as x=0, y=10
+	// configured to x=7, y=10
+}