diff --git a/src/eu/simstadt/regionchooser/RegionExtractor.java b/src/eu/simstadt/regionchooser/RegionExtractor.java
index 7175ff4b0ff84b27d8b23eb31e3570bae3632a4c..e839730e9429ed430141c1f320a8f71c1ee61527 100644
--- a/src/eu/simstadt/regionchooser/RegionExtractor.java
+++ b/src/eu/simstadt/regionchooser/RegionExtractor.java
@@ -3,8 +3,8 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.logging.Logger;
-import javax.xml.stream.XMLStreamException;
-import org.xml.sax.SAXParseException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
@@ -37,11 +37,16 @@
 	 * @param wktPolygon
 	 * @param string
 	 * @return a StringBuffer, full with the extracted Citygml, including header, buildings and footer.
-	 * @throws Exception
+	 * @throws ParseException
+	 * @throws IOException
+	 * @throws XPathEvalException
+	 * @throws NavException
+	 * @throws XPathParseException
+	 * @throws NumberFormatException
 	 */
 	static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, String wktPolygon, String srsName)
-			throws SAXParseException, XMLStreamException, ParseException, XPathParseException, NavException,
-			NumberFormatException, XPathEvalException, IOException {
+			throws ParseException, NumberFormatException, XPathParseException, NavException, XPathEvalException,
+			IOException {
 
 		int buildingsCount = 0;
 		int foundBuildingsCount = 0;
@@ -75,7 +80,8 @@ static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, Str
 	 * region comes from a huge file (e.g. from NYC), it might inherit this header with a huge envelope. Some methods
 	 * might get confused by this wrong envelope, so this method replaces the original envelope with the bounding box
 	 * from the extracting polygon. The real envelope might be even smaller, but it could only be known at the end of the
-	 * parsing, after having analyzed every building. The envelope should be written in the header.
+	 * parsing, after having analyzed every building. The envelope should be written in the header. If present, min and
+	 * max values for Z are kept.
 	 * 
 	 * @param header
 	 * @param envelope
@@ -84,11 +90,23 @@ static public StringBuffer selectRegionDirectlyFromCityGML(Path citygmlPath, Str
 	 */
 	private static String replaceEnvelopeInHeader(String header, Envelope envelope, String srsName) {
 		//NOTE: Sorry for using a regex to parse XML. The header in itself isn't correct, so this looked like the easiest solution.
-		String headerWithoutEnvelope = header.replaceFirst("(?is)<gml:boundedBy>.*?</gml:boundedBy>", "");
+		double zMin = 0;
+		double zMax = 0;
+		Pattern boundedByPattern = Pattern.compile(
+				"(?is)<gml:boundedBy>.*?<gml:lowerCorner>(.*?)</gml:lowerCorner>\\s*<gml:upperCorner>(.*?)</gml:upperCorner>.*?</gml:boundedBy>");
+		Matcher matcher = boundedByPattern.matcher(header);
+		String headerWithoutEnvelope = header;
+		if (matcher.find()) {
+			headerWithoutEnvelope = matcher.replaceFirst("");
+			zMin = Double.valueOf(matcher.group(1).split("\\s+")[2]);
+			zMax = Double.valueOf(matcher.group(2).split("\\s+")[2]);
+		}
 		String newEnvelope = "<gml:boundedBy>\r\n" +
 				"  <gml:Envelope srsName=\"" + srsName + "\" srsDimension=\"3\">\r\n" + //NOTE: Would srsDimension="2" be better? Should the original Z get extracted?
-				"    <gml:lowerCorner>" + envelope.getMinX() + " " + envelope.getMinY() + " 0</gml:lowerCorner>\r\n" +
-				"    <gml:upperCorner>" + envelope.getMaxX() + " " + envelope.getMaxY() + " 0</gml:upperCorner>\r\n" +
+				"    <gml:lowerCorner>" + envelope.getMinX() + " " + envelope.getMinY() + " " + zMin
+				+ "</gml:lowerCorner>\r\n" +
+				"    <gml:upperCorner>" + envelope.getMaxX() + " " + envelope.getMaxY() + " " + zMax
+				+ "</gml:upperCorner>\r\n" +
 				"  </gml:Envelope>\r\n" +
 				"</gml:boundedBy>\r\n";
 		return headerWithoutEnvelope + newEnvelope;
diff --git a/test/eu/simstadt/regionchooser/RegionExtractorTests.java b/test/eu/simstadt/regionchooser/RegionExtractorTests.java
index fa0fdfae5f6be88f38a6dce5ff9ab7fcd17b34e7..3ccf24b494baabf8b02c82b7b132821ee1736943 100644
--- a/test/eu/simstadt/regionchooser/RegionExtractorTests.java
+++ b/test/eu/simstadt/regionchooser/RegionExtractorTests.java
@@ -37,7 +37,6 @@ public void testExtract3BuildingsFromGSK3Model() throws Throwable {
 		assertTrue(churchGMLString.contains("DEBW_LOD2_2909"));
 		assertTrue(churchGMLString.contains("<core:CityModel")); // Header
 		assertTrue(churchGMLString.contains("</core:CityModel")); // Footer
-		System.out.println(churchGMLString);
 		assertTrue("The exported CityGML should contain a new envelope with the correct EPSG", churchGMLString
 				.contains("<gml:Envelope srsName=\"EPSG:31467\" srsDimension=\"3\">"));
 		assertTrue("The exported CityGML should contain a new envelope", churchGMLString
@@ -72,18 +71,17 @@ public void testExtractBuildingsAndChangeEnvelope() throws Throwable {
 		Path repo = Paths.get("../TestRepository");
 		Path citygmlPath = repo.resolve("NewYork.proj/FamilyCourt_LOD2_with_PLUTO_attributes.gml");
 		String familyCourtBuilding = RegionExtractor
-				.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:32118")
-				.toString();
+				.selectRegionDirectlyFromCityGML(citygmlPath, wktPolygon, "EPSG:32118").toString();
 		assertEquals(countRegexMatches(familyCourtBuilding, "<(core:)?cityObjectMember"), 1);
 		assertTrue(familyCourtBuilding.contains("Bldg_12210021066"));
 		assertFalse("The exported CityGML shouldn't contain the original envelope", familyCourtBuilding
 				.contains("<gml:lowerCorner>298393.46959639067 59277.34021543693 -11.892070104139751</gml:lowerCorner>"));
 		assertFalse("The exported CityGML shouldn't contain the original envelope", familyCourtBuilding
 				.contains("<gml:upperCorner>305641.79529639013 67101.44881543722 547.7591871983744</gml:upperCorner>"));
-		assertTrue("The exported CityGML should contain a new envelope", familyCourtBuilding
-				.contains("<gml:lowerCorner>299721.46983062755 61021.99295737501 "));
-		assertTrue("The exported CityGML should contain a new envelope", familyCourtBuilding
-				.contains("<gml:upperCorner>299823.9079725632 61122.68126771413 "));
+		assertTrue("The exported CityGML should contain a new envelope with the original altitudes", familyCourtBuilding
+				.contains("<gml:lowerCorner>299721.46983062755 61021.99295737501 -11.89"));
+		assertTrue("The exported CityGML should contain a new envelope with the original altitudes", familyCourtBuilding
+				.contains("<gml:upperCorner>299823.9079725632 61122.68126771413 547.75"));
 		assertTrue("The exported CityGML should contain a new envelope with the correct EPSG", familyCourtBuilding
 				.contains("<gml:Envelope srsName=\"EPSG:32118\" srsDimension=\"3\">"));
 	}