Implement ini option IniCommentDefaults

IniCommentDefaults is only if IniIncludeDefaults is used too. If both
are set options with default values are commtented out when written to the
ini file.
diff --git a/ini.go b/ini.go
index ce95d13..6952cac 100644
--- a/ini.go
+++ b/ini.go
@@ -38,6 +38,10 @@
 	// when writing options to an ini file.
 	IniIncludeDefaults = 1 << iota
 
+	// IniCommentDefaults indicates that if IniIncludeDefaults is used
+	// options with default values are written but commented out.
+	IniCommentDefaults
+
 	// IniIncludeComments indicates that comments containing the description
 	// of an option should be written when writing options to an ini file.
 	IniIncludeComments
diff --git a/ini_private.go b/ini_private.go
index 0371b87..9f56657 100644
--- a/ini_private.go
+++ b/ini_private.go
@@ -96,11 +96,16 @@
 
 		oname := optionIniName(option)
 
+		commentOption := ""
+		if (options&(IniIncludeDefaults|IniCommentDefaults)) == IniIncludeDefaults|IniCommentDefaults && reflect.DeepEqual(val.Interface(), option.defaultValue.Interface()) {
+			commentOption = "; "
+		}
+
 		switch val.Type().Kind() {
 		case reflect.Slice:
 			for idx := 0; idx < val.Len(); idx++ {
 				v, _ := convertToString(val.Index(idx), option.tag)
-				fmt.Fprintf(writer, "%s = %s\n", oname, v)
+				fmt.Fprintf(writer, "%s%s = %s\n", commentOption, oname, v)
 			}
 
 			if val.Len() == 0 {
@@ -111,7 +116,7 @@
 				k, _ := convertToString(key, option.tag)
 				v, _ := convertToString(val.MapIndex(key), option.tag)
 
-				fmt.Fprintf(writer, "%s = %s:%s\n", oname, k, v)
+				fmt.Fprintf(writer, "%s%s = %s:%s\n", commentOption, oname, k, v)
 			}
 
 			if val.Len() == 0 {
@@ -121,9 +126,9 @@
 			v, _ := convertToString(val, option.tag)
 
 			if len(v) != 0 {
-				fmt.Fprintf(writer, "%s = %s\n", oname, v)
+				fmt.Fprintf(writer, "%s%s = %s\n", commentOption, oname, v)
 			} else {
-				fmt.Fprintf(writer, "%s =\n", oname)
+				fmt.Fprintf(writer, "%s%s =\n", commentOption, oname)
 			}
 		}
 
diff --git a/ini_test.go b/ini_test.go
index dfc3e2b..7f78907 100644
--- a/ini_test.go
+++ b/ini_test.go
@@ -66,6 +66,64 @@
 	}
 }
 
+func TestWriteIniCommentDefaults(t *testing.T) {
+	var opts helpOptions
+
+	p := NewNamedParser("TestIni", Default)
+	p.AddGroup("Application Options", "The application options", &opts)
+
+	_, err := p.ParseArgs([]string{"command"})
+
+	if err != nil {
+		t.Fatalf("Unexpected error: %v", err)
+	}
+
+	inip := NewIniParser(p)
+
+	var b bytes.Buffer
+	inip.Write(&b, IniDefault|IniIncludeDefaults|IniCommentDefaults)
+
+	got := b.String()
+	expected := `[Application Options]
+; Show verbose debug information
+; verbose =
+
+; A slice of pointers to string
+; PtrSlice =
+
+; Test default value
+; Default = Some value
+
+; EmptyDescription = false
+
+; Option only available in ini
+; only-ini =
+
+[Other Options]
+; A slice of strings
+; StringSlice = some
+; StringSlice = value
+
+; A map from string to int
+; int-map = a:1
+
+[command.A command]
+; Use for extra verbosity
+; ExtraVerbose =
+
+`
+
+	if got != expected {
+		ret, err := helpDiff(got, expected)
+
+		if err != nil {
+			t.Errorf("Unexpected ini, expected:\n\n%s\n\nbut got\n\n%s", expected, got)
+		} else {
+			t.Errorf("Unexpected ini:\n\n%s", ret)
+		}
+	}
+}
+
 func TestReadIni(t *testing.T) {
 	var opts helpOptions