docs: private boolean checkVarContextProvider(final TypeMirror typeMirror) {
          final TypeElement element = (TypeElement) types.asElement(typeMirror);
          if (varContextProviders.contains(typeMirror)) { // this VarContextProvider is already processed
              return true;
          }
  
          if (!element.getKind().isInterface()) { //check whether class is interface
              messager.printMessage(
                      Diagnostic.Kind.ERROR,
                      format(
                              "%s should be interface",
                              element
                      ),
                      element
              );
              return false;
          }
  
          boolean extendsVariableContext = extendsVariableContext(element);
  
          if (!extendsVariableContext) { //check whether interface extends VariableContext
              messager.printMessage(
                      Diagnostic.Kind.ERROR,
                      format(
                              "%s should be extending %s",
                              element,
                              VariableContext.class.getName()
                      ),
                      element
              );
              return false;
          }
  
          final List<Variable> elements = new ArrayList<>();
          final VarContextProvider varContextProvider = element.getAnnotation(VarContextProvider.class);
  
          if (varContextProvider == null) { //must be annotated with @VarContextProvider
              messager.printMessage(
                      Diagnostic.Kind.ERROR,
                      format(
                              "%s should be annotated with @VarContextProvider",
                              element
                      ),
                      element
              );
              return false;
          }
  
          //check methods of interface
          for (Element enclosed : element.getEnclosedElements()) {
              final Var annotation = enclosed.getAnnotation(Var.class);
              if (annotation != null) {
                  final ExecutableType executableType = (ExecutableType) enclosed.asType();
                  final Name simpleName = enclosed.getSimpleName();
                  // check name of method
  
                  //should not have method with names info, debug, error,...
                  final List<String> logLevelsMethodNames = Arrays.stream(
                          LogLevel.values()
                  )
                          .map(
                                  LogLevel::getLevelMethodName
                          )
                          .collect(
                                  Collectors.toList()
                          );
  
                  //should not have method with names infoEvent, debugEvent, errorEvent,...
                  final List<String> logEventMethodNames = Arrays.stream(
                          LogLevel.values()
                  )
                          .map(
                                  LogLevel::getLogEventMethodName
                          )
                          .collect(
                                  Collectors.toList()
                          );
  
                  List<String> loggingEventFieldNames =
                          Arrays.stream(LoggingEvent.class.getDeclaredFields()).map(e -> e.getName()).collect(Collectors.toList());
                  if (
                          simpleName.contentEquals("log") || //should not have method with name log
                          logLevelsMethodNames.stream().anyMatch(simpleName::contentEquals) ||
                          logEventMethodNames.stream().anyMatch(simpleName::contentEquals) ||
                          loggingEventFieldNames.stream().anyMatch(simpleName::contentEquals)
                     )
                  {
                      messager.printMessage(
                              Diagnostic.Kind.ERROR,
                              format(
                                      "%s interface cannot have method named %s",
                                      element,
                                      simpleName
                              ),
                              element
                      );
                      return false;
                  }
                  if (!executableType.getReturnType().toString().equals(typeMirror.toString())) { //check return type
                      messager.printMessage(
                              Diagnostic.Kind.ERROR,
                              format(
                                      "%s.%s method must have return type %s",
                                      element,
                                      simpleName,
                                      element
                              ),
                              element
                      );
                      return false;
                  }
                  if (executableType.getParameterTypes().size() != 1) { //check number of parameters
                      messager.printMessage(
                              Diagnostic.Kind.ERROR,
                              format(
                                      "%s.%s method must have exactly one argument",
                                      element,
                                      simpleName
                              ),
                              element);
                      return false;
                  }
                  if (elements.stream().map(Variable::getName).anyMatch(e -> e.contentEquals(simpleName))) { //check whether there is no method with same name
                      messager.printMessage(
                              Diagnostic.Kind.ERROR,
                              format(
                                      "%s.%s method cannot be overloaded",
                                      element,
                                      simpleName
                              ),
                              element
                      );
                      return false;
                  }
                  elements.add(new Variable(simpleName, executableType.getParameterTypes().get(0)));
              }
          }
          if (elements.isEmpty()) { //
              messager.printMessage(
                      Diagnostic.Kind.WARNING,
                      format(
                              "%s has no @Var annotated methods",
                              element
                      ),
                      element
              );
          }
          varsHashMap.put(typeMirror, new VariableContextProvider(typeMirror, elements, varContextProvider.parametrization()));
          varContextProviders.add(typeMirror);
          return true;
      }