Refactored to closely follow RFC5322
diff --git a/parsemail_test.go b/parsemail_test.go
index 402ff11..6e2153c 100644
--- a/parsemail_test.go
+++ b/parsemail_test.go
@@ -11,47 +11,154 @@
 )
 
 func TestParseEmail(t *testing.T) {
-	var testData = []struct{
+	var testData = map[int]struct{
 		mailData string
 
 		subject string
-		from []string
-		sender string
-		to []string
-		replyTo []string
-		cc []string
-		bcc []string
+		date time.Time
+		from []mail.Address
+		sender mail.Address
+		to []mail.Address
+		replyTo []mail.Address
+		cc []mail.Address
+		bcc []mail.Address
 		messageID string
+		resentDate time.Time
+		resentFrom []mail.Address
+		resentSender mail.Address
+		resentTo []mail.Address
+		resentReplyTo []mail.Address
+		resentCc []mail.Address
+		resentBcc []mail.Address
+		resentMessageID string
 		inReplyTo []string
 		references []string
-		date time.Time
 		htmlBody string
 		textBody string
 		attachments []attachmentData
 		embeddedFiles []embeddedFileData
 		headerCheck func (mail.Header, *testing.T)
 	}{
-		{
+		1: {
+			mailData: RFC5322_Example_A11,
+			subject: "Saying Hello",
+			from: []mail.Address{
+				{"John Doe", "jdoe@machine.example"},
+			},
+			to: []mail.Address{
+				{"Mary Smith", "mary@example.net"},
+			},
+			sender: mail.Address{"Michael Jones", "mjones@machine.example"},
+			messageID: "1234@local.machine.example",
+			date: parseDate("Fri, 21 Nov 1997 09:55:06 -0600"),
+			textBody: `This is a message just to say hello.
+So, "Hello".`,
+		},
+		2: {
+			mailData: RFC5322_Example_A12,
+			from: []mail.Address{
+				{"Joe Q. Public", "john.q.public@example.com"},
+			},
+			to: []mail.Address{
+				{"Mary Smith", "mary@x.test"},
+				{"", "jdoe@example.org"},
+				{"Who?", "one@y.test"},
+			},
+			cc: []mail.Address{
+				{"", "boss@nil.test"},
+				{"Giant; \"Big\" Box", "sysservices@example.net"},
+			},
+			messageID: "5678.21-Nov-1997@example.com",
+			date: parseDate("Tue, 01 Jul 2003 10:52:37 +0200"),
+			textBody: `Hi everyone.`,
+		},
+		3: {
+			mailData: RFC5322_Example_A2a,
+			subject: "Re: Saying Hello",
+			from: []mail.Address{
+				{"Mary Smith", "mary@example.net"},
+			},
+			replyTo: []mail.Address{
+				{"Mary Smith: Personal Account", "smith@home.example"},
+			},
+			to: []mail.Address{
+				{"John Doe", "jdoe@machine.example"},
+			},
+			messageID: "3456@example.net",
+			inReplyTo: []string{"1234@local.machine.example"},
+			references: []string{"1234@local.machine.example"},
+			date: parseDate("Fri, 21 Nov 1997 10:01:10 -0600"),
+			textBody: `This is a reply to your hello.`,
+		},
+		4: {
+			mailData: RFC5322_Example_A2b,
+			subject: "Re: Saying Hello",
+			from: []mail.Address{
+				{"John Doe", "jdoe@machine.example"},
+			},
+			to: []mail.Address{
+				{"Mary Smith: Personal Account", "smith@home.example"},
+			},
+			messageID: "abcd.1234@local.machine.test",
+			inReplyTo: []string{"3456@example.net"},
+			references: []string{"1234@local.machine.example", "3456@example.net"},
+			date: parseDate("Fri, 21 Nov 1997 11:00:00 -0600"),
+			textBody: `This is a reply to your reply.`,
+		},
+		5: {
+			mailData: RFC5322_Example_A3,
+			subject: "Saying Hello",
+			from: []mail.Address{
+				{"John Doe", "jdoe@machine.example"},
+			},
+			to: []mail.Address{
+				{"Mary Smith", "mary@example.net"},
+			},
+			messageID: "1234@local.machine.example",
+			date: parseDate("Fri, 21 Nov 1997 09:55:06 -0600"),
+			resentFrom: []mail.Address{
+				{"Mary Smith", "mary@example.net"},
+			},
+			resentTo: []mail.Address{
+				{"Jane Brown", "j-brown@other.example"},
+			},
+			resentMessageID: "78910@example.net",
+			resentDate: parseDate("Mon, 24 Nov 1997 14:22:01 -0800"),
+			textBody: `This is a message just to say hello.
+So, "Hello".`,
+		},
+		6: {
 			mailData: Data1,
 			subject: "Test Subject 1",
-			from: []string{"Peter Paholík <peter.paholik@gmail.com>"},
-			to: []string{"dusan@kasan.sk"},
+			from: []mail.Address{
+				{"Peter Paholík", "peter.paholik@gmail.com"},
+			},
+			to: []mail.Address{
+				{"", "dusan@kasan.sk"},
+			},
 			messageID: "CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com",
 			date: parseDate("Fri, 07 Apr 2017 09:17:26 +0200"),
 			htmlBody: "<div dir=\"ltr\"><br></div>",
 			attachments: []attachmentData{
 				{
 					filename: "Peter Paholík 1 4 2017 2017-04-07.pdf",
+					contentType: "application/pdf",
 					base64data: "JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vT3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25kZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=",
 				},
 			},
 		},
-		{
+		7: {
 			mailData: Data2,
 			subject: "Re: Test Subject 2",
-			from: []string{"Sender Man <sender@domain.com>"},
-			to: []string{"info@receiver.com"},
-			cc: []string{"Cc Man <ccman@gmail.com>"},
+			from: []mail.Address{
+				{"Sender Man", "sender@domain.com"},
+			},
+			to: []mail.Address{
+				{"", "info@receiver.com"},
+			},
+			cc: []mail.Address{
+				{"Cc Man", "ccman@gmail.com"},
+			},
 			messageID: "0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com",
 			inReplyTo: []string{"9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu"},
 			references: []string{"2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com", "9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com"},
@@ -65,75 +172,119 @@
 			embeddedFiles: []embeddedFileData{
 				{
 					cid: "part2.9599C449.04E5EC81@develhell.com",
+					contentType: "image/png",
 					base64data: "iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwYYKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==",
 				},
 			},
 		},
 	}
 
-	for _, td := range testData {
+	for index, td := range testData {
 		e, err := parsemail.Parse(strings.NewReader(td.mailData))
 		if err != nil {
 			t.Error(err)
 		}
 
-		if td.subject != e.Subject() {
-			t.Errorf("Wrong subject. Expected: %s, Got: %s", td.subject, e.Subject())
+		if td.subject != e.Subject {
+			t.Errorf("[Test Case %v] Wrong subject. Expected: %s, Got: %s", index, td.subject, e.Subject)
 		}
 
-		if td.sender != e.Sender() {
-			t.Errorf("Wrong sender. Expected: %s, Got: %s", td.sender, e.Sender())
+		if td.messageID != e.MessageID {
+			t.Errorf("[Test Case %v] Wrong messageID. Expected: '%s', Got: '%s'", index, td.messageID, e.MessageID)
 		}
 
-		if !assertSliceEq(td.from, e.From()) {
-			t.Errorf("Wrong from. Expected: %s, Got: %s", td.from, e.From())
+		if !td.date.Equal(e.Date) {
+			t.Errorf("[Test Case %v] Wrong date. Expected: %v, Got: %v", index, td.date, e.Date)
 		}
 
-		if !assertSliceEq(td.inReplyTo, e.InReplyTo()) {
-			t.Errorf("Wrong in reply to. Expected: %s, Got: %s", td.inReplyTo, e.InReplyTo())
+		d := dereferenceAddressList(e.From)
+		if !assertAddressListEq(td.from, d) {
+			t.Errorf("[Test Case %v] Wrong from. Expected: %s, Got: %s", index, td.from, d)
 		}
 
-		if !assertSliceEq(td.references, e.References()) {
-			t.Errorf("Wrong references. Expected: %s, Got: %s", td.references, e.References())
+		var sender mail.Address
+		if e.Sender != nil {
+			sender = *e.Sender
+		}
+		if td.sender != sender {
+			t.Errorf("[Test Case %v] Wrong sender. Expected: %s, Got: %s", index, td.sender, sender)
 		}
 
-		if !assertSliceEq(td.to, e.To()) {
-			t.Errorf("Wrong to. Expected: %s, Got: %s", td.to, e.To())
+		d = dereferenceAddressList(e.To)
+		if !assertAddressListEq(td.to, d) {
+			t.Errorf("[Test Case %v] Wrong to. Expected: %s, Got: %s", index, td.to, d)
 		}
 
-		if !assertSliceEq(td.replyTo, e.ReplyTo()) {
-			t.Errorf("Wrong reply to. Expected: %s, Got: %s", td.replyTo, e.ReplyTo())
+		d = dereferenceAddressList(e.Cc)
+		if !assertAddressListEq(td.cc, d) {
+			t.Errorf("[Test Case %v] Wrong cc. Expected: %s, Got: %s", index, td.cc, d)
 		}
 
-		if !assertSliceEq(td.cc, e.Cc()) {
-			t.Errorf("Wrong cc. Expected: %s, Got: %s", td.cc, e.Cc())
+		d = dereferenceAddressList(e.Bcc)
+		if !assertAddressListEq(td.bcc, d) {
+			t.Errorf("[Test Case %v] Wrong bcc. Expected: %s, Got: %s", index, td.bcc, d)
 		}
 
-		if !assertSliceEq(td.bcc, e.Bcc()) {
-			t.Errorf("Wrong cc. Expected: %s, Got: %s", td.cc, e.Cc())
+		if td.resentMessageID != e.ResentMessageID {
+			t.Errorf("[Test Case %v] Wrong resent messageID. Expected: '%s', Got: '%s'", index, td.resentMessageID, e.ResentMessageID)
 		}
 
-		date, err := e.Date()
-		if err != nil {
-			t.Error(err)
-		} else if td.date != date {
-			t.Errorf("Wrong date. Expected: %v, Got: %v", td.date, date)
+		if !td.resentDate.Equal(e.ResentDate) && !td.resentDate.IsZero() && !e.ResentDate.IsZero() {
+			t.Errorf("[Test Case %v] Wrong resent date. Expected: %v, Got: %v", index, td.resentDate, e.ResentDate)
+		}
+
+		d = dereferenceAddressList(e.ResentFrom)
+		if !assertAddressListEq(td.resentFrom, d) {
+			t.Errorf("[Test Case %v] Wrong resent from. Expected: %s, Got: %s", index, td.resentFrom, d)
+		}
+
+		var resentSender mail.Address
+		if e.ResentSender != nil {
+			resentSender = *e.ResentSender
+		}
+		if td.resentSender != resentSender {
+			t.Errorf("[Test Case %v] Wrong resent sender. Expected: %s, Got: %s", index, td.resentSender, resentSender)
+		}
+
+		d = dereferenceAddressList(e.ResentTo)
+		if !assertAddressListEq(td.resentTo, d) {
+			t.Errorf("[Test Case %v] Wrong resent to. Expected: %s, Got: %s", index, td.resentTo, d)
+		}
+
+		d = dereferenceAddressList(e.ResentCc)
+		if !assertAddressListEq(td.resentCc, d) {
+			t.Errorf("[Test Case %v] Wrong resent cc. Expected: %s, Got: %s", index, td.resentCc, d)
+		}
+
+		d = dereferenceAddressList(e.ResentBcc)
+		if !assertAddressListEq(td.resentBcc, d) {
+			t.Errorf("[Test Case %v] Wrong resent bcc. Expected: %s, Got: %s", index, td.resentBcc, d)
+		}
+
+		if !assertSliceEq(td.inReplyTo, e.InReplyTo) {
+			t.Errorf("[Test Case %v] Wrong in reply to. Expected: %s, Got: %s", index, td.inReplyTo, e.InReplyTo)
+		}
+
+		if !assertSliceEq(td.references, e.References) {
+			t.Errorf("[Test Case %v] Wrong references. Expected: %s, Got: %s", index, td.references, e.References)
+		}
+
+		d = dereferenceAddressList(e.ReplyTo)
+		if !assertAddressListEq(td.replyTo, d) {
+			t.Errorf("[Test Case %v] Wrong reply to. Expected: %s, Got: %s", index, td.replyTo, d)
 		}
 
 		if td.htmlBody != e.HTMLBody {
-			t.Errorf("Wrong html body. Expected: '%s', Got: '%s'", td.htmlBody, e.HTMLBody)
+			t.Errorf("[Test Case %v] Wrong html body. Expected: '%s', Got: '%s'", index, td.htmlBody, e.HTMLBody)
 		}
 
 		if td.textBody != e.TextBody {
-			t.Errorf("Wrong text body. Expected: '%s', Got: '%s'", td.textBody, e.TextBody)
+			t.Errorf("[Test Case %v] Wrong text body. Expected: '%s', Got: '%s'", index, td.textBody, e.TextBody)
 		}
 
-		if td.messageID != e.MessageID() {
-			t.Errorf("Wrong messageID. Expected: '%s', Got: '%s'", td.messageID, e.MessageID())
-		}
 
 		if len(td.attachments) != len(e.Attachments) {
-			t.Errorf("Incorrect number of attachments! Expected: %v, Got: %v.", len(td.attachments), len(e.Attachments))
+			t.Errorf("[Test Case %v] Incorrect number of attachments! Expected: %v, Got: %v.", index, len(td.attachments), len(e.Attachments))
 		} else {
 			attachs := e.Attachments[:]
 
@@ -147,24 +298,24 @@
 					}
 
 					encoded := base64.StdEncoding.EncodeToString(b)
-					if ra.Filename == ad.filename && encoded == ad.base64data {
+					if ra.Filename == ad.filename && encoded == ad.base64data && ra.ContentType == ad.contentType {
 						found = true
 						attachs = append(attachs[:i], attachs[i+1:]...)
 					}
 				}
 
 				if !found {
-					t.Errorf("Attachment not found: %s", ad.filename)
+					t.Errorf("[Test Case %v] Attachment not found: %s", index, ad.filename)
 				}
 			}
 
 			if len(attachs) != 0 {
-				t.Errorf("Email contains %v unexpected attachments: %v", len(attachs), attachs)
+				t.Errorf("[Test Case %v] Email contains %v unexpected attachments: %v", index, len(attachs), attachs)
 			}
 		}
 
 		if len(td.embeddedFiles) != len(e.EmbeddedFiles) {
-			t.Errorf("Incorrect number of embedded files! Expected: %s, Got: %s.", len(td.embeddedFiles), len(e.EmbeddedFiles))
+			t.Errorf("[Test Case %v] Incorrect number of embedded files! Expected: %s, Got: %s.", index, len(td.embeddedFiles), len(e.EmbeddedFiles))
 		} else {
 			embeds := e.EmbeddedFiles[:]
 
@@ -179,19 +330,19 @@
 
 					encoded := base64.StdEncoding.EncodeToString(b)
 
-					if ra.CID == ad.cid && encoded == ad.base64data {
+					if ra.CID == ad.cid && encoded == ad.base64data && ra.ContentType == ad.contentType {
 						found = true
 						embeds = append(embeds[:i], embeds[i+1:]...)
 					}
 				}
 
 				if !found {
-					t.Errorf("Embedded file not found: %s", ad.cid)
+					t.Errorf("[Test Case %v] Embedded file not found: %s", index, ad.cid)
 				}
 			}
 
 			if len(embeds) != 0 {
-				t.Errorf("Email contains %v unexpected embedded files: %v", len(embeds), embeds)
+				t.Errorf("[Test Case %v] Email contains %v unexpected embedded files: %v", index, len(embeds), embeds)
 			}
 		}
 	}
@@ -208,11 +359,13 @@
 
 type attachmentData struct{
 	filename string
+	contentType string
 	base64data string
 }
 
 type embeddedFileData struct{
 	cid string
+	contentType string
 	base64data string
 }
 
@@ -242,6 +395,40 @@
 	return true
 }
 
+func assertAddressListEq(a, b []mail.Address) bool {
+	if len(a) == len(b) && len(a) == 0 {
+		return true
+	}
+
+	if a == nil && b == nil {
+		return true;
+	}
+
+	if a == nil || b == nil {
+		return false;
+	}
+
+	if len(a) != len(b) {
+		return false
+	}
+
+	for i := range a {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+
+	return true
+}
+
+func dereferenceAddressList(al []*mail.Address) (result []mail.Address) {
+	for _, a := range(al) {
+		result = append(result, *a)
+	}
+
+	return
+}
+
 var Data1 = `From: =?UTF-8?Q?Peter_Pahol=C3=ADk?= <peter.paholik@gmail.com>
 Date: Fri, 7 Apr 2017 09:17:26 +0200
 Message-ID: <CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com>
@@ -327,4 +514,88 @@
 --------------5DB4A1356834BB602A5F88B2
 
 --------------C70C0458A558E585ACB75FB4--
-`
\ No newline at end of file
+`
+
+var RFC5322_Example_A11 = `From: John Doe <jdoe@machine.example>
+Sender: Michael Jones <mjones@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+`
+
+var RFC5322_Example_A12 = `From: "Joe Q. Public" <john.q.public@example.com>
+To: Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>
+Cc: <boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>
+Date: Tue, 1 Jul 2003 10:52:37 +0200
+Message-ID: <5678.21-Nov-1997@example.com>
+
+Hi everyone.
+`
+
+//todo: not yet implemented in net/mail
+//once there is support for this, add it
+var RFC5322_Example_A13 = `From: Pete <pete@silly.example>
+To: A Group:Ed Jones <c@a.test>,joe@where.test,John <jdoe@one.test>;
+Cc: Undisclosed recipients:;
+Date: Thu, 13 Feb 1969 23:32:54 -0330
+Message-ID: <testabcd.1234@silly.example>
+
+Testing.
+`
+
+//we skipped the first message bcause it's the same as A 1.1
+var RFC5322_Example_A2a = `From: Mary Smith <mary@example.net>
+To: John Doe <jdoe@machine.example>
+Reply-To: "Mary Smith: Personal Account" <smith@home.example>
+Subject: Re: Saying Hello
+Date: Fri, 21 Nov 1997 10:01:10 -0600
+Message-ID: <3456@example.net>
+In-Reply-To: <1234@local.machine.example>
+References: <1234@local.machine.example>
+
+This is a reply to your hello.
+`
+
+var RFC5322_Example_A2b = `To: "Mary Smith: Personal Account" <smith@home.example>
+From: John Doe <jdoe@machine.example>
+Subject: Re: Saying Hello
+Date: Fri, 21 Nov 1997 11:00:00 -0600
+Message-ID: <abcd.1234@local.machine.test>
+In-Reply-To: <3456@example.net>
+References: <1234@local.machine.example> <3456@example.net>
+
+This is a reply to your reply.
+`
+
+var RFC5322_Example_A3 = `Resent-From: Mary Smith <mary@example.net>
+Resent-To: Jane Brown <j-brown@other.example>
+Resent-Date: Mon, 24 Nov 1997 14:22:01 -0800
+Resent-Message-ID: <78910@example.net>
+From: John Doe <jdoe@machine.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".`
+
+var RFC5322_Example_A4 = `Received: from x.y.test
+  by example.net
+  via TCP
+  with ESMTP
+  id ABC12345
+  for <mary@example.net>;  21 Nov 1997 10:05:43 -0600
+Received: from node.example by x.y.test; 21 Nov 1997 10:01:22 -0600
+From: John Doe <jdoe@node.example>
+To: Mary Smith <mary@example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234@local.node.example>
+
+This is a message just to say hello.
+So, "Hello".`