/// <summary>
        /// Uninstall a category of performance counters defined in this Enumerator
        /// </summary>
        /// <param name="typeT">enumerator that holds counters and defines PerformanceCounterCategoryAttribute and PerformanceCounterAttribute</param>
        /// <seealso cref="PerformanceCounterCategoryAttribute"/>
        /// <seealso cref="PerformanceCounterAttribute"/>
        /// <exception cref="System.NotSupportedException" />
        public static void Uninstall(Type typeT)
        {
            if (!typeT.IsEnum)
            {
                throw new NotSupportedException(
                          String.Format(
                              System.Globalization.CultureInfo.CurrentUICulture,
                              Properties.Resources.PerformanceHelper_EnumTypeErrorMessage,
                              typeT.Name));
            }

            PerformanceCounterCategoryAttribute categoryInfo = GetCategoryAttribute(typeT);

            if (categoryInfo == null)
            {
                throw new NotSupportedException(
                          String.Format(
                              System.Globalization.CultureInfo.CurrentUICulture,
                              Properties.Resources.PerformanceHelper_EnumTypeNoPerformanceCounterCategoryAttributeErrorMessage,
                              typeT.Name));
            }

            if (PerformanceCounterCategory.Exists(categoryInfo.Name))
            {
                PerformanceCounterCategory.Delete(categoryInfo.Name);
            }
        }
        /// <summary>
        /// Create an instance of CounterHelper to manage performance counters defined on T defininig an instance name for multi-instance counters.
        /// </summary>
        /// <typeparam name="T">enumerator that holds performance counter information</typeparam>
        /// <param name="instanceName">instance name to be used on multi-instance counters</param>
        /// <seealso cref="PerformanceCounterCategoryAttribute"/>
        /// <seealso cref="PerformanceCounterAttribute"/>
        /// <returns>returns an instance of CounterHelper</returns>
        public static CounterHelper <T> CreateCounterHelper <T>(string instanceName)
        {
            Type typeT = typeof(T);

            if (!typeT.IsEnum)
            {
                throw new NotSupportedException(
                          String.Format(
                              System.Globalization.CultureInfo.CurrentUICulture,
                              Properties.Resources.PerformanceHelper_EnumTypeErrorMessage,
                              typeT.Name));
            }

            PerformanceCounterCategoryAttribute categoryInfo = GetCategoryAttribute(typeT);

            if (categoryInfo == null)
            {
                throw new NotSupportedException(
                          String.Format(
                              System.Globalization.CultureInfo.CurrentUICulture,
                              Properties.Resources.PerformanceHelper_EnumTypeNoPerformanceCounterCategoryAttributeErrorMessage,
                              typeT.Name));
            }


            Array enumValues = Enum.GetValues(typeT);

            Dictionary <T, PerformanceCounterAttribute> enumCounterAttributes = new Dictionary <T, PerformanceCounterAttribute>();
            PerformanceCounterAttribute attr;

            foreach (T performanceCounter in enumValues)
            {
                attr = GetCounterAttribute(typeT, performanceCounter);
                if (attr != null)
                {
                    enumCounterAttributes.Add(performanceCounter, attr);
                }
            }

            if (PerformanceCounterCategory.Exists(categoryInfo.Name))
            {
                CounterHelper <T> counterHelper;
                if (categoryInfo.InstanceType == PerformanceCounterCategoryType.MultiInstance)
                {
                    if (string.IsNullOrEmpty(instanceName))
                    {
                        instanceName = string.Format("{0}_{1}", AppDomain.CurrentDomain.FriendlyName, Process.GetCurrentProcess().Id);
                    }
                    counterHelper = CounterHelperFactory.Create <T>(instanceName, categoryInfo, enumCounterAttributes);
                }
                else
                {
                    counterHelper = CounterHelperFactory.Create <T>(categoryInfo, enumCounterAttributes);
                }
                return(counterHelper);
            }
            return(null);
        }
        /// <summary>
        /// Get PerformanceCounterCategoryAttribute attached to an Enumeration
        /// </summary>
        /// <param name="enumType">enumerator</param>
        /// <returns>returns an instance of PerformanceCounterCategoryAttribute in case the attribute is found, otherwise null</returns>
        /// <seealso cref="PerformanceCounterCategoryAttribute"/>
        /// <exception cref="System.NotSupportedException" />
        private static PerformanceCounterCategoryAttribute GetCategoryAttribute(Type enumType)
        {
            if (enumType == null)
            {
                throw new NotSupportedException(Properties.Resources.PerformanceHelper_EnumTypeCannotBeNullErrorMessage);
            }

            PerformanceCounterCategoryAttribute attr = Attribute.GetCustomAttribute(enumType, typeof(PerformanceCounterCategoryAttribute)) as PerformanceCounterCategoryAttribute;

            return(attr);
        }
        /// <summary>
        /// Install a category of performance counters using the information on the enumerator
        /// </summary>
        /// <param name="typeT">enumerator that contains information on the performance counters</param>
        /// <seealso cref="PerformanceCounterCategoryAttribute"/>
        /// <seealso cref="PerformanceCounterAttribute"/>
        public static void Install(Type typeT)
        {
            if (!typeT.IsEnum)
            {
                throw new NotSupportedException(
                          String.Format(
                              System.Globalization.CultureInfo.CurrentUICulture,
                              Properties.Resources.PerformanceHelper_EnumTypeErrorMessage,
                              typeT.Name));
            }

            PerformanceCounterCategoryAttribute categoryInfo = GetCategoryAttribute(typeT);

            if (categoryInfo == null)
            {
                throw new NotSupportedException(
                          String.Format(
                              System.Globalization.CultureInfo.CurrentUICulture,
                              Properties.Resources.PerformanceHelper_EnumTypeNoPerformanceCounterCategoryAttributeErrorMessage,
                              typeT.Name));
            }

            Array enumValues = Enum.GetValues(typeT);

            /* removed cause i tested and now it supports more than 255
             * if (enumValues.Length > 255)
             *  throw new NotSupportedException(
             *      String.Format(
             *      System.Globalization.CultureInfo.CurrentUICulture,
             *      "{0}'s length must be less than or equal to 255.",
             *      typeT.Name));
             */

            if (PerformanceCounterCategory.Exists(categoryInfo.Name))
            {
                PerformanceCounterCategory.Delete(categoryInfo.Name);
            }

            CounterCreationDataCollection categoryCounters = new CounterCreationDataCollection();

            PerformanceCounterAttribute attr;

            foreach (object performanceCounter in enumValues)
            {
                attr = GetCounterAttribute(typeT, performanceCounter);
                if (attr != null)
                {
                    if (IsBaseType(attr.CounterType))
                    {
                        throw new NotSupportedException(
                                  String.Format(Properties.Resources.PerformanceHelper_BaseTypeSupportedInternalErrorMessage,
                                                attr.Name));
                    }

                    CounterCreationData counterData = new CounterCreationData(attr.Name, attr.Info, attr.CounterType);
                    categoryCounters.Add(counterData);
                    PerformanceCounterType?baseType = GetBaseType(counterData.CounterType);
                    if (baseType != null)
                    {
                        categoryCounters.Add(new CounterCreationData(GetCounterNameForBaseType(attr.Name),
                                                                     string.Format(Properties.Resources.PerformanceHelper_BaseCounterDescription, attr.Name),
                                                                     (PerformanceCounterType)baseType));
                    }
                }
            }
            if (categoryCounters.Count > 0)
            {
                PerformanceCounterCategory.Create(categoryInfo.Name, categoryInfo.Info, categoryInfo.InstanceType, categoryCounters);
            }
        }