/// <summary>
        /// Starts an existing custom C# activity locally and enables local debugging. You need to set a breakpoint in your custom component's code.
        /// </summary>
        /// <param name="pipelineName">The name of the pipeline which contains the custom C# activity</param>
        /// <param name="activityName">The name of the activity which you want to debug</param>
        /// <param name="sliceStart">SliceStart which is used when the activity is executed</param>
        /// <param name="sliceEnd">SliceStart which is used when the activity is executed</param>
        /// <param name="activityLogger">Allows you to specify a custom Activity Logger to do your logging. Default is a Console Logger.</param>
        /// <returns></returns>
        public IDictionary <string, string> ExecuteActivity(string pipelineName, string activityName, DateTime sliceStart, DateTime sliceEnd, IActivityLogger activityLogger)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Debugging Custom Activity '{0}' from Pipeline '{1}' ...", activityName, pipelineName);
            Console.WriteLine("The Code from the last build of the ADF project will be used ({0}). Make sure to rebuild the ADF project if it does not reflect your latest changes!", _buildPath);

            Dictionary <string, string> ret = null;
            string dependencyPath           = Path.Combine(Environment.CurrentDirectory, "CustomActivityDependencies_TEMP");

            if (Directory.Exists(dependencyPath))
            {
                try
                {
                    // it might happen that two activities are executed in the same run and the directory is blocked
                    // so we need to catch the exception and continue with our execution
                    // the folder might not be cleaned up properly in this case but during the execution of the first activity it will
                    Directory.Delete(dependencyPath, true);
                }
                catch (UnauthorizedAccessException e) { }
            }

            if (!Pipelines.ContainsKey(pipelineName))
            {
                throw new KeyNotFoundException(string.Format("A pipeline with the name \"{0}\" was not found. Please check the spelling and make sure it was loaded correctly in the ADF Local Environment and see the console output", pipelineName));
            }
            // don not apply Configuration again for GetADFObjectFromJson as this would overwrite changes done by MapSlices!!!
            Pipeline pipeline = (Pipeline)GetADFObjectFromJson(MapSlices(_armFiles.Single(x => x.Value["name"].ToString() == Pipelines[pipelineName].Name).Value, sliceStart, sliceEnd), "Pipeline", false);

            Activity activityMeta = pipeline.GetActivityByName(activityName);

            // create a list of all Input- and Output-Datasets defined for the Activity
            List <Dataset> activityInputDatasets  = _adfDataSets.Values.Where(adfDS => activityMeta.Inputs.Any(ds => adfDS.Name == ds.Name)).ToList();
            List <Dataset> activityOutputDatasets = _adfDataSets.Values.Where(adfDS => activityMeta.Outputs.Any(ds => adfDS.Name == ds.Name)).ToList();
            List <Dataset> activityAllDatasets    = activityInputDatasets.Concat(activityOutputDatasets).ToList();

            List <LinkedService> activityLinkedServices = new List <LinkedService>();

            // apply the Slice-Settings to all relevant objects (Datasets and Activity)
            for (int i = 0; i < activityAllDatasets.Count; i++)
            {
                // MapSlices for the used Datasets
                activityAllDatasets[i] = (Dataset)GetADFObjectFromJson(MapSlices(_armFiles[activityAllDatasets[i].Name + ".json"], sliceStart, sliceEnd), "Dataset", false);

                // currently, as of 2017-01-25, the same LinkedService might get added multiple times if it is referenced by multiple datasets
                // this is the same behavior as if the activity was executed with ADF Service!!!
                activityLinkedServices.Add(_adfLinkedServices.Values.Single(x => x.Name == activityAllDatasets[i].Properties.LinkedServiceName));
            }

            DotNetActivity dotNetActivityMeta = (DotNetActivity)activityMeta.TypeProperties;

            Console.WriteLine("The Custom Activity refers to the following ZIP-file: '{0}'", dotNetActivityMeta.PackageFile);
            FileInfo zipFile = _adfDependencies.Single(x => dotNetActivityMeta.PackageFile.EndsWith(x.Value.Name)).Value;

            Console.WriteLine("Using '{0}' from ZIP-file '{1}'!", dotNetActivityMeta.AssemblyName, zipFile.FullName);
            UnzipFile(zipFile, dependencyPath);

            Assembly        assembly = Assembly.LoadFrom(dependencyPath + "\\" + dotNetActivityMeta.AssemblyName);
            Type            type     = assembly.GetType(dotNetActivityMeta.EntryPoint);
            IDotNetActivity dotNetActivityExecute = Activator.CreateInstance(type) as IDotNetActivity;

            Console.WriteLine("Executing Function '{0}'...{1}--------------------------------------------------------------------------", dotNetActivityMeta.EntryPoint, Environment.NewLine);
            Console.ForegroundColor = ConsoleColor.Gray;

            ret = (Dictionary <string, string>)dotNetActivityExecute.Execute(activityLinkedServices, activityAllDatasets, activityMeta, activityLogger);

            if (Directory.Exists(dependencyPath))
            {
                try
                {
                    // This might fail as the DLL is still loaded in the current Application Domain
                    Directory.Delete(dependencyPath, true);
                }
                catch (UnauthorizedAccessException e) { }
            }

            return(ret);
        }