/// <summary>
        /// Registers all the services used by the application in the <paramref name="nucleus"/>.
        /// </summary>
        /// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
        protected override void DoBootstrap(IConfigurableNucleus nucleus)
        {
            // initialize the Facebook service
            nucleus.Register<IFacebookSocialService>(resolver => new FacebookSocialService(resolver.ResolveSingle<IConversionService>()));
            nucleus.Register<ISocialService>("facebook", resolver => resolver.ResolveSingle<IFacebookSocialService>());

            // register the social discovery service, initialized with all the social services
            nucleus.Register<ISocialServiceDiscoveryService>(resolver => new SocialServiceDiscoveryService(resolver.Resolve<ISocialService>()));
        }
		/// <summary>
		/// Scans the given <paramref name="assemblies"/> and register all the type marked with <see cref="ExportedAttribute"/> within the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the types.</param>
		/// <param name="assemblies">The <see cref="Assembly"/>s which to scan for types.</param>
		private static void Scan(IConfigurableNucleus nucleus, IEnumerable<Assembly> assemblies)
		{
			// validate arguments
			if (nucleus == null)
				throw new ArgumentNullException("nucleus");
			if (assemblies == null)
				throw new ArgumentNullException("assemblies");

			// select all the exported types
			var exportedTypes = assemblies.SelectMany(assembly => assembly.GetTypesSafe()).Where(candidate => !candidate.IsAbstract).SelectMany(type => type.GetCustomAttributes(typeof (ExportedAttribute), true).Select(attribute => new
			                                                                                                                                                                                                                           {
			                                                                                                                                                                                                                           	Type = type,
			                                                                                                                                                                                                                           	ExportedAttribute = (ExportedAttribute) attribute
			                                                                                                                                                                                                                           })).ToList();

			// select all the named types
			var namedTypes = exportedTypes.Where(candidate => candidate.ExportedAttribute is NamedAttribute).ToList();

			// remove all the named types from the exported types, group the remainder by their contract type and select only the first per contract type
			exportedTypes = exportedTypes.Except(namedTypes).ToList().GroupBy(candidate => candidate.Type.Name, (key, values) => values.First()).ToList();

			// deduplicate the named types by their name and select only the first one
			var deduplicatedNamedTypes = namedTypes.Select(type => new
			                                                       {
			                                                       	Name = StrongNameGenerator.Generate((NamedAttribute) type.ExportedAttribute),
			                                                       	type.Type,
			                                                       	type.ExportedAttribute
			                                                       }).GroupBy(candidate => candidate.Name, (key, values) => values.First(), StringComparer.OrdinalIgnoreCase).ToList();

			// find the methods method
			var createInstanceFactoryMethodInfo = typeof (Extensions).GetMethod("CreateInstanceFactory");
			if (createInstanceFactoryMethodInfo == null)
				throw new InvalidOperationException("Could not find CreateInstanceFactory method on Extensions");
			var registerWithKeyMethodInfo = typeof (IConfigurableNucleus).GetMethods().First(candidate => candidate.Name.Equals("Register") && candidate.GetParameters().Length == 2);
			if (registerWithKeyMethodInfo == null)
				throw new InvalidOperationException("Could not find Register with key method on IConfigurableNucleus");

			// register all the exported types
			foreach (var type in exportedTypes)
			{
				// create the factory
				var factoryInstance = createInstanceFactoryMethodInfo.MakeGenericMethod(type.ExportedAttribute.ContractType).Invoke(null, new object[] {type.Type});

				// register the component
				registerWithKeyMethodInfo.MakeGenericMethod(type.ExportedAttribute.ContractType).Invoke(nucleus, new[] {type.Type.FullName, factoryInstance});
			}

			// register all the named types
			foreach (var type in deduplicatedNamedTypes)
			{
				// create the factory
				var factoryInstance = createInstanceFactoryMethodInfo.MakeGenericMethod(type.ExportedAttribute.ContractType).Invoke(null, new object[] {type.Type});

				// register the component
				registerWithKeyMethodInfo.MakeGenericMethod(type.ExportedAttribute.ContractType).Invoke(nucleus, new[] {type.Name, factoryInstance});
			}
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		public void Bootstrap(IConfigurableNucleus nucleus)
		{
			// validate arguments
			if (nucleus == null)
				throw new ArgumentNullException("nucleus");

			// invoke template method
			DoBootstrap(nucleus);
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
			// register the ElasticSearch services
			nucleus.Register(resolver => new ConnectionManager());
			nucleus.Register(resolver => new IndexDefinitionResolver(resolver.ResolveSingle<ITypeService>(), resolver.ResolveSingle<ICachingService>()));
			nucleus.Register(resolver => new Indexer(resolver.ResolveSingle<ConnectionManager>(), resolver.ResolveSingle<IndexDefinitionResolver>()));
			nucleus.Register(resolver => new Searcher(resolver.ResolveSingle<ConnectionManager>(), resolver.ResolveSingle<IndexDefinitionResolver>(), resolver.Resolve<IQueryComponentMapper>()));
			nucleus.Register<BaseIndexEngine>("elasticsearch:indexengine", resolver => new ElasticSearchIndexEngine(resolver.ResolveSingle<Indexer>()));
			nucleus.Register<BaseQueryEngine>("elasticsearch:queryengine", resolver => new ElasticSearchQueryEngine(resolver.ResolveSingle<Searcher>(), resolver.ResolveSingle<IndexDefinitionResolver>()));
		}
 /// <summary>
 /// Registers all the services used by the application in the <paramref name="nucleus"/>.
 /// </summary>
 /// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
 protected override void DoBootstrap(IConfigurableNucleus nucleus)
 {
     // registers the portal service
     nucleus.Register<IPortalService>(resolver => new PortalService(
                                                  	resolver.ResolveSingle<ICachingService>(),
                                                  	resolver.ResolveSingle<ITemplateService>(),
                                                  	resolver.ResolveSingle<IApplicationResourceService>(),
                                                  	resolver.ResolveSingle<ITagScriptService>(),
                                                  	resolver.ResolveSingle<IConversionService>()
                                                  	));
 }
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
			// if elastic search is not configured, do not register its services
			var appSettings = ConfigurationManager.AppSettings;
			var connectionString = appSettings[Constants.ConnectionStringApplicationSettingKey];
			if (string.IsNullOrEmpty(connectionString))
				return;

			// register the SQL-server services.
			nucleus.Register(resolver => Create());
			nucleus.Register<BaseStorageEngine>(resolver => new SqlServerStorageEngine(resolver.ResolveSingle<SqlServerRepository>()));
			nucleus.Register<BaseQueryEngine>("sqlserver:queryengine", resolver => new SqlServerQueryEngine(
			                                                                       	resolver.ResolveSingle<SqlServerRepository>(),
			                                                                       	resolver.Resolve<IQueryComponentConverter>()
			                                                                       	));
		}
		/// <summary>
		/// Initializes the reflection service, which registers all the exported types with the given <paramref name="assemblies"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/>.</param>
		/// <param name="assemblies">The ordered set of <see cref="Assembly"/>s.</param>
		public void Initialize(IConfigurableNucleus nucleus, IEnumerable<Assembly> assemblies)
		{
			// validate arguments
			if (nucleus == null)
				throw new ArgumentNullException("nucleus");
			if (assemblies == null)
				throw new ArgumentNullException("assemblies");

			// set values
			assemblies = assemblies.ToArray();
			Assemblies = new Queue<Assembly>(assemblies);
			AssembliesReversed = new Stack<Assembly>(assemblies);

			// scan all the assemblies and register the types in them
			Scan(nucleus, Assemblies);
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
			// register default services
			nucleus.Register<ICachingService>(resolver => new HttpCachingService());
			nucleus.Register<IConversionService>(resolver => new ConversionService(resolver.Resolve<IConverter>(), resolver.Resolve<IComparer>()));
			nucleus.Register<ITemplateService>(resolver => new HtmlTemplateService(resolver.Resolve<SectionInterpreter>(), resolver.ResolveSingle<ICachingService>()));
			nucleus.Register<ITypeService>(resolver => new XmlTypeService(resolver.ResolveSingle<ICachingService>(), resolver.ResolveSingle<IApplicationResourceService>()));
			nucleus.Register<ISecurityService>(resolver => new WebSecurityService(resolver.ResolveSingle<IConversionService>(), resolver.Resolve<AuthenticationProvider>(), resolver.ResolveSingle<IEncryptionService>()));
			nucleus.Register<ISecurityPersistenceService>(resolver => new RepositorySecurityPersistenceService());
			nucleus.Register<ISecurityModelService>(resolver => new SecurityModelService(resolver.ResolveSingle<ISecurityPersistenceService>()));
			nucleus.Register<ITagScriptService>(resolver => new TagScriptService(resolver.ResolveSingle<ICachingService>()));
			nucleus.Register<IExpressionScriptService>(resolver => new ExpressionScriptService(resolver.Resolve<ExpressionPartInterpreter>(), resolver.ResolveSingle<ICachingService>()));
			nucleus.Register<IMailService>(resolver => new StandardMailService());
			nucleus.Register<INodeUrlService>(resolver => new NodeUrlService(resolver, resolver.ResolveSingle<ITypeService>()));
			nucleus.Register<IApplicationResourceService>(resolver => new EmbeddedApplicationResourceService("Web", resolver.Resolve<ResourcePathInterpreter>(), resolver.ResolveSingle<IReflectionService>()));
            nucleus.Register<IContentResourceService>(resolver => new WindowsContentResourceService(HttpRuntime.AppDomainAppPath, "Content"));

			// register custom services
			// TODO: register your custom services here
		}
        /// <summary>
        /// Registers all the services used by the application in the <paramref name="nucleus"/>.
        /// </summary>
        /// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
        protected override void DoBootstrap(IConfigurableNucleus nucleus)
        {
            nucleus.Register<ICachingService>(resolver => new HttpCachingService());
            nucleus.Register<IConversionService>(resolver => new ConversionService(resolver.Resolve<IConverter>(), resolver.Resolve<IComparer>()));
            nucleus.Register<ITemplateService>(resolver => new HtmlTemplateService(resolver.Resolve<SectionInterpreter>(), resolver.ResolveSingle<ICachingService>()));
            nucleus.Register<ITypeService>(resolver => new XmlTypeService(resolver.ResolveSingle<ICachingService>(), resolver.ResolveSingle<IApplicationResourceService>()));
            nucleus.Register<ISecurityService>(resolver => new WebSecurityService(resolver.ResolveSingle<IConversionService>(), resolver.Resolve<AuthenticationProvider>(), resolver.ResolveSingle<IEncryptionService>()));
            nucleus.Register<ISecurityPersistenceService>(resolver => new RepositorySecurityPersistenceService());
            nucleus.Register<ISecurityModelService>(resolver => new SecurityModelService(resolver.ResolveSingle<ISecurityPersistenceService>()));
            nucleus.Register<ITagScriptService>(resolver => new TagScriptService(resolver.ResolveSingle<ICachingService>()));
            nucleus.Register<IExpressionScriptService>(resolver => new ExpressionScriptService(resolver.Resolve<ExpressionPartInterpreter>(), resolver.ResolveSingle<ICachingService>()));
            nucleus.Register<IMailService>(resolver => new StandardMailService());
            nucleus.Register<INodeUrlService>(resolver => new NodeUrlService(resolver, resolver.ResolveSingle<ITypeService>()));
            nucleus.Register<IApplicationResourceService>(resolver => new EmbeddedApplicationResourceService("Web", resolver.Resolve<ResourcePathInterpreter>(), resolver.ResolveSingle<IReflectionService>()));
            nucleus.Register<IContentResourceService>(resolver => new S3ContentResourceService());
            //nucleus.Register<IContentResourceService>(resolver => new WindowsContentResourceService(HttpRuntime.AppDomainAppPath, "Content"));
            nucleus.Register<IAssetService>(resolver => new AssetService(resolver.ResolveSingle<IContentResourceService>()));

            // test service
            nucleus.Register(resolver=>new CoolAndUsefulService());
            nucleus.Register(resolver=>new PirateAndUsefulService());
            nucleus.Register<IMyUsefulService>("cool-speak", resolver=>resolver.ResolveSingle<CoolAndUsefulService>());
            nucleus.Register<IMyUsefulService>("pirate-speak", resolver=>resolver.ResolveSingle<PirateAndUsefulService>());
        }
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
			nucleus.Register<IEncryptionService>(resolver => DotNetCryptoEncryptionService.Create());
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
			// register the query argument parser
			nucleus.Register<IQueryParser>(resolver => new QueryParser(resolver.Resolve<QueryArgumentProcessor>()));
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected override void DoBootstrap(IConfigurableNucleus nucleus)
		{
			nucleus.Register<ISchedulerService>(resolver => new QuartzSchedulerService());
		}
		/// <summary>
		/// Registers all the services used by the application in the <paramref name="nucleus"/>.
		/// </summary>
		/// <param name="nucleus">The <see cref="IConfigurableNucleus"/> in which to register the services used by the application.</param>
		protected abstract void DoBootstrap(IConfigurableNucleus nucleus);