gt: 				if (file.length() != 0) {
context: package org.freeplane.features.url.mindmapmode;
  
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.net.MalformedURLException;
  import java.net.URI;
  import java.net.URISyntaxException;
  import java.net.URL;
  import java.nio.charset.StandardCharsets;
  import java.nio.file.Paths;
  import java.security.AccessController;
  import java.security.PrivilegedActionException;
  import java.security.PrivilegedExceptionAction;
  
  import org.freeplane.core.resources.TranslatedObject;
  import org.freeplane.core.undo.IUndoHandler;
  import org.freeplane.core.util.Compat;
  import org.freeplane.features.map.DocuMapAttribute;
  import org.freeplane.features.map.MapModel;
  import org.freeplane.features.map.MapWriter.Mode;
  import org.freeplane.features.map.NodeModel;
  import org.freeplane.features.map.mindmapmode.MMapController;
  import org.freeplane.features.map.mindmapmode.MMapModel;
  import org.freeplane.features.mode.Controller;
  import org.freeplane.features.mode.ModeController;
  import org.freeplane.features.styles.MapStyleModel;
  import org.freeplane.features.ui.IMapViewManager;
  import org.freeplane.features.url.mindmapmode.MFileManager.AlternativeFileMode;
  import org.freeplane.n3.nanoxml.XMLException;
  import org.freeplane.n3.nanoxml.XMLParseException;
  
  public class MapLoader{
  
  	private final ModeController modeController;
  
  	private URL sourceLocation;
  	private URL newMapLocation;
  	private boolean saveAfterLoading;
  	private boolean withView;
  	private boolean followSourceMap;
  	private boolean unsetMapLocation;
  	private boolean asDocumentation;
  	private String selectedNodeId;
  	private InputStream inputStream;
  
  
  	public MapLoader(ModeController modeController) {
  		super();
  		this.modeController = modeController;
  	}
  
  	public MapLoader load(URL url) {
  		this.sourceLocation = url;
  		return this;
  
  	}
  
  	public MapLoader load(File file) {
  		URL url = fileToUrlOrNull(file);
  		return load(url);
  
  	}
  
  	public MapLoader setInputStream(InputStream inputStream) {
  		this.inputStream = inputStream;
  		return this;
  	}
  
  	public MapLoader newMapLocation(File associatedFile) {
  		this.newMapLocation = fileToUrlOrNull(associatedFile);
  		this.saveAfterLoading = false;
  		return this;
  	}
  
  	public MapLoader followOldMap() {
  		this.followSourceMap = true;
  		return this;
  	}
  
  	public MapLoader unsetMapLocation(boolean follow) {
  		this.followSourceMap = follow;
  		return unsetMapLocation();
  	}
  
  	public MapLoader unsetMapLocation() {
  		this.unsetMapLocation = true;
  		return this;
  	}
  
  
  	public MapLoader saveAfterLoading() {
  		this.saveAfterLoading = true;
  		return this;
  	}
  
  	public MapLoader withView() {
  		this.withView = true;
  		return this;
  	}
  
  	public MapLoader asDocumentation() {
  		asDocumentation = true;
  		return this;
  	}
  
  	public MapLoader selectNodeById(String nodeId) {
  		withView = true;
  		selectedNodeId = nodeId;
  		return this;
  	}
  
  	public MapModel getMap() {
  		final MapModel oldMap = controller().getMap();
  		if(unsetMapLocation) {
  			newMapLocation = null;
  			saveAfterLoading = false;
  		}
  		else if(newMapLocation == null)
  			newMapLocation = sourceLocation;
  		asDocumentation = asDocumentation || modeController.containsExtension(DocuMapAttribute.class);
  
  		try {
  			MMapModel map = null;
  			if (withView && sourceLocation != null) {
  				assertNoTransaction(oldMap);
  				map = selectMapViewByUrl();
  			}
  			if (map == null) {
  				setWaitingCursor(true);
  				try{
  					map = loadMap();
  					if(map == null)
  					    return null;
  					if (withView) {
  						final File newFile = urlToFileOrNull(newMapLocation);
  						if(newFile != null && ! asDocumentation)
  							fileManager().lock(map, newFile);
  						createMapView(map);
  						enableAutosave(map);
  					}
  				}
  				finally {
  					setWaitingCursor(false);
  				}
  			}
  			if (withView) {
  				selectNode();
  			}
  			return map;
  		}
  		catch (RuntimeException e) {
  			throw e;
  		}
  		catch (Exception e) {
  			throw new RuntimeException(e);
  		}
  	}
  
  	private void setWaitingCursor(boolean isSet) {
  		controller().getViewController().setWaitingCursor(isSet);
  	}
  
  	private void enableAutosave(MMapModel map) {
  		if (! asDocumentation)
  			map.enableAutosave();
  	}
  
  	private void selectNode() {
  		if(selectedNodeId != null) {
  			mapController().select(selectedNodeId);
  		}
  	}
  
  	private void createMapView(MMapModel map) {
  		mapController().createMapView(map);
  	}
  
  	private MMapModel selectMapViewByUrl() throws MalformedURLException {
  		if (newMapLocation != null) {
  			final IMapViewManager mapViewManager = controller().getMapViewManager();
  			if (mapViewManager.tryToChangeToMapView( newMapLocation != null ? newMapLocation : sourceLocation)) {
  				selectNode();
  				final MapModel map = controller().getMap();
  				if(map instanceof MMapModel)
  					return (MMapModel) map;
  				else
  					throw new IllegalStateException("URL is already assigned to map with another type");
  			}
  		}
  		return null;
  	}
  
  	private static URL fileToUrlOrNull(final File file) {
  		try {
  			return Compat.fileToUrl(file.getCanonicalFile());
  		}
  		catch (IOException e) {
  			return null;
  		}
  	}
  
  	private MMapModel loadMap()
  			throws PrivilegedActionException {
  		if(newMapLocation != null) {
  			final MMapModel loadedMap = mapController().getMap(newMapLocation);
  			if(loadedMap != null) {
  				if (newMapLocation.equals(sourceLocation))
  					return loadedMap;
  				else
  					throw new IllegalStateException("URL is already assigned to another map");
  			}
  		}
  
  		final URL actualSourceLocation = inputStream != null ? null : asDocumentation ? sourceLocation : alternativeSourceLocation();
  		if(actualSourceLocation == null)
  		    return null;
  		final MMapModel map = createMindMap();
  		AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
  
  			@Override
  			public Void run() throws FileNotFoundException, XMLException, URISyntaxException, IOException {
  				if(inputStream != null) {
  					loadMapContent(map);
  				}
  				else {
  					if(actualSourceLocation != null) {
  						loadMap(map, actualSourceLocation);
  					}
  				}
  				return null;
  			}
  		});
  
  		if (map.getRootNode() == null)
  			map.createNewRoot();
  
  		if (actualSourceLocation == null || ! actualSourceLocation.equals(newMapLocation)) {
  			final Object rootText = map.getRootNode().getUserObject();
  			if (rootText instanceof TranslatedObject) {
  				map.getRootNode().setText(rootText.toString());
  			}
  		}
  
  
  		map.setURL(newMapLocation);
  		if(saveAfterLoading && ! newMapLocation.equals(actualSourceLocation)) {
  			fileManager().save(map, map.getFile());
  		}
  		else {
  			map.setSaved(actualSourceLocation != null && actualSourceLocation.equals(newMapLocation));
  		}
  		setFollowedMapProperties(map);
  		mapController().addLoadedMap(map);
  		mapController().fireMapCreated(map);
  		return map;
  	}
  
      private void setFollowedMapProperties(final MMapModel map) {
          if(sourceLocation != null && ! sourceLocation.equals(newMapLocation)) {
              File sourceFile = Compat.urlToFile(sourceLocation);
              if(sourceFile ==  null)
                  return;
              MapStyleModel properties = MapStyleModel.getExtension(map);
              URI sourceUri = sourceFile.toURI();
              String normalizedLocation = TemplateManager.INSTANCE.normalizeTemplateLocation(sourceUri).toString();
              properties.setProperty(MapStyleModel.ASSOCIATED_TEMPLATE_LOCATION_PROPERTY,normalizedLocation);
              if(followSourceMap) {
                  properties.setProperty(MapStyleModel.FOLLOWED_TEMPLATE_LOCATION_PROPERTY,normalizedLocation);
                  if(sourceUri.getScheme().equalsIgnoreCase("file")) {
                      File file = Paths.get(sourceUri).toFile();
                      properties.setProperty(MapStyleModel.FOLLOWED_MAP_LAST_TIME, Long.toString(file.lastModified()));
                  }
              }
  		}
      }
  
  	private void loadMap(final MMapModel map, URL sourceLocation)
  			throws IOException, XMLException, FileNotFoundException, XMLParseException {
  		MFileManager fileManager = fileManager();
  		if(sourceLocation != null) {
  			final File file = Compat.urlToFile(sourceLocation);
  			if (file == null) {
  				fileManager.load(sourceLocation, map);
  			}
  			else {
  				if(! file.canRead())
  					throw new FileNotFoundException(file.getAbsolutePath());
  