/// <summary>
        /// Cleans up the successors in the dependency graph.
        /// </summary>
        /// <param name="graph">Node to start with</param>
        internal void Clean(IGraph graph)
        {
            if (!_silentMode)
            {
                _logger.LogMsg("Cleaning all components...");
            }
            Logger.Instance().Log(TraceLevel.Info, "{0}: Cleaning components ...", CommandType);

            var dwSvc = new DownloadWatermarkService(graph.RootComponentTargetPath);

            //TODO: Use parallel foreach to gain cleanup speed. might infere with logging and therefore we are currently using single threaded only
            var cachedComponents = dwSvc.GetStoredDependencyWatermarks();

            foreach (var cacheComponent in cachedComponents)
            {
                // Properties of cachedComponent: Item1 = name, cachedComponent Item2 = version
                RevertComponent(dwSvc, cacheComponent.Item1, cacheComponent.Item2);
            }

            // Finish documents
            if (!_silentMode)
            {
                _logger.LogMsg("Cleaned components successfully!\n");
            }

            Logger.Instance().Log(TraceLevel.Info, "{0}: Cleaning components finished successfully", CommandType);
        }
        /// <summary>
        /// Downloads the successors in the dependency graph.
        /// </summary>
        /// <param name="graph">Node to start with</param>
        /// <param name="recursive">Indicates if the dependencies should be fetched recursively or not.</param>
        /// <param name="force">Indicates that we want to force a get operation and all files have to be overwritten</param>
        internal void Download(IGraph graph, bool recursive, bool force)
        {
            if (graph.RootComponent == null)
            {
                throw new DependencyServiceException("! Dependency graph does have an invalid root node!");
            }

            if (!_silentMode)
            {
                _logger.LogMsg("Downloading components...");
            }

            Logger.Instance().Log(TraceLevel.Info, "{0}: {1} downloading components {2} ...", CommandType, recursive ? "Recursively " : "Non-recursively ", force ? "(Forced Get mode) ..." : "(Normal mode)");

            // Retrieve watermark service for currently called dependency definition (root component)
            var wms = new DownloadWatermarkService(graph.RootComponentTargetPath);

            // Clean previously downloaded components that are not part of the list anymore (removed or version changed)
            var previousWatermarks   = wms.GetStoredDependencyWatermarks();
            var currentComponentList = graph.GetFlattenedGraph(false, recursive);

            // Copy currentComponentList into new Tuple<string, string> list
            var localComponentsToKeep = currentComponentList.Select(component => new Tuple <string, string>(component.Name.GetName(), component.Version.GetVersion())).ToList();
            var cleaner = new Cleaner(_logger, false);

            foreach (var previousWatermark in previousWatermarks)
            {
                if (!wms.IsComponentInList(localComponentsToKeep, previousWatermark))
                {
                    // Revert component which is not used anymore
                    cleaner.RevertComponent(wms, previousWatermark.Item1, previousWatermark.Item2);
                }
            }

            // Download current components
            foreach (var component in currentComponentList)
            {
                DownloadComponent(wms, component, recursive, force);
            }

            #region # Output detected problematic dependencies
            if (graph.SideBySideDependencies.Count() > 0 || graph.CircularDependencies.Count() > 0)
            {
                if (!_silentMode)
                {
                    _logger.LogMsg("- The following dependency anomalies have been detected:");
                }
                else
                {
                    Debug.WriteLine("- The following dependency anomalies have been detected:");
                }

                if (graph.SideBySideDependencies.Count() > 0)
                {
                    if (!_silentMode)
                    {
                        _logger.LogMsg("  x Side-by-side dependency warning:");
                    }

                    Logger.Instance().Log(TraceLevel.Info, "{0}: Side-by-side dependencies detected:", CommandType);

                    foreach (var validationError in graph.SideBySideDependencies)
                    {
                        if (!_silentMode)
                        {
                            _logger.LogMsg("   * " + validationError.Message);
                        }

                        Logger.Instance().Log(TraceLevel.Info, "{0}: {1}", CommandType, validationError.Message);
                    }
                }
                if (graph.CircularDependencies.Count() > 0)
                {
                    if (!_silentMode)
                    {
                        _logger.LogMsg("  x Circular dependency warning:");
                    }

                    Logger.Instance().Log(TraceLevel.Info, "{0}: Circular dependencies detected:", CommandType);

                    foreach (var validationError in graph.CircularDependencies)
                    {
                        if (!_silentMode)
                        {
                            _logger.LogMsg("   * " + validationError.Message);
                        }

                        Logger.Instance().Log(TraceLevel.Info, "{0}: {1}", CommandType, validationError.Message);
                    }
                }
            }
            #endregion

            // Finish documents
            if (!_silentMode)
            {
                _logger.LogMsg("Downloaded components successfully!\n");
            }
            Logger.Instance().Log(TraceLevel.Info, "{0}: Downloaded components successfully!", CommandType);
        }