// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/api/model/TestSource.java
// public interface TestSource {
// 
//     /**
//      * @return  complete test source
//      */
//     @NotNull
//     String getSourceText();
// 
//     /**
//      * @return  qualified class name for the given test source
//      */
//     @NotNull
//     String getQualifiedClassName();
// }
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/impl/expectation/RunResultExpectationBuilder.java
// @SuppressWarnings("UnusedReturnValue")
// public class RunResultExpectationBuilder {
// 
//     @Nullable private String  expectedExceptionClass;
//     @Nullable private String  expectedExceptionMessageSnippet;
//     @Nullable private String  expectedExceptionMessageText;
//     @Nullable private Integer thrownAtLine;
// 
//     @NotNull
//     public static RunResultExpectationBuilder expectRunResult() {
//         return new RunResultExpectationBuilder();
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionClass(@NotNull Class<?> clazz) {
//         return withExceptionClass(clazz.getName());
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionClass(@NotNull String clazz) {
//         expectedExceptionClass = clazz;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionMessageSnippet(@NotNull String snippet) {
//         expectedExceptionMessageSnippet = snippet;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionMessage(@NotNull String message) {
//         expectedExceptionMessageText = message;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder atLine(int line) {
//         thrownAtLine = line;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectation build() {
//         return new RunResultExpectation(expectedExceptionClass,
//                                         expectedExceptionMessageSnippet,
//                                         expectedExceptionMessageText,
//                                         thrownAtLine);
//     }
// }
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/impl/model/TestSourceImpl.java
// public class TestSourceImpl implements TestSource {
// 
//     @NotNull private final String               sourceText;
//     @NotNull private final String               className;
// 
//     public TestSourceImpl(@NotNull String sourceText, @NotNull String className) {
//         this.sourceText = sourceText;
//         this.className = className;
//     }
// 
//     @Override
//     @NotNull
//     public String getSourceText() {
//         return sourceText;
//     }
// 
//     @Override
//     @NotNull
//     public String getQualifiedClassName() {
//         return className;
//     }
// 
//     @Override
//     public String toString() {
//         return className + " source";
//     }
// }
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestConstants.java
// public static final String CLASS_NAME = "Test";
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestConstants.java
// public static final String METHOD_NAME = "test";
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestConstants.java
// public static final String PACKAGE = "tech.harmonysoft.oss.traute.test";


import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tech.harmonysoft.oss.traute.test.api.model.TestSource;
import tech.harmonysoft.oss.traute.test.impl.expectation.RunResultExpectationBuilder;
import tech.harmonysoft.oss.traute.test.impl.model.TestSourceImpl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import static java.util.stream.Collectors.joining;
import static org.junit.jupiter.api.Assertions.fail;
import static tech.harmonysoft.oss.traute.test.util.TestConstants.CLASS_NAME;
import static tech.harmonysoft.oss.traute.test.util.TestConstants.METHOD_NAME;
import static tech.harmonysoft.oss.traute.test.util.TestConstants.PACKAGE;
                                                @NotNull RunResultExpectationBuilder expectRunResult)
    {
        expectRunResult.withExceptionClass(NullPointerException.class)
                       .withExceptionMessageSnippet("Detected an attempt to return null from a method")
                       .atLine(findLineNumber(testSource, returnExpression));
    }

    @NotNull
    public static String getSources(@NotNull Collection<TestSource> sources) {
        return sources.stream()
                      .map(s -> s.getQualifiedClassName() + ".java:\n\n" + s.getSourceText())
                      .collect(joining("\n\n"));
    }

    @NotNull
    public static TestSource findInClassPath(@NotNull String root, @NotNull String qualifiedClassName) {
        InputStream in = ClassLoader
                .getSystemClassLoader()
                .getResourceAsStream(root + "/" + qualifiedClassName.replace('.', '/') + ".java");
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        int read;
        try {
            while ((read = in.read(buffer)) >= 0) {
                bOut.write(buffer, 0, read);
            }
        } catch (IOException e) {
            throw new IllegalStateException(String.format("Can't read source text for the class %s from source "
                                                          + "root '%s'", qualifiedClassName, root), e);
        }
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/api/model/TestSource.java
// public interface TestSource {
// 
//     /**
//      * @return  complete test source
//      */
//     @NotNull
//     String getSourceText();
// 
//     /**
//      * @return  qualified class name for the given test source
//      */
//     @NotNull
//     String getQualifiedClassName();
// }
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/impl/expectation/RunResultExpectationBuilder.java
// @SuppressWarnings("UnusedReturnValue")
// public class RunResultExpectationBuilder {
// 
//     @Nullable private String  expectedExceptionClass;
//     @Nullable private String  expectedExceptionMessageSnippet;
//     @Nullable private String  expectedExceptionMessageText;
//     @Nullable private Integer thrownAtLine;
// 
//     @NotNull
//     public static RunResultExpectationBuilder expectRunResult() {
//         return new RunResultExpectationBuilder();
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionClass(@NotNull Class<?> clazz) {
//         return withExceptionClass(clazz.getName());
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionClass(@NotNull String clazz) {
//         expectedExceptionClass = clazz;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionMessageSnippet(@NotNull String snippet) {
//         expectedExceptionMessageSnippet = snippet;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder withExceptionMessage(@NotNull String message) {
//         expectedExceptionMessageText = message;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectationBuilder atLine(int line) {
//         thrownAtLine = line;
//         return this;
//     }
// 
//     @NotNull
//     public RunResultExpectation build() {
//         return new RunResultExpectation(expectedExceptionClass,
//                                         expectedExceptionMessageSnippet,
//                                         expectedExceptionMessageText,
//                                         thrownAtLine);
//     }
// }
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/impl/model/TestSourceImpl.java
// public class TestSourceImpl implements TestSource {
// 
//     @NotNull private final String               sourceText;
//     @NotNull private final String               className;
// 
//     public TestSourceImpl(@NotNull String sourceText, @NotNull String className) {
//         this.sourceText = sourceText;
//         this.className = className;
//     }
// 
//     @Override
//     @NotNull
//     public String getSourceText() {
//         return sourceText;
//     }
// 
//     @Override
//     @NotNull
//     public String getQualifiedClassName() {
//         return className;
//     }
// 
//     @Override
//     public String toString() {
//         return className + " source";
//     }
// }
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestConstants.java
// public static final String CLASS_NAME = "Test";
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestConstants.java
// public static final String METHOD_NAME = "test";
// 
// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestConstants.java
// public static final String PACKAGE = "tech.harmonysoft.oss.traute.test";


// Path: core/test/src/test/java/tech/harmonysoft/oss/traute/test/util/TestUtil.java
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tech.harmonysoft.oss.traute.test.api.model.TestSource;
import tech.harmonysoft.oss.traute.test.impl.expectation.RunResultExpectationBuilder;
import tech.harmonysoft.oss.traute.test.impl.model.TestSourceImpl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import static java.util.stream.Collectors.joining;
import static org.junit.jupiter.api.Assertions.fail;
import static tech.harmonysoft.oss.traute.test.util.TestConstants.CLASS_NAME;
import static tech.harmonysoft.oss.traute.test.util.TestConstants.METHOD_NAME;
import static tech.harmonysoft.oss.traute.test.util.TestConstants.PACKAGE;

                                                @NotNull RunResultExpectationBuilder expectRunResult)
    {
        expectRunResult.withExceptionClass(NullPointerException.class)
                       .withExceptionMessageSnippet("Detected an attempt to return null from a method")
                       .atLine(findLineNumber(testSource, returnExpression));
    }

    @NotNull
    public static String getSources(@NotNull Collection<TestSource> sources) {
        return sources.stream()
                      .map(s -> s.getQualifiedClassName() + ".java:\n\n" + s.getSourceText())
                      .collect(joining("\n\n"));
    }

    @NotNull
    public static TestSource findInClassPath(@NotNull String root, @NotNull String qualifiedClassName) {
        InputStream in = ClassLoader
                .getSystemClassLoader()
                .getResourceAsStream(root + "/" + qualifiedClassName.replace('.', '/') + ".java");
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        int read;
        try {
            while ((read = in.read(buffer)) >= 0) {
                bOut.write(buffer, 0, read);
            }
        } catch (IOException e) {
            throw new IllegalStateException(String.format("Can't read source text for the class %s from source "
                                                          + "root '%s'", qualifiedClassName, root), e);
        }
        return new TestSourceImpl(new String(bOut.toByteArray(), StandardCharsets.UTF_8), qualifiedClassName);