Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/DetermineSdsModificationsUploadHook.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/DetermineSdsModificationsUploadHook.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/DetermineSdsModificationsUploadHook.java	(revision 30738)
@@ -32,144 +32,144 @@
 public class DetermineSdsModificationsUploadHook implements UploadHook
 {
-	private SeparateDataStorePlugin plugin;
+    private SeparateDataStorePlugin plugin;
 
-	DetermineSdsModificationsUploadHook(SeparateDataStorePlugin plugin)	{
-		this.plugin = plugin;
-	}
-	
+    DetermineSdsModificationsUploadHook(SeparateDataStorePlugin plugin)    {
+        this.plugin = plugin;
+    }
+    
     public boolean checkUpload(APIDataSet apiDataSet) {
-    	
-    	ArrayList<OsmPrimitive> droplist = new ArrayList<>();
-    	
-    	// check deleted primitives for special tags.
-    	for (OsmPrimitive del : apiDataSet.getPrimitivesToDelete()) {
-    		IPrimitive old = plugin.getOriginalPrimitive(del);
-    		if (hasSpecialTags(old)) {
-    			// request deletion of all tags for this object on special server.
-    			plugin.enqueueForUpload(del, new HashMap<String, String>(), false);
-    		}
-    	}
+        
+        ArrayList<OsmPrimitive> droplist = new ArrayList<>();
+        
+        // check deleted primitives for special tags.
+        for (OsmPrimitive del : apiDataSet.getPrimitivesToDelete()) {
+            IPrimitive old = plugin.getOriginalPrimitive(del);
+            if (hasSpecialTags(old)) {
+                // request deletion of all tags for this object on special server.
+                plugin.enqueueForUpload(del, new HashMap<String, String>(), false);
+            }
+        }
 
-    	// check modified primitives.
-       	for (OsmPrimitive upd : apiDataSet.getPrimitivesToUpdate()) {
-       		
-       		HashSet<String> allKeys = new HashSet<>();
-       		boolean specialTags = false;
-       		
-       		// process tags of new object
-       		for (String key : upd.keySet()) {
-       			allKeys.add(key);
-       			if (!specialTags && isSpecialKey(key)) specialTags = true;
-       		}
-       		
-       		// process tags of old object
-       		IPrimitive old = plugin.getOriginalPrimitive(upd);
-       		for (String key : old.keySet()) {
-       			allKeys.add(key);
-      			if (!specialTags && isSpecialKey(key)) specialTags = true;
-       		}
+        // check modified primitives.
+           for (OsmPrimitive upd : apiDataSet.getPrimitivesToUpdate()) {
+               
+               HashSet<String> allKeys = new HashSet<>();
+               boolean specialTags = false;
+               
+               // process tags of new object
+               for (String key : upd.keySet()) {
+                   allKeys.add(key);
+                   if (!specialTags && isSpecialKey(key)) specialTags = true;
+               }
+               
+               // process tags of old object
+               IPrimitive old = plugin.getOriginalPrimitive(upd);
+               for (String key : old.keySet()) {
+                   allKeys.add(key);
+                  if (!specialTags && isSpecialKey(key)) specialTags = true;
+               }
 
-       		// if neither has special tags, done with this object.
-       		if (!specialTags) continue;
-       		
-       		// special tags are involved. find out what, exactly, has changed.
-       		boolean changeInSpecialTags = false;
-       		boolean changeInOtherTags = false;
-       		for (String key : allKeys) {
-       			if (old.get(key) == null || upd.get(key) == null || !old.get(key).equals(upd.get(key))) {
-       				if (isSpecialKey(key)) changeInSpecialTags = true; else changeInOtherTags = true;
-       				if (changeInSpecialTags && changeInOtherTags) break;
-       			}
-       		}
-       		
-       		// change *only* in standard tags - done with this object.
-       		if (!changeInSpecialTags) continue;
-       		
-       		// assemble new set of special tags. might turn out to be empty.
-       		HashMap<String, String> newSpecialTags = new HashMap<>();
-       		for (String key : upd.keySet()) {
-       			if (isSpecialKey(key)) newSpecialTags.put(key, upd.get(key));
-       		}
-       		
-       		boolean uploadToOsm = changeInOtherTags;
-       		
-       		// not done yet: if no changes in standard tags, we need to find out if 
-       		// there were changes in the other properties (node: lat/lon, way/relation:
-       		// member list). If the answer is no, then the object must be removed from 
-       		// JOSM's normal upload queue, else we would be uploading a non-edit.
-       		if (!changeInOtherTags) {
-       			switch(old.getType()) {
-       			case NODE:
-       				INode nold = (INode) old;
-       				INode nupd = (INode) upd;
-       				uploadToOsm = !(nold.getCoor().equals(nupd.getCoor()));
-       				break;
-       			case WAY:
-       				IWay wold = (IWay) old;
-       				IWay wupd = (IWay) upd;
-       				if (wold.getNodesCount() != wupd.getNodesCount()) {
-       					uploadToOsm = true;
-       					break;
-       				} 
-       				for (int i = 0; i < wold.getNodesCount(); i++) {
-       					if (wold.getNodeId(i) != wupd.getNodeId(i)) {
-       						uploadToOsm = true;
-       						break;
-       					}
-       				}
-       				break;
-       			case RELATION:
-       				IRelation rold = (IRelation) old;
-       				IRelation rupd = (IRelation) upd;
-       				if (rold.getMembersCount()!= rupd.getMembersCount()) {
-       					uploadToOsm = true;
-       					break;
-       				} 
-       				for (int i = 0; i < rold.getMembersCount(); i++) {
-       					if (rold.getMemberType(i) != rupd.getMemberType(i) ||
-       						rold.getMemberId(i) != rupd.getMemberId(i)) {
-       						uploadToOsm = true;
-       						break;
-       					}
-       				}
-       				break;
-       			}
-       		}
-       		
-       		// request that new set of special tags be uploaded
-       		plugin.enqueueForUpload(upd, newSpecialTags, !uploadToOsm);
-       		
-       		// we cannot remove from getPrimitivesToUpdate, this would result in a 
-       		// ConcurrentModificationException.
-       		if (!uploadToOsm) droplist.add(upd);
-       		
-    	}
-       	
-    	apiDataSet.getPrimitivesToUpdate().removeAll(droplist);
-		       	
-       	// check added primitives. 
-       	for (OsmPrimitive add : apiDataSet.getPrimitivesToAdd()) {
-       		// assemble new set of special tags. might turn out to be empty.
-       		HashMap<String, String> newSpecialTags = new HashMap<>();
-       		for (String key : add.keySet()) {
-       			if (isSpecialKey(key)) newSpecialTags.put(key, add.get(key));
-       		}
-       		if (!newSpecialTags.isEmpty()) plugin.enqueueForUpload(add, newSpecialTags, false);
-    	}
-    	
-       	// FIXME it is possible that the list of OSM edits is totally empty.
-		return true;
+               // if neither has special tags, done with this object.
+               if (!specialTags) continue;
+               
+               // special tags are involved. find out what, exactly, has changed.
+               boolean changeInSpecialTags = false;
+               boolean changeInOtherTags = false;
+               for (String key : allKeys) {
+                   if (old.get(key) == null || upd.get(key) == null || !old.get(key).equals(upd.get(key))) {
+                       if (isSpecialKey(key)) changeInSpecialTags = true; else changeInOtherTags = true;
+                       if (changeInSpecialTags && changeInOtherTags) break;
+                   }
+               }
+               
+               // change *only* in standard tags - done with this object.
+               if (!changeInSpecialTags) continue;
+               
+               // assemble new set of special tags. might turn out to be empty.
+               HashMap<String, String> newSpecialTags = new HashMap<>();
+               for (String key : upd.keySet()) {
+                   if (isSpecialKey(key)) newSpecialTags.put(key, upd.get(key));
+               }
+               
+               boolean uploadToOsm = changeInOtherTags;
+               
+               // not done yet: if no changes in standard tags, we need to find out if 
+               // there were changes in the other properties (node: lat/lon, way/relation:
+               // member list). If the answer is no, then the object must be removed from 
+               // JOSM's normal upload queue, else we would be uploading a non-edit.
+               if (!changeInOtherTags) {
+                   switch(old.getType()) {
+                   case NODE:
+                       INode nold = (INode) old;
+                       INode nupd = (INode) upd;
+                       uploadToOsm = !(nold.getCoor().equals(nupd.getCoor()));
+                       break;
+                   case WAY:
+                       IWay wold = (IWay) old;
+                       IWay wupd = (IWay) upd;
+                       if (wold.getNodesCount() != wupd.getNodesCount()) {
+                           uploadToOsm = true;
+                           break;
+                       } 
+                       for (int i = 0; i < wold.getNodesCount(); i++) {
+                           if (wold.getNodeId(i) != wupd.getNodeId(i)) {
+                               uploadToOsm = true;
+                               break;
+                           }
+                       }
+                       break;
+                   case RELATION:
+                       IRelation rold = (IRelation) old;
+                       IRelation rupd = (IRelation) upd;
+                       if (rold.getMembersCount()!= rupd.getMembersCount()) {
+                           uploadToOsm = true;
+                           break;
+                       } 
+                       for (int i = 0; i < rold.getMembersCount(); i++) {
+                           if (rold.getMemberType(i) != rupd.getMemberType(i) ||
+                               rold.getMemberId(i) != rupd.getMemberId(i)) {
+                               uploadToOsm = true;
+                               break;
+                           }
+                       }
+                       break;
+                   }
+               }
+               
+               // request that new set of special tags be uploaded
+               plugin.enqueueForUpload(upd, newSpecialTags, !uploadToOsm);
+               
+               // we cannot remove from getPrimitivesToUpdate, this would result in a 
+               // ConcurrentModificationException.
+               if (!uploadToOsm) droplist.add(upd);
+               
+        }
+           
+        apiDataSet.getPrimitivesToUpdate().removeAll(droplist);
+                   
+           // check added primitives. 
+           for (OsmPrimitive add : apiDataSet.getPrimitivesToAdd()) {
+               // assemble new set of special tags. might turn out to be empty.
+               HashMap<String, String> newSpecialTags = new HashMap<>();
+               for (String key : add.keySet()) {
+                   if (isSpecialKey(key)) newSpecialTags.put(key, add.get(key));
+               }
+               if (!newSpecialTags.isEmpty()) plugin.enqueueForUpload(add, newSpecialTags, false);
+        }
+        
+           // FIXME it is possible that the list of OSM edits is totally empty.
+        return true;
 
     }
     
     boolean hasSpecialTags(IPrimitive p) {
-    	for (String key : p.keySet()) {
-    		if (isSpecialKey(key)) return true;
-    	}    
-    	return false;
+        for (String key : p.keySet()) {
+            if (isSpecialKey(key)) return true;
+        }    
+        return false;
     }
     
     boolean isSpecialKey(String key) {
-    	return key.startsWith(plugin.getIgnorePrefix());
+        return key.startsWith(plugin.getIgnorePrefix());
     }
 }
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/ReadPostprocessor.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/ReadPostprocessor.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/ReadPostprocessor.java	(revision 30738)
@@ -24,76 +24,76 @@
 
 public class ReadPostprocessor implements OsmServerReadPostprocessor {
-	
-	private ArrayList<Long> nodeList;
-	private ArrayList<Long> wayList;
-	private ArrayList<Long> relationList;
-	
-	private SeparateDataStorePlugin plugin;
+    
+    private ArrayList<Long> nodeList;
+    private ArrayList<Long> wayList;
+    private ArrayList<Long> relationList;
+    
+    private SeparateDataStorePlugin plugin;
 
-	public ReadPostprocessor(SeparateDataStorePlugin plugin) {
-		this.plugin = plugin;
-	}
-	
+    public ReadPostprocessor(SeparateDataStorePlugin plugin) {
+        this.plugin = plugin;
+    }
+    
     @Override
     public void postprocessDataSet(DataSet ds, ProgressMonitor progress) {
         
-		nodeList = new ArrayList<>();
-		wayList = new ArrayList<>();
-		relationList = new ArrayList<>();
+        nodeList = new ArrayList<>();
+        wayList = new ArrayList<>();
+        relationList = new ArrayList<>();
 
-		Visitor adder = new Visitor() {
-			@Override
-			public void visit(Node n) {
-				nodeList.add(n.getId());
-				plugin.originalNodes.put(n.getId(), n.save());
-			}
-			@Override
-			public void visit(Way w) {
-				wayList.add(w.getId());
-				plugin.originalWays.put(w.getId(), w.save());
-			}
-			@Override
-			public void visit(Relation e) {
-				relationList.add(e.getId());
-				plugin.originalNodes.put(e.getId(), e.save());
-			}
-			@Override
-			public void visit(Changeset cs) {}
-		};
-		
-		for (OsmPrimitive p : ds.allPrimitives()) {
-			p.accept(adder);
-		}
-			
-		SdsApi api = SdsApi.getSdsApi();
-		String rv = "";
-		try {
-			rv = api.requestShadowsFromSds(nodeList, wayList, relationList, progress);
-		} catch (SdsTransferException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-		
-		// this is slightly inefficient, as we're re-making the string into 
-		// an input stream when there was an input stream to be had inside the
-		// SdsApi already, but this encapsulates things better.
+        Visitor adder = new Visitor() {
+            @Override
+            public void visit(Node n) {
+                nodeList.add(n.getId());
+                plugin.originalNodes.put(n.getId(), n.save());
+            }
+            @Override
+            public void visit(Way w) {
+                wayList.add(w.getId());
+                plugin.originalWays.put(w.getId(), w.save());
+            }
+            @Override
+            public void visit(Relation e) {
+                relationList.add(e.getId());
+                plugin.originalNodes.put(e.getId(), e.save());
+            }
+            @Override
+            public void visit(Changeset cs) {}
+        };
+        
+        for (OsmPrimitive p : ds.allPrimitives()) {
+            p.accept(adder);
+        }
+            
+        SdsApi api = SdsApi.getSdsApi();
+        String rv = "";
+        try {
+            rv = api.requestShadowsFromSds(nodeList, wayList, relationList, progress);
+        } catch (SdsTransferException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        
+        // this is slightly inefficient, as we're re-making the string into 
+        // an input stream when there was an input stream to be had inside the
+        // SdsApi already, but this encapsulates things better.
         InputStream xmlStream;
-		try {
-			xmlStream = new ByteArrayInputStream(rv.getBytes("UTF-8"));
-	        InputSource inputSource = new InputSource(xmlStream);
-			SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new SdsParser(ds, plugin));
-		} catch (UnsupportedEncodingException e1) {
-			// TODO Auto-generated catch block
-			e1.printStackTrace();
-		} catch (SAXException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IOException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (ParserConfigurationException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+        try {
+            xmlStream = new ByteArrayInputStream(rv.getBytes("UTF-8"));
+            InputSource inputSource = new InputSource(xmlStream);
+            SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new SdsParser(ds, plugin));
+        } catch (UnsupportedEncodingException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        } catch (SAXException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (ParserConfigurationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
 
     }
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsApi.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsApi.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsApi.java	(revision 30738)
@@ -34,5 +34,5 @@
  *
  * This is modeled after JOSM's own OsmAPI class.
- * 
+ *
  */
 public class SdsApi extends SdsConnection {
@@ -42,5 +42,5 @@
     /** the collection of instantiated OSM APIs */
     private static HashMap<String, SdsApi> instances = new HashMap<>();
-    
+
     /**
      * replies the {@see OsmApi} for a given server URL
@@ -123,5 +123,5 @@
      * @param osm the primitive
      * @throws SdsTransferException if something goes wrong
-     
+
     public void createPrimitive(IPrimitive osm, ProgressMonitor monitor) throws SdsTransferException {
         String ret = "";
@@ -144,5 +144,5 @@
      * @param monitor the progress monitor
      * @throws SdsTransferException if something goes wrong
-     
+
     public void modifyPrimitive(IPrimitive osm, ProgressMonitor monitor) throws SdsTransferException {
         String ret = null;
@@ -165,5 +165,5 @@
      * @param osm the primitive
      * @throws SdsTransferException if something goes wrong
-     
+
     public void deletePrimitive(IPrimitive osm, ProgressMonitor monitor) throws SdsTransferException {
         ensureValidChangeset();
@@ -182,9 +182,9 @@
      * @param list the list of changed OSM Primitives
      * @param  monitor the progress monitor
-     * @return 
+     * @return
      * @return list of processed primitives
-     * @throws SdsTransferException 
+     * @throws SdsTransferException
      * @throws SdsTransferException if something is wrong
-     
+
     public Collection<IPrimitive> uploadDiff(Collection<? extends IPrimitive> list, ProgressMonitor monitor) throws SdsTransferException {
         try {
@@ -227,47 +227,47 @@
     }
     */
-    
+
     public String requestShadowsFromSds(List<Long> nodes, List<Long> ways, List<Long> relations, ProgressMonitor pm) throws SdsTransferException {
-    	
-    	StringBuilder request = new StringBuilder();
-    	String delim = "";
-    	String comma = "";
-    	
-    	if (nodes != null && !nodes.isEmpty()) {
-    		request.append(delim);
-    		delim = "&";
-    		comma = "";
-    		request.append("nodes=");
-    		for (long i : nodes) {
-    			request.append(comma);
-    			comma = ",";
-    			request.append(i);
-    		}
-    	}
-    	if (ways != null && !ways.isEmpty()) {
-    		request.append(delim);
-    		delim = "&";
-    		comma = "";
-    		request.append("ways=");
-    		for (long i : ways) {
-    			request.append(comma);
-    			comma = ",";
-    			request.append(i);
-    		}
-    	}
-    	if (relations != null && !relations.isEmpty()) {
-    		request.append(delim);
-    		delim = "&";
-    		comma = "";
-    		request.append("relations=");
-    		for (long i : relations) {
-    			request.append(comma);
-    			comma = ",";
-    			request.append(i);
-    		}
-    	}
-    	
-    	return sendRequest("POST", "collectshadows", request.toString(), pm ,true);
-   
+
+        StringBuilder request = new StringBuilder();
+        String delim = "";
+        String comma = "";
+
+        if (nodes != null && !nodes.isEmpty()) {
+            request.append(delim);
+            delim = "&";
+            comma = "";
+            request.append("nodes=");
+            for (long i : nodes) {
+                request.append(comma);
+                comma = ",";
+                request.append(i);
+            }
+        }
+        if (ways != null && !ways.isEmpty()) {
+            request.append(delim);
+            delim = "&";
+            comma = "";
+            request.append("ways=");
+            for (long i : ways) {
+                request.append(comma);
+                comma = ",";
+                request.append(i);
+            }
+        }
+        if (relations != null && !relations.isEmpty()) {
+            request.append(delim);
+            delim = "&";
+            comma = "";
+            request.append("relations=");
+            for (long i : relations) {
+                request.append(comma);
+                comma = ",";
+                request.append(i);
+            }
+        }
+
+        return sendRequest("POST", "collectshadows", request.toString(), pm ,true);
+
     }
 
@@ -304,13 +304,13 @@
         return sendRequest(requestMethod, urlSuffix, requestBody, monitor, doAuth, false);
     }
-    
+
     public boolean updateSds(String message, ProgressMonitor pm) {
-    	try {
-			sendRequest("POST", "createshadows", message, pm);
-		} catch (SdsTransferException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-    	return true;
+        try {
+            sendRequest("POST", "createshadows", message, pm);
+        } catch (SdsTransferException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return true;
     }
 
@@ -352,18 +352,18 @@
                     activeConnection.setDoOutput(true);
                     activeConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
-                    OutputStream out = activeConnection.getOutputStream();
-
-                    // It seems that certain bits of the Ruby API are very unhappy upon
-                    // receipt of a PUT/POST message without a Content-length header,
-                    // even if the request has no payload.
-                    // Since Java will not generate a Content-length header unless
-                    // we use the output stream, we create an output stream for PUT/POST
-                    // even if there is no payload.
-                    if (requestBody != null) {
-                        BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
-                        bwr.write(requestBody);
-                        bwr.flush();
+                    try (OutputStream out = activeConnection.getOutputStream()) {
+
+                        // It seems that certain bits of the Ruby API are very unhappy upon
+                        // receipt of a PUT/POST message without a Content-length header,
+                        // even if the request has no payload.
+                        // Since Java will not generate a Content-length header unless
+                        // we use the output stream, we create an output stream for PUT/POST
+                        // even if there is no payload.
+                        if (requestBody != null) {
+                            BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
+                            bwr.write(requestBody);
+                            bwr.flush();
+                        }
                     }
-                    out.close();
                 }
 
@@ -442,8 +442,8 @@
         }
     }
-    
+
     protected InputStream getInputStream(String urlStr, ProgressMonitor progressMonitor) throws SdsTransferException {
         urlStr = getBaseUrl() + urlStr;
-    	try {
+        try {
             URL url = null;
             try {
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsConnection.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsConnection.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsConnection.java	(revision 30738)
@@ -21,5 +21,5 @@
  */
 public class SdsConnection {
-	
+    
     protected boolean cancel = false;
     protected HttpURLConnection activeConnection;
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialAgent.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialAgent.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialAgent.java	(revision 30738)
@@ -120,11 +120,11 @@
     }
 
-	@Override
-	public void storeOAuthAccessToken(OAuthToken accessToken)
-			throws CredentialsAgentException {
-		// no-op
-		
-	}
-	
+    @Override
+    public void storeOAuthAccessToken(OAuthToken accessToken)
+            throws CredentialsAgentException {
+        // no-op
+        
+    }
+    
     @Override
     public CredentialsAgentResponse getCredentials(RequestorType requestorType, String host, boolean noSuccessWithLastResponse) throws CredentialsAgentException{
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialDialog.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialDialog.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsCredentialDialog.java	(revision 30738)
@@ -11,5 +11,5 @@
 public class SdsCredentialDialog extends CredentialDialog {
 
-	static public SdsCredentialDialog getSdsApiCredentialDialog(String username, String password, String host, String saveUsernameAndPasswordCheckboxText) {
+    static public SdsCredentialDialog getSdsApiCredentialDialog(String username, String password, String host, String saveUsernameAndPasswordCheckboxText) {
         SdsCredentialDialog dialog = new SdsCredentialDialog(saveUsernameAndPasswordCheckboxText);
         dialog.prepareForSdsApiCredentials(username, password);
@@ -21,7 +21,7 @@
 
     public SdsCredentialDialog(String saveUsernameAndPasswordCheckboxText) {
-    	super(saveUsernameAndPasswordCheckboxText);
+        super(saveUsernameAndPasswordCheckboxText);
     }
-    	 
+         
     public void prepareForSdsApiCredentials(String username, String password) {
         setTitle(tr("Enter credentials for Separate Data Store API"));
@@ -33,5 +33,5 @@
     private static class SdsApiCredentialsPanel extends CredentialPanel {
 
-		@Override
+        @Override
         protected void build() {
             super.build();
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsDiskAccessAction.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsDiskAccessAction.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsDiskAccessAction.java	(revision 30738)
@@ -16,11 +16,11 @@
 @SuppressWarnings("serial")
 public abstract class SdsDiskAccessAction extends DiskAccessAction {
-	
+    
     public SdsDiskAccessAction(String name, String iconName, String tooltip,
-			Shortcut shortcut) {
-		super(name, iconName, tooltip, shortcut);
-	}
+            Shortcut shortcut) {
+        super(name, iconName, tooltip, shortcut);
+    }
 
-	public static SwingFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title) {
+    public static SwingFileChooser createAndOpenFileChooser(boolean open, boolean multiple, String title) {
         String curDir = Main.pref.get("lastDirectory");
         if (curDir.equals("")) {
@@ -35,8 +35,8 @@
         fc.setMultiSelectionEnabled(multiple);
         fc.setAcceptAllFileFilterUsed(false);
-        		
+                
         fc.setFileFilter(new FileFilter() {
-        	public boolean accept(File pathname) { return pathname.getName().endsWith(".sds") || pathname.isDirectory(); }
-			public String getDescription() { return (tr("SDS data file")); }
+            public boolean accept(File pathname) { return pathname.getName().endsWith(".sds") || pathname.isDirectory(); }
+            public String getDescription() { return (tr("SDS data file")); }
         });     
 
@@ -83,6 +83,6 @@
         
         fc.setFileFilter(new FileFilter() {
-        	public boolean accept(File pathname) { return pathname.getName().endsWith(".sds") || pathname.isDirectory(); }
-			public String getDescription() { return (tr("SDS data file")); }
+            public boolean accept(File pathname) { return pathname.getName().endsWith(".sds") || pathname.isDirectory(); }
+            public String getDescription() { return (tr("SDS data file")); }
         }); 
         
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsLoadAction.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsLoadAction.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsLoadAction.java	(revision 30738)
@@ -26,10 +26,10 @@
 @SuppressWarnings("serial")
 public class SdsLoadAction extends SdsDiskAccessAction {
-	
-	private SeparateDataStorePlugin plugin;
+    
+    private SeparateDataStorePlugin plugin;
 
     public SdsLoadAction(SeparateDataStorePlugin p) {
         super(tr("Load..."), "sds_load", tr("Load separate data store data from a file."), null);
-    	plugin = p;
+        plugin = p;
     }
     
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsMenu.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsMenu.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsMenu.java	(revision 30738)
@@ -56,83 +56,83 @@
 
     void setEnabledState() {
-    	boolean en = (Main.map != null) && (Main.map.mapView != null) && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer);
-    	loadItem.setEnabled(en);
-    	saveItem.setEnabled(en);
+        boolean en = (Main.map != null) && (Main.map.mapView != null) && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer);
+        loadItem.setEnabled(en);
+        saveItem.setEnabled(en);
     }
   
-	@Override
-	public void activeLayerChange(Layer oldLayer, Layer newLayer) {	setEnabledState(); }
+    @Override
+    public void activeLayerChange(Layer oldLayer, Layer newLayer) {    setEnabledState(); }
 
-	@Override
-	public void layerAdded(Layer newLayer) { setEnabledState(); }
+    @Override
+    public void layerAdded(Layer newLayer) { setEnabledState(); }
 
-	@Override
-	public void layerRemoved(Layer oldLayer) { setEnabledState(); }
+    @Override
+    public void layerRemoved(Layer oldLayer) { setEnabledState(); }
 
-	private class SdsAboutAction extends JosmAction {
+    private class SdsAboutAction extends JosmAction {
 
-	    public SdsAboutAction() {
-	        super(tr("About"), "sds", tr("Information about SDS."), null, true);
-	    }
+        public SdsAboutAction() {
+            super(tr("About"), "sds", tr("Information about SDS."), null, true);
+        }
 
-	    public void actionPerformed(ActionEvent e) {
-	        JPanel about = new JPanel();
+        public void actionPerformed(ActionEvent e) {
+            JPanel about = new JPanel();
 
-	        JTextArea l = new JTextArea();
-	        l.setLineWrap(true);
-	        l.setWrapStyleWord(true);
-	        l.setEditable(false);
-	        l.setText("Separate Data Store\n\nThis plugin provides access to a \"Separate Data Store\" server. " +
-	        		"Whenever data is loaded from the OSM API, it queries the SDS for additional tags that have been stored for the objects just loaded, " +
-	        		"and adds these tags. When you upload data to JOSM, SDS tags will again be separated and, instead of sending them to OSM, they will be uplaoded to SDS." +
-	        		"\n\n" +
-	        		"This depends on SDS tags starting with a special prefix, which can be configured in the SDS preferences." + 
-	        		"\n\n" + 
-	        		"Using the SDS server will usually require an account to be set up there, which is completely independent of your OSM account.");
-	        
-	        l.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-	        l.setOpaque(false);
-	        l.setPreferredSize(new Dimension(500,300));
-	        JScrollPane sp = new JScrollPane(l);
-	        sp.setBorder(null);
-	        sp.setOpaque(false);
-	        	        
-	        about.add(sp);
-	        
-	        about.setPreferredSize(new Dimension(500,300));
+            JTextArea l = new JTextArea();
+            l.setLineWrap(true);
+            l.setWrapStyleWord(true);
+            l.setEditable(false);
+            l.setText("Separate Data Store\n\nThis plugin provides access to a \"Separate Data Store\" server. " +
+                    "Whenever data is loaded from the OSM API, it queries the SDS for additional tags that have been stored for the objects just loaded, " +
+                    "and adds these tags. When you upload data to JOSM, SDS tags will again be separated and, instead of sending them to OSM, they will be uplaoded to SDS." +
+                    "\n\n" +
+                    "This depends on SDS tags starting with a special prefix, which can be configured in the SDS preferences." + 
+                    "\n\n" + 
+                    "Using the SDS server will usually require an account to be set up there, which is completely independent of your OSM account.");
+            
+            l.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+            l.setOpaque(false);
+            l.setPreferredSize(new Dimension(500,300));
+            JScrollPane sp = new JScrollPane(l);
+            sp.setBorder(null);
+            sp.setOpaque(false);
+                        
+            about.add(sp);
+            
+            about.setPreferredSize(new Dimension(500,300));
 
-	        JOptionPane.showMessageDialog(Main.parent, about, tr("About SDS..."),
-	                JOptionPane.INFORMATION_MESSAGE, null);
-	    }
-	}
-	
-	private class SdsPreferencesAction extends JosmAction implements Runnable {
+            JOptionPane.showMessageDialog(Main.parent, about, tr("About SDS..."),
+                    JOptionPane.INFORMATION_MESSAGE, null);
+        }
+    }
+    
+    private class SdsPreferencesAction extends JosmAction implements Runnable {
 
-	    private SdsPreferencesAction() {
-	        super(tr("Preferences..."), "preference", tr("Open a preferences dialog for SDS."),
-	                null, true);
-	        putValue("help", ht("/Action/Preferences"));
-	    }
+        private SdsPreferencesAction() {
+            super(tr("Preferences..."), "preference", tr("Open a preferences dialog for SDS."),
+                    null, true);
+            putValue("help", ht("/Action/Preferences"));
+        }
 
-	    /**
-	     * Launch the preferences dialog.
-	     */
-	    public void actionPerformed(ActionEvent e) {
-	        run();
-	    }
+        /**
+         * Launch the preferences dialog.
+         */
+        public void actionPerformed(ActionEvent e) {
+            run();
+        }
 
-	    public void run() {
-	    	PreferenceDialog pd = new PreferenceDialog(Main.parent);
-	    	// unusual reflection mechanism to cater for older JOSM versions where 
-	    	// the selectPreferencesTabByName method was not public
-	    	try {
-	    		Method sptbn = pd.getClass().getMethod("selectPreferencesTabByName", String.class);
-	    		sptbn.invoke(pd, "sds");
-	    	} catch (Exception ex) {
-	    		// ignore
-	    	}
-	    	pd.setVisible(true);
-	    }
-	}
+        public void run() {
+            PreferenceDialog pd = new PreferenceDialog(Main.parent);
+            // unusual reflection mechanism to cater for older JOSM versions where 
+            // the selectPreferencesTabByName method was not public
+            try {
+                Method sptbn = pd.getClass().getMethod("selectPreferencesTabByName", String.class);
+                sptbn.invoke(pd, "sds");
+            } catch (Exception ex) {
+                // ignore
+            }
+            pd.setVisible(true);
+        }
+    }
 
 
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsOsmWriter.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsOsmWriter.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsOsmWriter.java	(revision 30738)
@@ -27,6 +27,6 @@
 public class SdsOsmWriter extends OsmWriter {
 
-	private SeparateDataStorePlugin plugin;
-	
+    private SeparateDataStorePlugin plugin;
+    
     public SdsOsmWriter(SeparateDataStorePlugin plugin, PrintWriter out, boolean osmConform, String version) {
         super(out, osmConform, version);
@@ -43,5 +43,5 @@
             Collections.sort(entries, byKeyComparator);
             for (Entry<String, String> e : entries) {
-            	String key = e.getKey();
+                String key = e.getKey();
                 if (!(osm instanceof Changeset) && ("created_by".equals(key))) continue;
                 if (key.startsWith(plugin.getIgnorePrefix())) continue;          
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsOsmWriterFactory.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsOsmWriterFactory.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsOsmWriterFactory.java	(revision 30738)
@@ -15,11 +15,11 @@
 public class SdsOsmWriterFactory extends OsmWriterFactory {
 
-	SeparateDataStorePlugin plugin;
-	
-	public SdsOsmWriterFactory(SeparateDataStorePlugin plugin) {
-		this.plugin = plugin;
-	}
-	
-	@Override
+    SeparateDataStorePlugin plugin;
+    
+    public SdsOsmWriterFactory(SeparateDataStorePlugin plugin) {
+        this.plugin = plugin;
+    }
+    
+    @Override
     protected OsmWriter createOsmWriterImpl(PrintWriter out, boolean osmConform, String version) {
         return new SdsOsmWriter(plugin, out, osmConform, version);
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsParser.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsParser.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsParser.java	(revision 30738)
@@ -54,5 +54,5 @@
         {
             String type = atts.getValue("osm_type");
-            String id = atts.getValue("osm_id");     	
+            String id = atts.getValue("osm_id");         
             currentPrimitive = dataSet.getPrimitiveById(Long.parseLong(id), OsmPrimitiveType.fromApiTypeName(type));
             if (currentPrimitive == null && ensureMatch) {
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsPluginPreferences.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsPluginPreferences.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsPluginPreferences.java	(revision 30738)
@@ -35,10 +35,10 @@
    
     public SdsPluginPreferences() {
-    	super("sds", tr("Separate Data Store"), tr("Configures access to the Separate Data Store."));
+        super("sds", tr("Separate Data Store"), tr("Configures access to the Separate Data Store."));
     }
     @Override
     public void addGui(final PreferenceTabbedPane gui) {
         final JPanel tab = gui.createPreferenceTab(this);
-        	
+            
         final JPanel access = new JPanel(new GridBagLayout());
         access.setBorder(BorderFactory.createTitledBorder(tr("Server")));
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsSaveAction.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsSaveAction.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsSaveAction.java	(revision 30738)
@@ -6,6 +6,4 @@
 import java.awt.event.ActionEvent;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -21,6 +19,6 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Utils;
 
-@SuppressWarnings("serial")
 public class SdsSaveAction extends SdsDiskAccessAction {
 
@@ -30,4 +28,5 @@
     }
 
+    @Override
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled())
@@ -40,5 +39,5 @@
         if (Main.isDisplayingMapView() && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer))
             layer = Main.map.mapView.getActiveLayer();
-        
+
         if (layer == null)
             return false;
@@ -64,5 +63,5 @@
             if (file.exists()) {
                 tmpFile = new File(file.getPath() + "~");
-                copy(file, tmpFile);
+                Utils.copyFile(file, tmpFile);
             }
 
@@ -70,7 +69,6 @@
             Writer writer = new OutputStreamWriter(out, "UTF-8");
 
-            SdsWriter w = new SdsWriter(new PrintWriter(writer));
             layer.data.getReadLock().lock();
-            try {
+            try (SdsWriter w = new SdsWriter(new PrintWriter(writer))) {
                 w.header();
                 for (IPrimitive p : layer.data.allNonDeletedPrimitives()) {
@@ -78,5 +76,4 @@
                 }
                 w.footer();
-                w.close();
             } finally {
                 layer.data.getReadLock().unlock();
@@ -87,5 +84,5 @@
             }
         } catch (IOException e) {
-            e.printStackTrace();
+            Main.error(e);
             JOptionPane.showMessageDialog(
                     Main.parent,
@@ -99,8 +96,8 @@
                 // be deleted.  So, restore the backup if we made one.
                 if (tmpFile != null && tmpFile.exists()) {
-                    copy(tmpFile, file);
+                    Utils.copyFile(tmpFile, file);
                 }
             } catch (IOException e2) {
-                e2.printStackTrace();
+                Main.error(e2);
                 JOptionPane.showMessageDialog(
                         Main.parent,
@@ -113,23 +110,3 @@
         return true;
     }
-
-    private void copy(File src, File dst) throws IOException {
-        FileInputStream srcStream;
-        FileOutputStream dstStream;
-        try {
-            srcStream = new FileInputStream(src);
-            dstStream = new FileOutputStream(dst);
-        } catch (FileNotFoundException e) {
-            JOptionPane.showMessageDialog(Main.parent, tr("Could not back up file. Exception is: {0}", e
-                    .getMessage()), tr("Error"), JOptionPane.ERROR_MESSAGE);
-            return;
-        }
-        byte buf[] = new byte[1 << 16];
-        int len;
-        while ((len = srcStream.read(buf)) != -1) {
-            dstStream.write(buf, 0, len);
-        }
-        srcStream.close();
-        dstStream.close();
-    }
 }
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsWriter.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsWriter.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SdsWriter.java	(revision 30738)
@@ -29,18 +29,18 @@
 
     public void write(IPrimitive what, Map<String,String> tags) {
-    	out.print("<osm_shadow osm_type=\"");
-    	out.print(what.getType().getAPIName());
-    	out.print("\" osm_id=\"");
-    	out.print(what.getId());
-    	out.println("\">");
+        out.print("<osm_shadow osm_type=\"");
+        out.print(what.getType().getAPIName());
+        out.print("\" osm_id=\"");
+        out.print(what.getId());
+        out.println("\">");
         
-    	if (tags != null) {
-    		for(Entry<String,String> e : tags.entrySet()) {
-    			out.println("    <tag k='"+ XmlWriter.encode(e.getKey()) +
-    					"' v='"+XmlWriter.encode(e.getValue())+ "' />");
-    		}
-    	}
-    	
-    	out.println("</osm_shadow>");
+        if (tags != null) {
+            for(Entry<String,String> e : tags.entrySet()) {
+                out.println("    <tag k='"+ XmlWriter.encode(e.getKey()) +
+                        "' v='"+XmlWriter.encode(e.getValue())+ "' />");
+            }
+        }
+        
+        out.println("</osm_shadow>");
     }
 
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SeparateDataStorePlugin.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SeparateDataStorePlugin.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/SeparateDataStorePlugin.java	(revision 30738)
@@ -29,29 +29,29 @@
 {
 
-	public HashMap<Long, IPrimitive> originalNodes = new HashMap<>();
-	public HashMap<Long, IPrimitive> originalWays = new HashMap<>();
-	public HashMap<Long, IPrimitive> originalRelations = new HashMap<>();
-	
-	public ArrayList<QueueItem> uploadQueue = new ArrayList<>();
-	
-	private PrimitiveVisitor learnVisitor = new PrimitiveVisitor() {
-		public void visit(INode i) { originalNodes.put(i.getId(), i); }
-		public void visit(IWay i) { originalWays.put(i.getId(), i); }
-		public void visit(IRelation i) { originalRelations.put(i.getId(), i); }
-	};
-	
-	class QueueItem {
-		public IPrimitive primitive;
-		public HashMap<String,String> tags;
-		public boolean sdsOnly;
-		public boolean processed;
-		public QueueItem(IPrimitive p, HashMap<String,String> t, boolean s) {
-			primitive = p;
-			tags = t;
-			sdsOnly = s;
-			processed = false;
-		}
-	}
-	
+    public HashMap<Long, IPrimitive> originalNodes = new HashMap<>();
+    public HashMap<Long, IPrimitive> originalWays = new HashMap<>();
+    public HashMap<Long, IPrimitive> originalRelations = new HashMap<>();
+    
+    public ArrayList<QueueItem> uploadQueue = new ArrayList<>();
+    
+    private PrimitiveVisitor learnVisitor = new PrimitiveVisitor() {
+        public void visit(INode i) { originalNodes.put(i.getId(), i); }
+        public void visit(IWay i) { originalWays.put(i.getId(), i); }
+        public void visit(IRelation i) { originalRelations.put(i.getId(), i); }
+    };
+    
+    class QueueItem {
+        public IPrimitive primitive;
+        public HashMap<String,String> tags;
+        public boolean sdsOnly;
+        public boolean processed;
+        public QueueItem(IPrimitive p, HashMap<String,String> t, boolean s) {
+            primitive = p;
+            tags = t;
+            sdsOnly = s;
+            processed = false;
+        }
+    }
+    
     /**
      * Creates the plugin
@@ -60,7 +60,7 @@
     {
         super(info);
-    	System.out.println("initializing SDS plugin");
-    	
-    	// this lets us see what JOSM load from the server, and augment it with our data:
+        System.out.println("initializing SDS plugin");
+        
+        // this lets us see what JOSM load from the server, and augment it with our data:
         OsmReader.registerPostprocessor(new ReadPostprocessor(this));
         
@@ -79,53 +79,53 @@
     }
 
-	public String getIgnorePrefix() {
+    public String getIgnorePrefix() {
         return Main.pref.get("sds-server.tag-prefix", "hot:");
-	}
-	
-	public IPrimitive getOriginalPrimitive(IPrimitive other) {
-		switch (other.getType()) {
-		case NODE: return originalNodes.get(other.getId());
-		case WAY: return originalWays.get(other.getId());
-		case RELATION: return originalRelations.get(other.getId());
-		}
-		return null;	
-	}
-	
-	protected void enqueueForUpload(IPrimitive prim, HashMap<String, String> tags, boolean onlySds) {
-		uploadQueue.add(new QueueItem(prim, tags, onlySds));
-	}
-	
-	/** 
-	 * Stores the given primitive in the plugin's cache in order to
-	 * determine changes later.
-	 * @param prim
-	 */
-	protected void learn(IPrimitive prim) {
-		if (prim instanceof OsmPrimitive) {
-			((OsmPrimitive)prim).save().accept(learnVisitor);
-		} else {
-			prim.accept(learnVisitor);
-		}
-	}
-	
-	/**
-	 * removes all elements from the upload queue that have the processed flag set.
-	 */
-	protected void clearQueue() {
-		ArrayList<QueueItem> newQueue = new ArrayList<>();
-		for (QueueItem q : uploadQueue) {
-			if (!q.processed) newQueue.add(q);
-		}
-		uploadQueue = newQueue;
-	}
-	
-	/**
-	 * reset the processed flag for all elements of the queue.
-	 */
-	protected void resetQueue() {
-		for (QueueItem q : uploadQueue) {
-			q.processed = false;
-		}
-	}
+    }
+    
+    public IPrimitive getOriginalPrimitive(IPrimitive other) {
+        switch (other.getType()) {
+        case NODE: return originalNodes.get(other.getId());
+        case WAY: return originalWays.get(other.getId());
+        case RELATION: return originalRelations.get(other.getId());
+        }
+        return null;    
+    }
+    
+    protected void enqueueForUpload(IPrimitive prim, HashMap<String, String> tags, boolean onlySds) {
+        uploadQueue.add(new QueueItem(prim, tags, onlySds));
+    }
+    
+    /** 
+     * Stores the given primitive in the plugin's cache in order to
+     * determine changes later.
+     * @param prim
+     */
+    protected void learn(IPrimitive prim) {
+        if (prim instanceof OsmPrimitive) {
+            ((OsmPrimitive)prim).save().accept(learnVisitor);
+        } else {
+            prim.accept(learnVisitor);
+        }
+    }
+    
+    /**
+     * removes all elements from the upload queue that have the processed flag set.
+     */
+    protected void clearQueue() {
+        ArrayList<QueueItem> newQueue = new ArrayList<>();
+        for (QueueItem q : uploadQueue) {
+            if (!q.processed) newQueue.add(q);
+        }
+        uploadQueue = newQueue;
+    }
+    
+    /**
+     * reset the processed flag for all elements of the queue.
+     */
+    protected void resetQueue() {
+        for (QueueItem q : uploadQueue) {
+            q.processed = false;
+        }
+    }
 
     public PreferenceSetting getPreferenceSetting() {
Index: applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/WritePostprocessor.java
===================================================================
--- applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/WritePostprocessor.java	(revision 30737)
+++ applications/editors/josm/plugins/sds/src/org/openstreetmap/hot/sds/WritePostprocessor.java	(revision 30738)
@@ -13,62 +13,60 @@
 public class WritePostprocessor implements OsmServerWritePostprocessor {
 
-	SeparateDataStorePlugin plugin;
+    SeparateDataStorePlugin plugin;
 
-	public WritePostprocessor(SeparateDataStorePlugin plugin) {
-		this.plugin = plugin;
-	}	
+    public WritePostprocessor(SeparateDataStorePlugin plugin) {
+        this.plugin = plugin;
+    }
 
-	@Override
-	public void postprocessUploadedPrimitives(Collection<IPrimitive> primitives,
-			ProgressMonitor progress) {
-		
-	    StringWriter swriter = new StringWriter();
-	    SdsWriter sdsWriter = new SdsWriter(new PrintWriter(swriter));
-	    sdsWriter.header();
-	    boolean somethingWritten = false;
-	   
-	    for (IPrimitive p : primitives) {
-			for (QueueItem q : plugin.uploadQueue) {
-				if (q.primitive.equals(p) && !q.sdsOnly) {
-					sdsWriter.write(q.primitive, q.tags);
-					somethingWritten = true;
-					q.processed = true;
-					continue;
-				}
-			}
-	    }
-	    
-		for (QueueItem q : plugin.uploadQueue) {
-			if (q.sdsOnly) {
-				sdsWriter.write(q.primitive, q.tags);
-				somethingWritten = true;
-				q.processed = true;
-			}
-		}
+    @Override
+    public void postprocessUploadedPrimitives(Collection<IPrimitive> primitives, ProgressMonitor progress) {
 
-		if (somethingWritten) {
-			sdsWriter.footer();
+        StringWriter swriter = new StringWriter();
+        try (SdsWriter sdsWriter = new SdsWriter(new PrintWriter(swriter))) {
+            sdsWriter.header();
+            boolean somethingWritten = false;
 
-			SdsApi api = SdsApi.getSdsApi();
-			System.out.println("sending message:\n" + swriter.toString());
-			api.updateSds(swriter.toString(), progress);
-		}
-		
-		sdsWriter.close();
-		
-		for (IPrimitive p : primitives) {
-			plugin.learn(p);
-		}
+            for (IPrimitive p : primitives) {
+                for (QueueItem q : plugin.uploadQueue) {
+                    if (q.primitive.equals(p) && !q.sdsOnly) {
+                        sdsWriter.write(q.primitive, q.tags);
+                        somethingWritten = true;
+                        q.processed = true;
+                        continue;
+                    }
+                }
+            }
 
-		for (QueueItem q : plugin.uploadQueue) {
-			if (q.sdsOnly) {
-				q.primitive.setModified(false);
-				plugin.learn(q.primitive);
-			}
-		}
-		
-		plugin.clearQueue();
-		// TODO: if exception -> resetQueue
-	}
+            for (QueueItem q : plugin.uploadQueue) {
+                if (q.sdsOnly) {
+                    sdsWriter.write(q.primitive, q.tags);
+                    somethingWritten = true;
+                    q.processed = true;
+                }
+            }
+
+            if (somethingWritten) {
+                sdsWriter.footer();
+
+                SdsApi api = SdsApi.getSdsApi();
+                System.out.println("sending message:\n" + swriter.toString());
+                api.updateSds(swriter.toString(), progress);
+            }
+        }
+
+        for (IPrimitive p : primitives) {
+            plugin.learn(p);
+        }
+
+        for (QueueItem q : plugin.uploadQueue) {
+            if (q.sdsOnly) {
+                q.primitive.setModified(false);
+                plugin.learn(q.primitive);
+            }
+        }
+
+        plugin.clearQueue();
+        // TODO: if exception -> resetQueue
+    }
 
 }
