public Set<String> getDeadlockedThreads() {
        final long[] ids = threads.findDeadlockedThreads();
        if (ids != null) {
            final Set<String> deadlocks = new HashSet<>();
            for (ThreadInfo info : threads.getThreadInfo(ids, MAX_STACK_TRACE_DEPTH)) {
                final StringBuilder stackTrace = new StringBuilder();
                for (StackTraceElement element : info.getStackTrace()) {
                    stackTrace.append("\t at ")
                            .append(element.toString())
                            .append(String.format("%n"));
                }

                deadlocks.add(
                        String.format("%s locked on %s (owned by %s):%n%s",
                                info.getThreadName(),
                                info.getLockName(),
                                info.getLockOwnerName(),
                                stackTrace.toString()
                        )
                );
            }
            return Collections.unmodifiableSet(deadlocks);
        }
        return Collections.emptySet();
    }
@Test
    public void returnsASetOfThreadsIfAnyAreDeadlocked() {
        final ThreadInfo thread1 = mock(ThreadInfo.class);
        when(thread1.getThreadName()).thenReturn("thread1");
        when(thread1.getLockName()).thenReturn("lock2");
        when(thread1.getLockOwnerName()).thenReturn("thread2");
        when(thread1.getStackTrace()).thenReturn(new StackTraceElement[]{
            new StackTraceElement("Blah", "bloo", "Blah.java", 150),
            new StackTraceElement("Blah", "blee", "Blah.java", 100)
        });

        final ThreadInfo thread2 = mock(ThreadInfo.class);
        when(thread2.getThreadName()).thenReturn("thread2");
        when(thread2.getLockName()).thenReturn("lock1");
        when(thread2.getLockOwnerName()).thenReturn("thread1");
        when(thread2.getStackTrace()).thenReturn(new StackTraceElement[]{
            new StackTraceElement("Blah", "blee", "Blah.java", 100),
            new StackTraceElement("Blah", "bloo", "Blah.java", 150)
        });

        final long[] ids = {1, 2};
        when(threads.findDeadlockedThreads()).thenReturn(ids);
        when(threads.getThreadInfo(eq(ids), anyInt()))
            .thenReturn(new ThreadInfo[]{thread1, thread2});

        assertThat(detector.getDeadlockedThreads())
            .containsOnly(String.format(Locale.US,
                "thread1 locked on lock2 (owned by thread2):%n" +
                    "\t at Blah.bloo(Blah.java:150)%n" +
                    "\t at Blah.blee(Blah.java:100)%n"),
                String.format(Locale.US,
                    "thread2 locked on lock1 (owned by thread1):%n" +
                        "\t at Blah.blee(Blah.java:100)%n" +
                        "\t at Blah.bloo(Blah.java:150)%n"));
    }