docs: public static Template<?> createTemplate(Context context, MethodTree decl) {
      MethodSymbol declSym = ASTHelpers.getSymbol(decl);
      ImmutableClassToInstanceMap<Annotation> annotations = UTemplater.annotationMap(declSym);
      ImmutableMap<String, VarSymbol> freeExpressionVars = freeExpressionVariables(decl);
      Context subContext = new SubContext(context);
      final UTemplater templater = new UTemplater(freeExpressionVars, subContext);
      ImmutableMap<String, UType> expressionVarTypes =
          ImmutableMap.copyOf(
              Maps.transformValues(
                  freeExpressionVars, (VarSymbol sym) -> templater.template(sym.type)));
  
      UType genericType = templater.template(declSym.type);
      List<UTypeVar> typeParameters;
      UMethodType methodType;
      if (genericType instanceof UForAll) {
        UForAll forAllType = (UForAll) genericType;
        typeParameters = forAllType.getTypeVars();
        methodType = (UMethodType) forAllType.getQuantifiedType();
      } else if (genericType instanceof UMethodType) {
        typeParameters = ImmutableList.of();
        methodType = (UMethodType) genericType;
      } else {
        throw new IllegalArgumentException(
            "Expected genericType to be either a ForAll or a UMethodType, but was " + genericType);
      }
  
      List<? extends StatementTree> bodyStatements = decl.getBody().getStatements();
      if (bodyStatements.size() == 1
          && Iterables.getOnlyElement(bodyStatements).getKind() == Kind.RETURN
          && context.get(REQUIRE_BLOCK_KEY) == null) {
        ExpressionTree expression =
            ((ReturnTree) Iterables.getOnlyElement(bodyStatements)).getExpression();
        return ExpressionTemplate.create(
            annotations,
            typeParameters,
            expressionVarTypes,
            templater.template(expression),
            methodType.getReturnType());
      } else {
        List<UStatement> templateStatements = new ArrayList<>();
        for (StatementTree statement : bodyStatements) {
          templateStatements.add(templater.template(statement));
        }
        return BlockTemplate.create(
            annotations, typeParameters, expressionVarTypes, templateStatements);
      }
    }