@Override
  protected boolean setupConfigurationFromContext(
      TestNGConfiguration configuration,
      ConfigurationContext context,
      Ref<PsiElement> sourceElement) {
    // TODO: check TestNG Pattern running first, before method/class (see
    // TestNGInClassConfigurationProducer for logic)
    // TODO: and PsiClassOwner not handled, which is in TestNGInClassConfigurationProducer

    Location location = context.getLocation();
    if (location == null) {
      return false;
    }

    Project project = context.getProject();
    PsiElement leaf = location.getPsiElement();

    if (!ProjectRootsUtil.isInProjectOrLibSource(leaf)) {
      return false;
    }

    if (!(leaf.getContainingFile() instanceof KtFile)) {
      return false;
    }

    KtFile jetFile = (KtFile) leaf.getContainingFile();

    if (ProjectStructureUtil.isJsKotlinModule(jetFile)) {
      return false;
    }

    KtNamedDeclaration declarationToRun = getDeclarationToRun(leaf);

    if (declarationToRun instanceof KtNamedFunction) {
      KtNamedFunction function = (KtNamedFunction) declarationToRun;

      @SuppressWarnings("unchecked")
      KtElement owner = PsiTreeUtil.getParentOfType(function, KtFunction.class, KtClass.class);

      if (owner instanceof KtClass) {
        PsiClass delegate = LightClassUtil.INSTANCE.getPsiClass((KtClass) owner);
        if (delegate != null) {
          for (PsiMethod method : delegate.getMethods()) {
            if (method.getNavigationElement() == function) {
              if (TestNGUtil.hasTest(method)) {
                return configure(configuration, location, context, project, delegate, method);
              }
              break;
            }
          }
        }
      }
    }

    if (declarationToRun instanceof KtClass) {
      PsiClass delegate = LightClassUtil.INSTANCE.getPsiClass((KtClassOrObject) declarationToRun);
      if (!isTestNGClass(delegate)) {
        return false;
      }

      return configure(configuration, location, context, project, delegate, null);
    }

    return false;
  }