Program: 15576
Project: 15576
Buggy source:
private Template getTemplate(TemplateLoader loader,String name,Locale locale,String encoding,boolean parse) throws IOException {
  boolean debug=LOG.isDebugEnabled();
  final String debugName=debug ? buildDebugName(name,locale,encoding,parse) : null;
  TemplateKey tk=new TemplateKey(name,locale,encoding,parse);
  CachedTemplate cachedTemplate;
  if (isStorageConcurrent) {
    cachedTemplate=(CachedTemplate)storage.get(tk);
  }
 else {
synchronized (storage) {
      cachedTemplate=(CachedTemplate)storage.get(tk);
    }
  }
  long now=System.currentTimeMillis();
  long lastModified=-1L;
  Object newlyFoundSource=null;
  boolean rethrown=false;
  try {
    if (cachedTemplate != null) {
      if (now - cachedTemplate.lastChecked < delay) {
        if (debug) {
          LOG.debug(debugName + "String_Node_Str");
        }
        Object t=cachedTemplate.templateOrException;
        if (t instanceof Template || t == null) {
          return (Template)t;
        }
 else         if (t instanceof RuntimeException) {
          throwLoadFailedException((RuntimeException)t);
        }
 else         if (t instanceof IOException) {
          rethrown=true;
          throwLoadFailedException((IOException)t);
        }
        throw new BugException("String_Node_Str" + t.getClass().getName());
      }
      cachedTemplate=cachedTemplate.cloneCachedTemplate();
      cachedTemplate.lastChecked=now;
      newlyFoundSource=findTemplateSource(name,locale);
      if (newlyFoundSource == null) {
        if (debug) {
          LOG.debug(debugName + "String_Node_Str");
        }
        storeNegativeLookup(tk,cachedTemplate,null);
        return null;
      }
      lastModified=loader.getLastModified(newlyFoundSource);
      boolean lastModifiedNotChanged=lastModified == cachedTemplate.lastModified;
      boolean sourceEquals=newlyFoundSource.equals(cachedTemplate.source);
      if (lastModifiedNotChanged && sourceEquals) {
        if (debug) {
          LOG.debug(debugName + "String_Node_Str" + newlyFoundSource+ "String_Node_Str");
        }
        storeCached(tk,cachedTemplate);
        return (Template)cachedTemplate.templateOrException;
      }
 else {
        if (debug && !sourceEquals) {
          LOG.debug("String_Node_Str" + "String_Node_Str" + sourceEquals + "String_Node_Str"+ StringUtil.jQuoteNoXSS(newlyFoundSource)+ "String_Node_Str"+ StringUtil.jQuoteNoXSS(cachedTemplate.source));
        }
        if (debug && !lastModifiedNotChanged) {
          LOG.debug("String_Node_Str" + "String_Node_Str" + lastModifiedNotChanged + "String_Node_Str"+ cachedTemplate.lastModified+ "String_Node_Str"+ lastModified);
        }
        cachedTemplate.source=newlyFoundSource;
      }
    }
 else {
      if (debug) {
        LOG.debug("String_Node_Str" + debugName + "String_Node_Str");
      }
      cachedTemplate=new CachedTemplate();
      cachedTemplate.lastChecked=now;
      newlyFoundSource=findTemplateSource(name,locale);
      if (newlyFoundSource == null) {
        storeNegativeLookup(tk,cachedTemplate,null);
        return null;
      }
      cachedTemplate.source=newlyFoundSource;
      cachedTemplate.lastModified=lastModified=Long.MIN_VALUE;
    }
    if (debug) {
      LOG.debug("String_Node_Str" + debugName + "String_Node_Str"+ StringUtil.jQuoteNoXSS(newlyFoundSource));
    }
    Object source=cachedTemplate.source;
    Template t=loadTemplate(loader,name,locale,encoding,parse,source);
    cachedTemplate.templateOrException=t;
    cachedTemplate.lastModified=lastModified == Long.MIN_VALUE ? loader.getLastModified(source) : lastModified;
    storeCached(tk,cachedTemplate);
    return t;
  }
 catch (  RuntimeException e) {
    if (cachedTemplate != null) {
      storeNegativeLookup(tk,cachedTemplate,e);
    }
    throw e;
  }
catch (  IOException e) {
    if (!rethrown) {
      storeNegativeLookup(tk,cachedTemplate,e);
    }
    throw e;
  }
 finally {
    if (newlyFoundSource != null) {
      loader.closeTemplateSource(newlyFoundSource);
    }
  }
}

Fixed version (ground truth):
private Template getTemplate(TemplateLoader loader,String name,Locale locale,String encoding,boolean parse) throws IOException {
  boolean debug=LOG.isDebugEnabled();
  final String debugName=debug ? buildDebugName(name,locale,encoding,parse) : null;
  TemplateKey tk=new TemplateKey(name,locale,encoding,parse);
  CachedTemplate cachedTemplate;
  if (isStorageConcurrent) {
    cachedTemplate=(CachedTemplate)storage.get(tk);
  }
 else {
synchronized (storage) {
      cachedTemplate=(CachedTemplate)storage.get(tk);
    }
  }
  final long now=System.currentTimeMillis();
  long lastModified=-1L;
  boolean rethrown=false;
  TemplateLookupResult newLookupResult=null;
  try {
    if (cachedTemplate != null) {
      if (now - cachedTemplate.lastChecked < delay) {
        if (debug) {
          LOG.debug(debugName + "String_Node_Str");
        }
        Object t=cachedTemplate.templateOrException;
        if (t instanceof Template || t == null) {
          return (Template)t;
        }
 else         if (t instanceof RuntimeException) {
          throwLoadFailedException((RuntimeException)t);
        }
 else         if (t instanceof IOException) {
          rethrown=true;
          throwLoadFailedException((IOException)t);
        }
        throw new BugException("String_Node_Str" + t.getClass().getName());
      }
      cachedTemplate=cachedTemplate.cloneCachedTemplate();
      cachedTemplate.lastChecked=now;
      newLookupResult=lookupTemplate(name,locale);
      if (newLookupResult == null) {
        if (debug) {
          LOG.debug(debugName + "String_Node_Str");
        }
        storeNegativeLookup(tk,cachedTemplate,null);
        return null;
      }
      final Object newLookupResultSource=newLookupResult.getTemplateSource();
      lastModified=loader.getLastModified(newLookupResultSource);
      boolean lastModifiedNotChanged=lastModified == cachedTemplate.lastModified;
      boolean sourceEquals=newLookupResultSource.equals(cachedTemplate.source);
      if (lastModifiedNotChanged && sourceEquals) {
        if (debug) {
          LOG.debug(debugName + "String_Node_Str" + newLookupResultSource+ "String_Node_Str");
        }
        storeCached(tk,cachedTemplate);
        return (Template)cachedTemplate.templateOrException;
      }
 else       if (debug) {
        if (!sourceEquals) {
          LOG.debug("String_Node_Str" + "String_Node_Str" + sourceEquals + "String_Node_Str"+ StringUtil.jQuoteNoXSS(newLookupResultSource)+ "String_Node_Str"+ StringUtil.jQuoteNoXSS(cachedTemplate.source));
        }
 else         if (!lastModifiedNotChanged) {
          LOG.debug("String_Node_Str" + "String_Node_Str" + lastModifiedNotChanged + "String_Node_Str"+ cachedTemplate.lastModified+ "String_Node_Str"+ lastModified);
        }
      }
    }
 else {
      if (debug) {
        LOG.debug("String_Node_Str" + debugName + "String_Node_Str");
      }
      cachedTemplate=new CachedTemplate();
      cachedTemplate.lastChecked=now;
      newLookupResult=lookupTemplate(name,locale);
      if (newLookupResult == null) {
        storeNegativeLookup(tk,cachedTemplate,null);
        return null;
      }
      cachedTemplate.lastModified=lastModified=Long.MIN_VALUE;
    }
    Object source=newLookupResult.getTemplateSource();
    cachedTemplate.source=source;
    if (debug) {
      LOG.debug("String_Node_Str" + debugName + "String_Node_Str"+ StringUtil.jQuoteNoXSS(source));
    }
    Template t=loadTemplate(loader,name,newLookupResult.getTemplateSourceName(),locale,encoding,parse,source);
    cachedTemplate.templateOrException=t;
    cachedTemplate.lastModified=lastModified == Long.MIN_VALUE ? loader.getLastModified(source) : lastModified;
    storeCached(tk,cachedTemplate);
    return t;
  }
 catch (  RuntimeException e) {
    if (cachedTemplate != null) {
      storeNegativeLookup(tk,cachedTemplate,e);
    }
    throw e;
  }
catch (  IOException e) {
    if (!rethrown) {
      storeNegativeLookup(tk,cachedTemplate,e);
    }
    throw e;
  }
 finally {
    if (newLookupResult != null) {
      loader.closeTemplateSource(newLookupResult.getTemplateSource());
    }
  }
}