private static void Export(Data data)
        {
            data.assetData = data.assetData.OrderBy(d => Path.GetExtension(d.path)).ToList();
            const string directory = "build/ReferenceViewer";

            Directory.CreateDirectory(directory);

            foreach (var assetData in data.assetData.Where(assetData => assetData.sceneData.Count != 0))
            {
                assetData.sceneData =
                    assetData.sceneData.Distinct(new CompareSelector<SceneData, string>(s => s.name + s.guid)).ToList();
            }
            File.WriteAllBytes(directory + "/data.dat", ObjectToByteArray(data));
        }
        public static void Build(Action callback = null)
        {
            if (!EditorApplication.SaveCurrentSceneIfUserWantsTo()) return;

            var currentScene = EditorApplication.currentScene;

            var data = new Data();

            Generate.Build(AssetDatabase.GetAllAssetPaths(), assetData =>
            {
                data.assetData.AddRange(assetData);
                EditorUtility.UnloadUnusedAssets();

                if(string.IsNullOrEmpty(currentScene))
                    EditorApplication.NewScene();
                else
                    EditorApplication.OpenScene(currentScene);

                Export(data);
                if (callback != null)
                    callback();
            });
        }
        private static void Find(Data data, params Object[] selectedObjects)
        {
            var items = new List <Item>();
            var guids = new List <string>();

            foreach (var selectedObject in selectedObjects)
            {
                var guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(selectedObject));
                if (AssetDatabase.IsSubAsset(selectedObject))
                {
                    var item = new Item();
                    item.searchedGUIContent = GetGUIContent(selectedObject);
                    item.type = selectedObject.GetType();

                    foreach (var assetData in data.assetData)
                    {
                        foreach (var subAssetData in assetData.subAssets)
                        {
                            var type = System.Reflection.Assembly.Load("UnityEngine.dll").GetType(subAssetData.typeName);
                            if (subAssetData.guid == guid && type == selectedObject.GetType())
                            {
                                item.referencedGUIContents.Add(GetGUIContent(assetData.guid));
                            }
                        }
                    }
                    item.referencedGUIContents = item.referencedGUIContents.Distinct(
                        new CompareSelector <GUIContent, string>(i => i.tooltip)).ToList();

                    items.Add(item);
                }
                else
                {
                    guids.Add(guid);

                    foreach (var assetData in data.assetData.Where(assetData => guid == assetData.guid))
                    {
                        foreach (var subAssetData in assetData.subAssets)
                        {
                            var type = System.Reflection.Assembly.Load("UnityEngine.dll").GetType(subAssetData.typeName);
                            var tex  = AssetPreview.GetMiniTypeThumbnail(type);

                            var item =
                                items.FirstOrDefault(_item => _item.searchedGUIContent.tooltip == GetGUIContent(selectedObject).tooltip);
                            if (item == null)
                            {
                                item = new Item {
                                    searchedGUIContent = GetGUIContent(selectedObject)
                                };
                                items.Add(item);
                            }
                            item.type = type;
                            item.referenceGUIContents.Add(new GUIContent(subAssetData.name, tex, AssetDatabase.GUIDToAssetPath(subAssetData.guid)));
                            item.referenceGUIContents = item.referenceGUIContents.Distinct(
                                new CompareSelector <GUIContent, string>(i => i.text)).ToList();
                        }
                    }
                }
            }

            items.AddRange(guids
                           .Select(guid => new
            {
                type       = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), typeof(Object)).GetType(),
                searched   = GetGUIContent(guid),
                referenced =
                    data.assetData.Where(assetData => assetData.reference.Contains(guid))
                    .Select(assetData => GetGUIContent(assetData.guid))
                    .Where(c => c.image && guid != AssetDatabase.AssetPathToGUID(c.tooltip))
                    .OrderBy(c => c.image.name)
                    .ToList(),
                reference =
                    data.assetData.Find(item => item.guid == guid)
                    .reference.Where(g => g != guid)
                    .Select(g => GetGUIContent(g))
                    .Where(c => c.image)
                    .OrderBy(c => c.image.name)
                    .ToList()
            })
                           .Where(item => (item.referenced.Count != 0 || item.reference.Count != 0) && item.searched.image)
                           .OrderBy(item => item.searched.image.name)
                           .Select(item => new Item
            {
                type = item.type,
                searchedGUIContent    = item.searched,
                referencedGUIContents = item.referenced,
                referenceGUIContents  = item.reference
            })
                           .ToList());
            items.Distinct(new CompareSelector <Item, string>(i => i.searchedGUIContent.tooltip));

            foreach (var item in items)
            {
                foreach (var i in item.referencedGUIContents)
                {
                    if (Path.GetExtension(i.tooltip) == ".unity")
                    {
                        var d   = data.assetData.Find(asset => asset.path == i.tooltip).sceneData;
                        var key = item.searchedGUIContent.tooltip + " - " + i.tooltip;
                        if (sceneReference.ContainsKey(key))
                        {
                            sceneReference[key].AddRange(d.Select(s => new GUIContent(s.name, AssetDatabase.GUIDToAssetPath(s.guid))).ToList());
                        }
                        else
                        {
                            sceneReference.Add(key, d.Select(s => new GUIContent(s.name, AssetDatabase.GUIDToAssetPath(s.guid))).ToList());
                        }
                    }
                }
            }
            var window = GetWindow <ReferenceViewer>();

            window.selectedFilter = 0;
            window.Results(items);
        }