/// <summary>
		/// Retrives a compiled script.
        /// 
        /// The method check scripts in following order:
        /// 1. Script Library database.
        /// 2. Modified source file on the file system.
        /// 3. Unmodified source file in precompiled WebPages.dll.
		/// </summary>
		/// <param name="sourceFile">Script source file.</param>
		/// <param name="requestContext">The current HTTP context. Can be <c>null</c> in case of desktop app.</param>
		/// <returns>The script type or a <B>null</B> reference on failure.</returns>
        /// <remarks>The method do check the script library database.</remarks>
        public ScriptInfo GetCompiledScript(PhpSourceFile/*!*/ sourceFile, RequestContext requestContext)
        {
            Debug.Assert(sourceFile != null);

            // try to get the script from precompiled script library first
            var scriptLibraryModule = applicationContext.ScriptLibraryDatabase.GetScriptModule(sourceFile.FullPath);
            if (scriptLibraryModule != null)
                return scriptLibraryModule.ScriptInfo;

            // loads precompiled assembly if exists and not loaded yet:
            GetPrecompiledAssembly();

            // enables source code watcher if not enabled yet:
            if (watcher != null && !watcher.EnableRaisingEvents)
            {
                Debug.WriteLine("WSSM", "Source code watcher is starting.");

                watcher.EnableRaisingEvents = true;
            }

            string ns = ScriptModule.GetSubnamespace(sourceFile.RelativePath, false);

            CacheEntry cache_entry;

            if (Configuration.Application.Compiler.OnlyPrecompiledCode)
            {
                // Load script from cache (WebPages.dll)
                if (TryGetCachedEntry(ns, out cache_entry))
                    return cache_entry.ScriptInfo;
                else
                    return null;
            }
            else
            {
                // Load script from cache or from ASP.NET Temporary files
                if (TryLoadCachedEntry(ns, sourceFile, out cache_entry))
                    return cache_entry.ScriptInfo;

                lock (this)
                {
                    // double checked lock, CompileScript should not be called on more threads
                    if (TryGetCachedEntry(ns, out cache_entry))
                        return cache_entry.ScriptInfo;

                    Debug.WriteLine("WSSM", "Compile script '{0}'.", sourceFile.ToString());
                    return CompileScriptNoLock(ns, sourceFile, requestContext);
                }
            }
        }