diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java
index 67cc8d4a33e9b78fb576ee1711ed54239fa305f3..f8e6cc25413f583f08c8e6b246badf532cda5805 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java
@@ -79,7 +79,7 @@ import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronize
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.translator.PrefixBasedNameTranslator;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.DSPropertyUtils;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.Monitor;
-import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.V3Utils;
+import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.V3Facade;
 import ch.systemsx.cisd.common.concurrent.ParallelizedExecutor;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.common.logging.Log4jSimpleLogger;
@@ -515,12 +515,10 @@ public class EntitySynchronizer
         AttachmentSynchronizationSummary synchronizationSummary = new AttachmentSynchronizationSummary();
 
         ParallelizedExecutionPreferences preferences = config.getParallelizedExecutionPrefs();
-        String asUrl = config.getDataSourceOpenbisURL();
-        String dssUrl = config.getDataSourceDSSURL();
-        V3Utils v3Utils = V3Utils.create(asUrl, dssUrl);
+        V3Facade v3FacadeToDataSource = new V3Facade(config);
         monitor.log("Services for accessing data source established");
         ParallelizedExecutor.process(attachmentHoldersToProcess, new AttachmentSynchronizationTaskExecutor(synchronizationSummary,
-                service, v3Utils,
+                service, v3FacadeToDataSource,
                 lastSyncTimestamp, config, monitor),
                 preferences.getMachineLoad(), preferences.getMaxThreads(), "process attachments", preferences.getRetriesOnFail(),
                 preferences.isStopOnFailure());
@@ -1396,15 +1394,11 @@ public class EntitySynchronizer
             throws NoSuchAlgorithmException, UnsupportedEncodingException
     {
         // get the file nodes in the incoming DS by querying the data source openbis
-        String asUrl = config.getDataSourceOpenbisURL();
-        String dssUrl = config.getDataSourceDSSURL();
-
-        V3Utils dssFileUtils = V3Utils.create(asUrl, dssUrl);
-        String sessionToken = dssFileUtils.login(config.getUser(), config.getPassword());
+        V3Facade v3FacadeToDataSource = new V3Facade(config);
 
         DataSetFileSearchCriteria criteria = new DataSetFileSearchCriteria();
         criteria.withDataSet().withCode().thatEquals(dataSetCode);
-        SearchResult<DataSetFile> result = dssFileUtils.searchFiles(sessionToken, criteria, new DataSetFileFetchOptions());
+        SearchResult<DataSetFile> result = v3FacadeToDataSource.searchFiles(criteria, new DataSetFileFetchOptions());
 
         // get the file nodes in the harvester openbis
         IDataStoreServerApi dssharvester = (IDataStoreServerApi) ServiceProvider.getDssServiceV3().getService();
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/AttachmentSynchronizationTaskExecutor.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/AttachmentSynchronizationTaskExecutor.java
index 55cdf7128520f3e1516872f2e00b74d5e2b1555e..59734e5108bb8a03cb4146c1d36862732cb0442e 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/AttachmentSynchronizationTaskExecutor.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/AttachmentSynchronizationTaskExecutor.java
@@ -34,7 +34,7 @@ import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.common.SyncEntityKind
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.config.SyncConfig;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.IncomingEntity;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.Monitor;
-import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.V3Utils;
+import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.V3Facade;
 import ch.systemsx.cisd.cifex.shared.basic.UserFailureException;
 import ch.systemsx.cisd.common.concurrent.ITaskExecutor;
 import ch.systemsx.cisd.common.exceptions.Status;
@@ -51,8 +51,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory;
 
 /**
- * 
- *
  * @author Ganime Betul Akin
  */
 public final class AttachmentSynchronizationTaskExecutor implements ITaskExecutor<IncomingEntity<?>>
@@ -65,28 +63,34 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
 
     private AttachmentSynchronizationSummary syncSummary;
 
-    private V3Utils v3Utils;
+    private V3Facade v3FacadeToDataSource;
 
     private final Monitor monitor;
 
+    private ICommonServer commonServer;
+
+    private String localSessionToken;
+
     /**
      * @param executionSummary will contain ids of attachment holders for which the attachment sync failed during parallel execution + counts of
      *            added, updated and deleted attachments
      * @param service
      * @param lastSyncTimestamp
      * @param config
-     * @param monitor 
+     * @param monitor
      */
     public AttachmentSynchronizationTaskExecutor(AttachmentSynchronizationSummary executionSummary,
-            IEncapsulatedOpenBISService service, V3Utils v3Utils,
+            IEncapsulatedOpenBISService service, V3Facade v3FacadeToDataSource,
             Date lastSyncTimestamp, SyncConfig config, Monitor monitor)
     {
         this.syncSummary = executionSummary;
         this.service = service;
-        this.v3Utils = v3Utils;
+        this.v3FacadeToDataSource = v3FacadeToDataSource;
         this.lastSyncTimestamp = lastSyncTimestamp;
         this.config = config;
         this.monitor = monitor;
+        commonServer = ServiceFinderUtils.getCommonServer(ServiceProvider.getConfigProvider().getOpenBisServerUrl());
+        localSessionToken = ServiceFinderUtils.login(commonServer, config.getHarvesterUser(), config.getHarvesterPass());
     }
 
     @Override
@@ -95,28 +99,23 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
         try
         {
             TechId techId = null;
-            ICommonServer commonServer = ServiceFinderUtils.getCommonServer(ServiceProvider.getConfigProvider().getOpenBisServerUrl());
-            String localSessionToken = ServiceFinderUtils.login(commonServer, config.getHarvesterUser(), config.getHarvesterPass());
-            IAttachmentsOperationsHandler attachmentsOperationsHandler = null;
+            AbstractEntityAttachmentsOperationsHandler attachmentsOperationsHandler = null;
             if (item.getEntityKind() == SyncEntityKind.EXPERIMENT)
             {
                 Experiment experiment = service.tryGetExperiment(ExperimentIdentifierFactory.parse(item.getEntity().getIdentifier()));
                 techId = new TechId(experiment.getId());
-                attachmentsOperationsHandler = new ExperimentAttachmentsOperationsHandler(config, commonServer, v3Utils, localSessionToken);
-            }
-            else if (item.getEntityKind() == SyncEntityKind.SAMPLE)
+                attachmentsOperationsHandler = new ExperimentAttachmentsOperationsHandler(config, commonServer, v3FacadeToDataSource, localSessionToken);
+            } else if (item.getEntityKind() == SyncEntityKind.SAMPLE)
             {
                 Sample sample = service.tryGetSampleByPermId(item.getEntity().getPermID());
                 techId = new TechId(sample.getId());
-                attachmentsOperationsHandler = new SampleAttachmentsOperationsHandler(config, commonServer, v3Utils, localSessionToken);
-            }
-            else if (item.getEntityKind() == SyncEntityKind.PROJECT)
+                attachmentsOperationsHandler = new SampleAttachmentsOperationsHandler(config, commonServer, v3FacadeToDataSource, localSessionToken);
+            } else if (item.getEntityKind() == SyncEntityKind.PROJECT)
             {
                 Project project = service.tryGetProject(ProjectIdentifierFactory.parse(item.getEntity().getIdentifier()));
                 techId = new TechId(project.getId());
-                attachmentsOperationsHandler = new ProjectAttachmentsOperationsHandler(config, commonServer, v3Utils, localSessionToken);
-            }
-            else
+                attachmentsOperationsHandler = new ProjectAttachmentsOperationsHandler(config, commonServer, v3FacadeToDataSource, localSessionToken);
+            } else
             {
                 return Status.createError("Attachments can be synchronized for only Projects, Experiments and Samples");
             }
@@ -126,7 +125,7 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
             // that do not have attachments.
             if (item.hasAttachments() == true)
             {
-                incomingAttachments = attachmentsOperationsHandler.listDataSourceAttachments(config, item.getPermID());
+                incomingAttachments = attachmentsOperationsHandler.listDataSourceAttachments(item.getPermID());
 
                 // place the incoming attachments in a map
                 for (Attachment incoming : incomingAttachments)
@@ -153,8 +152,7 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
                 {
                     addAttachments(incoming, 1, techId, attachmentsOperationsHandler);
                     syncSummary.addedCount.getAndIncrement();
-                }
-                else
+                } else
                 {
                     int version = existingAttachment.getVersion();
                     if (incoming.getVersion() < version)
@@ -162,16 +160,14 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
                         // Harvester has a later version of the attachment. Delete it from harvester
                         replaceAttachment(techId, incoming, attachmentsOperationsHandler);
                         syncSummary.updatedCount.getAndIncrement();
-                    }
-                    else if (incoming.getVersion() == version)
+                    } else if (incoming.getVersion() == version)
                     {
                         // check last sync date and meta data
                         if (incoming.getRegistrationDate().after(lastSyncTimestamp))
                         {
                             replaceAttachment(techId, incoming, attachmentsOperationsHandler);
                             syncSummary.updatedCount.getAndIncrement();
-                        }
-                        else
+                        } else
                         {
                             // check if meta data changed
                             if (equalsNullable(incoming.getTitle(), existingAttachment.getTitle()) == false
@@ -187,8 +183,7 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
                                 syncSummary.updatedCount.getAndIncrement();
                             }
                         }
-                    }
-                    else
+                    } else
                     {
                         // add all new versions from the incoming (do we need to check last sync date)
                         // Attachment attachmentVersion = getVersion(incoming, version);
@@ -206,8 +201,7 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
                     syncSummary.deletedCount.getAndIncrement();
                 }
             }
-        }
- catch (Exception e)
+        } catch (Exception e)
         {
             try
             {
@@ -240,13 +234,13 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
         }
     }
 
-    private void replaceAttachment(TechId techId, Attachment incoming, IAttachmentsOperationsHandler attachmentsOperationsHandler)
+    private void replaceAttachment(TechId techId, Attachment incoming, AbstractEntityAttachmentsOperationsHandler attachmentsOperationsHandler)
     {
         attachmentsOperationsHandler.deleteAttachment(techId, incoming.getFileName());
         addAttachments(incoming, 1, techId, attachmentsOperationsHandler);
     }
 
-    private void addAttachments(Attachment attachment, int fromVersion, TechId techId, IAttachmentsOperationsHandler handler)
+    private void addAttachments(Attachment attachment, int fromVersion, TechId techId, AbstractEntityAttachmentsOperationsHandler handler)
     {
 
         Integer version = attachment.getVersion();
@@ -272,182 +266,159 @@ public final class AttachmentSynchronizationTaskExecutor implements ITaskExecuto
             earliestVersion = versions.pollLast();
         }
     }
-}
-
-interface IAttachmentsOperationsHandler
-{
-    List<Attachment> listDataSourceAttachments(SyncConfig config, String permId);
-    
-    List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId);
-    
-    void addAttachment(TechId techId, NewAttachment attachment);
-
-    void deleteAttachment(TechId experimentId, String fileName);
 
-    void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment);
-}
-
-abstract class AbstractEntityAttachmentsOperationsHandler implements IAttachmentsOperationsHandler
-{
-    final ICommonServer commonServer;
+    private abstract static class AbstractEntityAttachmentsOperationsHandler
+    {
+        final ICommonServer commonServer;
 
-    final String sessionToken;
+        final String sessionToken;
 
-    final SyncConfig config;
+        final SyncConfig config;
 
-    protected V3Utils v3Utils;
+        protected V3Facade v3FacadeToDataSource;
 
-    AbstractEntityAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Utils v3Utils, String sessionToken)
-    {
-        this.commonServer = commonServer;
-        this.v3Utils = v3Utils;
-        this.sessionToken = sessionToken;
-        this.config = config;
-    }
+        AbstractEntityAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Facade v3FacadeToDataSource, String sessionToken)
+        {
+            this.commonServer = commonServer;
+            this.v3FacadeToDataSource = v3FacadeToDataSource;
+            this.sessionToken = sessionToken;
+            this.config = config;
+        }
 
-    @Override
-    public abstract List<Attachment> listDataSourceAttachments(SyncConfig config, String permId);
+        public abstract List<Attachment> listDataSourceAttachments(String permId);
 
-    @Override
-    public abstract List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId);
+        public abstract List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId);
 
-    @Override
-    public abstract void addAttachment(TechId techId, NewAttachment attachment);
+        public abstract void addAttachment(TechId techId, NewAttachment attachment);
 
-    @Override
-    public abstract void deleteAttachment(TechId experimentId, String fileName);
-    
-    @Override
-    public abstract void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment);
-}
+        public abstract void deleteAttachment(TechId experimentId, String fileName);
 
-class ExperimentAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler
-{
-    ExperimentAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Utils v3Utils, String sessionToken)
-    {
-        super(config, commonServer, v3Utils, sessionToken);
+        public abstract void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment);
     }
 
-    @Override
-    public List<Attachment> listDataSourceAttachments(SyncConfig config, String permId)
+    private static class ExperimentAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler
     {
-        V3Utils v3Utils = V3Utils.create(config.getDataSourceOpenbisURL(), config.getDataSourceDSSURL());
-        String sessionToken = v3Utils.login(config.getUser(), config.getPassword());
-        return v3Utils.getExperimentAttachments(sessionToken, new ExperimentPermId(permId));
-    }
+        ExperimentAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Facade v3FacadeToDataSource, String sessionToken)
+        {
+            super(config, commonServer, v3FacadeToDataSource, sessionToken);
+        }
 
-    @Override
-    public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId)
-    {
-        IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService();
-        Experiment experiment = service.tryGetExperimentByPermId(permId);
-        return service.listAttachments(AttachmentHolderKind.EXPERIMENT, experiment.getId());
-    }
+        @Override
+        public List<Attachment> listDataSourceAttachments(String permId)
+        {
+            return v3FacadeToDataSource.getExperimentAttachments(new ExperimentPermId(permId));
+        }
 
-    @Override
-    public void addAttachment(TechId techId, NewAttachment attachment)
-    {
-        commonServer.addExperimentAttachment(sessionToken, techId, attachment);
-    }
+        @Override
+        public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId)
+        {
+            IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService();
+            Experiment experiment = service.tryGetExperimentByPermId(permId);
+            return service.listAttachments(AttachmentHolderKind.EXPERIMENT, experiment.getId());
+        }
 
-    @Override
-    public void deleteAttachment(TechId experimentId, String fileName)
-    {
-        commonServer.deleteExperimentAttachments(sessionToken, experimentId, Arrays.asList(fileName),
-                "Synchronization from data source " + config.getDataSourceAlias()
-                        + " Attachment no longer exists on data source.");
-    }
+        @Override
+        public void addAttachment(TechId techId, NewAttachment attachment)
+        {
+            commonServer.addExperimentAttachment(sessionToken, techId, attachment);
+        }
 
-    @Override
-    public void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment)
-    {
-        commonServer.updateExperimentAttachments(sessionToken, experimentId, attachment);
-    }
-}
+        @Override
+        public void deleteAttachment(TechId experimentId, String fileName)
+        {
+            commonServer.deleteExperimentAttachments(sessionToken, experimentId, Arrays.asList(fileName),
+                    "Synchronization from data source " + config.getDataSourceAlias()
+                            + " Attachment no longer exists on data source.");
+        }
 
-class SampleAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler
-{
-    SampleAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Utils v3Utils, String sessionToken)
-    {
-        super(config, commonServer, v3Utils, sessionToken);
+        @Override
+        public void updateAttachment(TechId experimentId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment)
+        {
+            commonServer.updateExperimentAttachments(sessionToken, experimentId, attachment);
+        }
     }
 
-    @Override
-    public List<Attachment> listDataSourceAttachments(SyncConfig config, String permId)
+    private static class SampleAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler
     {
-        V3Utils dssFileUtils = V3Utils.create(config.getDataSourceOpenbisURL(), config.getDataSourceDSSURL());
-        String sessionToken = dssFileUtils.login(config.getUser(), config.getPassword());
-        return dssFileUtils.getSampleAttachments(sessionToken, new SamplePermId(permId));
-    }
+        SampleAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Facade v3FacadeToDataSource, String sessionToken)
+        {
+            super(config, commonServer, v3FacadeToDataSource, sessionToken);
+        }
 
-    @Override
-    public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId)
-    {
-        IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService();
-        Sample sample = service.tryGetSampleByPermId(permId);
-        return service.listAttachments(AttachmentHolderKind.SAMPLE, sample.getId());
-    }
+        @Override
+        public List<Attachment> listDataSourceAttachments(String permId)
+        {
+            return v3FacadeToDataSource.getSampleAttachments(new SamplePermId(permId));
+        }
 
-    @Override
-    public void addAttachment(TechId techId, NewAttachment attachment)
-    {
-        commonServer.addSampleAttachments(sessionToken, techId, attachment);
-    }
+        @Override
+        public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId)
+        {
+            IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService();
+            Sample sample = service.tryGetSampleByPermId(permId);
+            return service.listAttachments(AttachmentHolderKind.SAMPLE, sample.getId());
+        }
 
-    @Override
-    public void deleteAttachment(TechId sampleId, String fileName)
-    {
-        commonServer.deleteSampleAttachments(sessionToken, sampleId, Arrays.asList(fileName),
-                "Synchronization from data source " + config.getDataSourceAlias()
-                        + " Attachment no longer exists on data source.");
-    }
+        @Override
+        public void addAttachment(TechId techId, NewAttachment attachment)
+        {
+            commonServer.addSampleAttachments(sessionToken, techId, attachment);
+        }
 
-    @Override
-    public void updateAttachment(TechId sampleId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment)
-    {
-        commonServer.updateSampleAttachments(sessionToken, sampleId, attachment);
-    }
-}
+        @Override
+        public void deleteAttachment(TechId sampleId, String fileName)
+        {
+            commonServer.deleteSampleAttachments(sessionToken, sampleId, Arrays.asList(fileName),
+                    "Synchronization from data source " + config.getDataSourceAlias()
+                            + " Attachment no longer exists on data source.");
+        }
 
-class ProjectAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler
-{
-    ProjectAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Utils v3Utils, String sessionToken)
-    {
-        super(config, commonServer, v3Utils, sessionToken);
+        @Override
+        public void updateAttachment(TechId sampleId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment)
+        {
+            commonServer.updateSampleAttachments(sessionToken, sampleId, attachment);
+        }
     }
 
-    @Override
-    public List<Attachment> listDataSourceAttachments(SyncConfig config, String permId)
+    private static class ProjectAttachmentsOperationsHandler extends AbstractEntityAttachmentsOperationsHandler
     {
-        String sessionToken = v3Utils.login(config.getUser(), config.getPassword());
-        return v3Utils.getProjectAttachments(sessionToken, new ProjectPermId(permId));
-    }
+        ProjectAttachmentsOperationsHandler(SyncConfig config, ICommonServer commonServer, V3Facade v3FacadeToDataSource, String sessionToken)
+        {
+            super(config, commonServer, v3FacadeToDataSource, sessionToken);
+        }
 
-    @Override
-    public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId)
-    {
-        IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService();
-        Project project = service.tryGetProjectByPermId(permId);
-        return service.listAttachments(AttachmentHolderKind.PROJECT, project.getId());
-    }
+        @Override
+        public List<Attachment> listDataSourceAttachments(String permId)
+        {
+            return v3FacadeToDataSource.getProjectAttachments(new ProjectPermId(permId));
+        }
 
-    @Override
-    public void addAttachment(TechId techId, NewAttachment attachment)
-    {
-        commonServer.addProjectAttachments(sessionToken, techId, attachment);
-    }
+        @Override
+        public List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment> listHarvesterAttachments(String permId)
+        {
+            IEncapsulatedOpenBISService service = ServiceProvider.getOpenBISService();
+            Project project = service.tryGetProjectByPermId(permId);
+            return service.listAttachments(AttachmentHolderKind.PROJECT, project.getId());
+        }
 
-    @Override
-    public void deleteAttachment(TechId projectId, String fileName)
-    {
-        commonServer.deleteProjectAttachments(sessionToken, projectId, Arrays.asList(fileName),
-                "Synchronization from data source " + config.getDataSourceAlias()
-                        + " Attachment no longer exists on data source.");
-    }
+        @Override
+        public void addAttachment(TechId techId, NewAttachment attachment)
+        {
+            commonServer.addProjectAttachments(sessionToken, techId, attachment);
+        }
 
-    @Override
-    public void updateAttachment(TechId projectId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment)
-    {
-        commonServer.updateProjectAttachments(sessionToken, projectId, attachment);
+        @Override
+        public void deleteAttachment(TechId projectId, String fileName)
+        {
+            commonServer.deleteProjectAttachments(sessionToken, projectId, Arrays.asList(fileName),
+                    "Synchronization from data source " + config.getDataSourceAlias()
+                            + " Attachment no longer exists on data source.");
+        }
+
+        @Override
+        public void updateAttachment(TechId projectId, ch.systemsx.cisd.openbis.generic.shared.basic.dto.Attachment attachment)
+        {
+            commonServer.updateProjectAttachments(sessionToken, projectId, attachment);
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationIngestionService.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationIngestionService.java
index 40ad671c47f0aa7a2f5f6cd24bfdb77274f4c2d8..29515354a830c2f3ed06bd1eb8e2078befbb2f79 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationIngestionService.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationIngestionService.java
@@ -39,8 +39,9 @@ import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.download.DataSetFil
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.fetchoptions.DataSetFileFetchOptions;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.id.DataSetFilePermId;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.id.IDataSetFileId;
+import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.config.SyncConfig;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.DSPropertyUtils;
-import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.V3Utils;
+import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer.util.V3Facade;
 import ch.systemsx.cisd.common.io.IOUtilities;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
@@ -71,22 +72,19 @@ class DataSetRegistrationIngestionService extends IngestionService<DataSetInform
 
     private final String loginPass;
 
-    private final String asUrl;
-
-    private final String dssUrl;
-
     private final String harvesterTempDir;
 
-    public DataSetRegistrationIngestionService(Properties properties, File storeRoot, NewExternalData ds,
+    private SyncConfig config;
+
+    public DataSetRegistrationIngestionService(SyncConfig config, File storeRoot, NewExternalData ds,
             Logger operationLog)
     {
-        super(properties, storeRoot);
+        super(new Properties(), storeRoot);
+        this.config = config;
         this.dataSet = ds;
-        this.loginUser = properties.getProperty("user");
-        this.loginPass = properties.getProperty("pass");
-        this.asUrl = properties.getProperty("as-url");
-        this.dssUrl = properties.getProperty("dss-url");
-        this.harvesterTempDir = properties.getProperty("harvester-temp-dir");
+        this.loginUser = config.getUser();
+        this.loginPass = config.getPassword();
+        this.harvesterTempDir = config.getHarvesterTempDir();
     }
 
     @Override
@@ -206,10 +204,9 @@ class DataSetRegistrationIngestionService extends IngestionService<DataSetInform
 
     private void downloadDataSetFiles(File dir, String dataSetCode) throws Exception
     {
-        V3Utils dssFileUtils = V3Utils.create(asUrl, dssUrl);
-        String sessionToken = dssFileUtils.login(loginUser, loginPass);
+        V3Facade v3FacadeToDataSource = new V3Facade(config);
         DataSetFileFetchOptions dsFileFetchOptions = new DataSetFileFetchOptions();
-        SearchResult<DataSetFile> result = dssFileUtils.searchWithDataSetCode(sessionToken, dataSetCode, dsFileFetchOptions);
+        SearchResult<DataSetFile> result = v3FacadeToDataSource.searchWithDataSetCode(dataSetCode, dsFileFetchOptions);
         List<DataSetFile> files = result.getObjects();
 
         List<IDataSetFileId> fileIds = new LinkedList<IDataSetFileId>();
@@ -222,7 +219,7 @@ class DataSetRegistrationIngestionService extends IngestionService<DataSetInform
         // Download the files & print the contents
         DataSetFileDownloadOptions options = new DataSetFileDownloadOptions();
         options.setRecursive(false);
-        InputStream stream = dssFileUtils.downloadFiles(sessionToken, fileIds, options);
+        InputStream stream = v3FacadeToDataSource.downloadFiles(fileIds, options);
         DataSetFileDownloadReader reader = new DataSetFileDownloadReader(stream);
         DataSetFileDownload fileDownload = null;
         while ((fileDownload = reader.read()) != null)
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationTaskExecutor.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationTaskExecutor.java
index 7aa6f51faf02e68475435b965cb7482c529abff3..5393786a1a7df1ba942a0c390a32f916de0c969e 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationTaskExecutor.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/parallelizedExecutor/DataSetRegistrationTaskExecutor.java
@@ -60,10 +60,8 @@ public final class DataSetRegistrationTaskExecutor implements ITaskExecutor<Inco
     @Override
     public Status execute(IncomingDataSet dataSet)
     {
-        Properties props = setProperties();
-
         DataSetRegistrationIngestionService ingestionService =
-                new DataSetRegistrationIngestionService(props, storeRoot, dataSet.getDataSet(), operationLog);
+                new DataSetRegistrationIngestionService(config, storeRoot, dataSet.getDataSet(), operationLog);
         TableModel resultTable = ingestionService.createAggregationReport(new HashMap<String, Object>(), context);
         if (resultTable != null)
         {
@@ -91,15 +89,4 @@ public final class DataSetRegistrationTaskExecutor implements ITaskExecutor<Inco
         return Status.OK;
     }
 
-    private Properties setProperties()
-    {
-        Properties props = new Properties();
-        props.setProperty("user", config.getUser());
-        props.setProperty("pass", config.getPassword());
-        props.setProperty("as-url", config.getDataSourceOpenbisURL());
-        props.setProperty("dss-url", config.getDataSourceDSSURL());
-        props.setProperty("harvester-temp-dir", config.getHarvesterTempDir());
-        props.setProperty("do-not-create-original-dir", "true");
-        return props;
-    }
 }
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/util/V3Utils.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/util/V3Facade.java
similarity index 80%
rename from datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/util/V3Utils.java
rename to datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/util/V3Facade.java
index 3c5529972ebf9e40b38b159cc73785fc9ae2f938..6c5738b3b101caaa81df3e581d408b47a6f8d57f 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/util/V3Utils.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/util/V3Facade.java
@@ -41,6 +41,7 @@ import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.download.DataSetFil
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.fetchoptions.DataSetFileFetchOptions;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.id.IDataSetFileId;
 import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.search.DataSetFileSearchCriteria;
+import ch.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.config.SyncConfig;
 import ch.systemsx.cisd.openbis.dss.generic.server.EncapsulatedOpenBISService;
 
 /**
@@ -48,38 +49,40 @@ import ch.systemsx.cisd.openbis.dss.generic.server.EncapsulatedOpenBISService;
  *
  * @author Ganime Betul Akin
  */
-public class V3Utils
+public class V3Facade
 {
     public static final long TIMEOUT = 6 * DateUtils.MILLIS_PER_HOUR;
 
     private final IDataStoreServerApi dss;
+    
     private final IApplicationServerApi as;
 
-    public static V3Utils create(String asUrl, String dssUrl)
-    {
-        return new V3Utils(asUrl, dssUrl, TIMEOUT);
-    }
+    private final String sessionToken;
 
-    private V3Utils (String asUrl, String dssUrl, long timeout)
+    public V3Facade(SyncConfig config)
     {
+        String asUrl = config.getDataSourceOpenbisURL();
+        String dssUrl = config.getDataSourceDSSURL();
+        long timeout = TIMEOUT;
         String timeoutInMinutes = Long.toString(timeout / DateUtils.MILLIS_PER_MINUTE);
-        this.as = EncapsulatedOpenBISService.createOpenBisV3Service(asUrl, timeoutInMinutes);
-        this.dss = EncapsulatedOpenBISService.createDataStoreV3Service(dssUrl, timeoutInMinutes);
+        as = EncapsulatedOpenBISService.createOpenBisV3Service(asUrl, timeoutInMinutes);
+        dss = EncapsulatedOpenBISService.createDataStoreV3Service(dssUrl, timeoutInMinutes);
+        sessionToken = as.login(config.getUser(), config.getPassword());
      }
 
-    public SearchResult<DataSetFile> searchFiles(String sessionToken, DataSetFileSearchCriteria criteria, DataSetFileFetchOptions dsFileFetchOptions)
+    public SearchResult<DataSetFile> searchFiles(DataSetFileSearchCriteria criteria, DataSetFileFetchOptions dsFileFetchOptions)
     {
         return dss.searchFiles(sessionToken, criteria, dsFileFetchOptions);
     }
 
-    public SearchResult<DataSetFile> searchWithDataSetCode(String sessionToken, String dataSetCode, DataSetFileFetchOptions dsFileFetchOptions)
+    public SearchResult<DataSetFile> searchWithDataSetCode(String dataSetCode, DataSetFileFetchOptions dsFileFetchOptions)
     {
         DataSetFileSearchCriteria criteria = new DataSetFileSearchCriteria();
         criteria.withDataSet().withCode().thatEquals(dataSetCode);
-        return searchFiles(sessionToken, criteria, dsFileFetchOptions);
+        return searchFiles(criteria, dsFileFetchOptions);
     }
 
-    public List<Attachment> getExperimentAttachments(String sessionToken, IExperimentId experimentId)
+    public List<Attachment> getExperimentAttachments(IExperimentId experimentId)
     {
         ExperimentFetchOptions fetchOptions = new ExperimentFetchOptions();
         fetchOptions.withAttachments().withContent();
@@ -93,7 +96,7 @@ public class V3Utils
         return null;
     }
 
-    public List<Attachment> getSampleAttachments(String sessionToken, ISampleId sampleId)
+    public List<Attachment> getSampleAttachments(ISampleId sampleId)
     {
         SampleFetchOptions fetchOptions = new SampleFetchOptions();
         fetchOptions.withAttachments().withContent();
@@ -108,7 +111,7 @@ public class V3Utils
         return null;
     }
 
-    public List<Attachment> getProjectAttachments(String sessionToken, IProjectId projectId)
+    public List<Attachment> getProjectAttachments(IProjectId projectId)
     {
         ProjectFetchOptions fetchOptions = new ProjectFetchOptions();
         fetchOptions.withAttachments().withContent();
@@ -123,13 +126,9 @@ public class V3Utils
         return null;
     }
 
-    public InputStream downloadFiles(String sessionToken, List<IDataSetFileId> fileIds, DataSetFileDownloadOptions options)
+    public InputStream downloadFiles(List<IDataSetFileId> fileIds, DataSetFileDownloadOptions options)
     {
         return dss.downloadFiles(sessionToken, fileIds, options);
     }
 
-    public String login(String loginUser, String loginPass)
-    {
-        return as.login(loginUser, loginPass);
-    }
 }