diff --git a/tdt4140-gr1800/app.core/pom.xml b/tdt4140-gr1800/app.core/pom.xml
index 985bded0b7da356ee6f3f0c29de331329fd10e57..b780010c9f105853c0b5b201219ec08bacc1d0e0 100644
--- a/tdt4140-gr1800/app.core/pom.xml
+++ b/tdt4140-gr1800/app.core/pom.xml
@@ -25,6 +25,18 @@
 			<artifactId>jackson-annotations</artifactId>
 			<version>2.9.3</version>
 		</dependency>
+		<dependency>
+		    <groupId>com.fasterxml.jackson.dataformat</groupId>
+    			<artifactId>jackson-dataformat-xml</artifactId>
+    			<version>2.9.3</version>
+		</dependency>
+		
+		<!-- https://mvnrepository.com/artifact/io.jenetics/jpx -->
+		<dependency>
+		    <groupId>io.jenetics</groupId>
+		    <artifactId>jpx</artifactId>
+		    <version>1.2.2</version>
+		</dependency>
 
 		<dependency>
 			<groupId>junit</groupId>
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java
index 7c09f41946ba050362435e03f4f7f353f9342b9f..b7bd765c637941a2965d97c3e204df5e4c2230a7 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/App.java
@@ -4,21 +4,19 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.net.URI;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.stream.Collectors;
 
+import tdt4140.gr1800.app.gpx.GpxDocumentConverter;
 import tdt4140.gr1800.app.json.GeoLocationsJsonPersistence;
 
 public class App {
 
 	private GeoLocationsPersistence geoLocationsLoader = new GeoLocationsJsonPersistence();
 	
-	public void loadGeoLocations(URI uri) throws Exception {
-		geoLocations = geoLocationsLoader.loadLocations(uri.toURL().openStream());
-	}
-
-	private Collection<GeoLocations> geoLocations;
+	private Collection<GeoLocations> geoLocations = null;
 
 	public Iterable<String> getGeoLocationNames() {
 		Collection<String> names = new ArrayList<String>(geoLocations != null ? geoLocations.size() : 0);
@@ -69,8 +67,55 @@ public class App {
 		return result;
 	}
 
+	public void setGeoLocations(Collection<GeoLocations> geoLocations) {
+		this.geoLocations = new ArrayList<>(geoLocations);
+		fireGeoLocationsUpdated(null);
+	}
+
+	public void addGeoLocations(GeoLocations geoLocations) {
+		if (hasGeoLocations(geoLocations.getName())) {
+			throw new IllegalArgumentException("Duplicate geo-locations name: " + geoLocations.getName());
+		}
+		this.geoLocations.add(geoLocations);
+		fireGeoLocationsUpdated(geoLocations);
+	}
+	
+	public void removeGeoLocations(GeoLocations geoLocations) {
+		this.geoLocations.remove(geoLocations);
+		fireGeoLocationsUpdated(geoLocations);
+	}
+
+	private Collection<IGeoLocationsListener> geoLocationsListeners = new ArrayList<>();
+	
+	public void addGeoLocationsListener(IGeoLocationsListener listener) {
+		geoLocationsListeners.add(listener);
+	}
+
+	public void removeGeoLocationsListener(IGeoLocationsListener listener) {
+		geoLocationsListeners.remove(listener);
+	}
+
+	protected void fireGeoLocationsUpdated(GeoLocations geoLocations) {
+		for (IGeoLocationsListener listener : geoLocationsListeners) {
+			listener.geoLocationsUpdated(geoLocations);
+		}
+	}
+
 	// 
 
+	private IDocumentPersistence<Collection<GeoLocations>, File> documentPersistence = new IDocumentPersistence<Collection<GeoLocations>, File>() {
+		
+		@Override
+		public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
+			return geoLocationsLoader.loadLocations(new FileInputStream(documentLocation));
+		}
+
+		@Override
+		public void saveDocument(Collection<GeoLocations> document, File documentLocation) throws Exception {
+			geoLocationsLoader.saveLocations(document, new FileOutputStream(documentLocation));
+		}
+	};
+
 	private DocumentStorageImpl<Collection<GeoLocations>, File> documentStorage = new DocumentStorageImpl<Collection<GeoLocations>, File>() {
 
 		@Override
@@ -80,7 +125,7 @@ public class App {
 
 		@Override
 		protected void setDocument(Collection<GeoLocations> document) {
-			geoLocations = document;
+			setGeoLocations(document);
 		}
 
 		@Override
@@ -88,26 +133,43 @@ public class App {
 			return new ArrayList<GeoLocations>();
 		}
 
-		@Override
-		protected Collection<GeoLocations> loadDocument(File file) throws IOException {
-			try {
-				return geoLocationsLoader.loadLocations(new FileInputStream(file));
-			} catch (Exception e) {
-				throw new IOException(e);
-			}
+		public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
+			return documentPersistence.loadDocument(documentLocation);
 		}
-
-		@Override
-		protected void storeDocument(Collection<GeoLocations> document, File file) throws IOException {
-			try {
-				geoLocationsLoader.saveLocations(document, new FileOutputStream(file));
-			} catch (Exception e) {
-				throw new IOException(e);
-			}
+		
+		public void saveDocument(Collection<GeoLocations> document, File documentLocation) throws Exception {
+			documentPersistence.saveDocument(document, documentLocation);
+		}
+		
+		public Collection<IDocumentImporter<File>> getDocumentImporters() {
+			return documentLoaders.stream().map(loader -> new IDocumentImporter<File>() {
+				@Override
+				public void importDocument(File file) throws IOException {
+					try {
+						setDocumentAndLocation(loader.loadDocument(file), null);
+					} catch (Exception e) {
+						throw new IOException(e);
+					} 
+				}
+			}).collect(Collectors.toList());
 		}
 	};
 
 	public IDocumentStorage<File> getDocumentStorage() {
 		return documentStorage;
 	}
+
+	private Collection<IDocumentLoader<Collection<GeoLocations>, File>> documentLoaders = Arrays.asList(
+		new IDocumentLoader<Collection<GeoLocations>, File>() {
+			private GpxDocumentConverter gpxConverter = new GpxDocumentConverter();
+			@Override
+			public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
+				return gpxConverter.loadDocument(documentLocation);
+			}
+		}
+	);
+	
+	public Iterable<IDocumentLoader<Collection<GeoLocations>, File>> getDocumentLoaders() {
+		return documentLoaders;
+	}
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java
index 559279c2a795c5b1fa859a9a2c0129736fe71f33..b673c877d7fde81b765da55190e1a93347ccc816 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/DocumentStorageImpl.java
@@ -2,7 +2,7 @@ package tdt4140.gr1800.app.core;
 
 import java.io.IOException;
 
-public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L> {
+public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L>, IDocumentPersistence<D, L> {
 
 	private L documentLocation;
 
@@ -25,8 +25,6 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L> {
 	protected abstract void setDocument(D document);
 
 	protected abstract D createDocument();
-	protected abstract D loadDocument(L storage) throws IOException;
-	protected abstract void storeDocument(D document, L storage) throws IOException;
 	
 	@Override
 	public void newDocument() {
@@ -35,12 +33,20 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L> {
 
 	@Override
 	public void openDocument(L storage) throws IOException {
-		setDocumentAndLocation(loadDocument(storage), storage);
+		try {
+			setDocumentAndLocation(loadDocument(storage), storage);
+		} catch (Exception e) {
+			throw new IOException(e);
+		}
 	}
 
 	@Override
 	public void saveDocument() throws IOException {
-		storeDocument(getDocument(), getDocumentLocation());
+		try {
+			saveDocument(getDocument(), getDocumentLocation());
+		} catch (Exception e) {
+			throw new IOException(e);
+		}
 	}
 
 	public void saveDocumentAs(L documentLocation) throws IOException {
@@ -54,7 +60,7 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L> {
 		}
 	}
 	
-	public void saveCopyAs(L documentLocation) throws IOException {
-		storeDocument(getDocument(), documentLocation);
+	public void saveCopyAs(L documentLocation) throws Exception {
+		saveDocument(getDocument(), documentLocation);
 	}
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocated.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocated.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4ea1bae63c6531b4881fdc9bbb802bb461207d5
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocated.java
@@ -0,0 +1,19 @@
+package tdt4140.gr1800.app.core;
+
+public interface GeoLocated {
+
+	public LatLong getLatLong();
+	
+	default double getLatitude() {
+		return getLatLong().latitude;
+	}
+	default double getLongitude() {
+		return getLatLong().longitude;
+	}
+	default boolean equalsLatLong(GeoLocated geoLoc) {
+		return getLatitude() == geoLoc.getLatitude() && getLongitude() == geoLoc.getLongitude();
+	}
+	default double distance(GeoLocated geoLoc) {
+		return getLatLong().distance(geoLoc.getLatLong());
+	}
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java
index 3327a22c2cec46dd063dfb66670c362d526994ab..19e2fd43ad21eab376c81a1e26c97d147125ad14 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/GeoLocations.java
@@ -7,7 +7,7 @@ import java.util.Iterator;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
-public class GeoLocations implements Iterable<LatLong> {
+public class GeoLocations implements Iterable<GeoLocated> {
 
 	private String name;
 	
@@ -19,7 +19,7 @@ public class GeoLocations implements Iterable<LatLong> {
 		this.name = name;
 	}
 	
-	private Collection<LatLong> locations = new ArrayList<LatLong>();
+	private Collection<GeoLocated> locations = new ArrayList<GeoLocated>();
 	private boolean path = false;
 	
 	public GeoLocations(LatLong...latLongs) {
@@ -27,7 +27,7 @@ public class GeoLocations implements Iterable<LatLong> {
 			addLocation(latLongs[i]);
 		}
 	}
-	
+
 	public GeoLocations(String name, LatLong...latLongs) {
 		this(latLongs);
 		setName(name);
@@ -41,34 +41,34 @@ public class GeoLocations implements Iterable<LatLong> {
 		this.path = path;
 	}
 	
-	public Comparator<? super LatLong> closestComparator(LatLong latLong) {
-		return (latLong1, latLong2) -> (int) Math.signum(latLong.distance(latLong1) - latLong.distance(latLong2));
+	public Comparator<? super GeoLocated> closestComparator(GeoLocated latLong) {
+		return (geoLoc1, geoLoc2) -> (int) Math.signum(latLong.distance(geoLoc1) - latLong.distance(geoLoc2));
 	}
 
-	public Collection<LatLong> findLocationsNearby(LatLong latLong, double distance) {
+	public Collection<GeoLocated> findLocationsNearby(GeoLocated geoLoc, double distance) {
 		return locations.stream()
-				.filter(latLong2 -> distance == 0.0 ? latLong2.equals(latLong) : latLong.distance(latLong2) <= distance)
-				.sorted(closestComparator(latLong))
+				.filter(geoLoc2 -> distance == 0.0 ? geoLoc2.equalsLatLong(geoLoc) : geoLoc.distance(geoLoc2) <= distance)
+				.sorted(closestComparator(geoLoc))
 				.collect(Collectors.toList());
 	}
 
-	public LatLong findNearestLocation(LatLong latLong) {
-		Optional<LatLong> min = locations.stream()
-				.min(closestComparator(latLong));
+	public GeoLocated findNearestLocation(GeoLocated geoLoc) {
+		Optional<GeoLocated> min = locations.stream()
+				.min(closestComparator(geoLoc));
 		return min.isPresent() ? min.get() : null;
 	}
 
 	//
 	
-	public void addLocation(LatLong latLong) {
-		locations.add(latLong);
+	public void addLocation(LatLong geoLoc) {
+		locations.add(geoLoc);
 	}
 
-	public void removeLocations(LatLong latLong, double distance) {
-		Iterator<LatLong> it = locations.iterator();
+	public void removeLocations(GeoLocated geoLoc, double distance) {
+		Iterator<GeoLocated> it = locations.iterator();
 		while (it.hasNext()) {
-			LatLong latLong2 = it.next();
-			if (distance == 0.0 ? latLong2.equals(latLong) : latLong.distance(latLong2) <= distance) {
+			GeoLocated geoLoc2 = it.next();
+			if (distance == 0.0 ? geoLoc2.equalsLatLong(geoLoc) : geoLoc.getLatLong().distance(geoLoc2.getLatLong()) <= distance) {
 				it.remove();
 			}
 		}
@@ -79,7 +79,7 @@ public class GeoLocations implements Iterable<LatLong> {
 	}
 	
 	@Override
-	public Iterator<LatLong> iterator() {
+	public Iterator<GeoLocated> iterator() {
 		return locations.iterator();
 	}
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentImporter.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentImporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..c37c4c56d4786538644974664c932a578ddac800
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentImporter.java
@@ -0,0 +1,7 @@
+package tdt4140.gr1800.app.core;
+
+import java.io.IOException;
+
+public interface IDocumentImporter<L> {
+	public void importDocument(L documentLocation) throws IOException;
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentLoader.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..928fd9b860ee6cfa3050917c5fb8037634bcb2af
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentLoader.java
@@ -0,0 +1,5 @@
+package tdt4140.gr1800.app.core;
+
+public interface IDocumentLoader<D, L> {
+	public D loadDocument(L documentLocation) throws Exception;
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentPersistence.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentPersistence.java
new file mode 100644
index 0000000000000000000000000000000000000000..756f85d04ea4dd06618798eeab05c01f549fa913
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentPersistence.java
@@ -0,0 +1,4 @@
+package tdt4140.gr1800.app.core;
+
+public interface IDocumentPersistence<D, L> extends IDocumentLoader<D, L>, IDocumentSaver<D, L> {
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentSaver.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentSaver.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d2ee0a3807554f6f4868f669ec3621007d82d24
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentSaver.java
@@ -0,0 +1,5 @@
+package tdt4140.gr1800.app.core;
+
+public interface IDocumentSaver<D, L> {
+	public void saveDocument(D document, L documentLocation) throws Exception;
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java
index ceef9616362ec82ffd15246c7811942b39ddc35e..147bd16774ed90ac6e98643484c1392fd5e842bb 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IDocumentStorage.java
@@ -1,6 +1,7 @@
 package tdt4140.gr1800.app.core;
 
 import java.io.IOException;
+import java.util.Collection;
 
 public interface IDocumentStorage<L> {
 	public L getDocumentLocation();
@@ -9,4 +10,6 @@ public interface IDocumentStorage<L> {
 	public void newDocument();
 	public void openDocument(L documentLocation) throws IOException;
 	public void saveDocument() throws IOException;
+
+	public Collection<IDocumentImporter<L>> getDocumentImporters();
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IGeoLocationsListener.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IGeoLocationsListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..787f85d1d559a80439f2690f1ea04b5f782932ca
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/IGeoLocationsListener.java
@@ -0,0 +1,6 @@
+package tdt4140.gr1800.app.core;
+
+public interface IGeoLocationsListener {
+
+	public void geoLocationsUpdated(GeoLocations geoLocations);
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/LatLong.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/LatLong.java
index 5576e2526936153939127e79f614914ec0599538..c88e7e97adbf06c84c6c9cacc8da95d694ccca3e 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/LatLong.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/core/LatLong.java
@@ -1,6 +1,6 @@
 package tdt4140.gr1800.app.core;
 
-public class LatLong {
+public class LatLong implements GeoLocated {
 	
 	public final double latitude, longitude;
 
@@ -57,6 +57,13 @@ public class LatLong {
 		return new LatLong(lat, lon);
 	}
 	
+	// GeoLocated
+	
+	@Override
+	public LatLong getLatLong() {
+		return this;
+	}
+	
 	/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
 	/*::                                                                         :*/
 	/*::  This routine calculates the distance between two points (given the     :*/
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..55550bf54b9be9daba07ae3c71bb12ae3de6f396
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentConverter.java
@@ -0,0 +1,91 @@
+package tdt4140.gr1800.app.gpx;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+import io.jenetics.jpx.GPX;
+import io.jenetics.jpx.Route;
+import io.jenetics.jpx.Track;
+import io.jenetics.jpx.TrackSegment;
+import io.jenetics.jpx.WayPoint;
+import tdt4140.gr1800.app.core.GeoLocations;
+import tdt4140.gr1800.app.core.IDocumentLoader;
+import tdt4140.gr1800.app.core.LatLong;
+
+public class GpxDocumentConverter implements IDocumentLoader<Collection<GeoLocations>, File> {
+
+	private GpxDocumentLoader gpxLoader = new GpxDocumentLoader();
+	
+	@Override
+	public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
+		GPX gpx = gpxLoader.loadDocument(documentLocation.toURI().toURL());
+		return convert(gpx);
+	}
+
+	private String trackNameFormat = "%s";
+	private String trackCountFormat = "Track %s";
+	private String trackSegmentFormat = "%s.%s";
+
+	public void setTrackNameFormat(String trackNameFormat) {
+		this.trackNameFormat = trackNameFormat;
+	}
+	
+	public void setTrackCountFormat(String trackCountFormat) {
+		this.trackCountFormat = trackCountFormat;
+	}
+	
+	public void setTrackSegmentFormat(String trackSegmentFormat) {
+		this.trackSegmentFormat = trackSegmentFormat;
+	}
+
+	private String routeNameFormat = "%s";
+	private String routeCountFormat = "Route %s";
+	
+	public void setRouteNameFormat(String routeNameFormat) {
+		this.routeNameFormat = routeNameFormat;
+	}
+	
+	public void setRouteCountFormat(String routeCountFormat) {
+		this.routeCountFormat = routeCountFormat;
+	}
+	
+	public Collection<GeoLocations> convert(GPX gpx) throws Exception {
+		Collection<GeoLocations> geoLocations = new ArrayList<GeoLocations>();
+		int trackCount = 1;
+		for (Track track : gpx.getTracks()) {
+			String trackName = (track.getName().isPresent() ? String.format(trackNameFormat, track.getName().get()) : String.format(trackCountFormat, trackCount));
+			int segmentCount = 1;
+			for (TrackSegment segment : track) {
+				boolean singleTrack = track.getSegments().size() <= 1;
+				String name = (singleTrack ? trackName : String.format(trackSegmentFormat, trackName, segmentCount));
+				GeoLocations gl = new GeoLocations(name, convert(segment.getPoints()));
+				gl.setPath(true);
+				geoLocations.add(gl);
+			}
+		}
+		int routeCount = 1;
+		for (Route route : gpx.getRoutes()) {
+			String routeName = (route.getName().isPresent() ? String.format(routeNameFormat, route.getName().get()) : String.format(routeCountFormat, routeCount));
+			GeoLocations gl = new GeoLocations(routeName, convert(route.getPoints()));
+			gl.setPath(true);
+			geoLocations.add(gl);
+		}
+		if (! gpx.getWayPoints().isEmpty()) {
+			geoLocations.add(new GeoLocations("Waypoints", convert(gpx.getWayPoints())));
+		}
+		return geoLocations;
+	}
+
+	private LatLong[] convert(Collection<WayPoint> points) {
+		Collection<LatLong> latLongs = points.stream()
+				.map(point -> convert(point))
+				.collect(Collectors.toList());
+		return latLongs.toArray(new LatLong[latLongs.size()]);
+	}
+
+	private LatLong convert(WayPoint point) {
+		return new LatLong(point.getLatitude().doubleValue(), point.getLongitude().doubleValue());
+	}	
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..28e971d9f84e2f2a13c9e5b73843603d80cdcd0f
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/gpx/GpxDocumentLoader.java
@@ -0,0 +1,19 @@
+package tdt4140.gr1800.app.gpx;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import io.jenetics.jpx.GPX;
+import tdt4140.gr1800.app.core.IDocumentLoader;
+
+public class GpxDocumentLoader implements IDocumentLoader<GPX, URL> {
+	
+	public GPX loadDocument(InputStream inputStream) throws Exception {
+		return GPX.read(inputStream, true);
+	}
+
+	@Override
+	public GPX loadDocument(URL documentLocation) throws Exception {
+		return loadDocument(documentLocation.openStream());
+	}
+}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java
index da7aa070edbb165e2e29c7b87ffc7c57467a54aa..2f08083a2f4bea94a40612fc1357a0ef034a568b 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/json/GeoLocationsJsonSerializer.java
@@ -6,8 +6,8 @@ import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.databind.SerializerProvider;
 import com.fasterxml.jackson.databind.ser.std.StdSerializer;
 
+import tdt4140.gr1800.app.core.GeoLocated;
 import tdt4140.gr1800.app.core.GeoLocations;
-import tdt4140.gr1800.app.core.LatLong;
 
 public class GeoLocationsJsonSerializer extends StdSerializer<GeoLocations> {
 	
@@ -30,10 +30,10 @@ public class GeoLocationsJsonSerializer extends StdSerializer<GeoLocations> {
 		jsonGen.writeBoolean(geoLocations.isPath());
 		jsonGen.writeFieldName(LOCATIONS_FIELD_NAME);
 		jsonGen.writeStartArray();
-		for (LatLong latLon : geoLocations) {
+		for (GeoLocated geoLoc : geoLocations) {
 			jsonGen.writeStartArray();
-			jsonGen.writeNumber(latLon.latitude);
-			jsonGen.writeNumber(latLon.longitude);
+			jsonGen.writeNumber(geoLoc.getLatitude());
+			jsonGen.writeNumber(geoLoc.getLongitude());
 			jsonGen.writeEndArray();
 		}
 		jsonGen.writeEndArray();
diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java
index 1cdd829250a43a5d2473dbaeaae029082cf334b5..654d377ef4f568ad589920745531c41f6465de6d 100644
--- a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java
+++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsTest.java
@@ -29,11 +29,11 @@ public class GeoLocationsTest {
 	}
 
 	public static void assertGeoLocations(GeoLocations geoLocations, LatLong...latLongs) {
-		Iterator<LatLong> it = geoLocations.iterator();
+		Iterator<GeoLocated> it = geoLocations.iterator();
 		Assert.assertEquals(latLongs.length, geoLocations.size());
 		int pos = 0;
 		while (it.hasNext()) {
-			Assert.assertEquals(latLongs[pos], it.next());
+			checkGeoLocated(latLongs[pos], it.next());
 			pos++;
 		}
 	}
@@ -53,14 +53,18 @@ public class GeoLocationsTest {
 		assertGeoLocations(latLong1, latLong1, latLong2);
 	}
 
+	static void checkGeoLocated(GeoLocated geoLoc1, GeoLocated geoLoc2) {
+		Assert.assertTrue(geoLoc1.equalsLatLong(geoLoc2));
+	}
+	
 	@Test
 	public void testFindLocationsNearby() {
 		LatLong latLong = new LatLong(0, 0);
 		Assert.assertTrue(geoLocations.findLocationsNearby(latLong, 0).isEmpty());
 		geoLocations.addLocation(latLong);
-		Collection<LatLong> locationsNearby = geoLocations.findLocationsNearby(latLong, 0);
+		Collection<GeoLocated> locationsNearby = geoLocations.findLocationsNearby(latLong, 0);
 		Assert.assertEquals(1, locationsNearby.size());
-		Assert.assertEquals(latLong, geoLocations.iterator().next()); 
+		checkGeoLocated(latLong, geoLocations.iterator().next()); 
 	}
 	
 	@Test
@@ -68,8 +72,8 @@ public class GeoLocationsTest {
 		LatLong latLong = new LatLong(0, 0);
 		Assert.assertNull(geoLocations.findNearestLocation(latLong));
 		geoLocations.addLocation(latLong);
-		LatLong nearestlocations = geoLocations.findNearestLocation(latLong);
-		Assert.assertEquals(latLong, nearestlocations); 
+		GeoLocated nearestlocations = geoLocations.findNearestLocation(latLong);
+		checkGeoLocated(latLong, nearestlocations);
 	}
 	
 	@Test
diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GpxPersistenceTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GpxPersistenceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2850cc91b0733bb934bb7541809a4ad34d507b66
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GpxPersistenceTest.java
@@ -0,0 +1,93 @@
+package tdt4140.gr1800.app.core;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import io.jenetics.jpx.GPX;
+import tdt4140.gr1800.app.gpx.GpxDocumentConverter;
+import tdt4140.gr1800.app.gpx.GpxDocumentLoader;
+
+public class GpxPersistenceTest {
+
+	private GpxDocumentLoader loader;
+	private GpxDocumentConverter converter;
+	
+	@Before
+	public void setUp() {
+		loader = new GpxDocumentLoader();
+		converter = new GpxDocumentConverter();
+	}
+
+	@Test
+	public void testLoadDocument() {
+		try {
+			GPX gpx = loader.loadDocument(getClass().getResource("sample1.gpx"));
+			Assert.assertEquals(1, gpx.getTracks().size());
+			Assert.assertEquals(1, gpx.getTracks().get(0).getSegments().size());
+			Assert.assertEquals(3, gpx.getTracks().get(0).getSegments().get(0).getPoints().size());
+		} catch (Exception e) {
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testConvertSample1() {
+		try {
+			GPX gpx = loader.loadDocument(getClass().getResource("sample1.gpx"));
+			Collection<GeoLocations> geoLocations = converter.convert(gpx);
+			Assert.assertEquals(1, geoLocations.size());
+			GeoLocations track = geoLocations.iterator().next();
+			Assert.assertEquals("Example GPX Document", track.getName());	
+			Assert.assertEquals(3, track.size());
+			Assert.assertTrue(track.isPath());
+		} catch (Exception e) {
+			System.err.println(e);
+			Assert.fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testConvertAchterbroekRoute() {
+		try {
+			GPX gpx = loader.loadDocument(getClass().getResource("Achterbroek-route.gpx"));
+			Collection<GeoLocations> geoLocations = converter.convert(gpx);
+			Assert.assertEquals(2, geoLocations.size());
+			Iterator<GeoLocations> iterator = geoLocations.iterator();
+			GeoLocations route = iterator.next();
+			Assert.assertEquals("Achterbroek naar De Maatjes   13 km RT", route.getName());	
+			Assert.assertEquals(19, route.size());
+			Assert.assertTrue(route.isPath());
+			GeoLocations waypoints = iterator.next();
+			Assert.assertEquals("Achterbroek naar De Maatjes   13 km RT", route.getName());	
+			Assert.assertEquals(1, waypoints.size());
+			Assert.assertFalse(waypoints.isPath());
+		} catch (Exception e) {
+			System.err.println(e);
+			Assert.fail(e.getMessage());
+		}
+	}
+
+	@Test
+	public void testConvertAchterbroekTrack() {
+		try {
+			GPX gpx = loader.loadDocument(getClass().getResource("Achterbroek-track.gpx"));
+			Collection<GeoLocations> geoLocations = converter.convert(gpx);
+			Assert.assertEquals(2, geoLocations.size());
+			Iterator<GeoLocations> iterator = geoLocations.iterator();
+			GeoLocations track = iterator.next();
+			Assert.assertEquals("Achterbroek naar De Maatjes   13 km TR", track.getName());	
+			Assert.assertEquals(26, track.size());
+			Assert.assertTrue(track.isPath());
+			GeoLocations waypoints = iterator.next();
+			Assert.assertEquals(1, waypoints.size());
+			Assert.assertFalse(waypoints.isPath());
+		} catch (Exception e) {
+			System.err.println(e);
+			Assert.fail(e.getMessage());
+		}
+	}
+}
diff --git a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx
new file mode 100644
index 0000000000000000000000000000000000000000..e6ce49689300ce2b5c2b424e55bebbf697b36718
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-route.gpx
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<gpx
+  version="1.0"
+  creator="VB Net GPS:  vermeiren-willy@pandora.be"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns="http://www.topografix.com/GPX/1/0"
+  xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+
+<wpt lat="51.39709" lon="4.501519">
+   <name>START</name>
+</wpt>
+
+<rte>
+  <name>Achterbroek naar De Maatjes   13 km RT</name>
+    <rtept lat="51.39709" lon="4.501519">
+      <name>1</name>
+      <cmt>1</cmt>
+    </rtept>
+    <rtept lat="51.398635" lon="4.502678">
+      <name>2</name>
+      <cmt>2</cmt>
+    </rtept>
+    <rtept lat="51.405072" lon="4.498043">
+      <name>3</name>
+      <cmt>3</cmt>
+    </rtept>
+    <rtept lat="51.417346" lon="4.515038">
+      <name>4</name>
+      <cmt>4</cmt>
+    </rtept>
+    <rtept lat="51.41932" lon="4.513879">
+      <name>5</name>
+      <cmt>5</cmt>
+    </rtept>
+    <rtept lat="51.421552" lon="4.523535">
+      <name>6</name>
+      <cmt>6</cmt>
+    </rtept>
+    <rtept lat="51.423011" lon="4.522848">
+      <name>7</name>
+      <cmt>7</cmt>
+    </rtept>
+    <rtept lat="51.423826" lon="4.5295">
+      <name>8</name>
+      <cmt>8</cmt>
+    </rtept>
+    <rtept lat="51.427002" lon="4.528513">
+      <name>9</name>
+      <cmt>9</cmt>
+    </rtept>
+    <rtept lat="51.430402" lon="4.552363">
+      <name>10</name>
+      <cmt>10</cmt>
+    </rtept>
+    <rtept lat="51.426229" lon="4.555399">
+      <name>11</name>
+      <cmt>11</cmt>
+    </rtept>
+    <rtept lat="51.426015" lon="4.554734">
+      <name>12</name>
+      <cmt>12</cmt>
+    </rtept>
+    <rtept lat="51.423569" lon="4.556108">
+      <name>13</name>
+      <cmt>13</cmt>
+    </rtept>
+    <rtept lat="51.41932" lon="4.546237">
+      <name>14</name>
+      <cmt>14</cmt>
+    </rtept>
+    <rtept lat="51.410952" lon="4.534092">
+      <name>15</name>
+      <cmt>15</cmt>
+    </rtept>
+    <rtept lat="51.406231" lon="4.543018">
+      <name>16</name>
+      <cmt>16</cmt>
+    </rtept>
+    <rtept lat="51.396695" lon="4.515966">
+      <name>17</name>
+      <cmt>17</cmt>
+    </rtept>
+    <rtept lat="51.396017" lon="4.515853">
+      <name>18</name>
+      <cmt>18</cmt>
+    </rtept>
+    <rtept lat="51.397133" lon="4.502635">
+      <name>19</name>
+      <cmt>19</cmt>
+    </rtept>
+</rte>
+</gpx>
diff --git a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx
new file mode 100644
index 0000000000000000000000000000000000000000..279b657067b2ff6c9d7a6e326e94dad918644b5a
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/Achterbroek-track.gpx
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<gpx
+  version="1.0"
+  creator="VB Net GPS:  vermeiren-willy@pandora.be"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xmlns="http://www.topografix.com/GPX/1/0"
+  xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+
+<wpt lat="51.39709" lon="4.501519">
+   <name>START</name>
+</wpt>
+
+<trk>
+  <name>Achterbroek naar De Maatjes   13 km TR</name>
+  <trkseg>
+    <trkpt lat="51.39709" lon="4.501519">
+      <name>1</name>
+    </trkpt>
+    <trkpt lat="51.397705" lon="4.501452">
+      <name>2</name>
+    </trkpt>
+    <trkpt lat="51.398635" lon="4.502678">
+      <name>3</name>
+    </trkpt>
+    <trkpt lat="51.404042" lon="4.498472">
+      <name>4</name>
+    </trkpt>
+    <trkpt lat="51.405072" lon="4.498043">
+      <name>5</name>
+    </trkpt>
+    <trkpt lat="51.405456" lon="4.499259">
+      <name>6</name>
+    </trkpt>
+    <trkpt lat="51.417346" lon="4.515038">
+      <name>7</name>
+    </trkpt>
+    <trkpt lat="51.41932" lon="4.513879">
+      <name>8</name>
+    </trkpt>
+    <trkpt lat="51.421552" lon="4.523535">
+      <name>9</name>
+    </trkpt>
+    <trkpt lat="51.423011" lon="4.522848">
+      <name>10</name>
+    </trkpt>
+    <trkpt lat="51.423826" lon="4.5295">
+      <name>11</name>
+    </trkpt>
+    <trkpt lat="51.427002" lon="4.528513">
+      <name>12</name>
+    </trkpt>
+    <trkpt lat="51.427131" lon="4.534478">
+      <name>13</name>
+    </trkpt>
+    <trkpt lat="51.426819" lon="4.53744">
+      <name>14</name>
+    </trkpt>
+    <trkpt lat="51.430402" lon="4.552363">
+      <name>15</name>
+    </trkpt>
+    <trkpt lat="51.426229" lon="4.555399">
+      <name>16</name>
+    </trkpt>
+    <trkpt lat="51.426015" lon="4.554734">
+      <name>17</name>
+    </trkpt>
+    <trkpt lat="51.423569" lon="4.556108">
+      <name>18</name>
+    </trkpt>
+    <trkpt lat="51.423097" lon="4.553981">
+      <name>19</name>
+    </trkpt>
+    <trkpt lat="51.41932" lon="4.546237">
+      <name>20</name>
+    </trkpt>
+    <trkpt lat="51.410952" lon="4.534092">
+      <name>21</name>
+    </trkpt>
+    <trkpt lat="51.406231" lon="4.543018">
+      <name>22</name>
+    </trkpt>
+    <trkpt lat="51.396695" lon="4.515966">
+      <name>23</name>
+    </trkpt>
+    <trkpt lat="51.396017" lon="4.515853">
+      <name>24</name>
+    </trkpt>
+    <trkpt lat="51.396858" lon="4.506495">
+      <name>25</name>
+    </trkpt>
+    <trkpt lat="51.397133" lon="4.502635">
+      <name>26</name>
+    </trkpt>
+  </trkseg>
+</trk>
+</gpx>
diff --git a/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/sample1.gpx b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/sample1.gpx
new file mode 100644
index 0000000000000000000000000000000000000000..79b840dd8808e6834ce6ef5fed1a6b428b3d0767
--- /dev/null
+++ b/tdt4140-gr1800/app.core/src/test/resources/tdt4140/gr1800/app/core/sample1.gpx
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="Oregon 400t" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd">
+  <metadata>
+    <link href="http://www.garmin.com">
+      <text>Garmin International</text>
+    </link>
+    <time>2009-10-17T22:58:43Z</time>
+  </metadata>
+  <trk>
+    <name>Example GPX Document</name>
+    <trkseg>
+      <trkpt lat="47.644548" lon="-122.326897">
+        <ele>4.46</ele>
+        <time>2009-10-17T18:37:26Z</time>
+      </trkpt>
+      <trkpt lat="47.644548" lon="-122.33">
+        <ele>4.94</ele>
+        <time>2009-10-17T18:37:31Z</time>
+      </trkpt>
+      <trkpt lat="47.65" lon="-122.33">
+        <ele>6.87</ele>
+        <time>2009-10-17T18:37:34Z</time>
+      </trkpt>
+    </trkseg>
+  </trk>
+</gpx>
diff --git a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java
index f63754c3c4ab28db23b288e2e0711a50f0e504a5..8575711352c784bd9b29449bb148e06a556dbf81 100644
--- a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java
+++ b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FileMenuController.java
@@ -11,6 +11,7 @@ import javafx.fxml.FXML;
 import javafx.scene.control.Menu;
 import javafx.scene.control.MenuItem;
 import javafx.stage.FileChooser;
+import tdt4140.gr1800.app.core.IDocumentImporter;
 import tdt4140.gr1800.app.core.IDocumentStorage;
 
 public class FileMenuController {
@@ -126,4 +127,20 @@ public class FileMenuController {
 			documentStorage.setDocumentLocation(oldStorage);
 		}
 	}
+
+	@FXML
+	public void handleImportAction() {
+		FileChooser fileChooser = getFileChooser();
+		File selection = fileChooser.showOpenDialog(null);
+//		String path = selection.getPath();
+//		int pos = path.lastIndexOf('.');
+//		String ext = (pos > 0 ? path.substring(pos + 1) : null);
+		for (IDocumentImporter<File> importer : documentStorage.getDocumentImporters()) {
+			try {
+				importer.importDocument(selection);
+				break;
+			} catch (Exception e) {
+			}
+		}
+	}
 }
diff --git a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java
index 22dc763b0309af78a8b853be3261a04aafdfa2de..20c656259f1cb4765d8656bcfba0925eb30fdfcd 100644
--- a/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java
+++ b/tdt4140-gr1800/app.ui/src/main/java/tdt4140/gr1800/app/ui/FxAppController.java
@@ -2,6 +2,7 @@ package tdt4140.gr1800.app.ui;
 
 import java.util.Iterator;
 
+import fxmapcontrol.Location;
 import fxmapcontrol.MapBase;
 import fxmapcontrol.MapItemsControl;
 import fxmapcontrol.MapNode;
@@ -10,10 +11,12 @@ import javafx.fxml.FXML;
 import javafx.scene.control.ComboBox;
 import javafx.scene.control.Slider;
 import tdt4140.gr1800.app.core.App;
+import tdt4140.gr1800.app.core.GeoLocated;
 import tdt4140.gr1800.app.core.GeoLocations;
+import tdt4140.gr1800.app.core.IGeoLocationsListener;
 import tdt4140.gr1800.app.core.LatLong;
 
-public class FxAppController {
+public class FxAppController implements IGeoLocationsListener {
 
 	@FXML
 	private FileMenuController fileMenuController;
@@ -36,12 +39,17 @@ public class FxAppController {
 		app = new App();
 		fileMenuController.setDocumentStorage(app.getDocumentStorage());
 		fileMenuController.setOnDocumentChanged(documentStorage -> initMapMarkers());
+
 		geoLocationsSelector.getSelectionModel().selectedItemProperty().addListener((stringProperty, oldValue, newValue) -> updateGeoLocations());
 
 		mapView.getChildren().add(MapTileLayer.getOpenStreetMapLayer());
-		mapView.zoomLevelProperty().bind(zoomSlider.valueProperty());
+		zoomSlider.valueProperty().addListener((prop, oldValue, newValue) -> {
+			mapView.setZoomLevel(zoomSlider.getValue());			
+		});
 		markersParent = new MapItemsControl<MapNode>();
 		mapView.getChildren().add(markersParent);
+		
+		app.addGeoLocationsListener(this);
 	}
 
 	private Object updateGeoLocations() {
@@ -50,11 +58,12 @@ public class FxAppController {
 
 	private void initMapMarkers() {
 		markersParent.getItems().clear();
+		geoLocationsSelector.getItems().clear();
 		for (String geoLocationName : app.getGeoLocationNames()) {
 			GeoLocations geoLocations = app.getGeoLocations(geoLocationName);
 			MapMarker lastMarker = null;
-			for (LatLong latLong : geoLocations) {
-				MapMarker mapMarker = new MapMarker(latLong);
+			for (GeoLocated geoLoc : geoLocations) {
+				MapMarker mapMarker = new MapMarker(geoLoc.getLatLong());
 				markersParent.getItems().add(mapMarker);
 				if (geoLocations.isPath() && lastMarker != null) {
 					MapPathLine pathLine = new MapPathLine(lastMarker, mapMarker);
@@ -62,10 +71,10 @@ public class FxAppController {
 				}
 				lastMarker = mapMarker;
 			}
-			geoLocationsSelector.getItems().add(geoLocationName);
+			geoLocationsSelector.getItems().add(geoLocationName + " (" + geoLocations.size() + ")");
 		}
 		LatLong center = getCenter(null);
-		System.out.println("Map markers initialized");
+		mapView.setCenter(new Location(center.latitude, center.longitude));
 	}
 
 	private LatLong getCenter(GeoLocations geoLocations) {
@@ -79,8 +88,8 @@ public class FxAppController {
 			if (names != null) {
 				geoLocations = app.getGeoLocations(names.next());
 			}
-			for (LatLong latLong : geoLocations) {
-				double lat = latLong.latitude, lon = latLong.longitude;
+			for (GeoLocated geoLoc : geoLocations) {
+				double lat = geoLoc.getLatitude(), lon = geoLoc.getLongitude();
 				latSum += lat;
 				lonSum += lon;
 				num++;
@@ -91,4 +100,9 @@ public class FxAppController {
 		}
 		return new LatLong(latSum / num, lonSum / num);
 	}
+
+	@Override
+	public void geoLocationsUpdated(GeoLocations geoLocations) {
+		initMapMarkers();
+	}
 }
diff --git a/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml b/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml
index 9b1209b8feb26c402e0ffb0e15d9a69a63cc97bd..9515c49930b7552d21d2adf531bdd4dd09a54afb 100644
--- a/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml
+++ b/tdt4140-gr1800/app.ui/src/main/resources/tdt4140/gr1800/app/ui/FileMenu.fxml
@@ -3,14 +3,18 @@
 <?import java.lang.*?>
 <?import javafx.scene.control.Menu?>
 <?import javafx.scene.control.MenuItem?>
+<?import javafx.scene.control.SeparatorMenuItem?>
 
 <Menu xmlns:fx="http://javafx.com/fxml" text="File" fx:controller="tdt4140.gr1800.app.ui.FileMenuController">
 	<items>
 		<MenuItem text="New" onAction="#handleNewAction"/>
 		<MenuItem text="Open..." onAction="#handleOpenAction"/>
 		<Menu fx:id="recentMenu" text="Open Recent"/>
+		<SeparatorMenuItem/>
 		<MenuItem text="Save" onAction="#handleSaveAction"/>
 		<MenuItem text="Save As..." onAction="#handleSaveAsAction"/>
 		<MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/>
+		<SeparatorMenuItem/>
+		<MenuItem text="Import..." onAction="#handleImportAction"/>
 	</items>
 </Menu>