@Override
  public Template toTemplate(final Template template) {
    final ArrayList<Trees.TemplatePart> results = Lists.newArrayList();
    class Normalizer {
      private @Nullable TextFragment fragment;

      void collect() {
        for (Trees.TemplatePart part : template.parts()) {
          if (part instanceof TextBlock) {
            collectTextParts(((TextBlock) part).parts());
          } else {
            flushFragment();
            results.add(part);
          }
        }

        flushFragment();
      }

      void collectTextParts(Iterable<TextPart> parts) {
        for (Trees.TextPart text : parts) {
          if (text instanceof TextFragment) {
            if (fragment != null) {
              fragment = joinFraments(fragment, (TextFragment) text);
            } else {
              flushFragment();
              fragment = (TextFragment) text;
            }
          }
          if (text instanceof Newline) {
            flushNewline();
          }
        }
      }

      void flushFragment() {
        if (fragment != null && !fragment.value().isEmpty()) {
          results.add(TextLine.builder()
              .fragment(fragment)
              .build());
        }

        fragment = null;
      }

      void flushNewline() {
        results.add(TextLine.builder()
            .fragment(fragment != null ? fragment : TextFragment.of(""))
            .newline(true)
            .build());

        fragment = null;
      }

      TextFragment joinFraments(TextFragment left, TextFragment right) {
        return TextFragment.of(left.value().concat(right.value()));
      }
    }

    new Normalizer().collect();

    return template.withParts(results);
  }
Spacing trimming and redistribution should be run before balancing
generator-processor/src/org/immutables/generator/processor/Spacing.java