/// <summary>
        /// Determines whether a folder exists having a specific version
        /// </summary>
        /// <param name="name">The name of the component</param>
        /// <param name="version">The name of the component (branch folder)</param>
        /// <returns>true if the branch folder exists at the version; false otherwise</returns>
        public bool ComponentExists(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);
            ValidateComponentVersion(version);

            try
            {
                if (ProviderSubversion.Instance.ItemExists(name.ToString(), version.ToString()))
                {
                    foreach (var dependencyDefinitionFileName in ValidDependencyDefinitionFileNames)
                    {
                        var dependencyDefinitionFile = string.Format("{0}/{1}", name.ToString(), dependencyDefinitionFileName);
                        if (ProviderSubversion.Instance.ItemExists(dependencyDefinitionFile, version.ToString()))
                        {
                            Logger.Instance().Log(TraceLevel.Info, "{0}: Component {1}#{2} was found on Subversion", ResolverType, name, version);
                            return(true);
                        }
                    }
                }
            }
            catch (SvnAuthenticationException)
            {
                Logger.Instance().Log(TraceLevel.Error, "{0}: Unable to connect to repository {1}, because authentication failed. Please login once at your your Subversion client to store the credentials locally.", ResolverType, name);
                throw new InvalidProviderConfigurationException(string.Format("Could not connect to Subversion {0}, because Authentication failed.", name));
            }

            Logger.Instance().Log(TraceLevel.Warning, "{0}: Component {1}#{2} was not found on Subversion", ResolverType, name, version);
            return(false);
        }
        /// <summary>
        /// Determines whether a version control folder exists having a specific version
        /// </summary>
        /// <param name="name">The name of the component</param>
        /// <param name="version">The name of the component (branch folder)</param>
        /// <returns>true if the branch folder exists at the version; false otherwise</returns>
        public bool ComponentExists(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);
            ValidateComponentVersion(version);

            // Check if folder exists in source control
            if (!VersionControlServer.ServerItemExists(name.ToString(), version.TfsVersionSpec, DeletedState.NonDeleted, ItemType.Folder))
            {
                Logger.Instance().Log(TraceLevel.Warning, "{0}: Component {1}#{2} was not found in source control", ResolverType, name, version);
                return(false);
            }

            // Check if component.targets exists inside folder
            var folderItems = VersionControlServer.GetItems(VersionControlPath.Combine(name.ToString(), "*"), version.TfsVersionSpec, RecursionType.OneLevel);

            foreach (Item item in folderItems.Items)
            {
                var itemName = VersionControlPath.GetFileName(item.ServerItem);

                foreach (var dependencyDefinitionFileName in ValidDependencyDefinitionFileNames)
                {
                    if (string.Equals(itemName, dependencyDefinitionFileName, StringComparison.OrdinalIgnoreCase))
                    {
                        Logger.Instance().Log(TraceLevel.Info, "{0}: Component {1}#{2} was found in source control", ResolverType, name, version);
                        return(true);
                    }
                }
            }

            Logger.Instance().Log(TraceLevel.Warning, "{0}: Component {1}#{2} was not found in source control", ResolverType, name, version);
            return(false);
        }
        /// <summary>
        /// Loads a specific dependency definition file.
        /// </summary>
        /// <param name="name">The source control folder path for the component.</param>
        /// <param name="version">The component version.</param>
        /// <returns>The loaded dependency definition xml file</returns>
        public XDocument LoadComponentTarget(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);
            ValidateComponentVersion(version);

            foreach (var dependencyDefinitionFileName in ValidDependencyDefinitionFileNames)
            {
                var dependencyDefinitionFileLocation = VersionControlPath.Combine(name.ToString(), dependencyDefinitionFileName);
                if (!VersionControlServer.ServerItemExists(dependencyDefinitionFileLocation, version.TfsVersionSpec, DeletedState.Any, ItemType.File))
                {
                    Logger.Instance().Log(TraceLevel.Verbose, "{0}: Dependency definition file {1} for component {2}#{3} was not found", ResolverType, dependencyDefinitionFileLocation, name, version);
                    continue;
                }

                var item = VersionControlServer.GetItem(dependencyDefinitionFileLocation, version.TfsVersionSpec, DeletedState.Any, true);
                using (var content = item.DownloadFile())
                {
                    var xdoc = XDocument.Load(content);
                    Logger.Instance().Log(TraceLevel.Info, "{0}: Loading dependency definition file {1} for component {2}#{3} finished successfully", ResolverType, dependencyDefinitionFileLocation, name, version);
                    return(xdoc);
                }
            }

            return(null);
        }
        /// <summary>
        /// Validates the component name.
        /// </summary>
        /// <param name="name">The component name.</param>
        private static void ValidateComponentName(IComponentName name)
        {
            if (name == null)
            {
                Logger.Instance().Log(TraceLevel.Error, "Source control component was null");
                throw new ArgumentNullException("name", "Source control component was null");
            }

            if (string.IsNullOrEmpty(name.ToString()))
            {
                Logger.Instance().Log(TraceLevel.Error, "Source control path for binary repository component {0} was empty", name);
                throw new ArgumentException(string.Format("Source control path for binary repository component {0} was empty", name), "name");
            }
        }
        /// <summary>
        /// Validates the component name and check path for wildcards.
        /// </summary>
        /// <param name="name">The component name.</param>
        private static void ValidateComponentName(IComponentName name)
        {
            if (name == null)
            {
                Logger.Instance().Log(TraceLevel.Error, "Build result component name was null");
                throw new ArgumentNullException("name", "Build result component name was null");
            }

            if (string.IsNullOrEmpty(name.ToString()))
            {
                Logger.Instance().Log(TraceLevel.Error, "Team project and/or build definition for component {0} was empty", name);
                throw new ArgumentException(string.Format("Team project and/or build definition for component {0} was empty", name), "name");
            }
        }
        /// <summary>
        /// Validates the component name and check path for wildcards.
        /// </summary>
        /// <param name="name">The component name.</param>
        private static void ValidateComponentName(IComponentName name)
        {
            if (name == null)
            {
                Logger.Instance().Log(TraceLevel.Error, "File share component name was null");
                throw new ArgumentNullException("name", "File share component name was null");
            }

            if (string.IsNullOrEmpty(name.ToString()))
            {
                Logger.Instance().Log(TraceLevel.Error, "File share path for component {0} was empty", name);
                throw new ArgumentException(string.Format("File share path for component {0} was empty", name), "name");
            }
        }
        /// <summary>
        /// Determines whether a version control folder exists having a specific version
        /// </summary>
        /// <param name="name">The name of the component</param>
        /// <param name="version">The version for the component</param>
        /// <returns>True if a version folder exists at the version; false otherwise</returns>
        public bool ComponentExists(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);
            ValidateComponentVersion(version);

            if (VersionControlServer.ServerItemExists(VersionControlPath.Combine(PathPrefix, name.ToString()), VersionSpec.Latest, DeletedState.NonDeleted, ItemType.Folder))
            {
                var path = VersionControlPath.Combine(VersionControlPath.Combine(PathPrefix, name.ToString()), version.ToString());

                if (VersionControlServer.ServerItemExists(path, VersionSpec.Latest, DeletedState.NonDeleted, ItemType.Folder))
                {
                    // Check if component.targets exists inside folder
                    var folderItems = VersionControlServer.GetItems(VersionControlPath.Combine(path, "*"));
                    foreach (var item in folderItems.Items)
                    {
                        var itemName = VersionControlPath.GetFileName(item.ServerItem);

                        foreach (var dependencyDefinitionFileName in ValidDependencyDefinitionFileNames)
                        {
                            if (string.Equals(itemName, dependencyDefinitionFileName, StringComparison.OrdinalIgnoreCase))
                            {
                                Logger.Instance().Log(TraceLevel.Info, "{0}: Component {1}#{2} was found in binary repository", ResolverType, name, version);
                                return(true);
                            }

                            Logger.Instance().Log(TraceLevel.Verbose, "{0}: Dependency definition file {1} for component {2}#{3} was not found in binary repository", ResolverType, dependencyDefinitionFileName, name, version);
                        }
                    }
                }
            }

            Logger.Instance().Log(TraceLevel.Warning, "{0}: Component {1}#{2} was not found in binary repository", ResolverType, name, version);
            return(false);
        }
        /// <summary>
        /// Loads a specific dependency definition file.
        /// </summary>
        /// <param name="name">The name of the binary repository component.</param>
        /// <param name="version">The component version.</param>
        /// <returns>The loaded dependency definition xml file</returns>
        public XDocument LoadComponentTarget(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);
            ValidateComponentVersion(version);

            foreach (var dependencyDefinitionFileName in ValidDependencyDefinitionFileNames)
            {
                var dependencyDefinitionFileLocation = VersionControlPath.Combine(VersionControlPath.Combine(VersionControlPath.Combine(PathPrefix, name.ToString()), version.ToString()), dependencyDefinitionFileName);

                if (!VersionControlServer.ServerItemExists(dependencyDefinitionFileLocation, ItemType.File))
                {
                    Logger.Instance().Log(TraceLevel.Verbose, "{0}: Dependency definition file {1} for component {2}#{3} was not found", ResolverType, dependencyDefinitionFileLocation, name, version);
                    continue;
                }

                var dependencyDefinitionFileStream = VersionControlServer.GetItem(dependencyDefinitionFileLocation, VersionSpec.Latest).DownloadFile();
                var xdoc = XDocument.Load(dependencyDefinitionFileStream);

                // Close the previously opened filestream to ensure a cleanup
                dependencyDefinitionFileStream.Close();

                Logger.Instance().Log(TraceLevel.Info, "{0}: Loading dependency definition file {1} for component {2}#{3} finished successfully", ResolverType, dependencyDefinitionFileLocation, name, version);
                return(xdoc);
            }

            return(null);
        }
        /// <summary>
        /// Returns all versions for a component found in the repository.
        /// </summary>
        /// <param name="name">The component name.</param>
        /// <returns>The list of versions</returns>
        public IEnumerable <IComponentVersion> GetAvailableVersions(IComponentName name)
        {
            ValidateComponentName(name);

            Logger.Instance().Log(TraceLevel.Info, "{0}: Querying available component versions...", ResolverType);

            var availableVersions = new List <IComponentVersion>();

            if (VersionControlServer.ServerItemExists(VersionControlPath.Combine(PathPrefix, name.ToString()), VersionSpec.Latest, DeletedState.NonDeleted, ItemType.Folder))
            {
                var versionItems = VersionControlServer.GetItems(VersionControlPath.Combine(VersionControlPath.Combine(PathPrefix, name.ToString()), "*"));

                foreach (var version in versionItems.Items)
                {
                    if (version.ItemType.Equals(ItemType.Folder))
                    {
                        // Check if component.targets exists inside folder
                        var folderItems = VersionControlServer.GetItems(VersionControlPath.Combine(VersionControlPath.Combine(VersionControlPath.Combine(PathPrefix, name.ToString()), VersionControlPath.GetFileName(version.ServerItem)), "*"));
                        var dependencyDefinitionFileFound = false;

                        foreach (var item in folderItems.Items)
                        {
                            var itemName = VersionControlPath.GetFileName(item.ServerItem);

                            foreach (var dependencyDefinitionFileName in ValidDependencyDefinitionFileNames)
                            {
                                if (string.Equals(itemName, dependencyDefinitionFileName, StringComparison.OrdinalIgnoreCase))
                                {
                                    Logger.Instance().Log(TraceLevel.Info, "{0}: Found version {1}", ResolverType, VersionControlPath.GetFileName(version.ServerItem));
                                    availableVersions.Add(new ComponentVersion(VersionControlPath.GetFileName(version.ServerItem)));
                                    dependencyDefinitionFileFound = true;
                                }
                            }
                        }

                        if (!dependencyDefinitionFileFound)
                        {
                            Logger.Instance().Log(TraceLevel.Warning, "{0}: Skipping version {1} (Dependency definition file is not present)", ResolverType, VersionControlPath.GetFileName(version.ServerItem));
                        }
                    }
                }
            }
            else
            {
                Logger.Instance().Log(TraceLevel.Error, "{0}: Directory {1} for component {2} does not exist", ResolverType, VersionControlPath.Combine(PathPrefix, name.ToString()), name);
                throw new InvalidComponentException(string.Format("Could not find component {0} in binary repository", name));
            }

            Logger.Instance().Log(TraceLevel.Info, "{0}: Querying component versions finished successfully", ResolverType);

            return(availableVersions);
        }
        /// <summary>
        /// Determines whether a component exists having a specific version
        /// </summary>
        /// <param name="name">The name of the component</param>
        /// <param name="version">The specific version of the component</param>
        /// <returns>True if the component exists at the version; false otherwise</returns>
        public bool ComponentExists(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);
            ValidateComponentVersion(version);

            var componentVersionPath = Path.Combine(ResolverSettings.GetSetting(ResolverValidSettings.FileShareUrl), name.ToString(), version.ToString());

            if (Directory.Exists(componentVersionPath))
            {
                // ReSharper disable LoopCanBeConvertedToQuery
                foreach (var dependencyDefinitionFileName in _validDependencyDefinitionFileNames)
                // ReSharper restore LoopCanBeConvertedToQuery
                {
                    var dependencyDefinitionFile = Path.Combine(componentVersionPath, dependencyDefinitionFileName);
                    if (File.Exists(dependencyDefinitionFile))
                    {
                        Logger.Instance().Log(TraceLevel.Info, "{0}: Component {1}#{2} was found on file share", ResolverType, name, version);
                        return(true);
                    }
                }
            }

            Logger.Instance().Log(TraceLevel.Warning, "{0}: Component {1}#{2} was not found on file share", ResolverType, name, version);
            return(false);
        }
        /// <summary>
        /// Determines whether a component exists
        /// </summary>
        /// <param name="name">The name of the component</param>
        /// <returns>true if the component exists; false if not</returns>
        public bool ComponentExists(IComponentName name)
        {
            ValidateComponentName(name);

            if (Directory.Exists(Path.Combine(ResolverSettings.GetSetting(ResolverValidSettings.FileShareUrl), name.ToString())))
            {
                Logger.Instance().Log(TraceLevel.Info, "{0}: Component folder for component {1} was found on file share", ResolverType, name);
                return(true);
            }

            Logger.Instance().Log(TraceLevel.Warning, "{0}: Component folder for component {1} was not found on file share", ResolverType, name);
            return(false);
        }
        /// <summary>
        /// Loads a specific dependency definition file.
        /// </summary>
        /// <param name="name">The name of the component</param>
        /// <param name="version">The exact version of the component</param>
        /// <returns>The loaded dependency definition xml file</returns>
        public XDocument LoadComponentTarget(IComponentName name, IComponentVersion version)
        {
            ValidateComponentName(name);

            foreach (var dependencyDefinitionFileName in _validDependencyDefinitionFileNames)
            {
                var dependencyDefinitionFileLocation = Path.Combine(ResolverSettings.GetSetting(ResolverValidSettings.FileShareUrl), name.ToString(), version.ToString(), dependencyDefinitionFileName);
                if (!File.Exists(dependencyDefinitionFileLocation))
                {
                    Logger.Instance().Log(TraceLevel.Verbose, "{0}: Dependency definition file {1} for component {2}#{3} was not found", ResolverType, dependencyDefinitionFileLocation, name, version);
                    continue;
                }

                var xdoc = XDocument.Load(dependencyDefinitionFileLocation);

                Logger.Instance().Log(TraceLevel.Info, "{0}: Loading dependency definition file {1} for component {2}#{3} finished successfully", ResolverType, dependencyDefinitionFileLocation, name, version);
                return(xdoc);
            }

            return(null);
        }