Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/CadastrePlugin.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/CadastrePlugin.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/CadastrePlugin.java	(revision 34355)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.download.DownloadDialog;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
@@ -49,4 +50,5 @@
 import org.openstreetmap.josm.plugins.fr.cadastre.actions.mapmode.WMSAdjustAction;
 import org.openstreetmap.josm.plugins.fr.cadastre.actions.upload.CheckSourceUploadHook;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadSource;
 import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadTask;
 import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.pci.EdigeoPciImporter;
@@ -233,5 +235,5 @@
 
         MainApplication.getMenu().openLocation.addDownloadTaskClass(CadastreDownloadTask.class);
-        //DownloadDialog.addDownloadSource(new CadastreDownloadSource());
+        DownloadDialog.addDownloadSource(new CadastreDownloadSource());
     }
 
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadData.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadData.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadData.java	(revision 34355)
@@ -42,37 +42,37 @@
     }
 
-    final boolean isDownloadWater() {
+    public final boolean isDownloadWater() {
         return downloadWater;
     }
 
-    final boolean isDownloadBuilding() {
+    public final boolean isDownloadBuilding() {
         return downloadBuilding;
     }
 
-    final boolean isDownloadSymbol() {
+    public final boolean isDownloadSymbol() {
         return downloadSymbol;
     }
 
-    final boolean isDownloadParcel() {
+    public final boolean isDownloadParcel() {
         return downloadParcel;
     }
 
-    final boolean isDownloadParcelNumber() {
+    public final boolean isDownloadParcelNumber() {
         return downloadParcelNumber;
     }
 
-    final boolean isDownloadAddress() {
+    public final boolean isDownloadAddress() {
         return downloadAddress;
     }
 
-    final boolean isDownloadLocality() {
+    public final boolean isDownloadLocality() {
         return downloadLocality;
     }
 
-    final boolean isDownloadSection() {
+    public final boolean isDownloadSection() {
         return downloadSection;
     }
 
-    final boolean isDownloadCommune() {
+    public final boolean isDownloadCommune() {
         return downloadCommune;
     }
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadSource.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadSource.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadSource.java	(revision 34355)
@@ -4,4 +4,6 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import org.openstreetmap.josm.actions.downloadtasks.DownloadParams;
+import org.openstreetmap.josm.data.osm.UploadPolicy;
 import org.openstreetmap.josm.gui.download.AbstractDownloadSourcePanel;
 import org.openstreetmap.josm.gui.download.DownloadDialog;
@@ -21,5 +23,9 @@
     @Override
     public void doDownload(CadastreDownloadData data, DownloadSettings settings) {
-        // TODO download from cadastre API
+        if (settings.getDownloadBounds().isPresent()) {
+            new CadastreDownloadTask(data).download(
+                    new DownloadParams().withUploadPolicy(UploadPolicy.BLOCKED).withNewLayer(settings.asNewLayer()),
+                    settings.getDownloadBounds().get(), null);
+        }
     }
 
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadTask.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadTask.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreDownloadTask.java	(revision 34355)
@@ -4,12 +4,24 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.stream.Stream;
 
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadParams;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.DownloadPolicy;
+import org.openstreetmap.josm.data.osm.UploadPolicy;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.plugins.fr.cadastre.api.CadastreAPI;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -18,7 +30,43 @@
 public class CadastreDownloadTask extends DownloadOsmTask {
 
+    private static final String CADASTRE_URL = "https://cadastre.data.gouv.fr/data/dgfip-pci-vecteur/latest/edigeo/feuilles";
+
+    private final CadastreDownloadData data;
+
+    /**
+     * Constructs a new {@code CadastreDownloadTask} with default behaviour.
+     */
+    public CadastreDownloadTask() {
+        this(new CadastreDownloadData(true, true, true, true, true, true, true, true, true));
+    }
+
+    /**
+     * Constructs a new {@code CadastreDownloadTask} with parameterizable behaviour.
+     * @param data defines which data has to be downloaded
+     */
+    public CadastreDownloadTask(CadastreDownloadData data) {
+        this.data = Objects.requireNonNull(data);
+    }
+
     @Override
-    public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
-        return null;
+    public Future<?> download(DownloadParams settings, Bounds downloadArea, ProgressMonitor progressMonitor) {
+        List<Future<?>> tasks = new ArrayList<>();
+        try {
+            for (String id : CadastreAPI.getSheets(downloadArea)) {
+                String url = String.join("/", CADASTRE_URL, id.substring(0, 2), id.substring(0, 5), "edigeo-"+id+".tar.bz2");
+                tasks.add(MainApplication.worker.submit(new InternalDownloadTask(settings, url, progressMonitor)));
+            }
+        } catch (IOException e) {
+            Logging.error(e);
+        }
+        return MainApplication.worker.submit(() -> {
+            for (Future<?> f : tasks) {
+                try {
+                    f.get();
+                } catch (InterruptedException | ExecutionException e) {
+                    Logging.error(e);
+                }
+            }
+        });
     }
 
@@ -40,4 +88,11 @@
     }
 
+    static class CadastreDataLayer extends OsmDataLayer {
+
+        CadastreDataLayer(DataSet data, String name, File associatedFile) {
+            super(data, name, associatedFile);
+        }
+    }
+
     class InternalDownloadTask extends DownloadTask {
 
@@ -45,11 +100,34 @@
 
         InternalDownloadTask(DownloadParams settings, String url, ProgressMonitor progressMonitor) {
-            super(settings, new CadastreServerReader(url), progressMonitor);
+            super(settings, new CadastreServerReader(url, data), progressMonitor);
             this.url = url;
         }
 
         @Override
-        protected OsmDataLayer createNewLayer(String layerName) {
-            return super.createNewLayer(layerName != null ? layerName : url.substring(url.lastIndexOf('/')+1));
+        protected CadastreDataLayer createNewLayer(String layerName) {
+            String realLayerName = layerName != null ? layerName : url.substring(url.lastIndexOf('/')+1);
+            if (realLayerName == null || realLayerName.isEmpty()) {
+                realLayerName = settings.getLayerName();
+            }
+            if (realLayerName == null || realLayerName.isEmpty()) {
+                realLayerName = OsmDataLayer.createNewName();
+            }
+            dataSet.setDownloadPolicy(DownloadPolicy.BLOCKED);
+            dataSet.setUploadPolicy(UploadPolicy.BLOCKED);
+            return new CadastreDataLayer(dataSet, realLayerName, null);
+        }
+
+        private Stream<CadastreDataLayer> getCadastreDataLayers() {
+            return MainApplication.getLayerManager().getLayersOfType(CadastreDataLayer.class).stream();
+        }
+
+        @Override
+        protected long getNumModifiableDataLayers() {
+            return getCadastreDataLayers().count();
+        }
+
+        @Override
+        protected CadastreDataLayer getFirstModifiableDataLayer() {
+            return getCadastreDataLayers().findFirst().orElse(null);
         }
     }
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreServerReader.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreServerReader.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/download/CadastreServerReader.java	(revision 34355)
@@ -3,4 +3,6 @@
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Objects;
 
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -16,11 +18,14 @@
 
     private final String url;
+    private final CadastreDownloadData data;
 
     /**
      * Constructs a new {@code CadastreServerReader}.
      * @param url source URL
+     * @param data defines which data has to be downloaded
      */
-    public CadastreServerReader(String url) {
-        this.url = url;
+    public CadastreServerReader(String url, CadastreDownloadData data) {
+        this.url = Objects.requireNonNull(url);
+        this.data = Objects.requireNonNull(data);
     }
 
@@ -29,5 +34,5 @@
         try {
             progressMonitor.beginTask(tr("Contacting Server...", 10));
-            return new EdigeoPciImporter().parseDataSet(url);
+            return new EdigeoPciImporter().parseDataSet(url, data);
         } catch (Exception e) {
             throw new OsmTransferException(e);
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFile.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFile.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFile.java	(revision 34355)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadData;
 import org.openstreetmap.josm.tools.Logging;
 
@@ -212,5 +213,5 @@
     }
 
-    EdigeoFile fill(DataSet ds) {
+    EdigeoFile fill(DataSet ds, CadastreDownloadData data) {
         // To be overriden if relevant
         return this;
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileTHF.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileTHF.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileTHF.java	(revision 34355)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadData;
 import org.openstreetmap.josm.tools.Logging;
 
@@ -278,6 +279,6 @@
         }
 
-        void fill(DataSet ds) {
-            allFiles.forEach(f -> f.fill(ds));
+        void fill(DataSet ds, CadastreDownloadData data) {
+            allFiles.forEach(f -> f.fill(ds, data));
         }
 
@@ -487,9 +488,9 @@
 
     @Override
-    public EdigeoFileTHF fill(DataSet ds) {
-        super.fill(ds);
+    public EdigeoFileTHF fill(DataSet ds, CadastreDownloadData data) {
+        super.fill(ds, data);
         for (Lot lot : getLots()) {
             //ds.addDataSource(new DataSource(lot.gen.getGeoBounds().getBounds(), support.author));
-            lot.fill(ds);
+            lot.fill(ds, data);
         }
         ds.getWays().forEach(w -> {
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileVEC.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileVEC.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoFileVEC.java	(revision 34355)
@@ -12,4 +12,5 @@
 import java.util.Objects;
 import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
@@ -17,4 +18,5 @@
 
 import org.openstreetmap.josm.actions.CreateMultipolygonAction;
+import org.openstreetmap.josm.command.PurgeCommand;
 import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -29,4 +31,5 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.plugins.fr.cadastre.CadastrePlugin;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadData;
 import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.EdigeoFileSCD.McdAttributeDef;
 import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.EdigeoFileSCD.McdConstructionRelationDef;
@@ -437,5 +440,5 @@
 
     private static final List<Predicate<ObjectBlock>> ignoredObjects = new ArrayList<>();
-    private static final List<Pair<Predicate<ObjectBlock>, BiConsumer<ObjectBlock, OsmPrimitive>>> postProcessors = new ArrayList<>();
+    private static final List<EdigeoPostProcessor> postProcessors = new ArrayList<>();
 
     /**
@@ -482,6 +485,8 @@
      * @param predicate predicate to match
      */
-    public static void addObjectPostProcessor(BiConsumer<ObjectBlock, OsmPrimitive> consumer, Predicate<ObjectBlock> predicate) {
-        postProcessors.add(new Pair<>(Objects.requireNonNull(predicate, "predicate"), Objects.requireNonNull(consumer, "consumer")));
+    public static void addObjectPostProcessor(
+            BiConsumer<ObjectBlock, OsmPrimitive> consumer,
+            Predicate<ObjectBlock> predicate, BiPredicate<CadastreDownloadData, OsmPrimitive> filter) {
+        postProcessors.add(new EdigeoPostProcessor(predicate, filter, consumer));
     }
 
@@ -492,6 +497,8 @@
      * @param values attribute values
      */
-    public static void addObjectPostProcessor(BiConsumer<ObjectBlock, OsmPrimitive> consumer, String key, String... values) {
-        postProcessors.add(new Pair<>(predicate(key, values), Objects.requireNonNull(consumer, "consumer")));
+    public static void addObjectPostProcessor(
+            BiConsumer<ObjectBlock, OsmPrimitive> consumer,
+            BiPredicate<CadastreDownloadData, OsmPrimitive> filter, String key, String... values) {
+        postProcessors.add(new EdigeoPostProcessor(predicate(key, values), filter, consumer));
     }
 
@@ -501,6 +508,6 @@
      * @param keyValues OSM attribute key/values (int the form {@code foo=bar;bar=baz})
      */
-    public static void addObjectPostProcessor(String symId, String keyValues) {
-        postProcessors.add(new Pair<>(predicate("SYM_id", symId), (o, p) -> {
+    public static void addObjectPostProcessor(String symId, BiPredicate<CadastreDownloadData, OsmPrimitive> filter, String keyValues) {
+        postProcessors.add(new EdigeoPostProcessor(predicate("SYM_id", symId), filter, (o, p) -> {
             p.remove("SYM_id");
             for (String tag : keyValues.split(";")) {
@@ -545,7 +552,8 @@
 
     @Override
-    EdigeoFileVEC fill(DataSet ds) {
-        super.fill(ds);
+    EdigeoFileVEC fill(DataSet ds, CadastreDownloadData data) {
+        super.fill(ds, data);
         Projection proj = lot.geo.getCoorReference().getProjection();
+        List<OsmPrimitive> toPurge = new ArrayList<>();
         for (ObjectBlock obj : getObjects()) {
             if (!ignoredObjects.stream().anyMatch(p -> p.test(obj))) {
@@ -559,14 +567,25 @@
                 }
                 if (p != null) {
-                    for (Pair<Predicate<ObjectBlock>, BiConsumer<ObjectBlock, OsmPrimitive>> e : postProcessors) {
-                        if (e.a.test(obj)) {
-                            e.b.accept(obj, p);
+                    boolean purged = false;
+                    for (EdigeoPostProcessor e : postProcessors) {
+                        if (e.predicate.test(obj)) {
+                            if (e.filter.test(data, p)) {
+                                purged = toPurge.add(p);
+                                if (p instanceof Relation) {
+                                    toPurge.addAll(((Relation) p).getMemberPrimitivesList());
+                                }
+                            } else {
+                                e.consumer.accept(obj, p);
+                            }
                         }
                     }
-                    if (p.isTagged()) {
+                    if (!purged && p.isTagged()) {
                         p.put("source", CadastrePlugin.source);
                     }
                 }
             }
+        }
+        if (!toPurge.isEmpty()) {
+            PurgeCommand.build(toPurge, null).executeCommand();
         }
         return this;
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoPostProcessor.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoPostProcessor.java	(revision 34355)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/EdigeoPostProcessor.java	(revision 34355)
@@ -0,0 +1,33 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.fr.cadastre.edigeo;
+
+import java.util.Objects;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadData;
+import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.EdigeoFileVEC.ObjectBlock;
+
+/**
+ * Post-processor mapping Edigeo objects to OSM tagged objects.
+ */
+public class EdigeoPostProcessor {
+
+    final Predicate<ObjectBlock> predicate;
+    final BiPredicate<CadastreDownloadData, OsmPrimitive> filter;
+    final BiConsumer<ObjectBlock, OsmPrimitive> consumer;
+
+    /**
+     * Constructs a new {@code EdigeoPostProcessor}.
+     */
+    public EdigeoPostProcessor(
+            Predicate<ObjectBlock> predicate,
+            BiPredicate<CadastreDownloadData, OsmPrimitive> filter,
+            BiConsumer<ObjectBlock, OsmPrimitive> consumer) {
+        this.predicate = Objects.requireNonNull(predicate);
+        this.filter = Objects.requireNonNull(filter);
+        this.consumer = Objects.requireNonNull(consumer);
+    }
+}
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciImporter.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciImporter.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciImporter.java	(revision 34355)
@@ -9,4 +9,5 @@
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Objects;
 
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
@@ -17,4 +18,5 @@
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadData;
 import org.openstreetmap.josm.tools.Logging;
 
@@ -28,4 +30,5 @@
 
     protected File file;
+    protected CadastreDownloadData data;
 
     /**
@@ -52,5 +55,5 @@
     protected DataSet parseDataSet(InputStream in, ProgressMonitor instance) throws IllegalDataException {
         try {
-            return EdigeoPciReader.parseDataSet(in, file, instance);
+            return EdigeoPciReader.parseDataSet(in, file, data, instance);
         } catch (IOException e) {
             throw new IllegalDataException(e);
@@ -61,11 +64,13 @@
      * Import data from an URL.
      * @param source source URL
+     * @param data defines which data has to be downloaded
      * @return imported data set
      * @throws IOException if any I/O error occurs
      * @throws IllegalDataException if an error was found while parsing the data
      */
-    public DataSet parseDataSet(final String source) throws IOException, IllegalDataException {
+    public DataSet parseDataSet(final String source, CadastreDownloadData data) throws IOException, IllegalDataException {
         try (CachedFile cf = new CachedFile(source)) {
             this.file = cf.getFile();
+            this.data = Objects.requireNonNull(data);
             return parseDataSet(cf.getInputStream(), NullProgressMonitor.INSTANCE);
         }
Index: /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciReader.java
===================================================================
--- /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciReader.java	(revision 34354)
+++ /applications/editors/josm/plugins/cadastre-fr/src/org/openstreetmap/josm/plugins/fr/cadastre/edigeo/pci/EdigeoPciReader.java	(revision 34355)
@@ -14,4 +14,5 @@
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.function.BiPredicate;
 import java.util.function.Predicate;
 
@@ -29,6 +30,8 @@
 import org.openstreetmap.josm.io.AbstractReader;
 import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.plugins.fr.cadastre.download.CadastreDownloadData;
 import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.EdigeoFileTHF;
 import org.openstreetmap.josm.plugins.fr.cadastre.edigeo.EdigeoFileVEC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -37,4 +40,14 @@
  */
 public class EdigeoPciReader extends AbstractReader {
+
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> water = (x, p) -> !x.isDownloadWater();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> build = (x, p) -> !x.isDownloadBuilding();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> symbo = (x, p) -> !x.isDownloadSymbol();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> parce = (x, p) -> !x.isDownloadParcel();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> parcn = (x, p) -> !x.isDownloadParcelNumber();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> addre = (x, p) -> !x.isDownloadAddress();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> local = (x, p) -> !x.isDownloadLocality();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> secti = (x, p) -> !x.isDownloadSection();
+    private static final BiPredicate<CadastreDownloadData, OsmPrimitive> commu = (x, p) -> !x.isDownloadCommune();
 
     private static final Map<String, List<String>> highways = new HashMap<>();
@@ -56,17 +69,18 @@
                 "31", // Connecting arrows between parcelles and numbers
                 "62", // "Sports ground, small streams". What the fuck France?
-                "64"  // "parking, terrace, overhang". What the fuck France?
+                "64", // "parking, terrace, overhang". What the fuck France?
+                "98"  // "various punctual objects". What the fuck France?
         );
 
         // SYM_id mapping
-        EdigeoFileVEC.addObjectPostProcessor("12", "historic=wayside_cross"); // Calvaire
-        EdigeoFileVEC.addObjectPostProcessor("14", "amenity=place_of_worship;religion=christian"); // Church
-        EdigeoFileVEC.addObjectPostProcessor("15", "amenity=place_of_worship;religion=muslim"); // Mosque
-        EdigeoFileVEC.addObjectPostProcessor("16", "amenity=place_of_worship;religion=jewish"); // Synagogue
-        EdigeoFileVEC.addObjectPostProcessor("17", "boundary=administrative;admin_level=2"); // State limit
-        EdigeoFileVEC.addObjectPostProcessor("18", "boundary=administrative;admin_level=6"); // Department limit
-        EdigeoFileVEC.addObjectPostProcessor("19", "boundary=administrative;admin_level=8"); // Municipality limit trigger
-        EdigeoFileVEC.addObjectPostProcessor("21", "highway=road"); // Way
-        EdigeoFileVEC.addObjectPostProcessor("22", "highway=road"); // Road trigger
+        EdigeoFileVEC.addObjectPostProcessor("12", symbo, "historic=wayside_cross"); // Calvaire
+        EdigeoFileVEC.addObjectPostProcessor("14", symbo, "amenity=place_of_worship;religion=christian"); // Church
+        EdigeoFileVEC.addObjectPostProcessor("15", symbo, "amenity=place_of_worship;religion=muslim"); // Mosque
+        EdigeoFileVEC.addObjectPostProcessor("16", symbo, "amenity=place_of_worship;religion=jewish"); // Synagogue
+        EdigeoFileVEC.addObjectPostProcessor("17", commu, "boundary=administrative;admin_level=2"); // State limit
+        EdigeoFileVEC.addObjectPostProcessor("18", commu, "boundary=administrative;admin_level=6"); // Department limit
+        EdigeoFileVEC.addObjectPostProcessor("19", commu, "boundary=administrative;admin_level=8"); // Municipality limit trigger
+        EdigeoFileVEC.addObjectPostProcessor("21", symbo, "highway=road"); // Way
+        EdigeoFileVEC.addObjectPostProcessor("22", symbo, "highway=road"); // Road trigger
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> { // Path / Footway
             String highwayValue = "path";
@@ -81,22 +95,22 @@
             p.put("highway", highwayValue);
             p.remove("SYM_id");
-        }, "SYM_id", "23"); // Path / Footway
-        EdigeoFileVEC.addObjectPostProcessor("24", "man_made=pipeline"); // Pipeline
-        EdigeoFileVEC.addObjectPostProcessor("25", "man_made=pipeline"); // Aqueduct
-        EdigeoFileVEC.addObjectPostProcessor("26", "aerialway=cable_car"); // Aerialway
-        EdigeoFileVEC.addObjectPostProcessor("27", "power=line"); // Force transport line
-        EdigeoFileVEC.addObjectPostProcessor("29", "railway=rail"); // Railway
-        EdigeoFileVEC.addObjectPostProcessor("33", "bridge=yes"); // Bridge
-        EdigeoFileVEC.addObjectPostProcessor("34", "landuse=reservoir;natural=water;water=reservoir"); // reservoir, lake
-        EdigeoFileVEC.addObjectPostProcessor("37", "tunnel=yes"); // Tunnel
-        EdigeoFileVEC.addObjectPostProcessor("47", "railway=halt"); // Halt
-        EdigeoFileVEC.addObjectPostProcessor("48", "railway=stop"); // Stop
-        EdigeoFileVEC.addObjectPostProcessor("49", "railway=station"); // Station
-        EdigeoFileVEC.addObjectPostProcessor("50", "man_made=mast"); // Pylon
-        EdigeoFileVEC.addObjectPostProcessor("51", "landuse=cemetery;religion=christian"); // Christian cemetery
-        EdigeoFileVEC.addObjectPostProcessor("52", "landuse=cemetery;religion=muslim"); // Muslim cemetery
-        EdigeoFileVEC.addObjectPostProcessor("53", "landuse=cemetery;religion=jewish"); // Jewish cemetery
-        EdigeoFileVEC.addObjectPostProcessor("63", "man_made=water_well"); // Well
-        EdigeoFileVEC.addObjectPostProcessor("65", "leisure=swimming_pool;access=private"); // Swimming pool
+        }, symbo, "SYM_id", "23"); // Path / Footway
+        EdigeoFileVEC.addObjectPostProcessor("24", symbo, "man_made=pipeline"); // Pipeline
+        EdigeoFileVEC.addObjectPostProcessor("25", symbo, "man_made=pipeline"); // Aqueduct
+        EdigeoFileVEC.addObjectPostProcessor("26", symbo, "aerialway=cable_car"); // Aerialway
+        EdigeoFileVEC.addObjectPostProcessor("27", symbo, "power=line"); // Force transport line
+        EdigeoFileVEC.addObjectPostProcessor("29", symbo, "railway=rail"); // Railway
+        EdigeoFileVEC.addObjectPostProcessor("33", symbo, "bridge=yes"); // Bridge
+        EdigeoFileVEC.addObjectPostProcessor("34", water, "landuse=reservoir;natural=water;water=reservoir"); // reservoir, lake
+        EdigeoFileVEC.addObjectPostProcessor("37", symbo, "tunnel=yes"); // Tunnel
+        EdigeoFileVEC.addObjectPostProcessor("47", symbo, "railway=halt"); // Halt
+        EdigeoFileVEC.addObjectPostProcessor("48", symbo, "railway=stop"); // Stop
+        EdigeoFileVEC.addObjectPostProcessor("49", symbo, "railway=station"); // Station
+        EdigeoFileVEC.addObjectPostProcessor("50", symbo, "man_made=mast"); // Pylon
+        EdigeoFileVEC.addObjectPostProcessor("51", symbo, "landuse=cemetery;religion=christian"); // Christian cemetery
+        EdigeoFileVEC.addObjectPostProcessor("52", symbo, "landuse=cemetery;religion=muslim"); // Muslim cemetery
+        EdigeoFileVEC.addObjectPostProcessor("53", symbo, "landuse=cemetery;religion=jewish"); // Jewish cemetery
+        EdigeoFileVEC.addObjectPostProcessor("63", symbo, "man_made=water_well"); // Well
+        EdigeoFileVEC.addObjectPostProcessor("65", water, "leisure=swimming_pool;access=private"); // Swimming pool
 
         // Mapping TEX*_id => name (first step)
@@ -113,5 +127,5 @@
             }
             setName(p, sb.toString());
-        }, "TEX_id");
+        }, (x, p) -> false, "TEX_id");
 
         // Objects mapping
@@ -131,5 +145,5 @@
                 }
             }
-        }, o -> o.hasScdIdentifier("ZONCOMMUNI_id"));
+        }, o -> o.hasScdIdentifier("ZONCOMMUNI_id"), symbo);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
@@ -140,5 +154,5 @@
             p.remove("IDU_id");
             p.remove("TEX2_id");
-        }, o -> o.hasScdIdentifier("COMMUNE_id"));
+        }, o -> o.hasScdIdentifier("COMMUNE_id"), commu);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
@@ -158,34 +172,34 @@
             p.remove("SUPF_id");
         }, o -> o.hasScdIdentifier("SECTION_id") || o.hasScdIdentifier("SUBDSECT_id")
-             || o.hasScdIdentifier("PARCELLE_id") || o.hasScdIdentifier("SUBDFISC_id") || o.hasScdIdentifier("CHARGE_id"));
-
-        EdigeoFileVEC.addObjectPostProcessor((o, p) -> p.put("wall", "no"), "DUR_id", "02");
+             || o.hasScdIdentifier("PARCELLE_id") || o.hasScdIdentifier("SUBDFISC_id") || o.hasScdIdentifier("CHARGE_id"), parce);
+
+        EdigeoFileVEC.addObjectPostProcessor((o, p) -> p.put("wall", "no"), build, "DUR_id", "02");
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
             p.put("building", "yes");
             p.remove("DUR_id");
-        }, o -> o.hasScdIdentifier("BATIMENT_id"));
+        }, o -> o.hasScdIdentifier("BATIMENT_id"), build);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
             p.put("addr:housenumber", p.get("name"));
             p.remove("name");
-        }, o -> o.hasScdIdentifier("NUMVOIE_id"));
+        }, o -> o.hasScdIdentifier("NUMVOIE_id"), addre);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
             p.put("place", "unknown");
             p.put("fixme", "place type");
-        }, o -> o.hasScdIdentifier("LIEUDIT_id"));
+        }, o -> o.hasScdIdentifier("LIEUDIT_id"), local);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
             p.remove("ORI_id");
-        }, o -> o.hasScdIdentifier("TPOINT_id"));
+        }, o -> o.hasScdIdentifier("TPOINT_id"), (x, p) -> false);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
             p.put("highway", "road");
             p.put("area", "yes");
-        }, o -> o.hasScdIdentifier("TRONROUTE_id"));
+        }, o -> o.hasScdIdentifier("TRONROUTE_id"), symbo);
 
         EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
             p.put("waterway", "riverbank");
-        }, o -> o.hasScdIdentifier("TRONFLUV_id"));
+        }, o -> o.hasScdIdentifier("TRONFLUV_id"), water);
 
         // Mapping TEX*_id => name (last step)
@@ -194,6 +208,30 @@
                 setName(p, p.get(t));
                 p.remove(t);
-            }, t);
-        }
+            }, (x, p) -> false, t);
+        }
+
+        // Allow to filter parcel numbers
+        EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
+            // Do nothing
+        }, o -> true, (x, p) -> {
+            try {
+                return !x.isDownloadParcelNumber() && p.getNumKeys() == 1 && p.hasKey("name") && Integer.parseInt(p.get("name")) > -1;
+            } catch (NumberFormatException e) {
+                Logging.trace(e);
+                return false;
+            }
+        });
+
+        // Allow to filter labels
+        EdigeoFileVEC.addObjectPostProcessor((o, p) -> {
+            // Do nothing
+        }, o -> true, (x, p) -> {
+            try {
+                return !x.isDownloadSymbol() && p.getNumKeys() == 1 && p.hasKey("name") && Integer.parseInt(p.get("name")) <= -1;
+            } catch (NumberFormatException e) {
+                Logging.trace(e);
+                return true;
+            }
+        });
     }
 
@@ -228,10 +266,10 @@
     }
 
-    static DataSet parseDataSet(InputStream in, File file, ProgressMonitor instance) throws IOException {
+    static DataSet parseDataSet(InputStream in, File file, CadastreDownloadData data, ProgressMonitor instance) throws IOException {
         if (in != null) {
             in.close();
         }
         try {
-            return new EdigeoPciReader().parse(file.toPath(), instance);
+            return new EdigeoPciReader().parse(file.toPath(), data, instance);
         } catch (IOException e) {
             throw e;
@@ -241,5 +279,5 @@
     }
 
-    DataSet parse(Path path, ProgressMonitor instance) throws IOException, ReflectiveOperationException {
+    DataSet parse(Path path, CadastreDownloadData data, ProgressMonitor instance) throws IOException, ReflectiveOperationException {
         Path tmpDir = null;
         Path thfPath = path;
@@ -265,9 +303,9 @@
                 }
             }
-            DataSet data = new DataSet();
-            data.setUploadPolicy(UploadPolicy.DISCOURAGED);
-            EdigeoFileTHF thf = new EdigeoFileTHF(thfPath).read().fill(data);
-            data.setName(thf.getSupport().getBlockIdentifier());
-            return data;
+            DataSet ds = new DataSet();
+            ds.setUploadPolicy(UploadPolicy.BLOCKED);
+            EdigeoFileTHF thf = new EdigeoFileTHF(thfPath).read().fill(ds, data);
+            ds.setName(thf.getSupport().getBlockIdentifier());
+            return ds;
         } finally {
             if (tmpDir != null) {
