docs: public List<Record> handle(Record record) {
      StringBuilder b = new StringBuilder();
      
      //--Special case for Exceptions
      String[] content;
      if (record.content instanceof Throwable) {
        //(vars)
        List<String> lines = new ArrayList<String>();
        StackTraceElement[] trace = null;
        StackTraceElement topTraceElement= null;
        //(root message)
        Throwable exception = (Throwable) record.content;
        lines.add(record.content.toString());
        trace = exception.getStackTrace();
        topTraceElement = trace.length > 0 ? trace[0] : null;
        for(StackTraceElement e : exception.getStackTrace()){
          lines.add(tab + e.toString());
        }
        //(causes)
        while(exception.getCause() != null){
          System.out.println("TOP ELEMENT: " + topTraceElement);
          //((variables))
          exception = exception.getCause();
          trace = exception.getStackTrace();
          lines.add("Caused by: " + exception.getClass()+": " + exception.getMessage());
          for(int i=0; i<trace.length; i++){
            //((add trace element))
            StackTraceElement e = trace[i];
            lines.add(tab + e.toString());
            //((don't print redundant elements))
            if(topTraceElement != null &&
                e.getClassName().equals(topTraceElement.getClassName()) &&
                e.getMethodName().equals(topTraceElement.getMethodName())){
              lines.add(tab+"..."+(trace.length-i-1) + " more");
              break;
            }
          }
          //((update top element))
          topTraceElement = trace.length > 0 ? trace[0] : null;
        }
        //(set content array)
        content = new String[lines.size()];
        content = lines.toArray(content);
      } else if(record.content == null){
        content = new String[]{"null"};
      } else {
        content = record.content.toString().split("\n"); //would be nice to get rid of this 'split()' call at some point
      }
      
      //--Handle Tracks
      updateTracks(record.depth);
      if(this.missingOpenBracket){
        this.style(b, "{\n", trackColor, trackStyle);
        this.missingOpenBracket = false;
      }
      //--Process Record
      //(variables)
      int cursorPos = 0;
      int contentLinesPrinted = 0;
      //(loop)
      Color color = Color.NONE;
      Style style = Style.NONE;
      //(get channels)
      ArrayList<Object> printableChannels = new ArrayList<Object>();
      for(Object chan : record.channels()){
        if(chan instanceof Color){ color = (Color) chan; }
        else if(chan instanceof Style){ style = (Style) chan; }
        else if(chan != Redwood.FORCE){ printableChannels.add(chan); }
      }
      //--Write Channels
      if(leftMargin > 2) {	//don't print if not enough space
        //((print channels)
        if(printableChannels.size() > 0){ b.append("["); cursorPos += 1; }
        Object lastChan = null;
        for(int i=0; i<printableChannels.size(); i++) {
          Object chan = printableChannels.get(i);
          if(chan.equals(lastChan)){ continue; } //skip duplicate channels
          lastChan = chan;
          //(get chan)
          String chanToString = chan.toString();
          String toPrint = chan.toString();
          if(toPrint.length() > leftMargin-1){ toPrint = toPrint.substring(0,leftMargin-2); }
          if(cursorPos+toPrint.length() >= leftMargin){
            //(case: doesn't fit)
            while(cursorPos < leftMargin){ b.append(" "); cursorPos += 1; }
            if(contentLinesPrinted < content.length){
              writeContent(record.depth, style(new StringBuilder(),content[contentLinesPrinted],color,style).toString(), b);
              contentLinesPrinted += 1;
            }
            b.append("\n ");
            cursorPos = 1;
          }
          //(print flag)
          formatChannel(b, toPrint, chanToString);
          if(i < printableChannels.size()-1){ b.append(channelSeparatorChar); cursorPos += 1; }
          cursorPos += toPrint.length();
        }
        if(printableChannels.size() > 0){ b.append("]"); cursorPos += 1; }
      }
      //--Content
      //(write content)
      while(contentLinesPrinted < content.length) {
        while(cursorPos < leftMargin){ b.append(" "); cursorPos += 1; }
        writeContent(record.depth, style(new StringBuilder(),content[contentLinesPrinted],color,style).toString(), b);
        contentLinesPrinted += 1;
        if(contentLinesPrinted < content.length){ b.append("\n"); cursorPos = 0; }
      }
      //(print)
      if (b.length() == 0 || b.charAt(b.length() - 1) != '\n') {
        b.append("\n");
      }
      print(b.toString());
      //--Continue
      if(info != null){
        info.numElementsPrinted += 1;
      }
      ArrayList<Record> rtn = new ArrayList<Record>();
      rtn.add(record);
      return rtn;
    }