/// <summary>
        /// Task entry point.
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {
            if (!VerifyAndInitializeInputs())
            {
                return false;
            }

            if (!ComputePathToAxImp() || !ComputePathToTlbImp())
            {
                // unable to compute the path to tlbimp.exe, aximp.exe, or both and that is necessary to 
                // continue forward, so return now.
                return false;
            }

            allProjectRefs = new List<ComReferenceInfo>();
            allDependencyRefs = new List<ComReferenceInfo>();

            _timestampCache = (ResolveComReferenceCache)StateFileBase.DeserializeCache(StateFile, Log, typeof(ResolveComReferenceCache));

            if (_timestampCache == null || (_timestampCache != null && !_timestampCache.ToolPathsMatchCachePaths(_tlbimpPath, _aximpPath)))
            {
                if (!Silent)
                {
                    Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.NotUsingCacheFile", StateFile == null ? String.Empty : StateFile);
                }

                _timestampCache = new ResolveComReferenceCache(_tlbimpPath, _aximpPath);
            }
            else if (!Silent)
            {
                Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.UsingCacheFile", StateFile == null ? String.Empty : StateFile);
            }

            try
            {
                ConvertAttrReferencesToComReferenceInfo(allProjectRefs, TypeLibNames);
                ConvertFileReferencesToComReferenceInfo(allProjectRefs, TypeLibFiles);

                // add missing tlbimp references for aximp ones
                AddMissingTlbReferences();

                // see if we have any typelib name clashes. Ignore the return value - we now remove the conflicting refs
                // and continue (first one wins)
                CheckForConflictingReferences();

                SetFrameworkVersionFromString(_projectTargetFrameworkAsString);

                // Process each task item. If one of them fails we still process the rest of them, but
                // remember that the task should return failure.
                // DESIGN CHANGE: we no longer fail the task when one or more references fail to resolve. 
                // Unless we experience a catastrophic failure, we'll log warnings for those refs and proceed
                // (and return success)
                ArrayList moduleList = new ArrayList();
                ArrayList resolvedReferenceList = new ArrayList();

                ComDependencyWalker dependencyWalker = new ComDependencyWalker(Marshal.ReleaseComObject);
                bool allReferencesResolvedSuccessfully = true;
                for (int pass = 0; pass < 4; pass++)
                {
                    foreach (ComReferenceInfo projectRefInfo in allProjectRefs)
                    {
                        string wrapperType = projectRefInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool);

                        // first resolve all PIA refs, then regular tlb refs and finally ActiveX refs
                        if ((pass == 0 && ComReferenceTypes.IsPia(wrapperType)) ||
                            (pass == 1 && ComReferenceTypes.IsTlbImp(wrapperType)) ||
                            (pass == 2 && ComReferenceTypes.IsPiaOrTlbImp(wrapperType)) ||
                            (pass == 3 && ComReferenceTypes.IsAxImp(wrapperType)))
                        {
                            try
                            {
                                if (!this.ResolveReferenceAndAddToList(dependencyWalker, projectRefInfo, resolvedReferenceList, moduleList))
                                {
                                    allReferencesResolvedSuccessfully = false;
                                }
                            }
                            catch (ComReferenceResolutionException)
                            {
                                // problem resolving this reference? continue so that we can display all error messages
                            }
                            catch (StrongNameException)
                            {
                                // key extraction problem? No point in continuing, since all wrappers will hit the same problem.
                                // error message has already been logged
                                return false;
                            }
                            catch (FileLoadException ex)
                            {
                                // This exception is thrown when we try to load a delay signed assembly without disabling
                                // strong name verification first. So print a nice information if we're generating 
                                // delay signed wrappers, otherwise rethrow, since it's an unexpected exception.
                                if (DelaySign)
                                {
                                    Log.LogErrorWithCodeFromResources(null, projectRefInfo.SourceItemSpec, 0, 0, 0, 0, "ResolveComReference.LoadingDelaySignedAssemblyWithStrongNameVerificationEnabled", ex.Message);

                                    // no point in printing the same thing multiple times...
                                    return false;
                                }
                                else
                                {
                                    Debug.Assert(false, "Unexpected exception in ResolveComReference.Execute. " +
                                        "Please log a MSBuild bug specifying the steps to reproduce the problem.");
                                    throw;
                                }
                            }
                            catch (ArgumentException ex)
                            {
                                // This exception is thrown when we try to convert some of the Metadata from the project
                                // file and the conversion fails.  Most likely, the user needs to correct a type in the 
                                // project file.
                                Log.LogErrorWithCodeFromResources("General.InvalidArgument", ex.Message);
                                return false;
                            }
                            catch (SystemException ex)
                            {
                                Log.LogErrorWithCodeFromResources("ResolveComReference.FailedToResolveComReference",
                                    projectRefInfo.attr.guid, projectRefInfo.attr.wMajorVerNum, projectRefInfo.attr.wMinorVerNum,
                                    ex.Message);
                            }
                        }
                    }
                }

                SetCopyLocalToFalseOnGacOrNoPIAAssemblies(resolvedReferenceList, GlobalAssemblyCache.GetGacPath());

                ResolvedModules = (ITaskItem[])moduleList.ToArray(typeof(ITaskItem));
                ResolvedFiles = (ITaskItem[])resolvedReferenceList.ToArray(typeof(ITaskItem));

                // The Logs from AxImp and TlbImp aren't part of our log, but if the task failed, it will return false from 
                // GenerateWrapper, which should get passed all the way back up here.  
                return allReferencesResolvedSuccessfully && !Log.HasLoggedErrors;
            }
            finally
            {
                if ((_timestampCache != null) && _timestampCache.Dirty)
                {
                    _timestampCache.SerializeCache(StateFile, Log);
                }

                Cleanup();
            }
        }