code: private TemplateModel applyPreProcessorsIfNeeded(final ITemplateContext context, final TemplateModel templateModel) {
  
          final TemplateData templateData = templateModel.getTemplateData();
  
          if (this.configuration.getPreProcessors(templateData.getTemplateMode()).isEmpty()) {
              return templateModel;
          }
  
          final IEngineContext engineContext =
                  EngineContextManager.prepareEngineContext(this.configuration, templateData, context.getTemplateResolutionAttributes(), context);
  
          final ModelBuilderTemplateHandler builderHandler = new ModelBuilderTemplateHandler(this.configuration, templateData);
          final ITemplateHandler processingHandlerChain =
                  createTemplateProcessingHandlerChain(engineContext, true, false, builderHandler, null);
  
          templateModel.process(processingHandlerChain);
  
          EngineContextManager.disposeEngineContext(engineContext);
  
          return builderHandler.getModel();
  
      }
docs: /*
  This method manually applies preprocessors to template models that have just been parsed or obtained from
  cache. This is needed for fragments, just before these fragments (coming from templates, not simply parsed
  text) are returned to whoever needs them (usually the fragment insertion mechanism).
  
  NOTE that PRE-PROCESSOR INSTANCES ARE NOT SHARED among the different fragments being inserted
  in a template (or between fragments and the main template). The reason for this is that pre-processors are
  implementations of ITemplateHandler and therefore instances are inserted into processing chains that cannot
  be broken (if a pre-processor is used for the main template its "next" step in the chain cannot be
  'momentarily' changed in order to be a fragment-building handler instead of the ProcessorTemplateHandler)
  
  The only way therefore among pre-processor instances to actually share information is by setting it into
  the context.