if (template != null)
    {
      try
      {
        // create a velocity context
        VelocityContext velocityContext = VelocityManager.getCodeGenContext();
        //  SourceCodeBuffer tracks line number change during codegen
        SourceCodeBuffer out = new SourceCodeBuffer((int) source.size());
        //  create SourceCode wrappers for scripts
        Set<SourceCode> scriptSet = new LinkedHashSet<SourceCode>();
        for (Iterator iter = info.getScripts().iterator(); iter.hasNext(); )
        {
          Script script = (Script) iter.next();
          if (!script.isEmbedded())
          {
            scriptSet.add(new SourceCode(script.getText(), script.getXmlLineNumber(), out, map));
          }
          else
          {
            // use Source.getName() to construct the new VirtualFile name
            String n = source.getName().replace('\\', '/') + ":" + script.getXmlLineNumber() + "," + script.getEndXmlLineNumber();
            VirtualFile f = new TextFile(script.getText(), n, source.getParent(), MimeMappings.AS, source.getLastModified());
                        // line number map is for error reporting, so the names must come from error reporting...
                        LineNumberMap m = new LineNumberMap(source.getNameForReporting(), n);
                        m.put(script.getXmlLineNumber(), 1, (script.getEndXmlLineNumber() - script.getXmlLineNumber()));
                        // C: add this so that when unexpected EOF occurs, (last line + 1) maps to the last line
                        //    in the original XML Script block.
                        m.put(script.getEndXmlLineNumber(), script.getEndXmlLineNumber() - script.getXmlLineNumber() + 1, 1);
                        // 'n' must match 'n' in the include directive...
                        source.addSourceFragment(n, f, m);
                        // 'n' must match 'n' in the addSourceFragment call.
                        scriptSet.add(new SourceCode("include \"" + n + "\";", script.getXmlLineNumber(), out, map));
                    }
                }
                //  create SourceCode wrappers for metadata entries
                Set<SourceCode> metadataSet = new LinkedHashSet<SourceCode>();
                for (Iterator iter = info.getMetadata().iterator(); iter.hasNext(); )
                {
                    Script script = (Script)iter.next();
                    metadataSet.add(new SourceCode(script.getText(), script.getXmlLineNumber(), out, map));
                }
                //  create SourceCode wrappers for variable declarations
                Map<String, SourceCode> varDeclMap = new LinkedHashMap<String, SourceCode>();
                for (Iterator iter = info.getVarDecls().values().iterator(); iter.hasNext(); )
                {
                    DocumentInfo.VarDecl varDecl = (DocumentInfo.VarDecl)iter.next();
                    varDeclMap.put(varDecl.name, new SourceCode(varDecl.className, varDecl.line, out, map));
                }
                int superClassLineNumber = 1;
                Set<SourceCode> importNameSet = new LinkedHashSet<SourceCode>();
                for (Iterator i = info.getImportNames().iterator(); i.hasNext();)
                {
                    DocumentInfo.NameInfo importName = (DocumentInfo.NameInfo) i.next();
                    importNameSet.add(new SourceCode(importName.getName(), importName.getLine(), out, map));
                    if (importName.getName().equals(info.getQualifiedSuperClassName()))
                    {
                        superClassLineNumber = importName.getLine();
                    }
                }
                for (Iterator<String> i = bogusImports.iterator(); i.hasNext();)
                {
                    String importName = i.next();
                    importNameSet.add(new SourceCode(importName, 1, out, map));
                }
                Set<SourceCode> interfaceNameSet = new LinkedHashSet<SourceCode>();
                for (Iterator i = info.getInterfaceNames().iterator(); i.hasNext();)
                {
                    DocumentInfo.NameInfo interfaceName = (DocumentInfo.NameInfo) i.next();
                    interfaceNameSet.add(new SourceCode(interfaceName.getName(), interfaceName.getLine(), out, map));
                }
                // register values
                velocityContext.put("imports", importNameSet);
                velocityContext.put("variables", varDeclMap.entrySet());
                velocityContext.put("scripts", scriptSet);
                velocityContext.put("classMetaData", metadataSet);
                velocityContext.put("bindingManagementVariables", FrameworkDefs.bindingManagementVars);
                // C: should really give line number mappings to superclass name and interface names.
                velocityContext.put("superClassName", new SourceCode(info.getQualifiedSuperClassName(), superClassLineNumber, out, map));
                velocityContext.put("interfaceNames", interfaceNameSet);
                velocityContext.put("className", info.getClassName());
                velocityContext.put("packageName", info.getPackageName());
                // run the template!
                //long s2 = System.currentTimeMillis();
                //VelocityManager.parseTime += s2 - start;
                template.merge(velocityContext, out);