/// <summary>
        /// Resolves reference paths by searching for referenced items using the specified SearchPaths.
        /// </summary>
        /// <returns>True on success, or throws an exception on failure.</returns>
        public override bool Execute()
        {
            List <ITaskItem> resolvedReferences = new List <ITaskItem>();

            foreach (ITaskItem reference in this.WixReferences)
            {
                ITaskItem resolvedReference = ResolveWixReferences.ResolveReference(reference, this.SearchPaths, this.SearchFilenameExtensions, this.Log);

                this.Log.LogMessage(MessageImportance.Low, "Resolved path {0}", resolvedReference.ItemSpec);
                resolvedReferences.Add(resolvedReference);
            }

            this.ResolvedWixReferences = resolvedReferences.ToArray();
            return(true);
        }
        /// <summary>
        /// Resolves a single reference item by searcheing for referenced items using the specified SearchPaths.
        /// This method is made public so the resolution logic can be reused by other tasks.
        /// </summary>
        /// <param name="reference">The referenced item.</param>
        /// <param name="searchPaths">The paths to search.</param>
        /// <param name="searchFilenameExtensions">Filename extensions to check.</param>
        /// <param name="log">Logging helper.</param>
        /// <returns>The resolved reference item, or the original reference if it could not be resolved.</returns>
        public static ITaskItem ResolveReference(ITaskItem reference, string[] searchPaths, string[] searchFilenameExtensions, TaskLoggingHelper log)
        {
            if (reference == null)
            {
                throw new ArgumentNullException("reference");
            }

            if (searchPaths == null)
            {
                // Nothing to search, so just return the original reference item.
                return(reference);
            }

            if (searchFilenameExtensions == null)
            {
                searchFilenameExtensions = new string[] { };
            }

            // Copy all the metadata from the source
            TaskItem resolvedReference = new TaskItem(reference);

            log.LogMessage(MessageImportance.Low, "WixReference: {0}", reference.ItemSpec);

            // Now find the resolved path based on our order of precedence
            foreach (string searchPath in searchPaths)
            {
                log.LogMessage(MessageImportance.Low, "Trying {0}", searchPath);
                if (searchPath.Equals(HintPathToken, StringComparison.Ordinal))
                {
                    string path = reference.GetMetadata("HintPath");
                    log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
                    if (File.Exists(path))
                    {
                        resolvedReference.ItemSpec = path;
                        break;
                    }
                }
                else if (searchPath.Equals(RawFileNameToken, StringComparison.Ordinal))
                {
                    log.LogMessage(MessageImportance.Low, "Trying path {0}", resolvedReference.ItemSpec);
                    if (File.Exists(resolvedReference.ItemSpec))
                    {
                        break;
                    }

                    if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference,
                                                                       resolvedReference.ItemSpec, searchFilenameExtensions, log))
                    {
                        break;
                    }
                }
                else
                {
                    string path = Path.Combine(searchPath, Path.GetFileName(reference.ItemSpec));
                    log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
                    if (File.Exists(path))
                    {
                        resolvedReference.ItemSpec = path;
                        break;
                    }

                    if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference,
                                                                       path, searchFilenameExtensions, log))
                    {
                        break;
                    }
                }
            }

            // Normalize the item path
            resolvedReference.ItemSpec = resolvedReference.GetMetadata("FullPath");

            return(resolvedReference);
        }