Converter<E> compile() {
    head = tail = null;
    for (Node n = top; n != null; n = n.next) {
      switch (n.type) {
        case Node.LITERAL:
          addToList(new LiteralConverter<E>((String) n.getValue()));
          break;
        case Node.COMPOSITE_KEYWORD:
          CompositeNode cn = (CompositeNode) n;
          CompositeConverter<E> compositeConverter = createCompositeConverter(cn);
          if(compositeConverter == null) {
            addError("Failed to create converter for [%"+cn.getValue()+"] keyword");
            addToList(new LiteralConverter<E>("%PARSER_ERROR["+cn.getValue()+"]"));
            break;
          }
          compositeConverter.setFormattingInfo(cn.getFormatInfo());
          compositeConverter.setOptionList(cn.getOptions());
          Compiler<E> childCompiler = new Compiler<E>(cn.getChildNode(),
                  converterMap);
          childCompiler.setContext(context);
          Converter<E> childConverter = childCompiler.compile();
          compositeConverter.setChildConverter(childConverter);
          addToList(compositeConverter);
          break;
        case Node.SIMPLE_KEYWORD:
          SimpleKeywordNode kn = (SimpleKeywordNode) n;
          DynamicConverter<E> dynaConverter = createConverter(kn);
          if (dynaConverter != null) {
            dynaConverter.setFormattingInfo(kn.getFormatInfo());
            dynaConverter.setOptionList(kn.getOptions());
            addToList(dynaConverter);
          } else {
            // if the appropriate dynaconverter cannot be found, then replace
            // it with a dummy LiteralConverter indicating an error.
            Converter<E> errConveter = new LiteralConverter<E>("%PARSER_ERROR["
                    + kn.getValue() + "]");
            addStatus(new ErrorStatus("[" + kn.getValue()
                    + "] is not a valid conversion word", this));
            addToList(errConveter);
          }

      }
    }
    return head;
  }
@Test
  public void testComposite() throws Exception {
//    {
//      Parser<Object> p = new Parser<Object>("%(ABC)");
//      p.setContext(context);
//      Node t = p.parse();
//      Converter<Object> head = p.compile(t, converterMap);
//      String result = write(head, new Object());
//      assertEquals("ABC", result);
//    }
    {
      Context c = new ContextBase();
      Parser<Object> p = new Parser<Object>("%(ABC %hello)");
      p.setContext(c);
      Node t = p.parse();
      Converter<Object> head = p.compile(t, converterMap);
      String result = write(head, new Object());
      StatusPrinter.print(c);
      assertEquals("ABC Hello", result);
    }
    {
      Parser<Object> p = new Parser<Object>("%(ABC %hello)");
      p.setContext(context);
      Node t = p.parse();
      Converter<Object> head = p.compile(t, converterMap);
      String result = write(head, new Object());
      assertEquals("ABC Hello", result);
    }
  }