class DefaultExceptionHandler implements ExceptionHandler {

    public ExceptionSummary handleException(Throwable exception) {
        return handle("", exception);
    }

    private ExceptionSummary handle(String message, Throwable exception) {
        String reference = getReference(exception);

        List<ExceptionSummary> children = null;

        if (exception instanceof ProjectBuildingException) {
            List<ProjectBuildingResult> results = ((ProjectBuildingException) exception).getResults();

            children = new ArrayList<>();

            for (ProjectBuildingResult result : results) {
                ExceptionSummary child = handle(result);
                if (child != null) {
                    children.add(child);
                }
            }

            message = "The build could not read " + children.size() + " project" + (children.size() == 1 ? "" : "s");
        } else {
            message = getMessage(message, exception);
        }

        return new ExceptionSummary(exception, message, reference, children);
    }

    private ExceptionSummary handle(ProjectBuildingResult result) {
        List<ExceptionSummary> children = new ArrayList<>();

        for (ModelProblem problem : result.getProblems()) {
            ExceptionSummary child = handle(problem, result.getProjectId());
            if (child != null) {
                children.add(child);
            }
        }

        if (children.isEmpty()) {
            return null;
        }

        String message = System.lineSeparator()
                + "The project " + (result.getProjectId().isEmpty() ? "" : result.getProjectId() + " ")
                + "(" + result.getPomFile() + ") has "
                + children.size() + " error" + (children.size() == 1 ? "" : "s");

        return new ExceptionSummary(null, message, null, children);
    }

    private ExceptionSummary handle(ModelProblem problem, String projectId) {
        if (ModelProblem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) {
            String message = problem.getMessage();

            String location = ModelProblemUtils.formatLocation(problem, projectId);

            if (!location.isEmpty()) {
                message += " @ " + location;
            }

            return handle(message, problem.getException());
        } else {
            return null;
        }
    }

    private String getReference(Throwable exception) {<FILL_FUNCTION_BODY>}

    private boolean isNoteworthyException(Throwable exception) {
        if (exception == null) {
            return false;
        } else if (exception instanceof Error) {
            return true;
        } else if (exception instanceof RuntimeException) {
            return false;
        } else {
            return !exception.getClass().getName().startsWith("java");
        }
    }

    private String getMessage(String message, Throwable exception) {
        String fullMessage = (message != null) ? message : "";

        // To break out of possible endless loop when getCause returns "this"
        for (Throwable t = exception; t != null && t != t.getCause(); t = t.getCause()) {
            String exceptionMessage = t.getMessage();

            if (t instanceof AbstractMojoExecutionException) {
                String longMessage = ((AbstractMojoExecutionException) t).getLongMessage();
                if (longMessage != null && !longMessage.isEmpty()) {
                    if ((exceptionMessage == null || exceptionMessage.isEmpty())
                            || longMessage.contains(exceptionMessage)) {
                        exceptionMessage = longMessage;
                    } else if (!exceptionMessage.contains(longMessage)) {
                        exceptionMessage = join(exceptionMessage, System.lineSeparator() + longMessage);
                    }
                }
            }

            if (exceptionMessage == null || exceptionMessage.isEmpty()) {
                exceptionMessage = t.getClass().getSimpleName();
            }

            if (t instanceof UnknownHostException && !fullMessage.contains("host")) {
                fullMessage = join(fullMessage, "Unknown host " + exceptionMessage);
            } else if (!fullMessage.contains(exceptionMessage)) {
                fullMessage = join(fullMessage, exceptionMessage);
            }
        }

        return fullMessage.trim();
    }

    private String join(String message1, String message2) {
        String message = "";

        if (message1 != null && !message1.isEmpty()) {
            message = message1.trim();
        }

        if (message2 != null && !message2.isEmpty()) {
            if (message != null && !message.isEmpty()) {
                if (message.endsWith(".") || message.endsWith("!") || message.endsWith(":")) {
                    message += " ";
                } else {
                    message += ": ";
                }
            }

            message += message2;
        }

        return message;
    }
}

        String reference = "";

        if (exception != null) {
            if (exception instanceof MojoExecutionException) {
                reference = MojoExecutionException.class.getSimpleName();

                Throwable cause = exception.getCause();
                if (cause instanceof IOException) {
                    cause = cause.getCause();
                    if (cause instanceof ConnectException) {
                        reference = ConnectException.class.getSimpleName();
                    }
                }
            } else if (exception instanceof MojoFailureException) {
                reference = MojoFailureException.class.getSimpleName();
            } else if (exception instanceof LinkageError) {
                reference = LinkageError.class.getSimpleName();
            } else if (exception instanceof PluginExecutionException) {
                Throwable cause = exception.getCause();

                if (cause instanceof PluginContainerException) {
                    Throwable cause2 = cause.getCause();

                    if (cause2 instanceof NoClassDefFoundError) {
                        String message = cause2.getMessage();
                        if (message != null && message.contains("org/sonatype/aether/")) {
                            reference = "AetherClassNotFound";
                        }
                    }
                }

                if (reference == null || reference.isEmpty()) {
                    reference = getReference(cause);
                }

                if (reference == null || reference.isEmpty()) {
                    reference = exception.getClass().getSimpleName();
                }
            } else if (exception instanceof LifecycleExecutionException) {
                reference = getReference(exception.getCause());
            } else if (isNoteworthyException(exception)) {
                reference = exception.getClass().getSimpleName();
            }
        }

        if ((reference != null && !reference.isEmpty()) && !reference.startsWith("http:")) {
            reference = "http://cwiki.apache.org/confluence/display/MAVEN/" + reference;
        }

        return reference;
    
<no_super_class>