bool prepareRequest(request_rec *r, DirConfig *config, const char *filename, bool coreModuleWillBeRun = false) {
		TRACE_POINT();
		
		DirectoryMapper mapper(r, config, &cstat, config->getStatThrottleRate());
		try {
			if (mapper.getApplicationType() == PAT_NONE) {
				// (B) is not true.
				disableRequestNote(r);
				return false;
			}
		} catch (const DocumentRootDeterminationError &e) {
			auto_ptr<RequestNote> note(new RequestNote(mapper, config));
			note->errorReport = new ReportDocumentRootDeterminationError(e);
			apr_pool_userdata_set(note.release(), "Phusion Passenger",
				RequestNote::cleanup, r->pool);
			return true;
		} catch (const FileSystemException &e) {
			/* DirectoryMapper tried to examine the filesystem in order
			 * to autodetect the application type (e.g. by checking whether
			 * environment.rb exists. But something went wrong, probably
			 * because of a permission problem. This usually
			 * means that the user is trying to deploy an application, but
			 * set the wrong permissions on the relevant folders.
			 * Later, in the handler hook, we inform the user about this
			 * problem so that he can either disable Phusion Passenger's
			 * autodetection routines, or fix the permissions.
			 *
			 * If it's not a permission problem then we'll disable
			 * Phusion Passenger for the rest of the request.
			 */
			if (e.code() == EACCES || e.code() == EPERM) {
				auto_ptr<RequestNote> note(new RequestNote(mapper, config));
				note->errorReport = new ReportFileSystemError(e);
				apr_pool_userdata_set(note.release(), "Phusion Passenger",
					RequestNote::cleanup, r->pool);
				return true;
			} else {
				disableRequestNote(r);
				return false;
			}
		}
		
		// (B) is true.
		
		try {
			FileType fileType = getFileType(filename);
			if (fileType == FT_REGULAR) {
				// (C) is true.
				disableRequestNote(r);
				return false;
			}
			
			// (C) is not true. Check whether (D) is true.
			char *pageCacheFile;
			/* Only GET requests may hit the page cache. This is
			 * important because of REST conventions, e.g.
			 * 'POST /foo' maps to 'FooController#create',
			 * while 'GET /foo' maps to 'FooController#index'.
			 * We wouldn't want our page caching support to interfere
			 * with that.
			 */
			if (r->method_number == M_GET) {
				if (fileType == FT_DIRECTORY) {
					size_t len;
					
					len = strlen(filename);
					if (len > 0 && filename[len - 1] == '/') {
						pageCacheFile = apr_pstrcat(r->pool, filename,
							"index.html", (char *) NULL);
					} else {
						pageCacheFile = apr_pstrcat(r->pool, filename,
							".html", (char *) NULL);
					}
				} else {
					pageCacheFile = apr_pstrcat(r->pool, filename,
						".html", (char *) NULL);
				}
				if (!fileExists(pageCacheFile)) {
					pageCacheFile = NULL;
				}
			} else {
				pageCacheFile = NULL;
			}
			if (pageCacheFile != NULL) {
				// (D) is true.
				r->filename = pageCacheFile;
				r->canonical_filename = pageCacheFile;
				if (!coreModuleWillBeRun) {
					r->finfo.filetype = APR_NOFILE;
					ap_set_content_type(r, "text/html");
					ap_directory_walk(r);
					ap_file_walk(r);
				}
				return false;
			} else {
				// (D) is not true.
				RequestNote *note = new RequestNote(mapper, config);
				apr_pool_userdata_set(note, "Phusion Passenger",
					RequestNote::cleanup, r->pool);
				return true;
			}
		} catch (const FileSystemException &e) {
			/* Something went wrong while accessing the directory in which
			 * r->filename lives. We already know that this URI belongs to
			 * a backend application, so this error probably means that the
			 * user set the wrong permissions for his 'public' folder. We
			 * don't let the handler hook run so that Apache can decide how
			 * to display the error.
			 */
			disableRequestNote(r);
			return false;
		}
	}