private void InitTerrainTypesWithReflection(string paintToolName)
        {
            terrainToolType = Type.GetType("UnityEditor.Experimental.TerrainAPI." + paintToolName + ", " +
                                           "Unity.TerrainTools.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
            onPaintType = Type.GetType("UnityEditor.Experimental.TerrainAPI.OnPaintContext, " +
                                       "UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
            onSceneGUIContextType = Type.GetType("UnityEditor.Experimental.TerrainAPI.OnSceneGUIContext, " +
                                                 "UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");

            // Get the method and instance for the current tool being tested
            PropertyInfo propertyInfo = terrainToolType.GetProperty("instance", s_bindingFlags);
            MethodInfo   methodInfo   = propertyInfo.GetGetMethod();

            terrainToolInstance = methodInfo.Invoke(null, null);

            onPaintMethod    = terrainToolType.GetMethod("OnPaint");
            onSceneGUIMethod = terrainToolType.GetMethod("OnSceneGUI");

            MethodInfo loadSettingsInfo = terrainToolType.GetMethod("LoadSettings", s_bindingFlags);

            if (loadSettingsInfo != null)
            {
                loadSettingsInfo.Invoke(terrainToolInstance, null);
            }

            // LOAD TOOL SETTINGS
            baseBrushUIGroupType = Type.GetType("UnityEditor.Experimental.TerrainAPI.BaseBrushUIGroup, " +
                                                "Unity.TerrainTools.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
            brushSizeType = Type.GetType("UnityEditor.Experimental.TerrainAPI.IBrushSizeController, " +
                                         "Unity.TerrainTools.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
            brushStrengthType = Type.GetType("UnityEditor.Experimental.TerrainAPI.IBrushStrengthController, " +
                                             "Unity.TerrainTools.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
            brushRotationType = Type.GetType("UnityEditor.Experimental.TerrainAPI.IBrushRotationController, " +
                                             "Unity.TerrainTools.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");

            FieldInfo baseBrushUIGroupFieldInfo = terrainToolType.GetField("commonUI", BindingFlags.NonPublic | BindingFlags.Instance);

            if (baseBrushUIGroupFieldInfo == null)
            {
                PropertyInfo baseBrushUIGroupPropertyInfo = terrainToolType.GetProperty("commonUI", BindingFlags.NonPublic | BindingFlags.Instance);
                if (baseBrushUIGroupPropertyInfo != null)
                {
                    commonUIInstance = baseBrushUIGroupPropertyInfo.GetValue(terrainToolInstance) as BaseBrushUIGroup;
                }
            }
            else
            {
                commonUIInstance = baseBrushUIGroupFieldInfo.GetValue(terrainToolInstance) as BaseBrushUIGroup;
            }
            if (commonUIInstance == null)
            {
                throw new Exception("The commonUI of the brush can't be found - does it have one?");
            }

            brushSizeProperty     = baseBrushUIGroupType.GetProperty("brushSize", BindingFlags.Public | BindingFlags.Instance);
            brushStrengthProperty = baseBrushUIGroupType.GetProperty("brushStrength", BindingFlags.Public | BindingFlags.Instance);
            brushRotationProperty = baseBrushUIGroupType.GetProperty("brushRotation", BindingFlags.Public | BindingFlags.Instance);
        }
 static void CacheAnalyticsData(BaseBrushUIGroup brush)
 {
     m_Data.brush_name   = brush.brushName;
     m_Data.shortcuts    = s_UsedBrushShortcut;
     m_Data.mask_filters = brush.brushMaskFilterStack.filters?.
                           Where(x => x.enabled).
                           Select(x => x.GetType().Name).ToArray();
     m_Data.strength         = CompareSignificance(brush.brushStrength, m_Data.strength);
     m_Data.size             = CompareSignificance(brush.brushSize, m_Data.size);
     m_Data.rotation         = CompareSignificance(brush.brushRotation, m_Data.rotation);
     m_Data.spacing          = CompareSignificance(brush.brushSpacing, m_Data.spacing);
     m_Data.scatter          = CompareSignificance(brush.brushScatter, m_Data.scatter);
     m_Data.brush_parameters = s_ModifiedBrushParameters;
 }
        /// <summary>
        /// Update the analytics data to be sent when a user starts painting with new parameters/settings
        /// The users time is being tracked while painting
        /// Once the user changes any brush parameters original data is sent and the new data is cached to be compared later
        /// </summary>
        /// <param name="baseBrushSettings">Brush Base class containing common brush parameters</param>
        /// <param name="brushParamFunc">Function returning brush specific parameters</param>
        internal static void UpdateAnalytics(BaseBrushUIGroup baseBrushSettings, Func <TerrainToolsAnalytics.IBrushParameter[]> brushParamFunc)
        {
            if (!EnableAnalytics())
            {
                return;
            }

            s_PaintingDuration += Time.deltaTime;

            if (!s_ParameterChanged)
            {
                return;
            }

            SendAnalytics();
            CompareBrushSettings(brushParamFunc?.Invoke());
            CacheAnalyticsData(baseBrushSettings);
        }