public GroovyPageParser(
      String name, String uri, String filename, String gspSource, String expressionCodecName)
      throws IOException {
    Config config = Holders.getConfig();
    if (config != null) {
      setEnableSitemeshPreprocessing(
          config.getProperty(
              GroovyPageParser.CONFIG_PROPERTY_GSP_SITEMESH_PREPROCESS,
              Boolean.class,
              enableSitemeshPreprocessing));
    }

    GrailsPluginInfo pluginInfo = null;
    //        TODO: figure out a way to restore plugin metadata for GSP
    //        if (filename != null && BuildSettingsHolder.getSettings() != null) {
    //            pluginInfo =
    // GrailsPluginUtils.getPluginBuildSettings().getPluginInfoForSource(filename);
    //            if (pluginInfo != null) {
    //                pluginAnnotation = "@GrailsPlugin(name='" + pluginInfo.getName() + "',
    // version='" +
    //                    pluginInfo.getVersion() + "')";
    //            }
    //        }

    OutputEncodingSettings gspConfig = new OutputEncodingSettings(config);

    this.expressionCodecDirectiveValue = expressionCodecName;
    if (expressionCodecDirectiveValue == null) {
      expressionCodecDirectiveValue =
          gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.EXPRESSION_CODEC_NAME);
    }
    staticCodecDirectiveValue =
        gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.STATIC_CODEC_NAME);
    outCodecDirectiveValue =
        gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.OUT_CODEC_NAME);
    taglibCodecDirectiveValue =
        gspConfig.getCodecSettings(pluginInfo, OutputEncodingSettings.TAGLIB_CODEC_NAME);

    Map<String, String> directives = parseDirectives(gspSource);

    if (isSitemeshPreprocessingEnabled(directives.get(SITEMESH_PREPROCESS_DIRECTIVE))) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Preprocessing "
                + uri
                + " for sitemesh. Replacing head, title, meta and body elements with sitemesh:capture*.");
      }
      // GSP preprocessing for direct sitemesh integration: replace head -> g:captureHead, title ->
      // g:captureTitle, meta -> g:captureMeta, body -> g:captureBody
      gspSource = sitemeshPreprocessor.addGspSitemeshCapturing(gspSource);
      sitemeshPreprocessMode = true;
    }
    scan = new GroovyPageScanner(gspSource, uri);
    pageName = uri;
    environment = Environment.getCurrent();
    makeName(name);
    makeSourceName(filename);
  }