/// <summary>
        ///     Attempts to get a data cooker reference given a data cooker path.
        /// </summary>
        /// <param name="self">
        ///     A data extension repository to search.
        /// </param>
        /// <param name="dataCookerPath">
        ///     A path to a data cooker.
        /// </param>
        /// <param name="cooker">
        ///     Receives the result: a data cooker reference, or <c>null</c> if not found.
        /// </param>
        /// <returns>
        ///     true if the path resulted in a data cooker reference; false otherwise.
        /// </returns>
        public static bool TryGetDataCookerReference(
            this IDataExtensionRepository self,
            DataCookerPath dataCookerPath,
            out IDataCookerReference cooker)
        {
            Guard.NotNull(self, nameof(self));

            cooker = self.GetSourceDataCookerReference(dataCookerPath);
            if (cooker is null)
            {
                cooker = self.GetCompositeDataCookerReference(dataCookerPath);
            }

            return(!(cooker is null));
        }
        /// <summary>
        ///     This will process all of the data cooker requirements for the target data
        ///     extension (both source and composite). It will recursively descend through requirements,
        ///     determining if the target data extension may be used.
        /// </summary>
        /// <param name="availableDataExtensions">
        ///     Data extensions that have been exposed through the runtime.
        /// </param>
        private void ValidateDataCookerDependencies(
            IDataExtensionRepository availableDataExtensions)
        {
            Guard.NotNull(availableDataExtensions, nameof(availableDataExtensions));

            foreach (var requiredDataCookerPath in this.target.RequiredDataCookers)
            {
                IDataCookerReference dataCookerReference = null;

                var sourceId = requiredDataCookerPath.SourceParserId;
                if (string.IsNullOrWhiteSpace(sourceId))
                {
                    // Add composite data cooker

                    var requiredCookerReference = availableDataExtensions.GetCompositeDataCookerReference(requiredDataCookerPath);
                    if (requiredCookerReference == null)
                    {
                        this.UpdateAvailability(DataExtensionAvailability.MissingRequirement);
                        this.missingDataCookers.Add(requiredDataCookerPath);
                        continue;
                    }

                    dataCookerReference = requiredCookerReference;

                    this.dependencyReferences.AddRequiredCompositeDataCookerPath(requiredCookerReference.Path);
                }
                else
                {
                    // Add source data cooker

                    var requiredCookerReference = availableDataExtensions.GetSourceDataCookerReference(requiredDataCookerPath);
                    if (requiredCookerReference == null)
                    {
                        this.UpdateAvailability(DataExtensionAvailability.MissingRequirement);
                        this.missingDataCookers.Add(requiredDataCookerPath);
                        continue;
                    }

                    dataCookerReference = requiredCookerReference;

                    this.dependencyReferences.AddRequiredSourceDataCookerPath(requiredCookerReference.Path);
                }

                this.ProcessRequiredExtension(dataCookerReference, requiredDataCookerPath.CookerPath, availableDataExtensions);
            }
        }