// Path: engine/src/main/java/com/impossibl/stencil/api/Block.java
// public interface Block {
//   
//   /**
//    * Does the block have output available?
//    *  
//    * @return True if the block has output, false if not
//    */
//   boolean getHasOutput();
//   
//   /**
//    * Processes the block and writes the resulting text to the given character
//    * stream
//    * 
//    * @param out Character stream to write to
//    * @throws IOException
//    * @throws ExecutionException 
//    */
//   void write(Writer out) throws IOException, ExecutionException;
// 
// }
// 
// Path: engine/src/main/java/com/impossibl/stencil/api/Callable.java
// public interface Callable {
//   
//   public static final String ALL_PARAM_NAME = "*";
//   public static final String[] ALL_PARAMS = new String[] {ALL_PARAM_NAME};
// 
//   /**
//    * Gets the parameter names this callable will accept.
//    * 
//    * Returning a single parameter name of ALL_PARAM_NAME will result in
//    * the call method being invoked with all parameters passed.
//    * 
//    * @return Array of parameter names in order
//    * @see Callable#ALL_PARAM_NAME
//    * @see Callable#call
//    */
// 	String[] getParameterNames();
// 	
// 	/**
// 	 * Execute the callable with the given parameters.
// 	 * 
// 	 * Note: Positional parameters are passed with names equivalent to their
// 	 * position in the call (e.g. 0=..., 1=..., n=...)
// 	 *  
// 	 * @param params Map of parameters passed in
// 	 * @return The result of the execution
// 	 * @throws Throwable Author may throw any exception
// 	 */
// 	Object call(Map<String,?> params) throws Throwable;
// 	
// }
// 
// Path: engine/src/main/java/com/impossibl/stencil/api/Preparable.java
// public interface Preparable {
//   
//   public static final String ALL_BLOCK_NAME = "*";
//   public static final String[] ALL_BLOCKS = new String[] {ALL_BLOCK_NAME};
// 
//   public static final String UNNAMED_BLOCK_NAME = "+";
// 
//   /**
//    * Gets the block names this preparable will accept.
//    * 
//    * @return Array of parameter names in order
//    * @see Preparable#ALL_BLOCK_NAME
//    * @see Preparable#ALL_BLOCKS
//    * @see Preparable#UNNAMED_BLOCK_NAME
//    * @see Preparable#prepare(Map)
//    */
// 	String[] getBlockNames();
// 	
// 	
//   /**
//    * Execute the preparable with the given parameters.
//    * 
//    * @param params Map of blocks passed in; each value will be a Block or a map of blocks in the "all blocks" case
//    * @return The result of the execution
//    * @throws Throwable Author may throw any exception
//    */
// 	Object prepare(Map<String, ?> params) throws Throwable;
// 	
// }


import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import com.impossibl.stencil.api.Block;
import com.impossibl.stencil.api.Callable;
import com.impossibl.stencil.api.Named;
import com.impossibl.stencil.api.Preparable;
    return ALL_BLOCKS;
  }
  
  @Override
  public Object prepare(Map<String,?> params) throws IOException {
    
    StringWriter out = new StringWriter();
    
    for(Map.Entry<String, ?> paramEntry : params.entrySet()) {
      
      Object param = paramEntry.getValue();
      
      if (param instanceof Block) {
        
        ((Block) param).write(out);
        
      }
      else if (param instanceof Map) {
        
        @SuppressWarnings("unchecked")
        Map<String, Block> otherBlocks = (Map<String, Block>) param;
        
        for (Block block : otherBlocks.values()) {
          block.write(out);
        }
        
      }
      
    }
    
// Path: engine/src/main/java/com/impossibl/stencil/api/Block.java
// public interface Block {
//   
//   /**
//    * Does the block have output available?
//    *  
//    * @return True if the block has output, false if not
//    */
//   boolean getHasOutput();
//   
//   /**
//    * Processes the block and writes the resulting text to the given character
//    * stream
//    * 
//    * @param out Character stream to write to
//    * @throws IOException
//    * @throws ExecutionException 
//    */
//   void write(Writer out) throws IOException, ExecutionException;
// 
// }
// 
// Path: engine/src/main/java/com/impossibl/stencil/api/Callable.java
// public interface Callable {
//   
//   public static final String ALL_PARAM_NAME = "*";
//   public static final String[] ALL_PARAMS = new String[] {ALL_PARAM_NAME};
// 
//   /**
//    * Gets the parameter names this callable will accept.
//    * 
//    * Returning a single parameter name of ALL_PARAM_NAME will result in
//    * the call method being invoked with all parameters passed.
//    * 
//    * @return Array of parameter names in order
//    * @see Callable#ALL_PARAM_NAME
//    * @see Callable#call
//    */
// 	String[] getParameterNames();
// 	
// 	/**
// 	 * Execute the callable with the given parameters.
// 	 * 
// 	 * Note: Positional parameters are passed with names equivalent to their
// 	 * position in the call (e.g. 0=..., 1=..., n=...)
// 	 *  
// 	 * @param params Map of parameters passed in
// 	 * @return The result of the execution
// 	 * @throws Throwable Author may throw any exception
// 	 */
// 	Object call(Map<String,?> params) throws Throwable;
// 	
// }
// 
// Path: engine/src/main/java/com/impossibl/stencil/api/Preparable.java
// public interface Preparable {
//   
//   public static final String ALL_BLOCK_NAME = "*";
//   public static final String[] ALL_BLOCKS = new String[] {ALL_BLOCK_NAME};
// 
//   public static final String UNNAMED_BLOCK_NAME = "+";
// 
//   /**
//    * Gets the block names this preparable will accept.
//    * 
//    * @return Array of parameter names in order
//    * @see Preparable#ALL_BLOCK_NAME
//    * @see Preparable#ALL_BLOCKS
//    * @see Preparable#UNNAMED_BLOCK_NAME
//    * @see Preparable#prepare(Map)
//    */
// 	String[] getBlockNames();
// 	
// 	
//   /**
//    * Execute the preparable with the given parameters.
//    * 
//    * @param params Map of blocks passed in; each value will be a Block or a map of blocks in the "all blocks" case
//    * @return The result of the execution
//    * @throws Throwable Author may throw any exception
//    */
// 	Object prepare(Map<String, ?> params) throws Throwable;
// 	
// }


// Path: engine/src/main/java/com/impossibl/stencil/ext/std/RawFunction.java
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import com.impossibl.stencil.api.Block;
import com.impossibl.stencil.api.Callable;
import com.impossibl.stencil.api.Named;
import com.impossibl.stencil.api.Preparable;

    return ALL_BLOCKS;
  }
  
  @Override
  public Object prepare(Map<String,?> params) throws IOException {
    
    StringWriter out = new StringWriter();
    
    for(Map.Entry<String, ?> paramEntry : params.entrySet()) {
      
      Object param = paramEntry.getValue();
      
      if (param instanceof Block) {
        
        ((Block) param).write(out);
        
      }
      else if (param instanceof Map) {
        
        @SuppressWarnings("unchecked")
        Map<String, Block> otherBlocks = (Map<String, Block>) param;
        
        for (Block block : otherBlocks.values()) {
          block.write(out);
        }
        
      }
      
    }
    
    return out.toString();