public void ObjectAssetChildren()
 {
     IAssetExplorer explorer = new ReflectionExplorer(null);
     Asset objectAsset = ReflectionServices.GetAsset(typeof (object));
     Asset[] members = explorer.GetChildren(objectAsset).ToArray();
     Assert.Equal(12, members.Length);
 }
        public XDocument Generate(string path)
        {
            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Enrichers:");

            for (int i = 0; i < this.Enrichers.Count; i++)
            {
                IEnricher enricher = this.Enrichers[i];
                TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose,
                                                        0,
                                                        "[{0}] {1}",
                                                        i,
                                                        enricher.GetType().FullName);
            }

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Filters:");
            for (int i = 0; i < this.AssetFilters.Count; i++)
            {
                TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose,
                                                        0,
                                                        "[{0}] {1}",
                                                        i,
                                                        this.AssetFilters[i].GetType().FullName);
            }

            XDocument ret = new XDocument();

            IAssemblyLoader assemblyLoader = new ReflectionOnlyAssemblyLoader(
                this._cache,
                this._assemblyPaths.Select(Path.GetDirectoryName));

            Assembly assembly = assemblyLoader.LoadFrom(path);
            Asset assemblyAsset = ReflectionServices.GetAsset(assembly);

            XNamespace defaultNs = string.Empty;
            // pass in assemblyLoader instead
            IAssetExplorer assetExplorer = new ReflectionExplorer(assemblyLoader);
            IFilterContext filterContext = new FilterContext(this._cache,
                                                             this._container,
                                                             FilterState.Discovery,
                                                             this._filters.ToArray());
            // collect phase zero assets
            var assets = this.DiscoverAssets(assemblyAsset, assetExplorer, filterContext);

            // initiate output document creation
            ret.Add(new XElement(defaultNs + "bundle"));


            IProcessingContext pctx = new ProcessingContext(this._cache,
                                                            this._container,
                                                            this._filters,
                                                            assemblyLoader,
                                                            ret.Root,
                                                            null,
                                                            -1,
                                                            assetExplorer);

            foreach (IEnricher enricher in this._enrichers)
                enricher.RegisterNamespace(pctx);

            // asset related classes
            HashSet<Asset> emittedAssets = new HashSet<Asset>();

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Start, 0, "Generating document");

            int phase = 0;
            HashSet<Asset> referencedAssets = new HashSet<Asset>();

            long lastProgressOutput = Stopwatch.GetTimestamp();
            // main output loop
            while (assets.Count > 0)
            {
                int phaseAssetCount = 0;
                using (TraceSources.GeneratorSource.TraceActivity("Phase {0} ({1:N0} assets)", phase, assets.Count))
                {
                    foreach (Asset asset in assets)
                    {
                        // skip already emitted assets
                        if (!emittedAssets.Add(asset))
                            continue;

                        phaseAssetCount++;

                        if (((Stopwatch.GetTimestamp() - lastProgressOutput) / (double)Stopwatch.Frequency) > 5.0)
                        {
                            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Information, 0,
                                                                    "Phase {0} progress {1:P1} ({2:N0}/{3:N0})",
                                                                    phase,
                                                                    phaseAssetCount / (double)assets.Count,
                                                                    phaseAssetCount,
                                                                    assets.Count);

                            lastProgressOutput = Stopwatch.GetTimestamp();
                        }

                        TraceSources.GeneratorSource.TraceEvent(TraceEventType.Verbose, 0, "Generating {0}", asset);

                        // get hierarchy
                        LinkedList<Asset> hierarchy = new LinkedList<Asset>();

                        foreach (Asset hierarchyAsset in assetExplorer.GetAssetHierarchy(asset))
                            hierarchy.AddFirst(hierarchyAsset);

                        if (hierarchy.First != null)
                        {
                            this.BuildHierarchy(ret.Root,
                                                hierarchy.First,
                                                referencedAssets,
                                                emittedAssets,
                                                phase, assetExplorer);
                        }
                    }

                    ++phase;
                    assets.Clear();
                    referencedAssets.ExceptWith(emittedAssets);
                    assets = referencedAssets.ToList();
                    referencedAssets.Clear();
                }
            }

            TraceSources.GeneratorSource.TraceEvent(TraceEventType.Stop, 0, "Generating document");
            return ret;
        }