Added support for setting and clearing comments.
Return keys in the order they are in the original input.
Add support for writing properties files with comments.
diff --git a/parser.go b/parser.go
index a7028ca..297326c 100644
--- a/parser.go
+++ b/parser.go
@@ -32,6 +32,9 @@
 			continue
 		case itemKey:
 			key = token.val
+			if _, ok := properties.m[key]; !ok {
+				properties.k = append(properties.k, key)
+			}
 		}
 
 		token = p.expectOneOf(itemValue, itemEOF)
diff --git a/properties.go b/properties.go
index 898320e..ccf91fa 100644
--- a/properties.go
+++ b/properties.go
@@ -45,8 +45,14 @@
 	Prefix  string
 	Postfix string
 
+	// Stores the key/value pairs
 	m map[string]string
+
+	// Stores the comments per key.
 	c map[string][]string
+
+	// Stores the keys in order of appearance.
+	k []string
 }
 
 // NewProperties creates a new Properties struct with the default
@@ -55,8 +61,9 @@
 	return &Properties{
 		Prefix:  "${",
 		Postfix: "}",
-		m:       make(map[string]string),
-		c:       make(map[string][]string),
+		m:       map[string]string{},
+		c:       map[string][]string{},
+		k:       []string{},
 	}
 }
 
@@ -92,8 +99,14 @@
 
 // ----------------------------------------------------------------------------
 
-// GetComment returns the last comment before the given key or an
-// empty string.
+// ClearComments removes the comments for all keys.
+func (p *Properties) ClearComments() {
+	p.c = map[string][]string{}
+}
+
+// ----------------------------------------------------------------------------
+
+// GetComment returns the last comment before the given key or an empty string.
 func (p *Properties) GetComment(key string) string {
 	comments, ok := p.c[key]
 	if !ok || len(comments) == 0 {
@@ -114,6 +127,25 @@
 
 // ----------------------------------------------------------------------------
 
+// SetComment sets the comment for the key.
+func (p *Properties) SetComment(key, comment string) {
+	p.c[key] = []string{comment}
+}
+
+// ----------------------------------------------------------------------------
+
+// SetComments sets the comments for the key. If the comments are nil then
+// all comments for this key are deleted.
+func (p *Properties) SetComments(key string, comments []string) {
+	if comments == nil {
+		delete(p.c, key)
+		return
+	}
+	p.c[key] = comments
+}
+
+// ----------------------------------------------------------------------------
+
 // GetBool checks if the expanded value is one of '1', 'yes',
 // 'true' or 'on' if the key exists. The comparison is case-insensitive.
 // If the key does not exist the default value is returned.
@@ -384,11 +416,11 @@
 	return len(p.m)
 }
 
-// Keys returns all keys.
+// Keys returns all keys in the same order as in the input.
 func (p *Properties) Keys() []string {
-	keys := make([]string, 0, len(p.m))
-	for k, _ := range p.m {
-		keys = append(keys, k)
+	keys := make([]string, len(p.k))
+	for i, k := range p.k {
+		keys[i] = k
 	}
 	return keys
 }
@@ -412,7 +444,7 @@
 // String returns a string of all expanded 'key = value' pairs.
 func (p *Properties) String() string {
 	var s string
-	for key, _ := range p.m {
+	for _, key := range p.k {
 		value, _ := p.Get(key)
 		s = fmt.Sprintf("%s%s = %s\n", s, key, value)
 	}
@@ -420,17 +452,51 @@
 }
 
 // Write writes all unexpanded 'key = value' pairs to the given writer.
-func (p *Properties) Write(w io.Writer, enc Encoding) (int, error) {
-	total := 0
-	for key, value := range p.m {
-		s := fmt.Sprintf("%s = %s\n", encode(key, " :", enc), encode(value, "", enc))
-		n, err := w.Write([]byte(s))
-		if err != nil {
-			return total, err
+// Write returns the number of bytes written and any write error encountered.
+func (p *Properties) Write(w io.Writer, enc Encoding) (n int, err error) {
+	return p.WriteComment(w, "", enc)
+}
+
+// WriteComment writes all unexpanced 'key = value' pairs to the given writer.
+// If prefix is not empty then comments are written with a blank line and the
+// given prefix. The prefix should be either "#" or "!" to be compatible with
+// the properties file format. Otherwise, the properties parser will not be
+// able to read the file back in. It returns the number of bytes written and
+// any write error encountered.
+func (p *Properties) WriteComment(w io.Writer, prefix string, enc Encoding) (n int, err error) {
+	var x int
+
+	for _, key := range p.k {
+		value := p.m[key]
+
+		if prefix != "" {
+			if comments, ok := p.c[key]; ok {
+				// add a blank line between entries but not at the top
+				if len(comments) > 0 && n > 0 {
+					x, err = fmt.Fprintln(w)
+					if err != nil {
+						return
+					}
+					n += x
+				}
+
+				for _, c := range comments {
+					x, err = fmt.Fprintf(w, "%s %s\n", prefix, encode(c, "", enc))
+					if err != nil {
+						return
+					}
+					n += x
+				}
+			}
 		}
-		total += n
+
+		x, err = fmt.Fprintf(w, "%s = %s\n", encode(key, " :", enc), encode(value, "", enc))
+		if err != nil {
+			return
+		}
+		n += x
 	}
-	return total, nil
+	return
 }
 
 // ----------------------------------------------------------------------------
diff --git a/properties_test.go b/properties_test.go
index f0c6e49..a1b02bf 100644
--- a/properties_test.go
+++ b/properties_test.go
@@ -109,6 +109,8 @@
 	{"key=${USER}\nUSER=value", "key", "value", "USER", "value"},
 }
 
+// ----------------------------------------------------------------------------
+
 var commentTests = []struct {
 	input, key, value string
 	comments          []string
@@ -128,6 +130,8 @@
 	{"! comment1\n\n! comment2\n\nkey=value", "key", "value", []string{"comment1", "comment2"}},
 }
 
+// ----------------------------------------------------------------------------
+
 var errorTests = []struct {
 	input, msg string
 }{
@@ -147,6 +151,8 @@
 	{"key=valu${ke", "Malformed expression"},
 }
 
+// ----------------------------------------------------------------------------
+
 var writeTests = []struct {
 	input, output, encoding string
 }{
@@ -165,6 +171,28 @@
 
 // ----------------------------------------------------------------------------
 
+var writeCommentTests = []struct {
+	input, output, encoding string
+}{
+	// ISO-8859-1 tests
+	{"key = value", "key = value\n", "ISO-8859-1"},
+	{"# comment\nkey = value", "# comment\nkey = value\n", "ISO-8859-1"},
+	{"\n# comment\nkey = value", "# comment\nkey = value\n", "ISO-8859-1"},
+	{"# comment\n\nkey = value", "# comment\nkey = value\n", "ISO-8859-1"},
+	{"# comment1\n# comment2\nkey = value", "# comment1\n# comment2\nkey = value\n", "ISO-8859-1"},
+	{"#comment1\nkey1 = value1\n#comment2\nkey2 = value2", "# comment1\nkey1 = value1\n\n# comment2\nkey2 = value2\n", "ISO-8859-1"},
+
+	// UTF-8 tests
+	{"key = value", "key = value\n", "UTF-8"},
+	{"# comment⌘\nkey = value⌘", "# comment⌘\nkey = value⌘\n", "UTF-8"},
+	{"\n# comment⌘\nkey = value⌘", "# comment⌘\nkey = value⌘\n", "UTF-8"},
+	{"# comment⌘\n\nkey = value⌘", "# comment⌘\nkey = value⌘\n", "UTF-8"},
+	{"# comment1⌘\n# comment2⌘\nkey = value⌘", "# comment1⌘\n# comment2⌘\nkey = value⌘\n", "UTF-8"},
+	{"#comment1⌘\nkey1 = value1⌘\n#comment2⌘\nkey2 = value2⌘", "# comment1⌘\nkey1 = value1⌘\n\n# comment2⌘\nkey2 = value2⌘\n", "UTF-8"},
+}
+
+// ----------------------------------------------------------------------------
+
 var boolTests = []struct {
 	input, key string
 	def, value bool
@@ -299,6 +327,7 @@
 	{"", []string{}},
 	{"key = abc", []string{"key"}},
 	{"key = abc\nkey2=def", []string{"key", "key2"}},
+	{"key2 = abc\nkey=def", []string{"key2", "key"}},
 	{"key = abc\nkey=def", []string{"key"}},
 }
 
@@ -530,6 +559,26 @@
 		} else {
 			c.Assert(p.GetComment(test.key), Equals, "")
 		}
+
+		// test setting comments
+		if len(test.comments) > 0 {
+			// set single comment
+			p.ClearComments()
+			c.Assert(len(p.c), Equals, 0)
+			p.SetComment(test.key, test.comments[0])
+			c.Assert(p.GetComment(test.key), Equals, test.comments[0])
+
+			// set multiple comments
+			p.ClearComments()
+			c.Assert(len(p.c), Equals, 0)
+			p.SetComments(test.key, test.comments)
+			c.Assert(p.GetComments(test.key), DeepEquals, test.comments)
+
+			// clear comments for a key
+			p.SetComments(test.key, nil)
+			c.Assert(p.GetComment(test.key), Equals, "")
+			c.Assert(p.GetComments(test.key), IsNil)
+		}
 	}
 }
 
@@ -577,12 +626,10 @@
 		c.Assert(err, IsNil)
 		c.Assert(p.Len(), Equals, len(test.keys))
 		c.Assert(len(p.Keys()), Equals, len(test.keys))
-		for _, key := range test.keys {
-			_, ok := p.Get(key)
-			c.Assert(ok, Equals, true)
-		}
+		c.Assert(p.Keys(), DeepEquals, test.keys)
 	}
 }
+
 func (l *TestSuite) TestWrite(c *C) {
 	for _, test := range writeTests {
 		p, err := parse(test.input)
@@ -602,6 +649,25 @@
 	}
 }
 
+func (l *TestSuite) TestWriteComment(c *C) {
+	for _, test := range writeCommentTests {
+		p, err := parse(test.input)
+
+		buf := new(bytes.Buffer)
+		var n int
+		switch test.encoding {
+		case "UTF-8":
+			n, err = p.WriteComment(buf, "#", UTF8)
+		case "ISO-8859-1":
+			n, err = p.WriteComment(buf, "#", ISO_8859_1)
+		}
+		c.Assert(err, IsNil)
+		s := string(buf.Bytes())
+		c.Assert(n, Equals, len(test.output), Commentf("input=%q expected=%q obtained=%q", test.input, test.output, s))
+		c.Assert(s, Equals, test.output, Commentf("input=%q expected=%q obtained=%q", test.input, test.output, s))
+	}
+}
+
 func (l *TestSuite) TestCustomExpansionExpression(c *C) {
 	testKeyValuePrePostfix(c, "*[", "]*", "key=value\nkey2=*[key]*", "key", "value", "key2", "value")
 }