public override bool Execute()
        {
            DateTime startTime = DateTime.Now;

            Log.LogMessage(MessageImportance.High, "Writing package usage data...");

            string[] projectDirectoriesOutsideRoot = ProjectDirectories.NullAsEmpty()
                                                     .Where(dir => !dir.StartsWith(RootDir, StringComparison.Ordinal))
                                                     .ToArray();

            if (projectDirectoriesOutsideRoot.Any())
            {
                throw new ArgumentException(
                          $"All ProjectDirectories must be in RootDir '{RootDir}', but found " +
                          string.Join(", ", projectDirectoriesOutsideRoot));
            }

            Log.LogMessage(MessageImportance.Low, "Finding set of RIDs...");

            string[] possibleRids = PlatformsRuntimeJsonFiles.NullAsEmpty()
                                    .SelectMany(ReadRidsFromRuntimeJson)
                                    .Distinct()
                                    .ToArray();

            Log.LogMessage(MessageImportance.Low, "Reading package identities...");

            PackageIdentity[] restored = RestoredPackageFiles.NullAsEmpty()
                                         .Select(ReadNuGetPackageInfos.ReadIdentity)
                                         .Distinct()
                                         .ToArray();

            PackageIdentity[] tarballPrebuilt = TarballPrebuiltPackageFiles.NullAsEmpty()
                                                .Select(ReadNuGetPackageInfos.ReadIdentity)
                                                .Distinct()
                                                .ToArray();

            PackageIdentity[] sourceBuilt = SourceBuiltPackageFiles.NullAsEmpty()
                                            .Select(ReadNuGetPackageInfos.ReadIdentity)
                                            .Distinct()
                                            .ToArray();

            IEnumerable <PackageIdentity> prebuilt = restored.Except(sourceBuilt);

            PackageIdentity[] toCheck = NuGetPackageInfos.NullAsEmpty()
                                        .Select(item => new PackageIdentity(
                                                    item.GetMetadata("PackageId"),
                                                    NuGetVersion.Parse(item.GetMetadata("PackageVersion"))))
                                        .Concat(prebuilt)
                                        .ToArray();

            Log.LogMessage(MessageImportance.Low, "Finding project.assets.json files...");

            string[] assetFiles = Directory.GetFiles(
                RootDir,
                "project.assets.json",
                SearchOption.AllDirectories);

            Log.LogMessage(MessageImportance.Low, "Reading usage info...");

            var usages = new ConcurrentBag <Usage>();

            Parallel.ForEach(
                assetFiles,
                assetFile =>
            {
                var properties = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

                using (var file = File.OpenRead(assetFile))
                    using (var reader = new StreamReader(file))
                        using (var jsonReader = new JsonTextReader(reader))
                        {
                            while (jsonReader.Read())
                            {
                                if (jsonReader.TokenType == JsonToken.PropertyName &&
                                    jsonReader.Value is string value)
                                {
                                    properties.Add(value);
                                }
                            }
                        }

                foreach (var identity in toCheck
                         .Where(id => properties.Contains(id.Id + "/" + id.Version.OriginalVersion)))
                {
                    usages.Add(Usage.Create(
                                   // Store relative path for future report generation.
                                   assetFile.Substring(RootDir.Length),
                                   identity,
                                   possibleRids));
                }
            });

            Log.LogMessage(MessageImportance.Low, "Searching for unused packages...");

            foreach (PackageIdentity restoredWithoutUsagesFound in
                     toCheck.Except(usages.Select(u => u.PackageIdentity)))
            {
                usages.Add(Usage.Create(
                               null,
                               restoredWithoutUsagesFound,
                               possibleRids));
            }

            // Packages that were included in the tarball as prebuilts, but weren't even restored.
            PackageIdentity[] neverRestoredTarballPrebuilts = tarballPrebuilt
                                                              .Except(restored)
                                                              .ToArray();

            Log.LogMessage(MessageImportance.Low, $"Writing data to '{DataFile}'...");

            var data = new UsageData
            {
                CreatedByRid = TargetRid,
                Usages       = usages.ToArray(),
                NeverRestoredTarballPrebuilts = neverRestoredTarballPrebuilts,
                ProjectDirectories            = ProjectDirectories
                                                ?.Select(dir => dir.Substring(RootDir.Length))
                                                .ToArray()
            };

            Directory.CreateDirectory(Path.GetDirectoryName(DataFile));
            File.WriteAllText(DataFile, data.ToXml().ToString());

            Log.LogMessage(
                MessageImportance.High,
                $"Writing package usage data... done. Took {DateTime.Now - startTime}");

            return(!Log.HasLoggedErrors);
        }