Index: trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java	(revision 12485)
+++ trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java	(revision 12486)
@@ -20,8 +20,8 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.ViewportData;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.FileFilterAllFiles;
@@ -30,4 +30,6 @@
 import org.openstreetmap.josm.io.session.SessionImporter;
 import org.openstreetmap.josm.io.session.SessionReader;
+import org.openstreetmap.josm.io.session.SessionReader.SessionProjectionChoiceData;
+import org.openstreetmap.josm.io.session.SessionReader.SessionViewportData;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
@@ -73,5 +75,6 @@
         private Layer active;
         private List<Runnable> postLoadTasks;
-        private ViewportData viewport;
+        private SessionViewportData viewport;
+        private SessionProjectionChoiceData projectionChoice;
 
         /**
@@ -116,4 +119,10 @@
                 if (canceled)
                     return;
+                if (projectionChoice != null) {
+                    ProjectionPreference.setProjection(
+                            projectionChoice.getProjectionChoiceId(),
+                            projectionChoice.getSubPreferences(),
+                            false);
+                }
                 addLayers();
                 runPostLoadTasks();
@@ -132,6 +141,6 @@
                     Main.getLayerManager().setActiveLayer(active);
                 }
-                if (noMap) {
-                    Main.map.mapView.scheduleZoomTo(viewport);
+                if (noMap && viewport != null) {
+                    Main.map.mapView.scheduleZoomTo(viewport.getEastNorthViewport(Main.getProjection()));
                 }
             }
@@ -169,4 +178,5 @@
                     postLoadTasks = reader.getPostLoadTasks();
                     viewport = reader.getViewport();
+                    projectionChoice = reader.getProjectionChoice();
                 } finally {
                     if (tempFile) {
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/ProjectionPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/ProjectionPreference.java	(revision 12485)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/ProjectionPreference.java	(revision 12486)
@@ -501,9 +501,9 @@
      */
     private ProjectionChoice setupProjectionCombo() {
-        String pcId = projectionChoice != null ? projectionChoice : PROP_PROJECTION_DEFAULT.get();
+        String pcId = getCurrentProjectionChoiceId();
         ProjectionChoice pc = null;
         for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
             ProjectionChoice pc1 = projectionCombo.getItemAt(i);
-            pc1.setPreferences(getSubprojectionPreference(pc1));
+            pc1.setPreferences(getSubprojectionPreference(pc1.getId()));
             if (pc1.getId().equals(pcId)) {
                 projectionCombo.setSelectedIndex(i);
@@ -524,6 +524,21 @@
     }
 
-    private static Collection<String> getSubprojectionPreference(ProjectionChoice pc) {
-        return Main.pref.getCollection("projection.sub."+pc.getId(), null);
+    /**
+     * Get the id of the projection choice that is currently set.
+     * @return id of the projection choice that is currently set
+     */
+    public static String getCurrentProjectionChoiceId() {
+        return projectionChoice != null ? projectionChoice : PROP_PROJECTION_DEFAULT.get();
+    }
+
+    /**
+     * Get the preferences that have been selected the last time for the given
+     * projection choice.
+     * @param pcId id of the projection choice
+     * @return projection choice parameters that have been selected by the user
+     * the last time; null if user has never selected the given projection choice
+     */
+    public static Collection<String> getSubprojectionPreference(String pcId) {
+        return Main.pref.getCollection("projection.sub."+pcId, null);
     }
 
Index: trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 12485)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 12486)
@@ -16,4 +16,5 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -43,4 +44,5 @@
 import org.openstreetmap.josm.io.Compression;
 import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.MultiMap;
@@ -58,4 +60,92 @@
 public class SessionReader {
 
+    /**
+     * Data class for projection saved in the session file.
+     */
+    public static class SessionProjectionChoiceData {
+        private final String projectionChoiceId;
+        private final Collection<String> subPreferences;
+
+        /**
+         * Construct a new SessionProjectionChoiceData.
+         * @param projectionChoiceId projection choice id
+         * @param subPreferences parameters for the projection choice
+         */
+        public SessionProjectionChoiceData(String projectionChoiceId, Collection<String> subPreferences) {
+            this.projectionChoiceId = projectionChoiceId;
+            this.subPreferences = subPreferences;
+        }
+
+        /**
+         * Get the projection choice id.
+         * @return the projection choice id
+         */
+        public String getProjectionChoiceId() {
+            return projectionChoiceId;
+        }
+
+        /**
+         * Get the parameters for the projection choice
+         * @return parameters for the projection choice
+         */
+        public Collection<String> getSubPreferences() {
+            return subPreferences;
+        }
+    }
+
+    /**
+     * Data class for viewport saved in the session file.
+     */
+    public static class SessionViewportData {
+        private final LatLon center;
+        private final double meterPerPixel;
+
+        /**
+         * Construct a new SessionViewportData.
+         * @param center the lat/lon coordinates of the screen center
+         * @param meterPerPixel scale in meters per pixel
+         */
+        public SessionViewportData(LatLon center, double meterPerPixel) {
+            CheckParameterUtil.ensureParameterNotNull(center);
+            this.center = center;
+            this.meterPerPixel = meterPerPixel;
+        }
+
+        /**
+         * Get the lat/lon coordinates of the screen center.
+         * @return lat/lon coordinates of the screen center
+         */
+        public LatLon getCenter() {
+            return center;
+        }
+
+        /**
+         * Get the scale in meters per pixel.
+         * @return scale in meters per pixel
+         */
+        public double getScale() {
+            return meterPerPixel;
+        }
+
+        /**
+         * Convert this viewport data to a {@link ViewportData} object (with projected coordinates).
+         * @param proj the projection to convert from lat/lon to east/north
+         * @return the corresponding ViewportData object
+         */
+        public ViewportData getEastNorthViewport(Projection proj) {
+            EastNorth centerEN = proj.latlon2eastNorth(center);
+            // Get a "typical" distance in east/north units that
+            // corresponds to a couple of pixels. Shouldn't be too
+            // large, to keep it within projection bounds and
+            // not too small to avoid rounding errors.
+            double dist = 0.01 * proj.getDefaultZoomInPPD();
+            LatLon ll1 = proj.eastNorth2latlon(new EastNorth(centerEN.east() - dist, centerEN.north()));
+            LatLon ll2 = proj.eastNorth2latlon(new EastNorth(centerEN.east() + dist, centerEN.north()));
+            double meterPerEasting = ll1.greatCircleDistance(ll2) / dist / 2;
+            double scale = meterPerPixel / meterPerEasting; // unit: easting per pixel
+            return new ViewportData(centerEN, scale);
+        }
+    }
+
     private static final Map<String, Class<? extends SessionLayerImporter>> sessionLayerImporters = new HashMap<>();
 
@@ -66,5 +156,6 @@
     private int active = -1;
     private final List<Runnable> postLoadTasks = new ArrayList<>();
-    private ViewportData viewport;
+    private SessionViewportData viewport;
+    private SessionProjectionChoiceData projectionChoice;
 
     static {
@@ -130,8 +221,16 @@
     /**
      * Return the viewport (map position and scale).
-     * @return The viewport. Can be null when no viewport info is found in the file.
-     */
-    public ViewportData getViewport() {
+     * @return the viewport; can be null when no viewport info is found in the file
+     */
+    public SessionViewportData getViewport() {
         return viewport;
+    }
+
+    /**
+     * Return the projection choice data.
+     * @return the projection; can be null when no projection info is found in the file
+     */
+    public SessionProjectionChoiceData getProjectionChoice() {
+        return projectionChoice;
     }
 
@@ -339,39 +438,6 @@
         }
 
-        Element viewportEl = getElementByTagName(root, "viewport");
-        if (viewportEl != null) {
-            EastNorth center = null;
-            Element centerEl = getElementByTagName(viewportEl, "center");
-            if (centerEl != null && centerEl.hasAttribute("lat") && centerEl.hasAttribute("lon")) {
-                try {
-                    LatLon centerLL = new LatLon(Double.parseDouble(centerEl.getAttribute("lat")),
-                            Double.parseDouble(centerEl.getAttribute("lon")));
-                    center = Projections.project(centerLL);
-                } catch (NumberFormatException ex) {
-                    Main.warn(ex);
-                }
-            }
-            if (center != null) {
-                Element scaleEl = getElementByTagName(viewportEl, "scale");
-                if (scaleEl != null && scaleEl.hasAttribute("meter-per-pixel")) {
-                    try {
-                        double meterPerPixel = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel"));
-                        Projection proj = Main.getProjection();
-                        // Get a "typical" distance in east/north units that
-                        // corresponds to a couple of pixels. Shouldn't be too
-                        // large, to keep it within projection bounds and
-                        // not too small to avoid rounding errors.
-                        double dist = 0.01 * proj.getDefaultZoomInPPD();
-                        LatLon ll1 = proj.eastNorth2latlon(new EastNorth(center.east() - dist, center.north()));
-                        LatLon ll2 = proj.eastNorth2latlon(new EastNorth(center.east() + dist, center.north()));
-                        double meterPerEasting = ll1.greatCircleDistance(ll2) / dist / 2;
-                        double scale = meterPerPixel / meterPerEasting; // unit: easting per pixel
-                        viewport = new ViewportData(center, scale);
-                    } catch (NumberFormatException ex) {
-                        Main.warn(ex);
-                    }
-                }
-            }
-        }
+        viewport = readViewportData(root);
+        projectionChoice = readProjectionChoiceData(root);
 
         Element layersEl = getElementByTagName(root, "layers");
@@ -550,4 +616,47 @@
     }
 
+    private SessionViewportData readViewportData(Element root) {
+        Element viewportEl = getElementByTagName(root, "viewport");
+        if (viewportEl == null) return null;
+        LatLon center = null;
+        Element centerEl = getElementByTagName(viewportEl, "center");
+        if (centerEl == null || !centerEl.hasAttribute("lat") || !centerEl.hasAttribute("lon")) return null;
+        try {
+            center = new LatLon(Double.parseDouble(centerEl.getAttribute("lat")),
+                    Double.parseDouble(centerEl.getAttribute("lon")));
+        } catch (NumberFormatException ex) {
+            Main.warn(ex);
+        }
+        if (center == null) return null;
+        Element scaleEl = getElementByTagName(viewportEl, "scale");
+        if (scaleEl == null || !scaleEl.hasAttribute("meter-per-pixel")) return null;
+        try {
+            double scale = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel"));
+            return new SessionViewportData(center, scale);
+        } catch (NumberFormatException ex) {
+            Main.warn(ex);
+            return null;
+        }
+    }
+
+    private SessionProjectionChoiceData readProjectionChoiceData(Element root) {
+        Element projectionEl = getElementByTagName(root, "projection");
+        if (projectionEl == null) return null;
+        Element projectionChoiceEl = getElementByTagName(projectionEl, "projection-choice");
+        if (projectionChoiceEl == null) return null;
+        Element idEl = getElementByTagName(projectionChoiceEl, "id");
+        if (idEl == null) return null;
+        String id = idEl.getTextContent();
+        Element parametersEl = getElementByTagName(projectionChoiceEl, "parameters");
+        if (parametersEl == null) return null;
+        Collection<String> parameters = new ArrayList<>();
+        NodeList paramNl = parametersEl.getElementsByTagName("param");
+        for (int i=0; i<paramNl.getLength(); i++) {
+            Element paramEl = (Element) paramNl.item(i);
+            parameters.add(paramEl.getTextContent());
+        }
+        return new SessionProjectionChoiceData(id, parameters);
+    }
+
     /**
      * Show Dialog when there is an error for one layer.
Index: trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 12485)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 12486)
@@ -11,4 +11,5 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -40,4 +41,5 @@
 import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.MultiMap;
@@ -213,16 +215,6 @@
         doc.appendChild(root);
 
-        Element viewportEl = doc.createElement("viewport");
-        root.appendChild(viewportEl);
-        Element centerEl = doc.createElement("center");
-        viewportEl.appendChild(centerEl);
-        EastNorth center = Main.map.mapView.getCenter();
-        LatLon centerLL = Projections.inverseProject(center);
-        centerEl.setAttribute("lat", Double.toString(centerLL.lat()));
-        centerEl.setAttribute("lon", Double.toString(centerLL.lon()));
-        Element scale = doc.createElement("scale");
-        viewportEl.appendChild(scale);
-        double dist100px = Main.map.mapView.getDist100Pixel();
-        scale.setAttribute("meter-per-pixel", Double.toString(dist100px / 100));
+        writeViewPort(root);
+        writeProjection(root);
 
         Element layersEl = doc.createElement("layers");
@@ -263,4 +255,44 @@
     }
 
+    private void writeViewPort(Element root) {
+        Document doc = root.getOwnerDocument();
+        Element viewportEl = doc.createElement("viewport");
+        root.appendChild(viewportEl);
+        Element centerEl = doc.createElement("center");
+        viewportEl.appendChild(centerEl);
+        EastNorth center = Main.map.mapView.getCenter();
+        LatLon centerLL = Projections.inverseProject(center);
+        centerEl.setAttribute("lat", Double.toString(centerLL.lat()));
+        centerEl.setAttribute("lon", Double.toString(centerLL.lon()));
+        Element scale = doc.createElement("scale");
+        viewportEl.appendChild(scale);
+        double dist100px = Main.map.mapView.getDist100Pixel();
+        scale.setAttribute("meter-per-pixel", Double.toString(dist100px / 100));
+    }
+
+    private void writeProjection(Element root) {
+        Document doc = root.getOwnerDocument();
+        Element projectionEl = doc.createElement("projection");
+        root.appendChild(projectionEl);
+        String pcId = ProjectionPreference.getCurrentProjectionChoiceId();
+        Element projectionChoiceEl = doc.createElement("projection-choice");
+        projectionEl.appendChild(projectionChoiceEl);
+        Element idEl = doc.createElement("id");
+        projectionChoiceEl.appendChild(idEl);
+        idEl.setTextContent(pcId);
+        Collection<String> parameters = ProjectionPreference.getSubprojectionPreference(pcId);
+        Element parametersEl = doc.createElement("parameters");
+        projectionChoiceEl.appendChild(parametersEl);
+        for (String param : parameters) {
+            Element paramEl = doc.createElement("param");
+            parametersEl.appendChild(paramEl);
+            paramEl.setTextContent(param);
+        }
+        String code = Main.getProjection().toCode();
+        Element codeEl = doc.createElement("code");
+        projectionEl.appendChild(codeEl);
+        codeEl.setTextContent(code);
+    }
+
     /**
      * Writes given .jos document to an output stream.
