@NotNull
 protected List<AbstractTestProxy> getFailedTests(@NotNull Project project) {
   TestFrameworkRunningModel model = getModel();
   if (model == null) return Collections.emptyList();
   //noinspection unchecked
   return getFilter(project, model.getProperties().getScope())
       .select(model.getRoot().getAllTests());
 }
  @Nullable
  @Override
  public MyRunProfile getRunProfile() {
    TestFrameworkRunningModel model = getModel();
    if (model == null) return null;
    return new MyRunProfile(model.getProperties().getConfiguration()) {
      @NotNull
      @Override
      public Module[] getModules() {
        return ((RebarEunitRunConfiguration) getPeer()).getModules();
      }

      @Nullable
      @Override
      public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env)
          throws ExecutionException {
        RebarEunitRunConfiguration runConfiguration = createRerunFailedTestsRunConfiguration();
        return new RebarEunitRunningState(env, runConfiguration);
      }

      private RebarEunitRunConfiguration createRerunFailedTestsRunConfiguration() {
        final Project project = getProject();
        RebarEunitRunConfiguration configuration = new RebarEunitRunConfiguration(project, "");
        final List<ErlangFunction> failedGeneratedTests = new ArrayList<ErlangFunction>();
        List<ErlangFunction> failedTests =
            ContainerUtil.mapNotNull(
                getFailedTests(project),
                new Function<AbstractTestProxy, ErlangFunction>() {
                  @Nullable
                  @Override
                  public ErlangFunction fun(AbstractTestProxy testProxy) {
                    Location location = testProxy.getLocation(project);
                    PsiElement psiElement = location != null ? location.getPsiElement() : null;
                    ErlangFunction function =
                        psiElement instanceof ErlangFunction ? (ErlangFunction) psiElement : null;
                    if (function != null && function.getArity() != 0) {
                      failedGeneratedTests.add(function);
                    }
                    return function;
                  }
                });
        Set<ErlangFile> suites =
            ContainerUtil.map2Set(
                failedTests,
                new Function<ErlangFunction, ErlangFile>() {
                  @Nullable
                  @Override
                  public ErlangFile fun(ErlangFunction function) {
                    PsiFile containingFile = function.getContainingFile();
                    return containingFile instanceof ErlangFile
                        ? (ErlangFile) containingFile
                        : null;
                  }
                });
        suites.remove(null);

        if (!failedGeneratedTests.isEmpty()) {
          notifyGeneratedTestsFailed(failedGeneratedTests);
        }

        configuration.setCommand(
            RebarEunitConfigurationUtil.createDefaultRebarCommand(suites, failedTests, false));
        configuration.setName("");
        configuration.setSkipDependencies(true);

        return configuration;
      }

      private void notifyGeneratedTestsFailed(final List<ErlangFunction> failedGeneratedTests) {
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  public void run() {
                    Notifications.Bus.notify(
                        new Notification(
                            "TestRunner",
                            "Some tests cannot be rerun directly",
                            "Some of failed tests were obtained via generator functions and cannot be rerun directly.\n"
                                + createFailedTestsListMessage(failedGeneratedTests),
                            NotificationType.WARNING));
                  }
                });
      }

      private String createFailedTestsListMessage(List<ErlangFunction> failedTests) {
        final int maxShownTests = 3;
        List<String> testNames = takeFunctionNames(failedTests, maxShownTests);
        int notShownTestsCount = failedTests.size() - testNames.size();
        String more = notShownTestsCount > 0 ? " and " + notShownTestsCount + " more" : "";
        return "Tests failed: " + StringUtil.join(testNames, ", ") + more;
      }

      private List<String> takeFunctionNames(List<ErlangFunction> failedFunctions, int n) {
        ArrayList<String> result = new ArrayList<String>(n);
        Iterator<ErlangFunction> iterator = failedFunctions.iterator();
        while (iterator.hasNext() && n > 0) {
          result.add(ErlangPsiImplUtil.getQualifiedFunctionName(iterator.next()));
        }
        return result;
      }
    };
  }