protected InMemoryCompiledFunctionRepository compile(
     final FunctionCompilationContext context,
     final FunctionRepository functions,
     final Instant atInstant,
     final InMemoryCompiledFunctionRepository before,
     final InMemoryCompiledFunctionRepository after,
     final ExecutorService executorService) {
   final InMemoryCompiledFunctionRepository compiled =
       new InMemoryCompiledFunctionRepository(context);
   final ExecutorCompletionService<CompiledFunctionDefinition> completionService =
       new ExecutorCompletionService<CompiledFunctionDefinition>(executorService);
   int numCompiles = 0;
   for (final FunctionDefinition function : functions.getAllFunctions()) {
     if (addFunctionFromCachedRepository(before, after, compiled, function, atInstant)) {
       continue;
     }
     completionService.submit(
         new Callable<CompiledFunctionDefinition>() {
           @Override
           public CompiledFunctionDefinition call() throws Exception {
             try {
               s_logger.debug("Compiling {}", function);
               return function.compile(context, atInstant);
             } catch (Exception e) {
               s_logger.error("Compiling {} threw {}", function.getShortName(), e);
               throw e;
             }
           }
         });
     numCompiles++;
   }
   for (int i = 0; i < numCompiles; i++) {
     Future<CompiledFunctionDefinition> future;
     try {
       future = completionService.take();
     } catch (InterruptedException e1) {
       Thread.interrupted();
       throw new OpenGammaRuntimeException("Interrupted while compiling function definitions.");
     }
     try {
       CompiledFunctionDefinition compiledFunction = future.get();
       compiled.addFunction(compiledFunction);
     } catch (Exception e) {
       s_logger.debug("Error compiling function definition", e);
       // Don't propagate the error outwards; it just won't be in the compiled repository
     }
   }
   return compiled;
 }
 @Override
 public CompiledFunctionRepository compile(
     final FunctionRepository repository,
     final FunctionCompilationContext context,
     final ExecutorService executor,
     final InstantProvider atInstantProvider) {
   clearInvalidCache(context.getFunctionInitId());
   final Instant atInstant = Instant.of(atInstantProvider);
   final Pair<FunctionRepository, Instant> key = Pair.of(repository, atInstant);
   // Try a previous compilation
   final InMemoryCompiledFunctionRepository previous = getPreviousCompilation(key);
   if (previous != null) {
     if (previous.getLatestInvocationTime() == null) {
       return previous;
     } else {
       if (!atInstant.isAfter(previous.getLatestInvocationTime())) {
         return previous;
       }
     }
   }
   // Try a future compilation
   final InMemoryCompiledFunctionRepository next = getNextCompilation(key);
   if (next != null) {
     if (next.getEarliestInvocationTime() == null) {
       return next;
     } else {
       if (!atInstant.isBefore(next.getEarliestInvocationTime())) {
         return next;
       }
     }
   }
   // Try the exact timestamp
   InMemoryCompiledFunctionRepository compiled = getCachedCompilation(key);
   if (compiled != null) {
     return compiled;
   }
   // Create a compilation, salvaging results from previous and next if possible
   compiled = compile(context, repository, atInstant, previous, next, executor);
   cacheCompilation(key, compiled);
   return compiled;
 }
 protected boolean addFunctionFromCachedRepository(
     final InMemoryCompiledFunctionRepository before,
     final InMemoryCompiledFunctionRepository after,
     final InMemoryCompiledFunctionRepository compiled,
     final FunctionDefinition function,
     final Instant atInstant) {
   if (before != null) {
     final CompiledFunctionDefinition compiledFunction =
         before.findDefinition(function.getUniqueId());
     if (compiledFunction.getLatestInvocationTime() == null) {
       // previous one always valid
       compiled.addFunction(compiledFunction);
       return true;
     } else {
       final Instant validUntil = Instant.of(compiledFunction.getLatestInvocationTime());
       if (!validUntil.isBefore(atInstant)) {
         // previous one still valid
         compiled.addFunction(compiledFunction);
         return true;
       }
     }
   }
   if (after != null) {
     final CompiledFunctionDefinition compiledFunction =
         after.findDefinition(function.getUniqueId());
     if (compiledFunction.getEarliestInvocationTime() == null) {
       // next one always valid
       compiled.addFunction(compiledFunction);
       return true;
     } else {
       final Instant validFrom = Instant.of(compiledFunction.getEarliestInvocationTime());
       if (!validFrom.isAfter(atInstant)) {
         // next one already valid
         compiled.addFunction(compiledFunction);
         return true;
       }
     }
   }
   return false;
 }