/// <summary>
 /// Finds a project name by short name, unique name or custom unique name.
 /// </summary>
 /// <param name="name">name of the project</param>
 /// <param name="EnvDTEProjectName">project name instance</param>
 /// <returns>true if the project name with the specified name is found.</returns>
 public bool TryGetNuGetProjectName(string name, out EnvDTEProjectName EnvDTEProjectName)
 {
     return _projectNamesCache.TryGetValue(name, out EnvDTEProjectName) ||
            TryGetProjectNameByShortName(name, out EnvDTEProjectName);
 }
 /// <summary>
 /// Removes a project from the project name dictionary.
 /// </summary>
 private void RemoveProjectName(EnvDTEProjectName envDTEProjectName)
 {
     _projectNamesCache.Remove(envDTEProjectName.CustomUniqueName);
     _projectNamesCache.Remove(envDTEProjectName.UniqueName);
     _projectNamesCache.Remove(envDTEProjectName.FullName);
     _envDTEProjectCache.Remove(envDTEProjectName);
     _nuGetProjectCache.Remove(envDTEProjectName);
 }
        /// <summary>
        /// Removes a project from the short name cache.
        /// </summary>
        /// <param name="envDTEProjectName">The short name of the project.</param>
        private void RemoveShortName(EnvDTEProjectName envDTEProjectName)
        {
            HashSet<EnvDTEProjectName> projectNames;
            if (_shortNameCache.TryGetValue(envDTEProjectName.ShortName, out projectNames))
            {
                projectNames.Remove(envDTEProjectName);

                // Remove the item from the dictionary if we've removed the last project
                if (projectNames.Count == 0)
                {
                    _shortNameCache.Remove(envDTEProjectName.ShortName);
                }
            }
        }
        /// <summary>
        /// Adds an entry to the short name cache returning any conflicting project name.
        /// </summary>
        /// <returns>The first conflicting short name.</returns>
        private void AddShortName(EnvDTEProjectName EnvDTEProjectName)
        {
            HashSet<EnvDTEProjectName> projectNames;
            if (!_shortNameCache.TryGetValue(EnvDTEProjectName.ShortName, out projectNames))
            {
                projectNames = new HashSet<EnvDTEProjectName>();
                _shortNameCache.Add(EnvDTEProjectName.ShortName, projectNames);
            }

            projectNames.Add(EnvDTEProjectName);
        }
        /// <summary>
        /// Tries to find a project by short name. Returns the project name if and only if it is non-ambiguous.
        /// </summary>
        public bool TryGetProjectNameByShortName(string name, out EnvDTEProjectName EnvDTEProjectName)
        {
            EnvDTEProjectName = null;

            HashSet<EnvDTEProjectName> projectNames;
            if (_shortNameCache.TryGetValue(name, out projectNames))
            {
                // Get the item at the front of the queue
                EnvDTEProjectName = projectNames.Count == 1 ? projectNames.Single() : null;

                // Only return true if the short name is unambiguous
                return EnvDTEProjectName != null;
            }

            return false;
        }
        /// <summary>
        /// Add a project to the cache.
        /// </summary>
        /// <param name="project">project to add to the cache.</param>
        /// <returns>The project name of the added project.</returns>
        public EnvDTEProjectName AddProject(EnvDTEProject project, VSNuGetProjectFactory factory)
        {
            // First create a project name from the project
            var EnvDTEProjectName = new EnvDTEProjectName(project);

            // Do nothing if we already have an entry
            if (_envDTEProjectCache.ContainsKey(EnvDTEProjectName))
            {
                return EnvDTEProjectName;
            }

            AddShortName(EnvDTEProjectName);

            _projectNamesCache[EnvDTEProjectName.CustomUniqueName] = EnvDTEProjectName;
            _projectNamesCache[EnvDTEProjectName.UniqueName] = EnvDTEProjectName;
            _projectNamesCache[EnvDTEProjectName.FullName] = EnvDTEProjectName;

            // Add the entry mapping project name to the actual project
            _envDTEProjectCache[EnvDTEProjectName] = project;
            _nuGetProjectCache[EnvDTEProjectName] = factory.CreateNuGetProject(project);

            return EnvDTEProjectName;
        }