Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 7392)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 7395)
@@ -122,4 +122,7 @@
     private final Object selectionLock = new Object();
 
+    /**
+     * Constructs a new {@code DataSet}.
+     */
     public DataSet() {
         /*
@@ -130,4 +133,8 @@
     }
 
+    /**
+     * Returns the lock used for reading.
+     * @return the lock used for reading
+     */
     public Lock getReadLock() {
         return lock.readLock();
@@ -165,8 +172,12 @@
 
     /**
-     * Maintain a list of used tags for autocompletion
+     * Maintains a list of used tags for autocompletion.
      */
     private AutoCompletionManager autocomplete;
 
+    /**
+     * Returns the autocompletion manager, which maintains a list of used tags for autocompletion.
+     * @return the autocompletion manager
+     */
     public AutoCompletionManager getAutoCompletionManager() {
         if (autocomplete == null) {
@@ -200,8 +211,18 @@
     }
 
+    /**
+     * Determines if upload is being discouraged (i.e. this dataset contains private data which should not be uploaded)
+     * @return {@code true} if upload is being discouraged, {@code false} otherwise
+     * @see #setUploadDiscouraged
+     */
     public final boolean isUploadDiscouraged() {
         return uploadDiscouraged;
     }
 
+    /**
+     * Sets the "upload discouraged" flag.
+     * @param uploadDiscouraged {@code true} if this dataset contains private data which should not be uploaded
+     * @see #isUploadDiscouraged
+     */
     public final void setUploadDiscouraged(boolean uploadDiscouraged) {
         this.uploadDiscouraged = uploadDiscouraged;
@@ -213,8 +234,19 @@
     private Map<String, String> changeSetTags = new HashMap<>();
 
+    /**
+     * Replies the set of changeset tags to be applied when or if this is ever uploaded.
+     * @return the set of changeset tags
+     * @see #addChangeSetTag
+     */
     public Map<String, String> getChangeSetTags() {
         return changeSetTags;
     }
 
+    /**
+     * Adds a new changeset tag.
+     * @param k Key
+     * @param v Value
+     * @see #getChangeSetTags
+     */
     public void addChangeSetTag(String k, String v) {
         this.changeSetTags.put(k,v);
@@ -240,4 +272,9 @@
     }
 
+    /**
+     * Searches for nodes in the given bounding box.
+     * @param bbox the bounding box
+     * @return List of nodes in the given bbox. Can be empty but not null
+     */
     public List<Node> searchNodes(BBox bbox) {
         lock.readLock().lock();
@@ -265,4 +302,9 @@
     }
 
+    /**
+     * Searches for ways in the given bounding box.
+     * @param bbox the bounding box
+     * @return List of ways in the given bbox. Can be empty but not null
+     */
     public List<Way> searchWays(BBox bbox) {
         lock.readLock().lock();
@@ -288,4 +330,9 @@
     }
 
+    /**
+     * Searches for relations in the given bounding box.
+     * @param bbox the bounding box
+     * @return List of relations in the given bbox. Can be empty but not null
+     */
     public List<Relation> searchRelations(BBox bbox) {
         lock.readLock().lock();
@@ -310,5 +357,6 @@
 
     /**
-     * @return A collection containing all primitives of the dataset. Data are not ordered
+     * Returns a collection containing all primitives of the dataset.
+     * @return A collection containing all primitives of the dataset. Data is not ordered
      */
     public Collection<OsmPrimitive> allPrimitives() {
@@ -317,5 +365,7 @@
 
     /**
-     * @return A collection containing all not-deleted primitives (except keys).
+     * Returns a collection containing all not-deleted primitives.
+     * @return A collection containing all not-deleted primitives.
+     * @see OsmPrimitive#isDeleted
      */
     public Collection<OsmPrimitive> allNonDeletedPrimitives() {
@@ -323,12 +373,29 @@
     }
 
+    /**
+     * Returns a collection containing all not-deleted complete primitives.
+     * @return A collection containing all not-deleted complete primitives.
+     * @see OsmPrimitive#isDeleted
+     * @see OsmPrimitive#isIncomplete
+     */
     public Collection<OsmPrimitive> allNonDeletedCompletePrimitives() {
         return getPrimitives(OsmPrimitive.nonDeletedCompletePredicate);
     }
 
+    /**
+     * Returns a collection containing all not-deleted complete physical primitives.
+     * @return A collection containing all not-deleted complete physical primitives (nodes and ways).
+     * @see OsmPrimitive#isDeleted
+     * @see OsmPrimitive#isIncomplete
+     */
     public Collection<OsmPrimitive> allNonDeletedPhysicalPrimitives() {
         return getPrimitives(OsmPrimitive.nonDeletedPhysicalPredicate);
     }
 
+    /**
+     * Returns a collection containing all modified primitives.
+     * @return A collection containing all modified primitives.
+     * @see OsmPrimitive#isModified
+     */
     public Collection<OsmPrimitive> allModifiedPrimitives() {
         return getPrimitives(OsmPrimitive.modifiedPredicate);
@@ -336,5 +403,5 @@
 
     /**
-     * Adds a primitive to the dataset
+     * Adds a primitive to the dataset.
      *
      * @param primitive the primitive.
@@ -414,8 +481,16 @@
     private static final Collection<SelectionChangedListener> selListeners = new CopyOnWriteArrayList<>();
 
+    /**
+     * Adds a new selection listener.
+     * @param listener The selection listener to add
+     */
     public static void addSelectionListener(SelectionChangedListener listener) {
         ((CopyOnWriteArrayList<SelectionChangedListener>)selListeners).addIfAbsent(listener);
     }
 
+    /**
+     * Removes a selection listener.
+     * @param listener The selection listener to remove
+     */
     public static void removeSelectionListener(SelectionChangedListener listener) {
         selListeners.remove(listener);
@@ -437,4 +512,8 @@
     private Collection<OsmPrimitive> selectionSnapshot;
 
+    /**
+     * Returns selected nodes and ways.
+     * @return selected nodes and ways
+     */
     public Collection<OsmPrimitive> getSelectedNodesAndWays() {
         return new FilteredCollection<>(getSelected(), new Predicate<OsmPrimitive>() {
@@ -447,5 +526,5 @@
 
     /**
-     * returns an unmodifiable collection of *WaySegments* whose virtual
+     * Returns an unmodifiable collection of *WaySegments* whose virtual
      * nodes should be highlighted. WaySegments are used to avoid having
      * to create a VirtualNode class that wouldn't have much purpose otherwise.
@@ -458,6 +537,5 @@
 
     /**
-     * returns an unmodifiable collection of WaySegments that should be
-     * highlighted.
+     * Returns an unmodifiable collection of WaySegments that should be highlighted.
      *
      * @return unmodifiable collection of WaySegments
@@ -495,5 +573,6 @@
 
     /**
-     * Return selected nodes.
+     * Returns selected nodes.
+     * @return selected nodes
      */
     public Collection<Node> getSelectedNodes() {
@@ -502,5 +581,6 @@
 
     /**
-     * Return selected ways.
+     * Returns selected ways.
+     * @return selected ways
      */
     public Collection<Way> getSelectedWays() {
@@ -509,5 +589,6 @@
 
     /**
-     * Return selected relations.
+     * Returns selected relations.
+     * @return selected relations
      */
     public Collection<Relation> getSelectedRelations() {
@@ -516,4 +597,5 @@
 
     /**
+     * Determines whether the selection is empty or not
      * @return whether the selection is empty or not
      */
@@ -522,8 +604,17 @@
     }
 
+    /**
+     * Determines whether the given primitive is selected or not
+     * @param osm the primitive
+     * @return whether {@code osm} is selected or not
+     */
     public boolean isSelected(OsmPrimitive osm) {
         return selectedPrimitives.contains(osm);
     }
 
+    /**
+     * Toggles the selected state of the given collection of primitives.
+     * @param osm The primitives to toggle
+     */
     public void toggleSelected(Collection<? extends PrimitiveId> osm) {
         boolean changed = false;
@@ -540,7 +631,13 @@
         }
     }
+
+    /**
+     * Toggles the selected state of the given collection of primitives.
+     * @param osm The primitives to toggle
+     */
     public void toggleSelected(PrimitiveId... osm) {
         toggleSelected(Arrays.asList(osm));
     }
+
     private boolean __toggleSelected(PrimitiveId primitiveId) {
         OsmPrimitive primitive = getPrimitiveByIdChecked(primitiveId);
@@ -617,4 +714,10 @@
     }
 
+    /**
+     * Sets the current selection to the primitives in <code>osm</code>
+     * and notifies all {@link SelectionChangedListener}.
+     *
+     * @param osm the primitives to set
+     */
     public void setSelected(PrimitiveId... osm) {
         if (osm.length == 1 && osm[0] == null) {
@@ -627,5 +730,5 @@
 
     /**
-     * Adds   the primitives in <code>selection</code> to the current selection
+     * Adds the primitives in <code>selection</code> to the current selection
      * and notifies all {@link SelectionChangedListener}.
      *
@@ -636,4 +739,10 @@
     }
 
+    /**
+     * Adds the primitives in <code>osm</code> to the current selection
+     * and notifies all {@link SelectionChangedListener}.
+     *
+     * @param osm the primitives to add
+     */
     public void addSelected(PrimitiveId... osm) {
         addSelected(Arrays.asList(osm));
@@ -682,5 +791,5 @@
 
     /**
-     * Remove the selection from every value in the collection.
+     * Removes the selection from every value in the collection.
      * @param osm The collection of ids to remove the selection from.
      */
@@ -688,4 +797,9 @@
         clearSelection(Arrays.asList(osm));
     }
+
+    /**
+     * Removes the selection from every value in the collection.
+     * @param list The collection of ids to remove the selection from.
+     */
     public void clearSelection(Collection<? extends PrimitiveId> list) {
         boolean changed = false;
@@ -705,4 +819,8 @@
         }
     }
+
+    /**
+     * Clears the current selection.
+     */
     public void clearSelection() {
         if (!selectedPrimitives.isEmpty()) {
@@ -715,5 +833,6 @@
     }
 
-    @Override public DataSet clone() {
+    @Override
+    public DataSet clone() {
         getReadLock().lock();
         try {
@@ -776,6 +895,5 @@
 
     /**
-     * returns a  primitive with a given id from the data set. null, if no such primitive
-     * exists
+     * Returns a primitive with a given id from the data set. null, if no such primitive exists
      *
      * @param id  uniqueId of the primitive. Might be &lt; 0 for newly created primitives
@@ -788,4 +906,10 @@
     }
 
+    /**
+     * Returns a primitive with a given id from the data set. null, if no such primitive exists
+     *
+     * @param primitiveId type and uniqueId of the primitive. Might be &lt; 0 for newly created primitives
+     * @return the primitive
+     */
     public OsmPrimitive getPrimitiveById(PrimitiveId primitiveId) {
         return primitivesMap.get(primitiveId);
@@ -949,8 +1073,16 @@
     }
 
+    /**
+     * Adds a new data set listener.
+     * @param dsl The data set listener to add
+     */
     public void addDataSetListener(DataSetListener dsl) {
         listeners.addIfAbsent(dsl);
     }
 
+    /**
+     * Removes a data set listener.
+     * @param dsl The data set listener to remove
+     */
     public void removeDataSetListener(DataSetListener dsl) {
         listeners.remove(dsl);
@@ -1078,4 +1210,7 @@
     }
 
+    /**
+     * Cleanups all deleted primitives (really delete them from the dataset).
+     */
     public void cleanupDeletedPrimitives() {
         beginUpdate();
@@ -1169,5 +1304,5 @@
 
     /**
-     * Moves all primitives and datasources from DataSet "from" to this DataSet
+     * Moves all primitives and datasources from DataSet "from" to this DataSet.
      * @param from The source DataSet
      */
@@ -1177,6 +1312,7 @@
 
     /**
-     * Moves all primitives and datasources from DataSet "from" to this DataSet
+     * Moves all primitives and datasources from DataSet "from" to this DataSet.
      * @param from The source DataSet
+     * @param progressMonitor The progress monitor
      */
     public void mergeFrom(DataSet from, ProgressMonitor progressMonitor) {
Index: trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java	(revision 7392)
+++ trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java	(revision 7395)
@@ -285,6 +285,5 @@
                 } else if (intersection == PolygonIntersection.SECOND_INSIDE_FIRST) {
                     innerCandidates.add(innerWay);
-                }
-                else if (intersection == PolygonIntersection.CROSSING) {
+                } else if (intersection == PolygonIntersection.CROSSING) {
                     //ways intersect
                     return null;
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 7392)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 7395)
@@ -28,17 +28,25 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
 
+/**
+ * Multipolygon data used to represent complex areas, see <a href="https://wiki.openstreetmap.org/wiki/Relation:multipolygon">wiki</a>.
+ * @since 2788
+ */
 public class Multipolygon {
+
     /** preference key for a collection of roles which indicate that the respective member belongs to an
      * <em>outer</em> polygon. Default is <tt>outer</tt>.
      */
     public static final String PREF_KEY_OUTER_ROLES = "mappaint.multipolygon.outer.roles";
+
     /** preference key for collection of role prefixes which indicate that the respective
      *  member belongs to an <em>outer</em> polygon. Default is empty.
      */
     public static final String PREF_KEY_OUTER_ROLE_PREFIXES = "mappaint.multipolygon.outer.role-prefixes";
+
     /** preference key for a collection of roles which indicate that the respective member belongs to an
      * <em>inner</em> polygon. Default is <tt>inner</tt>.
      */
     public static final String PREF_KEY_INNER_ROLES = "mappaint.multipolygon.inner.roles";
+
     /** preference key for collection of role prefixes which indicate that the respective
      *  member belongs to an <em>inner</em> polygon. Default is empty.
@@ -53,7 +61,6 @@
      * <p>The decision is taken based on preference settings, see the four preference keys
      * above.</p>
-     *
-     */
-    private static class MultipolygonRoleMatcher implements PreferenceChangedListener{
+     */
+    private static class MultipolygonRoleMatcher implements PreferenceChangedListener {
         private final List<String> outerExactRoles = new ArrayList<>();
         private final List<String> outerRolePrefixes = new ArrayList<>();
@@ -70,7 +77,7 @@
         }
 
-        private void setNormalized(Collection<String> literals, List<String> target){
+        private void setNormalized(Collection<String> literals, List<String> target) {
             target.clear();
-            for(String l: literals) {
+            for (String l: literals) {
                 if (l == null) {
                     continue;
@@ -115,5 +122,5 @@
         }
 
-        public boolean isOuterRole(String role){
+        public boolean isOuterRole(String role) {
             if (role == null) return false;
             for (String candidate: outerExactRoles) {
@@ -126,5 +133,5 @@
         }
 
-        public boolean isInnerRole(String role){
+        public boolean isInnerRole(String role) {
             if (role == null) return false;
             for (String candidate: innerExactRoles) {
@@ -139,6 +146,5 @@
 
     /*
-     * Init a private global matcher object which will listen to preference
-     * changes.
+     * Init a private global matcher object which will listen to preference changes.
      */
     private static MultipolygonRoleMatcher roleMatcher;
@@ -493,5 +499,5 @@
             }
 
-            if (nodes == null) {
+            if (nodes == null && w != null) {
                 nodes = w.getNodes();
                 wayIds.add(w.getUniqueId());
@@ -568,8 +574,16 @@
     }
 
+    /**
+     * Replies the list of outer ways.
+     * @return the list of outer ways
+     */
     public List<Way> getOuterWays() {
         return outerWays;
     }
 
+    /**
+     * Replies the list of inner ways.
+     * @return the list of inner ways
+     */
     public List<Way> getInnerWays() {
         return innerWays;
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java	(revision 7392)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java	(revision 7395)
@@ -35,15 +35,15 @@
 
 /**
- * A memory cache for Multipolygon objects.
+ * A memory cache for {@link Multipolygon} objects.
  * @since 4623
  */
 public final class MultipolygonCache implements DataSetListener, LayerChangeListener, ProjectionChangeListener, SelectionChangedListener {
 
-    private static final MultipolygonCache INSTANCE = new MultipolygonCache(); 
-    
+    private static final MultipolygonCache INSTANCE = new MultipolygonCache();
+
     private final Map<NavigatableComponent, Map<DataSet, Map<Relation, Multipolygon>>> cache;
-    
+
     private final Collection<PolyData> selectedPolyData;
-    
+
     private MultipolygonCache() {
         this.cache = new HashMap<>();
@@ -62,8 +62,21 @@
     }
 
+    /**
+     * Gets a multipolygon from cache.
+     * @param nc The navigatable component
+     * @param r The multipolygon relation
+     * @return A multipolygon object for the given relation, or {@code null}
+     */
     public final Multipolygon get(NavigatableComponent nc, Relation r) {
         return get(nc, r, false);
     }
 
+    /**
+     * Gets a multipolygon from cache.
+     * @param nc The navigatable component
+     * @param r The multipolygon relation
+     * @param forceRefresh if {@code true}, a new object will be created even of present in cache
+     * @return A multipolygon object for the given relation, or {@code null}
+     */
     public final Multipolygon get(NavigatableComponent nc, Relation r, boolean forceRefresh) {
         Multipolygon multipolygon = null;
@@ -89,5 +102,9 @@
         return multipolygon;
     }
-    
+
+    /**
+     * Clears the cache for the given navigatable component.
+     * @param nc the navigatable component
+     */
     public final void clear(NavigatableComponent nc) {
         Map<DataSet, Map<Relation, Multipolygon>> map = cache.remove(nc);
@@ -98,4 +115,8 @@
     }
 
+    /**
+     * Clears the cache for the given dataset.
+     * @param ds the data set
+     */
     public final void clear(DataSet ds) {
         for (Map<DataSet, Map<Relation, Multipolygon>> map1 : cache.values()) {
@@ -108,8 +129,11 @@
     }
 
+    /**
+     * Clears the whole cache.
+     */
     public final void clear() {
         cache.clear();
     }
-    
+
     private final Collection<Map<Relation, Multipolygon>> getMapsFor(DataSet ds) {
         List<Map<Relation, Multipolygon>> result = new ArrayList<>();
@@ -122,9 +146,9 @@
         return result;
     }
-    
+
     private static final boolean isMultipolygon(OsmPrimitive p) {
         return p instanceof Relation && ((Relation) p).isMultipolygon();
     }
-    
+
     private final void updateMultipolygonsReferringTo(AbstractDatasetChangedEvent event) {
         updateMultipolygonsReferringTo(event, event.getPrimitives(), event.getDataset());
@@ -135,7 +159,7 @@
         updateMultipolygonsReferringTo(event, primitives, ds, null);
     }
-    
+
     private final Collection<Map<Relation, Multipolygon>> updateMultipolygonsReferringTo(
-            AbstractDatasetChangedEvent event, Collection<? extends OsmPrimitive> primitives, 
+            AbstractDatasetChangedEvent event, Collection<? extends OsmPrimitive> primitives,
             DataSet ds, Collection<Map<Relation, Multipolygon>> initialMaps) {
         Collection<Map<Relation, Multipolygon>> maps = initialMaps;
@@ -147,5 +171,5 @@
                     }
                     processEvent(event, (Relation) p, maps);
-                    
+
                 } else if (p instanceof Way && p.getDataSet() != null) {
                     for (OsmPrimitive ref : p.getReferrers()) {
@@ -164,5 +188,5 @@
         return maps;
     }
-    
+
     private final void processEvent(AbstractDatasetChangedEvent event, Relation r, Collection<Map<Relation, Multipolygon>> maps) {
         if (event instanceof NodeMovedEvent || event instanceof WayNodesChangedEvent) {
@@ -173,9 +197,9 @@
             }
         } else {
-            // Default (non-optimal) action: remove multipolygon from cache 
+            // Default (non-optimal) action: remove multipolygon from cache
             removeMultipolygonFrom(r, maps);
         }
     }
-    
+
     private final void dispatchEvent(AbstractDatasetChangedEvent event, Relation r, Collection<Map<Relation, Multipolygon>> maps) {
         for (Map<Relation, Multipolygon> map : maps) {
@@ -192,5 +216,5 @@
         }
     }
-    
+
     private final void removeMultipolygonFrom(Relation r, Collection<Map<Relation, Multipolygon>> maps) {
         for (Map<Relation, Multipolygon> map : maps) {
@@ -236,5 +260,5 @@
     @Override
     public void dataChanged(DataChangedEvent event) {
-        // Do not call updateMultipolygonsReferringTo as getPrimitives() 
+        // Do not call updateMultipolygonsReferringTo as getPrimitives()
         // can return all the data set primitives for this event
         Collection<Map<Relation, Multipolygon>> maps = null;
@@ -280,10 +304,10 @@
     @Override
     public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        
+
         for (Iterator<PolyData> it = selectedPolyData.iterator(); it.hasNext();) {
             it.next().selected = false;
             it.remove();
         }
-        
+
         DataSet ds = null;
         Collection<Map<Relation, Multipolygon>> maps = null;
Index: trunk/src/org/openstreetmap/josm/tools/FilteredCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/FilteredCollection.java	(revision 7392)
+++ trunk/src/org/openstreetmap/josm/tools/FilteredCollection.java	(revision 7395)
@@ -7,10 +7,16 @@
  * The same as SubclassFilteredCollection, but does not restrict the type
  * of the collection to a certain subclass.
+ * @param <T> element type of the underlying collection
+ * @since 3802
  */
 public class FilteredCollection<T> extends SubclassFilteredCollection<T, T> {
 
+    /**
+     * Constructs a new {@code FilteredCollection}.
+     * @param collection The base collection to filter
+     * @param predicate The predicate to use as filter
+     */
     public FilteredCollection(Collection<? extends T> collection, Predicate<? super T> predicate) {
         super(collection, predicate);
     }
-
 }
Index: trunk/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java	(revision 7392)
+++ trunk/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java	(revision 7395)
@@ -14,4 +14,5 @@
  * @param <T> element type of filtered collection (and subclass of S). The predicate
  *      must accept only objects of type T.
+ * @since 3147
  */
 public class SubclassFilteredCollection<S, T extends S> extends AbstractCollection<T> {
@@ -63,4 +64,9 @@
     }
 
+    /**
+     * Constructs a new {@code SubclassFilteredCollection}.
+     * @param collection The base collection to filter
+     * @param predicate The predicate to use as filter
+     */
     public SubclassFilteredCollection(Collection<? extends S> collection, Predicate<? super S> predicate) {
         this.collection = collection;
@@ -90,4 +96,3 @@
         return !iterator().hasNext();
     }
-
 }
