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 defe620ce876081d95e6852dc0e453bc1a830285..cf24b4022bad5f2646f4f4d74e9e603875e18d1e 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,6 +4,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -77,8 +78,8 @@ public class App {
 	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));
+		public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
+			return geoLocationsLoader.loadLocations(inputStream);
 		}
 
 		@Override
@@ -106,20 +107,24 @@ public class App {
 			return new ArrayList<GeoLocations>();
 		}
 
-		public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
-			return documentPersistence.loadDocument(documentLocation);
+		protected InputStream toInputStream(File storage) throws IOException {
+			return new FileInputStream(storage);
+		}
+		
+		public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
+			return documentPersistence.loadDocument(inputStream);
 		}
 		
 		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>() {
+		public Collection<IDocumentImporter> getDocumentImporters() {
+			return documentLoaders.stream().map(loader -> new IDocumentImporter() {
 				@Override
-				public void importDocument(File file) throws IOException {
+				public void importDocument(InputStream inputStream) throws IOException {
 					try {
-						setDocumentAndLocation(loader.loadDocument(file), null);
+						setDocumentAndLocation(loader.loadDocument(inputStream), null);
 					} catch (Exception e) {
 						throw new IOException(e);
 					} 
@@ -132,17 +137,17 @@ public class App {
 		return documentStorage;
 	}
 
-	private Collection<IDocumentLoader<Collection<GeoLocations>, File>> documentLoaders = Arrays.asList(
-		new IDocumentLoader<Collection<GeoLocations>, File>() {
+	private Collection<IDocumentLoader<Collection<GeoLocations>>> documentLoaders = Arrays.asList(
+		new IDocumentLoader<Collection<GeoLocations>>() {
 			private GpxDocumentConverter gpxConverter = new GpxDocumentConverter();
 			@Override
-			public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
-				return gpxConverter.loadDocument(documentLocation);
+			public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
+				return gpxConverter.loadDocument(inputStream);
 			}
 		}
 	);
 	
-	public Iterable<IDocumentLoader<Collection<GeoLocations>, File>> getDocumentLoaders() {
+	public Iterable<IDocumentLoader<Collection<GeoLocations>>> getDocumentLoaders() {
 		return documentLoaders;
 	}
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java
index 6a104a6bd96db82210a2bbad3a8fd39625bd10ca..f8aee013f0aa7b15ec16aefc37cac9754fb82f7e 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/DocumentStorageImpl.java
@@ -1,6 +1,7 @@
 package tdt4140.gr1800.app.doc;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 
@@ -60,11 +61,13 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L>,
 	public void newDocument() {
 		setDocumentAndLocation(createDocument(), null);
 	}
+	
+	protected abstract InputStream toInputStream(L storage) throws IOException;
 
 	@Override
 	public void openDocument(L storage) throws IOException {
 		try {
-			setDocumentAndLocation(loadDocument(storage), storage);
+			setDocumentAndLocation(loadDocument(toInputStream(storage)), storage);
 		} catch (Exception e) {
 			throw new IOException(e);
 		}
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java
index ba8b8ec2aa68702c1400a09032ab41c6f6140b23..2b9327b74773afe7409a67f0048ca17a7820aa7f 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentImporter.java
@@ -1,7 +1,8 @@
 package tdt4140.gr1800.app.doc;
 
 import java.io.IOException;
+import java.io.InputStream;
 
-public interface IDocumentImporter<L> {
-	public void importDocument(L documentLocation) throws IOException;
+public interface IDocumentImporter {
+	public void importDocument(InputStream inputStream) throws IOException;
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java
index ecb029b5d7668f17d9024a2599c94d70475689f8..8c719fe9720e03adc8ca65d2555f2babc07e66db 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentLoader.java
@@ -1,5 +1,7 @@
 package tdt4140.gr1800.app.doc;
 
-public interface IDocumentLoader<D, L> {
-	public D loadDocument(L documentLocation) throws Exception;
+import java.io.InputStream;
+
+public interface IDocumentLoader<D> {
+	public D loadDocument(InputStream inputStream) throws Exception;
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java
index 9fbd23a7f7d04405e7b678fc7ab2ce448c46f9f8..0da1f8d2939a5fc079d0ade8f3b392e9b338fb71 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentPersistence.java
@@ -1,4 +1,4 @@
 package tdt4140.gr1800.app.doc;
 
-public interface IDocumentPersistence<D, L> extends IDocumentLoader<D, L>, IDocumentSaver<D, L> {
+public interface IDocumentPersistence<D, L> extends IDocumentLoader<D>, IDocumentSaver<D, L> {
 }
diff --git a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java
index a037c42a38494ed0736c191f44a40f0e1dd03661..1f30c37808e5eaaab146f93a2d931af16683b03a 100644
--- a/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java
+++ b/tdt4140-gr1800/app.core/src/main/java/tdt4140/gr1800/app/doc/IDocumentStorage.java
@@ -14,5 +14,5 @@ public interface IDocumentStorage<L> {
 	public void openDocument(L documentLocation) throws IOException;
 	public void saveDocument() throws IOException;
 
-	public Collection<IDocumentImporter<L>> getDocumentImporters();
+	public Collection<IDocumentImporter> getDocumentImporters();
 }
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
index 7324eb5c112618c1ebbc5413155c696d727b8858..7c1f2d915f5f77cbc5a0f77899fc735a432d6bcc 100644
--- 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
@@ -1,6 +1,6 @@
 package tdt4140.gr1800.app.gpx;
 
-import java.io.File;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.stream.Collectors;
@@ -14,13 +14,13 @@ import tdt4140.gr1800.app.core.GeoLocations;
 import tdt4140.gr1800.app.core.LatLong;
 import tdt4140.gr1800.app.doc.IDocumentLoader;
 
-public class GpxDocumentConverter implements IDocumentLoader<Collection<GeoLocations>, File> {
+public class GpxDocumentConverter implements IDocumentLoader<Collection<GeoLocations>> {
 
 	private GpxDocumentLoader gpxLoader = new GpxDocumentLoader();
 	
 	@Override
-	public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception {
-		GPX gpx = gpxLoader.loadDocument(documentLocation.toURI().toURL());
+	public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
+		GPX gpx = gpxLoader.loadDocument(inputStream);
 		return convert(gpx);
 	}
 
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
index b7dcb43a46239d18a34e3b1dce828ce2a803d0b0..0f520d3f17ae9dc235f72c89cb1f564a2454ec6c 100644
--- 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
@@ -1,19 +1,14 @@
 package tdt4140.gr1800.app.gpx;
 
 import java.io.InputStream;
-import java.net.URL;
 
 import io.jenetics.jpx.GPX;
 import tdt4140.gr1800.app.doc.IDocumentLoader;
 
-public class GpxDocumentLoader implements IDocumentLoader<GPX, URL> {
-	
-	public GPX loadDocument(InputStream inputStream) throws Exception {
-		return GPX.read(inputStream, true);
-	}
+public class GpxDocumentLoader implements IDocumentLoader<GPX> {
 
 	@Override
-	public GPX loadDocument(URL documentLocation) throws Exception {
-		return loadDocument(documentLocation.openStream());
+	public GPX loadDocument(InputStream inputStream) throws Exception {
+		return GPX.read(inputStream, true);
 	}
 }
diff --git a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java
index 73a426f00181d39a7dca1c71e00d64e50d0d89c6..7f2fc277192000846ea1eead52fba3e5653b74d0 100644
--- a/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java
+++ b/tdt4140-gr1800/app.core/src/test/java/tdt4140/gr1800/app/core/GeoLocationsPersistenceTest.java
@@ -2,7 +2,6 @@ package tdt4140.gr1800.app.core;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
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
index 2850cc91b0733bb934bb7541809a4ad34d507b66..67a6fb87b40eec0f9e4cbba8b98875a593492a59 100644
--- 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
@@ -25,7 +25,7 @@ public class GpxPersistenceTest {
 	@Test
 	public void testLoadDocument() {
 		try {
-			GPX gpx = loader.loadDocument(getClass().getResource("sample1.gpx"));
+			GPX gpx = loader.loadDocument(getClass().getResourceAsStream("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());
@@ -37,7 +37,7 @@ public class GpxPersistenceTest {
 	@Test
 	public void testConvertSample1() {
 		try {
-			GPX gpx = loader.loadDocument(getClass().getResource("sample1.gpx"));
+			GPX gpx = loader.loadDocument(getClass().getResourceAsStream("sample1.gpx"));
 			Collection<GeoLocations> geoLocations = converter.convert(gpx);
 			Assert.assertEquals(1, geoLocations.size());
 			GeoLocations track = geoLocations.iterator().next();
@@ -53,7 +53,7 @@ public class GpxPersistenceTest {
 	@Test
 	public void testConvertAchterbroekRoute() {
 		try {
-			GPX gpx = loader.loadDocument(getClass().getResource("Achterbroek-route.gpx"));
+			GPX gpx = loader.loadDocument(getClass().getResourceAsStream("Achterbroek-route.gpx"));
 			Collection<GeoLocations> geoLocations = converter.convert(gpx);
 			Assert.assertEquals(2, geoLocations.size());
 			Iterator<GeoLocations> iterator = geoLocations.iterator();
@@ -74,7 +74,7 @@ public class GpxPersistenceTest {
 	@Test
 	public void testConvertAchterbroekTrack() {
 		try {
-			GPX gpx = loader.loadDocument(getClass().getResource("Achterbroek-track.gpx"));
+			GPX gpx = loader.loadDocument(getClass().getResourceAsStream("Achterbroek-track.gpx"));
 			Collection<GeoLocations> geoLocations = converter.convert(gpx);
 			Assert.assertEquals(2, geoLocations.size());
 			Iterator<GeoLocations> iterator = geoLocations.iterator();
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 9eb8409bd6d79ea7f9a9eba6c405d788f60864fb..d3e590495be7d4f0330bba1391f8f79242e004a9 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
@@ -1,14 +1,19 @@
 package tdt4140.gr1800.app.ui;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
 import javafx.scene.control.Menu;
 import javafx.scene.control.MenuItem;
+import javafx.scene.control.TextInputDialog;
 import javafx.stage.FileChooser;
 import tdt4140.gr1800.app.doc.IDocumentImporter;
 import tdt4140.gr1800.app.doc.IDocumentStorage;
@@ -130,22 +135,65 @@ public class FileMenuController {
 	}
 
 	@FXML
-	public void handleImportAction() {
+	public void handleFileImportAction() {
 		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);
-		handleImportAction(selection);
+		handleFileImportAction(selection);
 	}
 
-	void handleImportAction(File selection) {
-		for (IDocumentImporter<File> importer : documentStorage.getDocumentImporters()) {
+	void handleFileImportAction(File selection) {
+		for (IDocumentImporter importer : documentStorage.getDocumentImporters()) {
 			try {
-				importer.importDocument(selection);
+				importer.importDocument(new FileInputStream(selection));
 				break;
 			} catch (Exception e) {
 			}
 		}
 	}
+	
+	private TextInputDialog inputDialog;
+
+	@FXML
+	public void handleURLImportAction() {
+		if (inputDialog == null) {
+			inputDialog = new TextInputDialog();
+		}
+		inputDialog.setTitle("Import from URL");
+		inputDialog.setHeaderText("Enter URL to import from");
+		inputDialog.setContentText("Enter URL: ");
+		// https://developer.garmin.com/downloads/connect-api/sample_file.gpx
+		URL url = null;
+		while (url == null) {
+			Optional<String> result = inputDialog.showAndWait();
+			if (! result.isPresent()) {
+				return;
+			}
+			try {
+				url = new URL(result.get());
+				if (handleURLImportAction(url)) {
+					return;
+				}
+				url = null;
+				inputDialog.setHeaderText("Problems reading it...");
+				inputDialog.setContentText("Enter another URL: ");
+			} catch (MalformedURLException e1) {
+				inputDialog.setContentText("Enter a valid URL: ");
+			}
+		}
+	}
+
+	boolean handleURLImportAction(URL url) {
+		for (IDocumentImporter importer : documentStorage.getDocumentImporters()) {
+			try {
+				importer.importDocument(url.openStream());
+				return true;
+			} catch (Exception e) {
+				System.err.println(e.getMessage());
+			}
+		}
+		return false;
+	}
 }
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 5de3493684996e64d7318ffeb16707366da68b04..a9c97faf32a2f7546dabf083e35cd568b6076a53 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
@@ -15,6 +15,9 @@
 		<MenuItem text="Save As..." 							onAction="#handleSaveAsAction"/>
 		<MenuItem text="Save Copy As..." 					onAction="#handleSaveCopyAsAction"/>
 		<SeparatorMenuItem/>
-		<MenuItem text="Import..." 							onAction="#handleImportAction"/>
+		<Menu text="Import">
+			<MenuItem text="File..." 						onAction="#handleFileImportAction"/>
+			<MenuItem text="URL..." 							onAction="#handleURLImportAction"/>
+		</Menu>
 	</items>
 </Menu>