Introduce GlobalVariable and GlobalParam. Rename Variable_instance to DeclaredVariable. Get rid of Variable_declaration. Variables should implement Variable_instance. Normal variables don't bother with injectGlobalScope, GlobalVariables do. Variables become their own closures. Forget all the ref counting nonsense, it is not necessary. Normal variables resolve immediately and push themselves on the stack. GlobalVariables resolve on demand. ==================================================== Elements test suite Errors test suite apply:import within for-each is not allowed xsl:number format-number xsl:strip-space and xsl:preserve-space lang() unparsed-entity-uri() xsl:fallback attribute sets two arg version of document() node-set version of document() xsl:sort/@lang forward compatibility element-available function-available output combining (partially done for cdata-section-elements) Performance variable pool string pool? use underlying_impl in XPath axis walker - DONE use underlying_impl in XPath functions - DONE short circuit evaluation in functions only convert to full NodeSet at boundary - DONE use a proxy to return propagate values out of functions params - avoid creating closure for xsl:param if the param has been passed - DONE - if running, resolve variable immediately, don't bother to create closure - when declaring variable, don't create closure/resolve if higher-precedence variable already exists - bin variable_instance_pointer, think I can pass by value - actually, I think we avoid the whole closure creation business by getting the variables to pass in themselves, or a simple wrapper around themselves. Top-level variables can hang on to a pointer to the toplevel injected context. Top level variables are the only ones that need to worry about precedence. Immediate variable can just look up by name, then get on with it.