diff --git a/.gitignore b/.gitignore
index 3f231dc3badacb13a05e6278595312025af3386d..367ae23f205545bb69b9f1a69e7ebf5f0abd8bc6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,4 @@
 /.idea/*
 !/.idea/copyright/
 .DS_Store
-/out/*/
\ No newline at end of file
+/out/*/*
\ No newline at end of file
diff --git a/client.go b/client.go
index 308f7763ad23a338741abd5b83af063c0f968d95..19b69498a7a6dd08cb2deb013828aef94592d57d 100644
--- a/client.go
+++ b/client.go
@@ -20,12 +20,12 @@ type ApiClient struct {
 func (c *ApiClient) Station(evaId int64) ([]Station, error) {
 	var err error
 
-	url := fmt.Sprintf("%s/timetable/station/%d", c.IrisBaseUrl, evaId)
+	uri := fmt.Sprintf("%s/timetable/station/%d", c.IrisBaseUrl, evaId)
 
 	var stations []Station
 
 	var response *http.Response
-	if response, err = c.HttpClient.Get(url); err != nil {
+	if response, err = c.HttpClient.Get(uri); err != nil {
 		return stations, err
 	}
 
@@ -44,12 +44,12 @@ func (c *ApiClient) Timetable(evaId int64, date time.Time) (Timetable, error) {
 	var err error
 
 	BahnFormat := "060102/15"
-	url := fmt.Sprintf("%s/timetable/plan/%d/%s", c.IrisBaseUrl, evaId, date.Format(BahnFormat))
+	uri := fmt.Sprintf("%s/timetable/plan/%d/%s", c.IrisBaseUrl, evaId, date.Format(BahnFormat))
 
 	var timetable Timetable
 
 	var response *http.Response
-	if response, err = c.HttpClient.Get(url); err != nil {
+	if response, err = c.HttpClient.Get(uri); err != nil {
 		return timetable, err
 	}
 
@@ -194,3 +194,27 @@ func (c *ApiClient) Suggestions(line string, date time.Time) ([]Suggestion, erro
 
 	return suggestions, err
 }
+
+func (c *ApiClient) HafasMessages(trainlink string) ([]HafasMessage, error) {
+	var err error
+
+	uri := fmt.Sprintf("%s/traininfo.exe/dn/%s?rt=1&ajax=1", c.HafasBaseUrl, trainlink)
+
+	var messages []HafasMessage
+	request, err := http.NewRequest("GET", uri, nil)
+
+	var response *http.Response
+	if response, err = c.HttpClient.Do(request); err != nil {
+		return messages, err
+	}
+
+	if messages, err = HafasMessagesFromReader(response.Body); err != nil {
+		return messages, err
+	}
+
+	if err = response.Body.Close(); err != nil {
+		return messages, err
+	}
+
+	return messages, err
+}
diff --git a/data/hafas_messages/0.html b/data/hafas_messages/0.html
new file mode 100644
index 0000000000000000000000000000000000000000..531590df12f7e0f8f92b2ad715192d64417b7bc8
--- /dev/null
+++ b/data/hafas_messages/0.html
@@ -0,0 +1,29 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819900">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/1.html b/data/hafas_messages/1.html
new file mode 100644
index 0000000000000000000000000000000000000000..2b3e52b335e596e619f8473ab9df17a782f79831
--- /dev/null
+++ b/data/hafas_messages/1.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesHigh">
+<div id="HIM_Text__824313">
+<span class="bold">
+Kassel-Wilhelmsh&#246;he&nbsp;-&nbsp;
+Hannover Hbf:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Au&#223;ergew&#246;hnlich hohes Reisendenaufkommen! Reisende, die noch keine Fahrkarte gekauft haben, w&#228;hlen bitte eine andere Verbindung.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/10.html b/data/hafas_messages/10.html
new file mode 100644
index 0000000000000000000000000000000000000000..9934c7ef541cd79f703db827ed0090f14e00abad
--- /dev/null
+++ b/data/hafas_messages/10.html
@@ -0,0 +1,39 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__823996">
+<span class="bold">
+Nauen&nbsp;-&nbsp;
+Berlin-Sch&#246;nefeld Flughafen:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Beachten Sie bitte, es ist heute ein k&#252;rzerer Zug als regul&#228;r im Einsatz (nur 4 Wagen statt 5). Rollstuhlmitnahme heute nur im Steuerwagen m&#246;glich.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819900">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/11.html b/data/hafas_messages/11.html
new file mode 100644
index 0000000000000000000000000000000000000000..ab5d5c47980ede2cdc66d7030823ef8d57689b7b
--- /dev/null
+++ b/data/hafas_messages/11.html
@@ -0,0 +1,32 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__811470">
+<span class="bold">
+Rostock Hbf&nbsp;-&nbsp;
+Elsterwerda:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__824012">
+<span class="bold">
+Rostock Hbf&nbsp;-&nbsp;
+Elsterwerda:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Rollstuhlmitnahme und die 1. Klasse befindet sich im Steuerwagen.
+</span>
+</div>
+<div id="HIM_Text__811475">
+<span class="bold">
+Rostock Hbf&nbsp;-&nbsp;
+Elsterwerda:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/12.html b/data/hafas_messages/12.html
new file mode 100644
index 0000000000000000000000000000000000000000..531590df12f7e0f8f92b2ad715192d64417b7bc8
--- /dev/null
+++ b/data/hafas_messages/12.html
@@ -0,0 +1,29 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819900">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/13.html b/data/hafas_messages/13.html
new file mode 100644
index 0000000000000000000000000000000000000000..d077ec71b9b756b595f20dbe02e006fe75912563
--- /dev/null
+++ b/data/hafas_messages/13.html
@@ -0,0 +1,22 @@
+<div id="HIM_Text" class="himMessagesHigh">
+<div id="HIM_Text__814042">
+<span class="bold">
+Stuttgart Hbf&nbsp;-&nbsp;
+M&#252;nchen Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Halte Ulm Hbf, G&#252;nzburg, Augsburg Hbf und M&#252;nchen-Pasing entfallen. Bitte &#252;berpr&#252;fen Sie Ihre Verbindung noch einmal kurz vor der Reise.
+</span>
+</div>
+<div id="HIM_Text__814086">
+<span class="bold">
+Stuttgart Hbf&nbsp;-&nbsp;
+M&#252;nchen Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Ankunft verz&#246;gert sich bis zu 30 Minuten.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/14.html b/data/hafas_messages/14.html
new file mode 100644
index 0000000000000000000000000000000000000000..ad2178ef810bbe82a4bcc9b9c67fc57640c740bf
--- /dev/null
+++ b/data/hafas_messages/14.html
@@ -0,0 +1,82 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__811900">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__824002">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Beachten Sie bitte, es ist heute ein k&#252;rzerer Zug als regul&#228;r im Einsatz (nur 4 Wagen statt 5)
+</span>
+</div>
+<div id="HIM_Text__811909">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811913">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811915">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811917">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811918">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811922">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Schwedt(Oder):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/15.html b/data/hafas_messages/15.html
new file mode 100644
index 0000000000000000000000000000000000000000..939b7020b83b47ad46e6268012df0b2b0a46bbd7
--- /dev/null
+++ b/data/hafas_messages/15.html
@@ -0,0 +1,82 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__811900">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811932">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811934">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811937">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811941">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811945">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811947">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811950">
+<span class="bold">
+Berlin Hbf (tief)&nbsp;-&nbsp;
+Falkenberg(Elster):&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich am Schluss des Zuges.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/16.html b/data/hafas_messages/16.html
new file mode 100644
index 0000000000000000000000000000000000000000..531590df12f7e0f8f92b2ad715192d64417b7bc8
--- /dev/null
+++ b/data/hafas_messages/16.html
@@ -0,0 +1,29 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819900">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/17.html b/data/hafas_messages/17.html
new file mode 100644
index 0000000000000000000000000000000000000000..531590df12f7e0f8f92b2ad715192d64417b7bc8
--- /dev/null
+++ b/data/hafas_messages/17.html
@@ -0,0 +1,29 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819900">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/18.html b/data/hafas_messages/18.html
new file mode 100644
index 0000000000000000000000000000000000000000..6679632e715d7ef57198f3e5e798532c1fce04f9
--- /dev/null
+++ b/data/hafas_messages/18.html
@@ -0,0 +1,52 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__811457">
+<span class="bold">
+Elsterwerda&nbsp;-&nbsp;
+Neubrandenburg:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811459">
+<span class="bold">
+Elsterwerda&nbsp;-&nbsp;
+Neubrandenburg:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811461">
+<span class="bold">
+Elsterwerda&nbsp;-&nbsp;
+Neubrandenburg:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811462">
+<span class="bold">
+Elsterwerda&nbsp;-&nbsp;
+Neubrandenburg:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+<div id="HIM_Text__811464">
+<span class="bold">
+Elsterwerda&nbsp;-&nbsp;
+Neubrandenburg:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Fahrradwagen befindet sich an der Spitze des Zuges.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/19.html b/data/hafas_messages/19.html
new file mode 100644
index 0000000000000000000000000000000000000000..bdbb91109989970712bd50e882a7eb662da2bc62
--- /dev/null
+++ b/data/hafas_messages/19.html
@@ -0,0 +1,11 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/2.html b/data/hafas_messages/2.html
new file mode 100644
index 0000000000000000000000000000000000000000..03772d7e1d4b3595b2cc06978dc1cb8c94eded61
--- /dev/null
+++ b/data/hafas_messages/2.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesHigh">
+<div id="HIM_Text__824314">
+<span class="bold">
+Kassel-Wilhelmsh&#246;he&nbsp;-&nbsp;
+Hannover Hbf:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Au&#223;ergew&#246;hnlich hohes Reisendenaufkommen! Reisende, die noch keine Fahrkarte gekauft haben, w&#228;hlen bitte eine andere Verbindung.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/20.html b/data/hafas_messages/20.html
new file mode 100644
index 0000000000000000000000000000000000000000..ba53f9e823a23352e4190cd6fb9c7909457d0295
--- /dev/null
+++ b/data/hafas_messages/20.html
@@ -0,0 +1,20 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/21.html b/data/hafas_messages/21.html
new file mode 100644
index 0000000000000000000000000000000000000000..531590df12f7e0f8f92b2ad715192d64417b7bc8
--- /dev/null
+++ b/data/hafas_messages/21.html
@@ -0,0 +1,29 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__819897">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819899">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+<div id="HIM_Text__819900">
+<span class="bold">
+Berlin Zoologischer Garten:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Aufz&#252;ge in Berlin Zoologischer Garten Gleis 3/4 au&#223;er Betrieb. Grund: Sperrung der Haupthalle und des Zwischendecks im Bahnhof Berlin Zoologischer Garten ab 25.03. Bitte beachten Sie die ver&#228;nderte Wegeleitung im Bahnhof. Der Aufzug vom und zum Gleis 3/4 steht in dieser Zeit leider nicht zur Verf&#252;gung. Umfahrung f&#252;r mobilit&#228;tseingeschr&#228;nkte Reisende &#252;ber Berlin-Charlottenburg und Berlin Hauptbahnhof.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/22.html b/data/hafas_messages/22.html
new file mode 100644
index 0000000000000000000000000000000000000000..6ab25cc010deb1af397234ef15c01b5a90addaee
--- /dev/null
+++ b/data/hafas_messages/22.html
@@ -0,0 +1,32 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__815867">
+<span class="bold">
+Gem&#252;nden(Main)&nbsp;-&nbsp;
+W&#252;rzburg Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Ankunft verz&#246;gert sich um voraussichtlich 10 bis zu 15 Minuten.
+</span>
+</div>
+<div id="HIM_Text__819427">
+<span class="bold">
+Gem&#252;nden(Main)&nbsp;-&nbsp;
+W&#252;rzburg Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Ankunft verz&#246;gert sich um voraussichtlich 20 bis zu 25 Minuten.
+</span>
+</div>
+<div id="HIM_Text__819428">
+<span class="bold">
+Gem&#252;nden(Main)&nbsp;-&nbsp;
+W&#252;rzburg Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Ankunft verz&#246;gert sich um voraussichtlich 10 bis zu 15 Minuten.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/23.html b/data/hafas_messages/23.html
new file mode 100644
index 0000000000000000000000000000000000000000..da45e1e6771aa07b735643651b8124a484df2d5c
--- /dev/null
+++ b/data/hafas_messages/23.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__818868">
+<span class="bold">
+Frankfurt(Main)Hbf&nbsp;-&nbsp;
+Limburg(Lahn):&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Wegen Oberleitungsarbeiten zwischen Frankfurt(Main)Hbf und Frankfurt-H&#246;chst kommt es bei den Z&#252;gen der Linien RB22 / RE20 im Zeitraum von Freitag, 3. Mai bis Sonntag, 23. Juni 2019 (an ausgew&#228;hlten Tagen) zu Fahrplan&#228;nderungen. Die betroffenen Z&#252;ge der Linien RB22 / RE20 bekommen eine Versp&#228;tung von bis zu 10 Minuten. Bitte rechnen Sie mit Gleis&#228;nderungen. Informieren Sie sich fr&#252;hzeitig &#252;ber Ihre geplanten Verbindungen und w&#228;hlen Sie gegebenenfalls eine fr&#252;here Zugverbindung, um Ihre Anschl&#252;sse an Ihren Umsteigebahnh&#246;fen erreichen zu k&#246;nnen.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/24.html b/data/hafas_messages/24.html
new file mode 100644
index 0000000000000000000000000000000000000000..02b5f1eb9248d7b1b150cb2c8f8eea380c2c3b41
--- /dev/null
+++ b/data/hafas_messages/24.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesLow">
+<div id="HIM_Text__788609">
+<span class="bold">
+Stralsund Hbf&nbsp;-&nbsp;
+Karlsruhe Hbf:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Seit dem 09. Dezember 2018 verkehren auf der zweist&#252;ndlichen Linie 26 von Karlsruhe nach Hamburg und weiter nach Stralsund (via Frankfurt Hbf, Marburg, Kassel), statt der bisher eingesetzten Intercity-Wagen, moderne ICE-Z&#252;ge. F&#252;r die Nutzung dieser ICE-Z&#252;ge gelten die bundesweit einheitlichen Konditionen f&#252;r die Nutzung von ICE-Z&#252;gen: Sowohl f&#252;r Flexpreis-Fahrkarten als auch f&#252;r Zeitkarten ist zwischen Karlsruhe und Rostock eine ICE-Berechtigung zum aktuell g&#252;ltigen Preis erforderlich. Fahrkarten des Nahverkehrs sowie der Verkehrsverb&#252;nde haben in den ICE-Z&#252;gen keine G&#252;ltigkeit.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/3.html b/data/hafas_messages/3.html
new file mode 100644
index 0000000000000000000000000000000000000000..1768cb59d20193ef3873aaf120c2a3b8d02f30c5
--- /dev/null
+++ b/data/hafas_messages/3.html
@@ -0,0 +1,22 @@
+<div id="HIM_Text" class="himMessagesHigh">
+<div id="HIM_Text__820800">
+<span class="bold">
+Ahrensburg&nbsp;-&nbsp;
+Bad Oldesloe:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Der Zug f&#228;llt zwischen Ahrensburg und Bad Oldesloe aus. Ein Ersatzverkehr von Ahrensburg nach Bad Oldesloe ist eingerichtet. Bitte &#252;berpr&#252;fen Sie Ihre Verbindung noch einmal kurz vor der Reise.
+</span>
+</div>
+<div id="HIM_Text__820803">
+<span class="bold">
+Bargteheide&nbsp;-&nbsp;
+Bad Oldesloe:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Der Zug f&#228;llt zwischen Bargteheide und Bad Oldesloe aus. Ein Ersatzverkehr von Bargteheide nach Bad Oldesloe ist eingerichtet. Bitte &#252;berpr&#252;fen Sie Ihre Verbindung noch einmal kurz vor der Reise.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/4.html b/data/hafas_messages/4.html
new file mode 100644
index 0000000000000000000000000000000000000000..86d064f0cbda2cc1542056c6989f905f7824951b
--- /dev/null
+++ b/data/hafas_messages/4.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesHigh">
+<div id="HIM_Text__797833">
+<span class="bold">
+Neum&#252;nster&nbsp;-&nbsp;
+Kiel Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Der Zug f&#228;llt zwischen Neum&#252;nster und Kiel Hbf aus. Ein Ersatzverkehr von Neum&#252;nster nach Kiel Hbf ist eingerichtet. Bitte &#252;berpr&#252;fen Sie Ihre Verbindung noch einmal kurz vor der Reise.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/5.html b/data/hafas_messages/5.html
new file mode 100644
index 0000000000000000000000000000000000000000..41d0276f3c09e7ea9f807639f78f7cb4557415a9
--- /dev/null
+++ b/data/hafas_messages/5.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__805562">
+<span class="bold">
+Rendsburg&nbsp;-&nbsp;
+Flensburg:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Ankunft verz&#246;gert sich bis zu 15 Minuten. Bitte &#252;berpr&#252;fen Sie Ihre Verbindung noch einmal kurz vor der Reise.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/6.html b/data/hafas_messages/6.html
new file mode 100644
index 0000000000000000000000000000000000000000..2820117220eaf65b60de670748ef360b060ce323
--- /dev/null
+++ b/data/hafas_messages/6.html
@@ -0,0 +1,11 @@
+<div id="HIM_Text" class="himMessagesLow">
+<div id="HIM_Text__819298">
+<span class="bold">
+Uelzen:&nbsp;
+St&#246;rung.&nbsp;
+</span>
+<span class="">
+Aufzug Gl 101 wird umgebaut (Letzte Aktualisierung 13:10)
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/7.html b/data/hafas_messages/7.html
new file mode 100644
index 0000000000000000000000000000000000000000..504fdf26b341a4b2e9d3ee7021615c74a6e70f32
--- /dev/null
+++ b/data/hafas_messages/7.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__820812">
+<span class="bold">
+Hamburg Hbf&nbsp;-&nbsp;
+L&#252;beck Hbf:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Der Zug h&#228;lt zus&#228;tzlich in Ahrensburg und Bargteheide. Bitte &#252;berpr&#252;fen Sie Ihre Verbindung noch einmal kurz vor der Reise.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/8.html b/data/hafas_messages/8.html
new file mode 100644
index 0000000000000000000000000000000000000000..4a5c77a1225723528b385d67d8b83cd4a7819510
--- /dev/null
+++ b/data/hafas_messages/8.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__807918">
+<span class="bold">
+Hamburg Hbf&nbsp;-&nbsp;
+Ahrensburg:&nbsp;
+Bauarbeiten.&nbsp;
+</span>
+<span class="">
+Die Ankunft verz&#246;gert sich bis zu 10 Minuten.
+</span>
+</div>
+</div>
diff --git a/data/hafas_messages/9.html b/data/hafas_messages/9.html
new file mode 100644
index 0000000000000000000000000000000000000000..a2a19a419bf484ec79f195cf530dfd2f71bae10d
--- /dev/null
+++ b/data/hafas_messages/9.html
@@ -0,0 +1,12 @@
+<div id="HIM_Text" class="himMessagesMiddle">
+<div id="HIM_Text__823981">
+<span class="bold">
+Berlin S&#252;dkreuz&nbsp;-&nbsp;
+Nauen:&nbsp;
+Information.&nbsp;
+</span>
+<span class="">
+Der Zug verkehrt in umgekehrter Wagenreihung. Die Rollstuhlmitnahme und die 1. Klasse befindet sich im Steuerwagen.
+</span>
+</div>
+</div>
diff --git a/external_hafas_messages.go b/external_hafas_messages.go
new file mode 100644
index 0000000000000000000000000000000000000000..19f7e395a4ef822c23ee922bddf550dddbde9e15
--- /dev/null
+++ b/external_hafas_messages.go
@@ -0,0 +1,101 @@
+package bahn
+
+import (
+	"bytes"
+	"github.com/andybalholm/cascadia"
+	"golang.org/x/net/html"
+	"io"
+	"regexp"
+	"strings"
+)
+
+func HafasMessagesFromBytes(source []byte) ([]HafasMessage, error) {
+	return HafasMessagesFromReader(bytes.NewReader(source))
+}
+
+var hafasMessageHighSelector = cascadia.MustCompile(".himMessagesHigh > div")
+var hafasMessageMiddleSelector = cascadia.MustCompile(".himMessagesMiddle > div")
+var hafasMessageLowSelector = cascadia.MustCompile(".himMessagesLow > div")
+
+var hafasMessageValiditySelector = cascadia.MustCompile("span.bold")
+var hafasMessageContentSelector = cascadia.MustCompile("span:not(.bold)")
+
+var hafasMessageValidityRegex = regexp.MustCompile("^(?P<From>.+?)(?:\\p{Z}-\\p{Z}\\n(?P<To>.+?))?(?::\\p{Z}\\n(?P<Subject>.+?)\\.?)?$")
+var hafasMessageIdRegex = regexp.MustCompile("^HIM_Text__(?P<Id>\\d+)$")
+
+func HafasMessagesFromReader(source io.Reader) ([]HafasMessage, error) {
+	var err error
+	var messages []HafasMessage
+
+	var document *html.Node
+	if document, err = html.Parse(source); err != nil {
+		return messages, err
+	}
+
+	parseMessage := func(node *html.Node, priority HafasMessagePriority) {
+		validityNode := hafasMessageValiditySelector.MatchFirst(node)
+		contentNode := hafasMessageContentSelector.MatchFirst(node)
+
+		validity := strings.TrimSpace(parseText(validityNode))
+		content := strings.TrimSpace(parseText(contentNode))
+
+		var id string
+		for _, attr := range node.Attr {
+			if attr.Namespace == "" && attr.Key == "id" {
+				id = attr.Val
+			}
+		}
+
+		parsedId := parseRegexGroups(hafasMessageIdRegex, strings.TrimSpace(id))
+		parsedValidity := parseRegexGroups(hafasMessageValidityRegex, strings.TrimSpace(validity))
+
+		messages = append(messages, HafasMessage{
+			Priority: priority,
+			Id:       parsedId["Id"],
+			From:     parsedValidity["From"],
+			To:       parsedValidity["To"],
+			Subject:  parsedValidity["Subject"],
+			Content:  content,
+		})
+	}
+
+	for _, node := range hafasMessageHighSelector.MatchAll(document) {
+		parseMessage(node, HafasMessagePriorityHigh)
+	}
+	for _, node := range hafasMessageMiddleSelector.MatchAll(document) {
+		parseMessage(node, HafasMessagePriorityMiddle)
+	}
+	for _, node := range hafasMessageLowSelector.MatchAll(document) {
+		parseMessage(node, HafasMessagePriorityLow)
+	}
+	return messages, nil
+}
+
+func parseText(node *html.Node) string {
+	var result string
+	parseTextInternal(node, &result)
+	return result
+}
+
+func parseTextInternal(node *html.Node, out *string) {
+	if node.Type == html.TextNode {
+		*out += node.Data
+	} else {
+		for c := node.FirstChild; c != nil; c = c.NextSibling {
+			parseTextInternal(c, out)
+		}
+	}
+}
+
+func parseRegexGroups(regex *regexp.Regexp, url string) map[string]string {
+	match := regex.FindStringSubmatch(url)
+
+	paramsMap := make(map[string]string)
+	for i, name := range regex.SubexpNames() {
+		if i > 0 && i <= len(match) {
+			paramsMap[name] = match[i]
+		}
+	}
+
+	return paramsMap
+}
diff --git a/go.mod b/go.mod
index 5ab00a1392ad5ee8e70f440ff50e3cfdf3d5f118..67489268802bf6d6f7606b48c7e0dbb9158ecd8f 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,8 @@ module git.kuschku.de/justjanne/bahn-api
 
 go 1.12
 
-require gopkg.in/yaml.v2 v2.2.2
+require (
+	github.com/andybalholm/cascadia v1.0.0
+	golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01
+	gopkg.in/yaml.v2 v2.2.2
+)
diff --git a/go.sum b/go.sum
index bd555a333b28a333cf16695266068d5e3008d632..f8b4c0f6ffb77589d625f59db961e341cd5b37ee 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,7 @@
+github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
+github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01 h1:po1f06KS05FvIQQA2pMuOWZAUXiy1KYdIf0ElUU2Hhc=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/model_hafas_messages.go b/model_hafas_messages.go
new file mode 100644
index 0000000000000000000000000000000000000000..bdb3a05519a159cbbefd45483ebce1cdcbbec364
--- /dev/null
+++ b/model_hafas_messages.go
@@ -0,0 +1,18 @@
+package bahn
+
+type HafasMessage struct {
+	Id       string               `json:"id,omitempty"yaml:"id,omitempty"`
+	Priority HafasMessagePriority `json:"priority,omitempty"yaml:"priority,omitempty"`
+	From     string               `json:"from,omitempty"yaml:"from,omitempty"`
+	To       string               `json:"to,omitempty"yaml:"to,omitempty"`
+	Subject  string               `json:"subject,omitempty"yaml:"subject,omitempty"`
+	Content  string               `json:"content,omitempty"yaml:"content,omitempty"`
+}
+
+type HafasMessagePriority string
+
+const (
+	HafasMessagePriorityLow    HafasMessagePriority = "LOW"
+	HafasMessagePriorityMiddle HafasMessagePriority = "MIDDLE"
+	HafasMessagePriorityHigh   HafasMessagePriority = "HIGH"
+)
diff --git a/out/canonicalize.sh b/out/canonicalize.sh
index a2694c1ac1f8f19bc7e5c7096cbe8ef43ac617d5..afc1ba25c5bef2fdb7962f1e2d4f7ee586eeea0e 100755
--- a/out/canonicalize.sh
+++ b/out/canonicalize.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-function cleanup_xml {
+function cleanup_xml_roundtrip {
     for i in $(seq 0 1 $2); do
         CURRENT_FILE="${1}/${i}"
         CURRENT_FILE_ROUNDTRIP="${CURRENT_FILE}.roundtrip.xml"
@@ -15,7 +15,7 @@ function cleanup_xml {
     done
 }
 
-function cleanup_json {
+function cleanup_json_roundtrip {
     for i in $(seq 0 1 $2); do
         CURRENT_FILE="${1}/${i}"
         CURRENT_FILE_ROUNDTRIP="${CURRENT_FILE}.roundtrip.json"
@@ -29,10 +29,21 @@ function cleanup_json {
     done
 }
 
+function cleanup_json {
+    for i in $(seq 0 1 $2); do
+        CURRENT_FILE="${1}/${i}"
+        CURRENT_FILE_JSON="${CURRENT_FILE}.json"
+
+        jq "." "${CURRENT_FILE_JSON}" > "${CURRENT_FILE}.tmp"
+        mv "${CURRENT_FILE}.tmp" "${CURRENT_FILE_JSON}"
+    done
+}
+
 CURRENT_DIR=$(dirname $(realpath "$0"))
 
-cleanup_xml "${CURRENT_DIR}/iris_station" 2
-cleanup_xml "${CURRENT_DIR}/iris_realtime" 4
-cleanup_xml "${CURRENT_DIR}/iris_timetable" 4
-cleanup_xml "${CURRENT_DIR}/iris_wingdef" 2
-cleanup_json "${CURRENT_DIR}/apps_wagenreihung" 226
+cleanup_xml_roundtrip "${CURRENT_DIR}/iris_station" 2
+cleanup_xml_roundtrip "${CURRENT_DIR}/iris_realtime" 4
+cleanup_xml_roundtrip "${CURRENT_DIR}/iris_timetable" 4
+cleanup_xml_roundtrip "${CURRENT_DIR}/iris_wingdef" 2
+cleanup_json_roundtrip "${CURRENT_DIR}/apps_wagenreihung" 226
+cleanup_json "${CURRENT_DIR}/hafas_messages" 24
diff --git a/roundtrip_test.go b/roundtrip_test.go
index 5675f9c32d5490b77abb82e2d6c5b29ce00632ce..7a7ec632b8ec5926b6ad98770548abbb10dd3e71 100644
--- a/roundtrip_test.go
+++ b/roundtrip_test.go
@@ -132,7 +132,7 @@ func jsonInput(raw interface{}, filename string) {
 	}
 }
 
-func xmlOutput(raw interface{}, data interface{}, filename string) {
+func xmlRoundtrip(raw interface{}, data interface{}, filename string) {
 	var err error
 
 	if err = encodeXml(raw, filename+".roundtrip.xml"); err != nil {
@@ -148,7 +148,7 @@ func xmlOutput(raw interface{}, data interface{}, filename string) {
 	}
 }
 
-func jsonOutput(raw interface{}, data interface{}, filename string) {
+func jsonRoundtrip(raw interface{}, data interface{}, filename string) {
 	var err error
 
 	if err = encodeJson(raw, filename+".roundtrip.json"); err != nil {
@@ -164,6 +164,18 @@ func jsonOutput(raw interface{}, data interface{}, filename string) {
 	}
 }
 
+func jsonOutput(raw interface{}, data interface{}, filename string) {
+	var err error
+
+	if err = encodeYaml(data, filename+".yaml"); err != nil {
+		panic(err.Error())
+	}
+
+	if err = encodeJson(data, filename+".json"); err != nil {
+		panic(err.Error())
+	}
+}
+
 const InputFolder = "data"
 const OutputFolder = "out"
 
@@ -172,6 +184,7 @@ var timetableData []byte
 var realtimeData []byte
 var wingDefinitionData []byte
 var coachSequenceData []byte
+var hafasMessageData []byte
 
 func TestMain(m *testing.M) {
 	var err error
@@ -191,6 +204,9 @@ func TestMain(m *testing.M) {
 	if coachSequenceData, err = ioutil.ReadFile(fmt.Sprintf("%s/%s/%d.json", InputFolder, "apps_wagenreihung", 0)); err != nil {
 		panic(err)
 	}
+	if hafasMessageData, err = ioutil.ReadFile(fmt.Sprintf("%s/%s/%d.html", InputFolder, "hafas_messages", 0)); err != nil {
+		panic(err)
+	}
 
 	os.Exit(m.Run())
 }
@@ -225,7 +241,13 @@ func BenchmarkCoachSequence(b *testing.B) {
 	}
 }
 
-func BenchmarkRoundtrip(b *testing.B) {
+func BenchmarkHafasMessages(b *testing.B) {
+	if _, err := HafasMessagesFromBytes(coachSequenceData); err != nil {
+		b.Error(err.Error())
+	}
+}
+
+func TestRoundtrip(t *testing.T) {
 	for i := 0; i < 3; i++ {
 		var raw rawStations
 		folderName := "iris_station"
@@ -233,7 +255,7 @@ func BenchmarkRoundtrip(b *testing.B) {
 		output := fmt.Sprintf("%s/%s/%d", OutputFolder, folderName, i)
 		xmlInput(&raw, input)
 		data := parseStations(raw)
-		xmlOutput(&raw, &data, output)
+		xmlRoundtrip(&raw, &data, output)
 	}
 
 	for i := 0; i < 5; i++ {
@@ -243,7 +265,7 @@ func BenchmarkRoundtrip(b *testing.B) {
 		output := fmt.Sprintf("%s/%s/%d", OutputFolder, folderName, i)
 		xmlInput(&raw, input)
 		data := parseTimetable(raw)
-		xmlOutput(&raw, &data, output)
+		xmlRoundtrip(&raw, &data, output)
 	}
 
 	for i := 0; i < 5; i++ {
@@ -253,7 +275,7 @@ func BenchmarkRoundtrip(b *testing.B) {
 		output := fmt.Sprintf("%s/%s/%d", OutputFolder, folderName, i)
 		xmlInput(&raw, input)
 		data := parseTimetable(raw)
-		xmlOutput(&raw, &data, output)
+		xmlRoundtrip(&raw, &data, output)
 	}
 
 	for i := 0; i < 3; i++ {
@@ -263,7 +285,7 @@ func BenchmarkRoundtrip(b *testing.B) {
 		output := fmt.Sprintf("%s/%s/%d", OutputFolder, folderName, i)
 		xmlInput(&raw, input)
 		data := parseWingDefinition(raw)
-		xmlOutput(&raw, &data, output)
+		xmlRoundtrip(&raw, &data, output)
 	}
 
 	for i := 0; i < 227; i++ {
@@ -273,6 +295,22 @@ func BenchmarkRoundtrip(b *testing.B) {
 		output := fmt.Sprintf("%s/%s/%d", OutputFolder, folderName, i)
 		jsonInput(&raw, input)
 		data := parseCoachSequence(raw)
+		jsonRoundtrip(&raw, &data, output)
+	}
+
+	for i := 0; i < 25; i++ {
+		var raw []HafasMessage
+		folderName := "hafas_messages"
+		input := fmt.Sprintf("%s/%s/%d.html", InputFolder, folderName, i)
+		output := fmt.Sprintf("%s/%s/%d", OutputFolder, folderName, i)
+		f, err := os.Open(input)
+		if err != nil {
+			panic(err)
+		}
+		data, err := HafasMessagesFromReader(f)
+		if err != nil {
+			panic(err)
+		}
 		jsonOutput(&raw, &data, output)
 	}
 }