// Path: engine/src/main/java/com/impossibl/stencil/api/ExtensionMethods.java
// public interface ExtensionMethods {
//   
// }


import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import com.google.common.base.Objects;
import com.impossibl.stencil.api.ExtensionMethods;
package com.impossibl.stencil.engine.internal;



public class ExtensionMethodManager {
  
  private static class MethodId {

    public Class<?> extendedClass;
    public String extensionMethodName;

    public MethodId(Class<?> extendedClass, String extensionMethodName) {
      this.extendedClass = extendedClass;
      this.extensionMethodName = extensionMethodName;
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(extendedClass, extensionMethodName);
    }

    @Override
    public boolean equals(Object obj) {
      MethodId other = (MethodId) obj;
      return
          Objects.equal(extendedClass, other.extendedClass) && 
          Objects.equal(extensionMethodName, other.extensionMethodName);
    }
    
  }
  
  private static Map<MethodId,Method> extensionMap = createExtensionFunctionMap();
  
  static Map<MethodId, Method> createExtensionFunctionMap() {
    
    Map<MethodId, Method> exts = new HashMap<>();
    
// Path: engine/src/main/java/com/impossibl/stencil/api/ExtensionMethods.java
// public interface ExtensionMethods {
//   
// }


// Path: engine/src/main/java/com/impossibl/stencil/engine/internal/ExtensionMethodManager.java
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import com.google.common.base.Objects;
import com.impossibl.stencil.api.ExtensionMethods;

package com.impossibl.stencil.engine.internal;



public class ExtensionMethodManager {
  
  private static class MethodId {

    public Class<?> extendedClass;
    public String extensionMethodName;

    public MethodId(Class<?> extendedClass, String extensionMethodName) {
      this.extendedClass = extendedClass;
      this.extensionMethodName = extensionMethodName;
    }

    @Override
    public int hashCode() {
      return Objects.hashCode(extendedClass, extensionMethodName);
    }

    @Override
    public boolean equals(Object obj) {
      MethodId other = (MethodId) obj;
      return
          Objects.equal(extendedClass, other.extendedClass) && 
          Objects.equal(extensionMethodName, other.extensionMethodName);
    }
    
  }
  
  private static Map<MethodId,Method> extensionMap = createExtensionFunctionMap();
  
  static Map<MethodId, Method> createExtensionFunctionMap() {
    
    Map<MethodId, Method> exts = new HashMap<>();
    
    ServiceLoader<ExtensionMethods> extensionLoader = ServiceLoader.load(ExtensionMethods.class);