package adaptorlib;

import java.io.*;
import java.text.MessageFormat;
import java.util.Date;
import java.util.logging.*;

public class CustomFormatter extends Formatter {
  private static final String newline = System.getProperty("line.separator");
  private Date date = new Date();
  private MessageFormat formatter = new MessageFormat(
      "\u001b[3{5}m{0,date,HH:mm:ss.SSS} {1}\u001b[3{5}m {2} {3}:\u001b[m {4}");
  private StringBuffer buffer = new StringBuffer();
  private PrintWriter writer = new PrintWriter(new StringBufferWriter(buffer));
  private int highlightColor = 6;
  private final int numberOfColors = 8;

  public synchronized String format(LogRecord record) {
    buffer.delete(0, buffer.length());

    date.setTime(record.getMillis());
    String threadName;
    if (record.getThreadID() == Thread.currentThread().getId())
      threadName = Thread.currentThread().getName();
    else
      threadName = "" + record.getThreadID();
    int backgroundColor = (record.getThreadID() % (numberOfColors - 1)) + 1;
    threadName = "\u001b[3" + backgroundColor + "m" + threadName;
    String method = record.getSourceClassName() + "."
        + record.getSourceMethodName() + "()";
    if (method.length() > 30)
      method = method.substring(method.length() - 30);
    formatter.format(
        new Object[] {date, threadName, method,
          record.getLevel().getLocalizedName(), formatMessage(record),
          highlightColor
        }, buffer, null);
    buffer.append(newline);
    if (record.getThrown() != null)
      record.getThrown().printStackTrace(writer);

    String formatted = buffer.toString();
    buffer.delete(0, buffer.length());
    return formatted;
  }
}

class StringBufferWriter extends Writer {
  private StringBuffer sb;

  public StringBufferWriter(StringBuffer sb) {
    this.sb = sb;
  }

  public void close() {
    sb = null;
  }

  public void flush() throws IOException {
    if (sb == null)
      throw new IOException("Writer closed");
  }

  public void write(char[] cbuf, int off, int len) throws IOException {
    if (sb == null)
      throw new IOException("Writer closed");
    sb.append(cbuf, off, len);
  }
}

@@ -116,16 +116,148 @@
 ing.*;%0A%0A
+/**%0A * Custom log formatter for ease of development. It is specifically targeted to%0A * use in console output on Unix terminals.%0A */%0A
 public c
@@ -405,24 +405,255 @@
 new Date();%0A
+  // The format for a color is '%5Cx1b%5B30;40m' where 30 and 40 are the foreground%0A  // and background colors, respectively. The ';' isn't required. If you don't%0A  // provide a foreground or background, it will be set to the default.%0A
   private Me
@@ -736,16 +736,28 @@
 ss.SSS%7D 
+%5Cu001b%5B3%7B6%7Dm
 %7B1%7D%5Cu001
@@ -926,39 +926,264 @@
 ;%0A  
-private int highlightColor = 6;
+/**%0A   * Default highlight color is a cyan on my terminal. This color needs to be%0A   * readable on both light-on-dark and dark-on-light setups.%0A   */%0A  private int highlightColor = 6;%0A  /** Colors range from 30-37 for foreground and 40-47 for background */
 %0A  p
@@ -1557,145 +1557,214 @@
     
-int backgroundColor = (record.getThreadID() %25 (numberOfColors - 1)) + 1;%0A    threadName = %22%5Cu001b%5B3%22 + backgroundColor + %22m%22 + threadName
+// We know that one of the colors is used for the background. The default%0A    // for terminals is 40, so we avoid using color 30 here.%0A    int threadColor = (record.getThreadID() %25 (numberOfColors - 1)) + 1
 ;%0A  
@@ -2112,16 +2112,29 @@
 ghtColor
+, threadColor
 %0A       

Add missing JavaDoc to new CustomFormatter and perform some forgotten cleanups