public String abbreviate(String fqClassName) {
    StringBuilder buf = new StringBuilder(targetLength);
    if (fqClassName == null) {
      throw new IllegalArgumentException("Class name may not be null");
    }

    int inLen = fqClassName.length();
    if (inLen < targetLength) {
      return fqClassName;
    }

    int[] dotIndexesArray = new int[ClassicConstants.MAX_DOTS];
    // a.b.c contains 2 dots but 2+1 parts.
    // see also http://jira.qos.ch/browse/LBCLASSIC-110
    int[] lengthArray = new int[ClassicConstants.MAX_DOTS + 1];

    int dotCount = computeDotIndexes(fqClassName, dotIndexesArray);

    // System.out.println();
    // System.out.println("Dot count for [" + className + "] is " + dotCount);
    // if there are not dots than abbreviation is not possible
    if (dotCount == 0) {
      return fqClassName;
    }
    // printArray("dotArray: ", dotArray);
    computeLengthArray(fqClassName, dotIndexesArray, lengthArray, dotCount);
    // printArray("lengthArray: ", lengthArray);
    for (int i = 0; i <= dotCount; i++) {
      if (i == 0) {
        buf.append(fqClassName.substring(0, lengthArray[i] - 1));
      } else {
        buf.append(fqClassName.substring(dotIndexesArray[i - 1],
            dotIndexesArray[i - 1] + lengthArray[i]));
      }
      // System.out.println("i=" + i + ", buf=" + buf);
    }

    return buf.toString();
  }
@Test
  public void testXDot() {
    {
      TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(21);
      String name = "com.logback.wombat.alligator.Foobar";
      assertEquals("c.l.w.a.Foobar", abbreviator.abbreviate(name));
    }
    
    {
      TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(22);
      String name = "com.logback.wombat.alligator.Foobar";
      assertEquals("c.l.w.alligator.Foobar", abbreviator.abbreviate(name));
    }
    
    {
      TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(1);
      String name = "com.logback.wombat.alligator.tomato.Foobar";
      assertEquals("c.l.w.a.t.Foobar", abbreviator.abbreviate(name));
    }
    
    {
      TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(21);
      String name = "com.logback.wombat.alligator.tomato.Foobar";
      assertEquals("c.l.w.a.tomato.Foobar", abbreviator.abbreviate(name));
    }
    
    {
      TargetLengthBasedClassNameAbbreviator abbreviator = new TargetLengthBasedClassNameAbbreviator(29);
      String name = "com.logback.wombat.alligator.tomato.Foobar";
      assertEquals("c.l.w.alligator.tomato.Foobar", abbreviator.abbreviate(name));
    }
  }