private void DoInspectorModifierGUI(NodeGUI node)
        {
            EditorGUILayout.HelpBox("Modifier: Force apply asset settings to given assets.", MessageType.Info);
            UpdateNodeName(node);

            GUILayout.Space(10f);

            var currentModifierTargetType = IntegratedGUIModifier.ModifierOperationTargetTypeName(node.nodeId);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                // show incoming type of Assets and reset interface.
                {
                    var isOperationDataExist = false;
                    IntegratedGUIModifier.ValidateModifiyOperationData(
                        node.nodeId,
                        node.currentPlatform,
                        () => {
                        GUILayout.Label("No modifier data found, please Reload first.");
                    },
                        () => {
                        isOperationDataExist = true;
                    }
                        );

                    if (!isOperationDataExist)
                    {
                        return;
                    }

                    using (new EditorGUILayout.HorizontalScope()) {
                        GUILayout.Label("Target Type:");
                        GUILayout.Label(currentModifierTargetType);
                    }

                    /*
                     *      reset whole platform's data for this modifier.
                     */
                    if (GUILayout.Button("Reset Modifier"))
                    {
                        var modifierFolderPath = FileUtility.PathCombine(AssetBundleGraphSettings.MODIFIER_OPERATOR_DATAS_PLACE, node.nodeId);
                        FileUtility.RemakeDirectory(modifierFolderPath);
                        node.Save();
                        modifierOperatorInstance = null;
                        return;
                    }
                }

                GUILayout.Space(10f);

                var usingScriptMode = !string.IsNullOrEmpty(node.scriptClassName);

                // use modifier script manually.
                {
                    GUIStyle s = new GUIStyle("TextFieldDropDownText");

                    /*
                     *      check prefabricator script-type string.
                     */
                    if (string.IsNullOrEmpty(node.scriptClassName))
                    {
                        s.fontStyle = FontStyle.Bold;
                        s.fontSize  = 12;
                    }
                    else
                    {
                        var loadedType = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(node.scriptClassName);

                        if (loadedType == null)
                        {
                            s.fontStyle = FontStyle.Bold;
                            s.fontSize  = 12;
                        }
                    }

                    var before = !string.IsNullOrEmpty(node.scriptClassName);
                    usingScriptMode = EditorGUILayout.ToggleLeft("Use ModifierOperator Script", !string.IsNullOrEmpty(node.scriptClassName));

                    // detect mode changed.
                    if (before != usingScriptMode)
                    {
                        // checked. initialize value of scriptClassName.
                        if (usingScriptMode)
                        {
                            node.BeforeSave();
                            node.scriptClassName = "MyModifier";
                            node.Save();
                        }

                        // unchecked.
                        if (!usingScriptMode)
                        {
                            node.BeforeSave();
                            node.scriptClassName = string.Empty;
                            node.Save();
                        }
                    }

                    if (!usingScriptMode)
                    {
                        EditorGUI.BeginDisabledGroup(true);
                    }
                    GUILayout.Label("ここをドロップダウンにする。2");
                    var newScriptClass = EditorGUILayout.TextField("Classname", node.scriptClassName, s);
                    if (newScriptClass != node.scriptClassName)
                    {
                        node.BeforeSave();
                        node.scriptClassName = newScriptClass;
                        node.Save();
                    }
                    if (!usingScriptMode)
                    {
                        EditorGUI.EndDisabledGroup();
                    }
                }

                GUILayout.Space(10f);

                if (usingScriptMode)
                {
                    EditorGUI.BeginDisabledGroup(true);
                }

                // show for each platform tab.

                var currentPlatform = node.currentPlatform;
                node.currentPlatform = UpdateCurrentPlatform(node.currentPlatform);

                /*
                 *      if platform tab is changed, renew modifierOperatorInstance for that tab.
                 */
                if (currentPlatform != node.currentPlatform)
                {
                    modifierOperatorInstance = null;
                }

                /*
                 *      reload modifierOperator instance from saved modifierOperator data.
                 */
                if (modifierOperatorInstance == null)
                {
                    var modifierOperatorDataPath = IntegratedGUIModifier.ModifierDataPathForeachPlatform(node.nodeId, node.currentPlatform);

                    // choose default modifierOperatorData if platform specified file is not exist.
                    if (!File.Exists(modifierOperatorDataPath))
                    {
                        modifierOperatorDataPath = IntegratedGUIModifier.ModifierDataPathForDefaultPlatform(node.nodeId);
                    }

                    var loadedModifierOperatorDataStr = string.Empty;
                    using (var sr = new StreamReader(modifierOperatorDataPath)) {
                        loadedModifierOperatorDataStr = sr.ReadToEnd();
                    }

                    var modifierOperatorType = TypeUtility.SupportedModifierOperatorDefinition[currentModifierTargetType];

                    /*
                     *      create instance from saved modifierOperator data.
                     */
                    modifierOperatorInstance = typeof(NodeGUIEditor)
                                               .GetMethod("FromJson")
                                               .MakeGenericMethod(modifierOperatorType) // set desired generic type here.
                                               .Invoke(this, new object[] { loadedModifierOperatorDataStr }) as ModifierOperators.OperatorBase;
                }

                /*
                 *      Show ModifierOperator Inspector.
                 */
                if (modifierOperatorInstance != null)
                {
                    Action changed = () => {
                        var data       = JsonUtility.ToJson(modifierOperatorInstance);
                        var prettified = AssetBundleGraphEditorWindow.PrettifyJson(data);

                        var modifierOperatorDataPath = IntegratedGUIModifier.ModifierDataPathForeachPlatform(node.nodeId, node.currentPlatform);

                        using (var sw = new StreamWriter(modifierOperatorDataPath)) {
                            sw.Write(prettified);
                        }

                        // reflect change of data.
                        AssetDatabase.Refresh();

                        modifierOperatorInstance = null;
                    };

                    GUILayout.Space(10f);

                    modifierOperatorInstance.DrawInspector(changed);
                }

                var deleted = UpdateDeleteSetting(node);
                if (deleted)
                {
                    // source platform depended data is deleted. reload instance for reloading instance from data.
                    modifierOperatorInstance = null;
                }

                if (usingScriptMode)
                {
                    EditorGUI.EndDisabledGroup();
                }
            }
        }
        public void Setup(string nodeName, string nodeId, string connectionIdToNextNode, Dictionary <string, List <Asset> > groupedSources, List <string> alreadyCached, Action <string, string, Dictionary <string, List <Asset> >, List <string> > Output)
        {
            if (groupedSources.Keys.Count == 0)
            {
                return;
            }

            // Modifier merges multiple incoming groups into one.
            if (1 < groupedSources.Keys.Count)
            {
                Debug.LogWarning(nodeName + " Modifier merges incoming group into \"" + groupedSources.Keys.ToList()[0]);
            }

            var groupMergeKey = groupedSources.Keys.ToList()[0];

            // merge all assets into single list.
            var inputSources = new List <Asset>();

            foreach (var groupKey in groupedSources.Keys)
            {
                inputSources.AddRange(groupedSources[groupKey]);
            }

            if (!inputSources.Any())
            {
                return;
            }

            // initialize as object.
            var modifierType = string.Empty;

            var first = true;

            foreach (var inputSource in inputSources)
            {
                var modifyTargetAssetPath = inputSource.importFrom;
                var assumedType           = TypeUtility.FindTypeOfAsset(modifyTargetAssetPath);

                if (assumedType == null || assumedType == typeof(object))
                {
                    continue;
                }

                if (first)
                {
                    first        = false;
                    modifierType = assumedType.ToString();
                    continue;
                }

                if (modifierType != assumedType.ToString())
                {
                    throw new NodeException("multiple Asset Type detected. consider reduce Asset Type number to only 1 by Filter. detected Asset Types is:" + modifierType + " , and " + assumedType.ToString(), nodeId);
                }
            }

            // modifierType is fixed.

            if (!string.IsNullOrEmpty(specifiedScriptClass))
            {
                Debug.LogError("modifierのScript版実装中。");
                return;
            }

            // check support.
            if (!TypeUtility.SupportedModifierOperatorDefinition.ContainsKey(modifierType))
            {
                throw new NodeException("current incoming Asset Type:" + modifierType + " is unsupported.", nodeId);
            }

            // generate modifierOperatorData if data is not exist yet.
            {
                var modifierOperationDataFolderPath = AssetBundleGraphSettings.MODIFIER_OPERATOR_DATAS_PLACE;
                if (!Directory.Exists(modifierOperationDataFolderPath))
                {
                    Directory.CreateDirectory(modifierOperationDataFolderPath);
                }

                var opDataFolderPath = FileUtility.PathCombine(modifierOperationDataFolderPath, nodeId);
                if (!Directory.Exists(opDataFolderPath))
                {
                    Directory.CreateDirectory(opDataFolderPath);
                }

                // ready default platform path.
                var modifierOperatorDataPathForDefaultPlatform = FileUtility.PathCombine(opDataFolderPath, ModifierOperatiorDataName(AssetBundleGraphSettings.PLATFORM_DEFAULT_NAME));

                /*
                 *      create default platform ModifierOperatorData if not exist.
                 *      default ModifierOperatorData is the target platform for every platform by default.
                 */
                if (!File.Exists(modifierOperatorDataPathForDefaultPlatform))
                {
                    var operatorType = TypeUtility.SupportedModifierOperatorDefinition[modifierType];

                    var operatorInstance = Activator.CreateInstance(operatorType) as ModifierOperators.OperatorBase;

                    var defaultRenderTextureOp = operatorInstance.DefaultSetting();

                    /*
                     *      generated json data is typed as supported ModifierOperation type.
                     */
                    var jsonData   = JsonUtility.ToJson(defaultRenderTextureOp);
                    var prettified = AssetBundleGraphEditorWindow.PrettifyJson(jsonData);
                    using (var sw = new StreamWriter(modifierOperatorDataPathForDefaultPlatform)) {
                        sw.WriteLine(prettified);
                    }
                }
            }

            // validate saved data.
            ValidateModifiyOperationData(
                nodeId,
                currentPlatformStr,
                () => {
                throw new NodeException("No ModifierOperatorData found. please Setup first.", nodeId);
            },
                () => {
                /*do nothing.*/
            }
                );

            var outputSources = new List <Asset>();

            /*
             *      all assets types are same and do nothing to assets in setup.
             */
            foreach (var asset in inputSources)
            {
                outputSources.Add(Asset.DuplicateAsset(asset));
            }

            var outputDict = new Dictionary <string, List <Asset> >();

            outputDict[groupMergeKey] = outputSources;

            Output(nodeId, connectionIdToNextNode, outputDict, new List <string>());
        }