private bool IsTypeVisibleForHosting(RuntimeClassProviderEventArgs e)
		{
			try
			{
				// ok, yes, now make sure that no one has hidden it from the SnapInHostingEngine
				SnapInAttributeReader r = new SnapInAttributeReader(e.Type);
				SnapInVisibilityAttribute a = r.GetSnapInHostVisibilityAttribute();

				if (a != null)
					return a.Visible;					
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return true;
		}
		/// <summary>
		/// Creates a category for the type including it's version (defaulted to "1.0.0.0" for versionless types) in the specified configuration, using the specified type, and specified category name.
		/// </summary>
		/// <param name="configuration">The configuration in which the category will be created</param>
		/// <param name="type">The type for which the category will be created</param>
		/// <param name="categoryName">The category name in which creation will occur</param>
		/// <returns></returns>
		public static XmlConfigurationCategory CreateCategoryForTypeVersion(XmlConfiguration configuration, Type type, CategoryNames categoryName)
		{
			try
			{
				if (configuration != null)
				{					
					if (type != null)
					{
						// start in the specified category
						XmlConfigurationCategory searchCategory = configuration.Categories[@"SnapIns\" + categoryName.ToString()];
						if (searchCategory != null)
						{
							SnapInAttributeReader reader = new SnapInAttributeReader(type);
							if (reader != null)
							{
								Version version = null;
								SnapInVersionAttribute versionAttribute = reader.GetSnapInVersionAttribute();
								if (versionAttribute != null)
									version = versionAttribute.Version;
								else
									version = new Version(1, 0, 0, 0);
								
								string path = string.Format("{0}\\{1}\\{2}", @"SnapIns\" + categoryName.ToString(), type.FullName, version.ToString());
								return configuration.Categories[path, true];
							}
						}
					}
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return null;
		}
		/// <summary>
		/// Determines if the specified Type's Version is an upgrade from the specified versions
		/// </summary>
		/// <param name="versions">The array of versions to compare</param>
		/// <param name="type">The type whos version to compare against</param>
		/// <returns></returns>
		public static bool IsVersionOfTypeAnUpgrade(Version[] versions, Type type)
		{
			try
			{
				if (type != null)
				{
					SnapInAttributeReader reader = new SnapInAttributeReader(type);
					if (reader != null)
					{
						SnapInVersionAttribute versionAttribute = reader.GetSnapInVersionAttribute();
						if (versionAttribute != null)
						{
							bool newer = true;
							foreach(Version version in versions)
							{				
								if (version > versionAttribute.Version)
									newer = false;								
							}
							return newer;
						}
					}					
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return false;
		}
		/// <summary>
		/// Determines if the specified Type's Version (queried via attributes and reflection) is included in the array of Versions specified
		/// </summary>
		/// <param name="versions">The array of versions to search</param>
		/// <param name="type">The type to search for</param>
		/// <returns></returns>
		public static bool IsVersionOfTypeIncluded(Version[] versions, Type type)
		{
			try
			{
				if (type != null)
				{
					SnapInAttributeReader reader = new SnapInAttributeReader(type);
					if (reader != null)
					{
						SnapInVersionAttribute versionAttribute = reader.GetSnapInVersionAttribute();
						if (versionAttribute != null)
						{
							foreach(Version version in versions)
							{
								if (Version.Equals(version, versionAttribute.Version))
									return true;
							}
						}
					}					
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return false;
		}
		private void ExtractAttributesFromMetaData(Type type)
		{
			try
			{
				SnapInAttributeReader reader = new SnapInAttributeReader(type);
				if (reader != null)
				{
					// company name
					SnapInCompanyAttribute companyAttribute = reader.GetSnapInCompanyAttribute();
					if (companyAttribute != null)
						_company = companyAttribute.CompanyName;

					// description
					SnapInDescriptionAttribute descriptionAttribute = reader.GetSnapInDescriptionAttribute();
					if (descriptionAttribute != null)
						_description = descriptionAttribute.Description;

					// developers
					SnapInDevelopersAttribute developersAttribute = reader.GetSnapInDeveloperAttributes();
					if (developersAttribute != null)
						_developers = developersAttribute.DevelopersNames;

					// image
					SnapInImageAttribute imageAttribute = reader.GetSnapInImageAttribute();
					if (imageAttribute != null)
						_image = (Bitmap)imageAttribute.GetImage(type);

					// product families
					SnapInProductFamilyMemberAttribute[] productFamilyAttributes = reader.GetSnapInProductFamilyMemberAttribute();
					if (productFamilyAttributes != null)
					{
						_productFamilies = new string[productFamilyAttributes.Length];
						for(int i = 0; i < productFamilyAttributes.Length; i++)
							_productFamilies[i] = productFamilyAttributes[i].ProductFamily;
					}
					
					// title
					SnapInTitleAttribute titleAttribute = reader.GetSnapInTitleAttribute();
					if (titleAttribute != null)
						_title = titleAttribute.Title;						
					
					// version
					SnapInVersionAttribute versionAttribute = reader.GetSnapInVersionAttribute();
					if (versionAttribute != null)
						_version = versionAttribute.Version;
				}	

				if (_developers == null)
					_developers = new string[] {};

				if (_productFamilies == null)
					_productFamilies = new string[] {};

				// ensure default image
				if (_image == null)
					_image = _defaultImage;
							
				// ensure title 
				if (_title == null || _title == string.Empty)
					_title = type.FullName;

				if (_version == null)
					_version = new Version("1.0.0.0");
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
		}
		/// <summary>
		/// Handles the BuildingFeatureList event from the FeatureEngine
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		internal static void OnFeatureEngineBuildingFeatureList(object sender, FeatureCollectionEventArgs e)
		{
			SnapInHostingEngine hostingEngine = SnapInHostingEngine.GetExecutingInstance();

			// add features for resetting the configuration files
			e.Features.Add(new ConfigurationFeature(SnapInHostingEngine.DefaultCommonConfigurationName, "The common configuration stores options common to all users.", FeatureActions.ResetToDefault));
			e.Features.Add(new ConfigurationFeature(SnapInHostingEngine.DefaultLocalUserConfigurationName, "The local user configuration stores options specific to the current user.", FeatureActions.ResetToDefault));

			// since this event may fire before we have loaded any snapins (as a result of the _troubleshoot flag from the command line or app config )
			// we need to make sure we descriptors before we try this
			if ( hostingEngine.SnapInDescriptors != null )
			{
				// add features for reinstalling the snapins
				foreach(SnapInDescriptor descriptor in hostingEngine.SnapInDescriptors)
				{
					try
					{
						SnapInAttributeReader r = new SnapInAttributeReader(descriptor.Type);
						SnapInTitleAttribute ta = r.GetSnapInTitleAttribute();
						SnapInDescriptionAttribute da = r.GetSnapInDescriptionAttribute();

						string name = descriptor.Type.FullName;
						string description = null;

						if (ta != null)
							name = ta.Title;

						if (da != null)
							description = da.Description;

						e.Features.Add(new SnapInFeature(name, description, descriptor.Type, FeatureActions.Reinstall));
					}
					catch(System.Exception systemException)
					{
						System.Diagnostics.Trace.WriteLine(systemException);
					}
				}
			}
		}