public class InterfaceHdrRecord
    extends Record
{
    public final static short sid = 0xe1;

    /**
     * suggested (and probably correct) default
     */

    public final static short CODEPAGE = ( short ) 0x4b0;

    public InterfaceHdrRecord()
    {
    }

    /**
     * Constructs an Codepage record and sets its fields appropriately.
     *
     * @param id     id must be 0xe1 or an exception will be throw upon validation
     * @param size  the size of the data area of the record
     * @param data  data of the record (should not contain sid/len)
     */

    public InterfaceHdrRecord(short id, short size, byte [] data)
    {
        super(id, size, data);
    }

    /**
     * Constructs an Codepage record and sets its fields appropriately.
     *
     * @param id     id must be 0xe1 or an exception will be throw upon validation
     * @param size  the size of the data area of the record
     * @param data  data of the record (should not contain sid/len)
     * @param offset of the record's data
     */

    public InterfaceHdrRecord(short id, short size, byte [] data, int offset)
    {
        super(id, size, data, offset);
    }

    protected void validateSid(short id)
    {
        if (id != sid)
        {
            throw new RecordFormatException("NOT A INTERFACEHDR RECORD");
        }
    }

    protected void fillFields(byte [] data, short size, int offset)
    {
        field_1_codepage = LittleEndian.getShort(data, 0 + offset);
    }

    /**
     * set the codepage for the file
     *
     * @param cp - the codepage
     * @see #CODEPAGE
     */

    public void setCodepage(short cp)
    {
        field_1_codepage = cp;
    }

    /**
     * get the codepage for the file
     *
     * @return the codepage
     * @see #CODEPAGE
     */

    public short getCodepage()
    {
        return field_1_codepage;
    }

    public String toString()
    {
        StringBuffer buffer = new StringBuffer();

        buffer.append("[INTERFACEHDR]\n");
        buffer.append("    .codepage        = ")
            .append(Integer.toHexString(getCodepage())).append("\n");
        buffer.append("[/INTERFACEHDR]\n");
        return buffer.toString();
    }

    public int serialize(int offset, byte [] data)
    {
        LittleEndian.putShort(data, 0 + offset, sid);
        LittleEndian.putShort(data, 2 + offset);
        LittleEndian.putShort(data, 4 + offset, getCodepage());
        return getRecordSize();
    }

    public int getRecordSize()
    {
        return 6;
    }

    public short getSid()
    {
        return this.sid;

    public int getRecordSize()
    {
        return 6;


org.apache.camel.util.EndpointHelper

public final class EndpointHelper {
    private static final transient Log LOG = LogFactory.getLog(EndpointHelper.class);

    private EndpointHelper() {
    }
    /**
     * Creates a {@link PollingConsumer} and polls all pending messages on the endpoint
     * and invokes the given {@link Processor} to process each {@link Exchange} and then closes
     * down the consumer and throws any exceptions thrown.
     *
     * @param endpoint
     * @param processor
     */
    public static void pollEndpoint(Endpoint endpoint, Processor processor, long timeout) throws Exception {
        PollingConsumer consumer = endpoint.createPollingConsumer();
        try {
            consumer.start();

            while (true) {
                Exchange exchange = consumer.receive(timeout);
                if (exchange == null) {
                    break;
                } else {
                    processor.process(exchange);
                }
            }
        } finally {
            try {
                consumer.stop();
            } catch (Exception e) {
                LOG.warn("Failed to stop PollingConsumer: " + e, e);
            }
        }
    }

    /**
     * Creates a {@link PollingConsumer} and polls all pending messages on the
     * endpoint and invokes the given {@link Processor} to process each
     * {@link Exchange} and then closes down the consumer and throws any
     * exceptions thrown.
     *
     * @param endpoint
     * @param processor
     */
    public static void pollEndpoint(Endpoint endpoint, Processor processor) throws Exception {
        pollEndpoint(endpoint, processor, 1000L);


org.apache.camel.view.XmlGraphGenerator

public class XmlGraphGenerator extends GraphGeneratorSupport {
    private boolean addUrl = true;

    public XmlGraphGenerator(String dir) {
        super(dir, ".xml");
    }

    protected void generateFile(PrintWriter writer, Map<String, List<RouteType>> map) {
        writer.println("<?xml version='1.0' encoding='UTF-8'?>");
        writer.println("<Graph>");
        writer.println();

        if (map.size() > 0) {
            writer.println("<Node id='root' name='Camel Routes' description='Collection of Camel Routes' nodeType='root'/>");
        }
        printRoutes(writer, map);

        writer.println();
        writer.println("</Graph>");
    }

    protected void printRoutes(PrintWriter writer, Map<String, List<RouteType>> map) {
        Set<Map.Entry<String, List<RouteType>>> entries = map.entrySet();
        for (Map.Entry<String, List<RouteType>> entry : entries) {
            String group = entry.getKey();
            printRoutes(writer, group, entry.getValue());
        }
    }

    protected void printRoutes(PrintWriter writer, String group, List<RouteType> routes) {
        group = encode(group);
        if (group != null) {
            int idx = group.lastIndexOf('.');
            String name = group;
            if (idx > 0 && idx < group.length() - 1) {
                name = group.substring(idx + 1);
            }
            writer.println("<Node id='" + group + "' name='" + name + "' description='" + group + "' nodeType='group'/>");
            writer.println("<Edge fromID='root' toID='" + group + "'/>");
        }
        for (RouteType route : routes) {
            List<FromType> inputs = route.getInputs();
            boolean first = true;
            for (FromType input : inputs) {
                NodeData nodeData = getNodeData(input);
                if (first) {
                    first = false;
                    if (group != null) {
                        writer.println("<Edge fromID='" + group + "' toID='" + encode(nodeData.id) + "'/>");
                    }
                }
                printRoute(writer, route, nodeData);
            }
            writer.println();
        }
    }

    protected void printRoute(PrintWriter writer, final RouteType route, NodeData nodeData) {
        printNode(writer, nodeData);

        NodeData from = nodeData;
        for (ProcessorType output : route.getOutputs()) {
            NodeData newData = printNode(writer, from, output);
            from = newData;
        }
    }

    protected NodeData printNode(PrintWriter writer, NodeData fromData, ProcessorType node) {
        if (node instanceof MulticastType) {
            List<ProcessorType> outputs = node.getOutputs();
            for (ProcessorType output : outputs) {
                printNode(writer, fromData, output);
            }
            return fromData;
        }
        NodeData toData = getNodeData(node);

        printNode(writer, toData);

        if (fromData != null) {
            writer.print("<Edge fromID=\"");
            writer.print(encode(fromData.id));
            writer.print("\" toID=\"");
            writer.print(encode(toData.id));
            String association = toData.edgeLabel;
            if (isNullOrBlank(association)) {
                writer.print("\" association=\"");
                writer.print(encode(association));
            }
            writer.println("\"/>");
        }

        List<ProcessorType> outputs = toData.outputs;
        if (outputs != null) {
            for (ProcessorType output : outputs) {
                NodeData newData = printNode(writer, toData, output);
                if (!isMulticastNode(node)) {
                    toData = newData;
                }
            }
        }
        return toData;
    }

    protected void printNode(PrintWriter writer, NodeData data) {
        if (!data.nodeWritten) {
            data.nodeWritten = true;

            writer.println();
            writer.print("<Node id=\"");
            writer.print(encode(data.id));
            writer.print("\" name=\"");
            String name = data.label;
            if (isNullOrBlank(name)) {
                name = data.tooltop;
            }
            writer.print(encode(name));
            writer.print("\" nodeType=\"");
            String nodeType = data.image;
            if (isNullOrBlank(nodeType)) {
                nodeType = data.shape;
                if (isNullOrBlank(nodeType)) {
                    nodeType = "node";
                }
            }
            writer.print(encode(nodeType));
            writer.print("\" description=\"");
            writer.print(encode(data.tooltop));
            if (addUrl) {
                writer.print("\" url=\"");
                writer.print(encode(data.url));
            }
            writer.println("\"/>");
        }
    }

    protected String encode(String text) {
        if (text == null) {
            return "";
        }
        return text.replaceAll("\"", """).replaceAll("<", "<").
                replaceAll(">", ">").replaceAll("&", "&");

FUNC_DECL LOOP VAR_DECL PARAM PARAM VAR_DECL CALL CALL CALL CALL

FUNC_DECL LOOP VAR_DECL PARAM PARAM PARAM CALL VAR_DECL CALL ASSIGN CALL

FUNC_DECL RETURN IF VAR_DECL IF VAR_DECL IF PARAM PARAM PARAM BINARY_OP BINARY_OP CALL BINARY_OP LOOP LITERAL_ANCHOR IF VAR_DECL LITERAL_ANCHOR CALL RETURN LOOP VAR_DECL CALL CALL CALL CALL CALL CALL IF VAR_DECL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL CALL CALL CALL CALL CALL CALL LITERAL_ANCHOR ASSIGN

FUNC_DECL IF PARAM PARAM IF IF VAR_DECL IF VAR_DECL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL ASSIGN LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL IF LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR LITERAL_ANCHOR CALL CALL CALL ASSIGN ASSIGN CALL LITERAL_ANCHOR ASSIGN LITERAL_ANCHOR


public class TransformerHandlerImpl
        implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler,
                   LexicalHandler, TransformerHandler, DeclHandler
{

  private boolean m_insideParse = false;

  /**
   * Construct a TransformerHandlerImpl.
   *
   * @param transformer Non-null reference to the Xalan transformer impl.
   * @param doFragment True if the result should be a document fragement.
   * @param baseSystemID  The system ID to use as the base for relative URLs.
   */
  public TransformerHandlerImpl(TransformerImpl transformer,
                                boolean doFragment, String baseSystemID)
  {

    super();

    m_transformer = transformer;
    m_baseSystemID = baseSystemID;

    XPathContext xctxt = transformer.getXPathContext();
    DTM dtm = xctxt.getDTM(null, true, transformer, true, true);

    m_dtm = dtm;
    dtm.setDocumentBaseURI(baseSystemID);

    m_contentHandler = dtm.getContentHandler();
    m_dtdHandler = dtm.getDTDHandler();
    m_entityResolver = dtm.getEntityResolver();
    m_errorHandler = dtm.getErrorHandler();
    m_lexicalHandler = dtm.getLexicalHandler();
  }

  /**
   * Do what needs to be done to shut down the CoRoutine management.
   */
  protected void clearCoRoutine()
  {
    clearCoRoutine(null);
  }

  /**
   * Do what needs to be done to shut down the CoRoutine management.
   */
  protected void clearCoRoutine(SAXException ex)
  {
    if(null != ex)
      m_transformer.setExceptionThrown(ex);

    if(m_dtm instanceof SAX2DTM)
    {
      if(DEBUG)
        System.err.println("In clearCoRoutine...");
      try
      {
        SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);
        if(null != m_contentHandler
           && m_contentHandler instanceof IncrementalSAXSource_Filter)
        {
          IncrementalSAXSource_Filter sp =
            (IncrementalSAXSource_Filter)m_contentHandler;
          sp.deliverMoreNodes(false);
        }

        sax2dtm.clearCoRoutine(true);
        m_contentHandler = null;
        m_dtdHandler = null;
        m_entityResolver = null;
        m_errorHandler = null;
        m_lexicalHandler = null;
      }
      catch(Throwable throwable)
      {
        throwable.printStackTrace();
      }

      if(DEBUG)
        System.err.println("...exiting clearCoRoutine");
    }
  }

  /**
   * Enables the user of the TransformerHandler to set the
   * to set the Result for the transformation.
   *
   * @param result A Result instance, should not be null.
   *
   * @throws IllegalArgumentException if result is invalid for some reason.
   */
  public void setResult(Result result) throws IllegalArgumentException
  {

    if (null == result)

    try
    {
      ContentHandler handler =
        m_transformer.createResultContentHandler(result);

      m_transformer.setContentHandler(handler);
    }
    catch (javax.xml.transform.TransformerException te)
    {
    }

    m_result = result;
  }

  /**
   * Set the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @param systemID Base URI for the source tree.
   */
  public void setSystemId(String systemID)
  {
    m_baseSystemID = systemID;
    m_dtm.setDocumentBaseURI(systemID);
  }

  /**
   * Get the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @return The systemID that was set with {@link #setSystemId}.
   */
  public String getSystemId()
  {
    return m_baseSystemID;
  }

  /**
   * Get the Transformer associated with this handler, which
   * is needed in order to set parameters and output properties.
   *
   * @return The Transformer associated with this handler
   */
  public Transformer getTransformer()
  {
    return m_transformer;
  }

  /**
   * Filter an external entity resolution.
   *
   * @param publicId The entity's public identifier, or null.
   * @param systemId The entity's system identifier.
   * @return A new InputSource or null for the default.
   *
   * @throws IOException
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @throws java.io.IOException The client may throw an
   *            I/O-related exception while obtaining the
   *            new InputSource.
   * @see org.xml.sax.EntityResolver#resolveEntity
   */
  public InputSource resolveEntity(String publicId, String systemId)
          throws SAXException, IOException
  {

    if (m_entityResolver != null)
    {
      return m_entityResolver.resolveEntity(publicId, systemId);
    }
    else
    {
      return null;
    }
  }

  /**
   * Filter a notation declaration event.
   *
   * @param name The notation name.
   * @param publicId The notation's public identifier, or null.
   * @param systemId The notation's system identifier, or null.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.DTDHandler#notationDecl
   */
  public void notationDecl(String name, String publicId, String systemId)
          throws SAXException
  {

    if (m_dtdHandler != null)
    {
      m_dtdHandler.notationDecl(name, publicId, systemId);
    }
  }

  /**
   * Filter an unparsed entity declaration event.
   *
   * @param name The entity name.
   * @param publicId The entity's public identifier, or null.
   * @param systemId The entity's system identifier, or null.
   * @param notationName The name of the associated notation.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void unparsedEntityDecl(
          String name, String publicId, String systemId, String notationName)
            throws SAXException
  {

    if (m_dtdHandler != null)
    {
      m_dtdHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
    }
  }

  /**
   * Filter a new document locator event.
   *
   * @param locator The document locator.
   * @see org.xml.sax.ContentHandler#setDocumentLocator
   */
  public void setDocumentLocator(Locator locator)
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#setDocumentLocator: "
                         + locator.getSystemId());

    this.m_locator = locator;

    if(null == m_baseSystemID)
    {
      setSystemId(locator.getSystemId());
    }

    if (m_contentHandler != null)
    {
      m_contentHandler.setDocumentLocator(locator);
    }
  }

  /**
   * Filter a start document event.
   *
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startDocument
   */
  public void startDocument() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startDocument");

    m_insideParse = true;

    if (m_contentHandler != null)
    {
      if(DTMManager.getIncremental())
      {
        m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());

        int cpriority = Thread.currentThread().getPriority();

        m_transformer.runTransformThread( cpriority );
      }

      m_contentHandler.startDocument();
   }

  }

  /**
   * Filter an end document event.
   *
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endDocument
   */
  public void endDocument() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endDocument");

    m_insideParse = false;

    if (m_contentHandler != null)
    {
      m_contentHandler.endDocument();
    }

    if(DTMManager.getIncremental())
    {
      m_transformer.waitTransformThread();
    }
    else
    {
      m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
      m_transformer.run();
    }
   /* Thread transformThread = m_transformer.getTransformThread();

    if (null != transformThread)
    {
      try
      {

        transformThread.join();

        if (!m_transformer.hasTransformThreadErrorCatcher())
        {
          Exception e = m_transformer.getExceptionThrown();

          if (null != e)
            throw new org.xml.sax.SAXException(e);
        }

        m_transformer.setTransformThread(null);
      }
      catch (InterruptedException ie){}
    }*/
  }

  /**
   * Filter a start Namespace prefix mapping event.
   *
   * @param prefix The Namespace prefix.
   * @param uri The Namespace URI.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startPrefixMapping
   */
  public void startPrefixMapping(String prefix, String uri)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startPrefixMapping: "
                         + prefix + ", " + uri);

    if (m_contentHandler != null)
    {
      m_contentHandler.startPrefixMapping(prefix, uri);
    }
  }

  /**
   * Filter an end Namespace prefix mapping event.
   *
   * @param prefix The Namespace prefix.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endPrefixMapping
   */
  public void endPrefixMapping(String prefix) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endPrefixMapping: "
                         + prefix);

    if (m_contentHandler != null)
    {
      m_contentHandler.endPrefixMapping(prefix);
    }
  }

  /**
   * Filter a start element event.
   *
   * @param uri The element's Namespace URI, or the empty string.
   * @param localName The element's local name, or the empty string.
   * @param qName The element's qualified (prefixed) name, or the empty
   *        string.
   * @param atts The element's attributes.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startElement
   */
  public void startElement(
          String uri, String localName, String qName, Attributes atts)
            throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startElement: " + qName);

    if (m_contentHandler != null)
    {
      m_contentHandler.startElement(uri, localName, qName, atts);
    }
  }

  /**
   * Filter an end element event.
   *
   * @param uri The element's Namespace URI, or the empty string.
   * @param localName The element's local name, or the empty string.
   * @param qName The element's qualified (prefixed) name, or the empty
   *        string.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endElement
   */
  public void endElement(String uri, String localName, String qName)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endElement: " + qName);

    if (m_contentHandler != null)
    {
      m_contentHandler.endElement(uri, localName, qName);
    }
  }

  /**
   * Filter a character data event.
   *
   * @param ch An array of characters.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#characters
   */
  public void characters(char ch[], int start, int length) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#characters: " + start + ", "
                         + length);

    if (m_contentHandler != null)
    {
      m_contentHandler.characters(ch, start, length);
    }
  }

  /**
   * Filter an ignorable whitespace event.
   *
   * @param ch An array of characters.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#ignorableWhitespace
   */
  public void ignorableWhitespace(char ch[], int start, int length)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#ignorableWhitespace: "
                         + start + ", " + length);

    if (m_contentHandler != null)
    {
      m_contentHandler.ignorableWhitespace(ch, start, length);
    }
  }

  /**
   * Filter a processing instruction event.
   *
   * @param target The processing instruction target.
   * @param data The text following the target.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#processingInstruction
   */
  public void processingInstruction(String target, String data)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#processingInstruction: "
                         + target + ", " + data);

    if (m_contentHandler != null)
    {
      m_contentHandler.processingInstruction(target, data);
    }
  }

  /**
   * Filter a skipped entity event.
   *
   * @param name The name of the skipped entity.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#skippedEntity
   */
  public void skippedEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#skippedEntity: " + name);

    if (m_contentHandler != null)
    {
      m_contentHandler.skippedEntity(name);
    }
  }

  /**
   * Filter a warning event.
   *
   * @param e The nwarning as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#warning
   */
  public void warning(SAXParseException e) throws SAXException
  {
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).warning(e);
    }
    else
    {
      try
      {
        errorListener.warning(new javax.xml.transform.TransformerException(e));
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Filter an error event.
   *
   * @param e The error as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#error
   */
  public void error(SAXParseException e) throws SAXException
  {

    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).error(e);
      if(null != m_errorHandler){}
    }
    else
    {
      try
      {
        errorListener.error(new javax.xml.transform.TransformerException(e));
        if(null != m_errorHandler){}
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Filter a fatal error event.
   *
   * @param e The error as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#fatalError
   */
  public void fatalError(SAXParseException e) throws SAXException
  {
    if(null != m_errorHandler)
    {
      try
      {
        m_errorHandler.fatalError(e);
      }
      catch(SAXParseException se)
      {
      }
    }

    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();

    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).fatalError(e);
      if(null != m_errorHandler){}
    }
    else
    {
      try
      {
        errorListener.fatalError(new javax.xml.transform.TransformerException(e));
        if(null != m_errorHandler){}
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Report the start of DTD declarations, if any.
   *
   *
Any declarations are assumed to be in the internal subset
   * unless otherwise indicated by a {@link #startEntity startEntity}
   * event.

   *
   *
Note that the start/endDTD events will appear within
   * the start/endDocument events from ContentHandler and
   * before the first startElement event.

   *
   * @param name The document type name.
   * @param publicId The declared public identifier for the
   *        external DTD subset, or null if none was declared.
   * @param systemId The declared system identifier for the
   *        external DTD subset, or null if none was declared.
   * @throws SAXException The application may raise an
   *            exception.
   * @see #endDTD
   * @see #startEntity
   */
  public void startDTD(String name, String publicId, String systemId)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startDTD: " + name + ", "
                         + publicId + ", " + systemId);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startDTD(name, publicId, systemId);
    }
  }

  /**
   * Report the end of DTD declarations.
   *
   * @throws SAXException The application may raise an exception.
   * @see #startDTD
   */
  public void endDTD() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endDTD");

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endDTD();
    }
  }

  /**
   * Report the beginning of an entity in content.
   *
   *
NOTE:</entity> entity references in attribute
   * values -- and the start and end of the document entity --
   * are never reported.

   *
   *
The start and end of the external DTD subset are reported
   * using the pseudo-name "[dtd]".  All other events must be
   * properly nested within start/end entity events.

   *
   *
Note that skipped entities will be reported through the
   * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
   * event, which is part of the ContentHandler interface.

   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @throws SAXException The application may raise an exception.
   * @see #endEntity
   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
   */
  public void startEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startEntity: " + name);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startEntity(name);
    }
  }

  /**
   * Report the end of an entity.
   *
   * @param name The name of the entity that is ending.
   * @throws SAXException The application may raise an exception.
   * @see #startEntity
   */
  public void endEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endEntity: " + name);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endEntity(name);
    }
  }

  /**
   * Report the start of a CDATA section.
   *
   *
The contents of the CDATA section will be reported through
   * the regular {@link org.xml.sax.ContentHandler#characters
   * characters} event.

   *
   * @throws SAXException The application may raise an exception.
   * @see #endCDATA
   */
  public void startCDATA() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startCDATA");

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startCDATA();
    }
  }

  /**
   * Report the end of a CDATA section.
   *
   * @throws SAXException The application may raise an exception.
   * @see #startCDATA
   */
  public void endCDATA() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endCDATA");

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endCDATA();
    }
  }

  /**
   * Report an XML comment anywhere in the document.
   *
   *
This callback will be used for comments inside or outside the
   * document element, including comments in the external DTD
   * subset (if read).

   *
   * @param ch An array holding the characters in the comment.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The application may raise an exception.
   */
  public void comment(char ch[], int start, int length) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#comment: " + start + ", "
                         + length);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.comment(ch, start, length);
    }
  }

  /**
   * Report an element type declaration.
   *
   *
The content model will consist of the string "EMPTY", the
   * string "ANY", or a parenthesised group, optionally followed
   * by an occurrence indicator.  The model will be normalized so
   * that all whitespace is removed,and will include the enclosing
   * parentheses.

   *
   * @param name The element type name.
   * @param model The content model as a normalized string.
   * @throws SAXException The application may raise an exception.
   */
  public void elementDecl(String name, String model) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#elementDecl: " + name + ", "
                         + model);

    if (null != m_declHandler)
    {
      m_declHandler.elementDecl(name, model);
    }
  }

  /**
   * Report an attribute type declaration.
   *
   *
Only the effective (first) declaration for an attribute will
   * be reported.  The type will be one of the strings "CDATA",
   * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
   * "ENTITIES", or "NOTATION", or a parenthesized token group with
   * the separator "|" and all whitespace removed.

   *
   * @param eName The name of the associated element.
   * @param aName The name of the attribute.
   * @param type A string representing the attribute type.
   * @param valueDefault A string representing the attribute default
   *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
   *        none of these applies.
   * @param value A string representing the attribute's default value,
   *        or null if there is none.
   * @throws SAXException The application may raise an exception.
   */
  public void attributeDecl(
          String eName, String aName, String type, String valueDefault, String value)
            throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#attributeDecl: " + eName
                         + ", " + aName + ", etc...");

    if (null != m_declHandler)
    {
      m_declHandler.attributeDecl(eName, aName, type, valueDefault, value);
    }
  }

  /**
   * Report an internal entity declaration.
   *
   *
Only the effective (first) declaration for each entity
   * will be reported.

   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @param value The replacement text of the entity.
   * @throws SAXException The application may raise an exception.
   * @see #externalEntityDecl
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void internalEntityDecl(String name, String value)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#internalEntityDecl: " + name
                         + ", " + value);

    if (null != m_declHandler)
    {
      m_declHandler.internalEntityDecl(name, value);
    }
  }

  /**
   * Report a parsed external entity declaration.
   *
   *
Only the effective (first) declaration for each entity
   * will be reported.

   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @param publicId The declared public identifier of the entity, or
   *        null if none was declared.
   * @param systemId The declared system identifier of the entity.
   * @throws SAXException The application may raise an exception.
   * @see #internalEntityDecl
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void externalEntityDecl(
          String name, String publicId, String systemId) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#externalEntityDecl: " + name
                         + ", " + publicId + ", " + systemId);

    if (null != m_declHandler)
    {
      m_declHandler.externalEntityDecl(name, publicId, systemId);
    }
  }

  /** Set to true for diagnostics output.         */
  private static boolean DEBUG = false;

  /**
   * The transformer this will use to transform a
   * source tree into a result tree.
   */
  private TransformerImpl m_transformer;

  /** The system ID to use as a base for relative URLs. */
  private String m_baseSystemID;

  /** The result for the transformation. */
  private Result m_result = null;

  /** The locator for this TransformerHandler. */
  private Locator m_locator = null;

  /** The entity resolver to aggregate to. */
  private EntityResolver m_entityResolver = null;

  /** The DTD handler to aggregate to. */
  private DTDHandler m_dtdHandler = null;

  /** The content handler to aggregate to. */
  private ContentHandler m_contentHandler = null;

  /** The error handler to aggregate to. */
  private ErrorHandler m_errorHandler = null;

  /** The lexical handler to aggregate to. */
  private LexicalHandler m_lexicalHandler = null;

  /** The decl handler to aggregate to. */
  private DeclHandler m_declHandler = null;

  /** The Document Table Instance we are transforming. */
  DTM m_dtm;

FUNC_DECL IF PARAM PARAM PARAM PARAM BINARY_OP LITERAL_ANCHOR CALL

FUNC_DECL IF IF BINARY_OP ASSIGN IF LITERAL_ANCHOR LITERAL_ANCHOR CALL CALL CALL LITERAL_ANCHOR VAR_DECL CALL CALL CALL CALL CALL

FUNC_DECL IF IF IF CALL BINARY_OP ASSIGN LITERAL_ANCHOR LITERAL_ANCHOR CALL CALL CALL CALL CALL LITERAL_ANCHOR CALL

FUNC_DECL VAR_DECL VAR_DECL PARAM PARAM PARAM ASSIGN ASSIGN ASSIGN ASSIGN ASSIGN CALL ASSIGN ASSIGN ASSIGN CALL CALL CALL CALL CALL CALL CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR


public class ExtensionsTable
{
  /**
   * <meta name="usage" content="internal"/>
   * Table of extensions that may be called from the expression language
   * via the call(name, ...) function.  Objects are keyed on the call
   * name.
   */
  public Hashtable m_extensionFunctionNamespaces = new Hashtable();

  /**
   * The StylesheetRoot associated with this extensions table.
   */
  private StylesheetRoot m_sroot;

  /**
   * <meta name="usage" content="advanced"/>
   * The constructor (called from TransformerImpl) registers the
   * StylesheetRoot for the transformation and instantiates an
   * ExtensionHandler for each extension namespace.
   */
  public ExtensionsTable(StylesheetRoot sroot)
    throws javax.xml.transform.TransformerException
  {
    m_sroot = sroot;
    Vector extensions = m_sroot.getExtensions();
    for (int i = 0; i < extensions.size(); i++)
    {
      ExtensionNamespaceSupport extNamespaceSpt =
                 (ExtensionNamespaceSupport)extensions.elementAt(i);
      ExtensionHandler extHandler = extNamespaceSpt.launch();
        if (extHandler != null)
          addExtensionNamespace(extNamespaceSpt.getNamespace(), extHandler);
      }
    }

  /**
   * Get an ExtensionHandler object that represents the
   * given namespace.
   * @param extns A valid extension namespace.
   *
   * @return ExtensionHandler object that represents the
   * given namespace.
   */
  public ExtensionHandler get(String extns)
  {
    return (ExtensionHandler) m_extensionFunctionNamespaces.get(extns);
  }

  /**
   * <meta name="usage" content="advanced"/>
   * Register an extension namespace handler. This handler provides
   * functions for testing whether a function is known within the
   * namespace and also for invoking the functions.
   *
   * @param uri the URI for the extension.
   * @param extNS the extension handler.
   */
  public void addExtensionNamespace(String uri, ExtensionHandler extNS)
  {
    m_extensionFunctionNamespaces.put(uri, extNS);
  }

  /**
   * Execute the function-available() function.
   * @param ns       the URI of namespace in which the function is needed
   * @param funcName the function name being tested
   *
   * @return whether the given function is available or not.
   *
   * @throws javax.xml.transform.TransformerException
   */
  public boolean functionAvailable(String ns, String funcName)
          throws javax.xml.transform.TransformerException
  {
    boolean isAvailable = false;

    if (null != ns)
    {
      ExtensionHandler extNS =
           (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
      if (extNS != null)
        isAvailable = extNS.isFunctionAvailable(funcName);
    }
    return isAvailable;
  }

  /**
   * Execute the element-available() function.
   * @param ns       the URI of namespace in which the function is needed
   * @param elemName name of element being tested
   *
   * @return whether the given element is available or not.
   *
   * @throws javax.xml.transform.TransformerException
   */
  public boolean elementAvailable(String ns, String elemName)
          throws javax.xml.transform.TransformerException
  {
    boolean isAvailable = false;
    if (null != ns)
    {
      ExtensionHandler extNS =
               (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
        isAvailable = extNS.isElementAvailable(elemName);
    }
    return isAvailable;
  }

  /**
   * Handle an extension function.
   * @param ns        the URI of namespace in which the function is needed
   * @param funcName  the function name being called
   * @param argVec    arguments to the function in a vector
   * @param methodKey a unique key identifying this function instance in the
   *                  stylesheet
   * @param exprContext a context which may be passed to an extension function
   *                  and provides callback functions to access various
   *                  areas in the environment
   *
   * @return result of executing the function
   *
   * @throws javax.xml.transform.TransformerException
   */
  public Object extFunction(String ns, String funcName,
                            Vector argVec, Object methodKey,
                            ExpressionContext exprContext)
            throws javax.xml.transform.TransformerException
  {
    Object result = null;
    if (null != ns)
    {
      ExtensionHandler extNS =
        (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
      if (null != extNS)
      {
        try
        {
          result = extNS.callFunction(funcName, argVec, methodKey,
                                      exprContext);
        }
        catch (javax.xml.transform.TransformerException e)
        {
          throw e;
        }
        catch (Exception e)
        {
          throw new javax.xml.transform.TransformerException(e);
        }
      }
      else
      {
        throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN, new Object[]{ns, funcName }));
      }
    }
    return result;
  }

  /**
   * Handle an extension function.
   * @param extFunction  the extension function
   * @param argVec    arguments to the function in a vector
   * @param exprContext a context which may be passed to an extension function
   *                  and provides callback functions to access various
   *                  areas in the environment
   *
   * @return result of executing the function
   *
   * @throws javax.xml.transform.TransformerException
   */
  public Object extFunction(FuncExtFunction extFunction, Vector argVec,
                            ExpressionContext exprContext)
         throws javax.xml.transform.TransformerException
  {
    Object result = null;
    String ns = extFunction.getNamespace();
    if (null != ns)
    {
      ExtensionHandler extNS =
        (ExtensionHandler) m_extensionFunctionNamespaces.get(ns);
      if (null != extNS)
      {
        try
        {
          result = extNS.callFunction(extFunction, argVec, exprContext);
        }
        catch (javax.xml.transform.TransformerException e)
        {
          throw e;
        }
        catch (Exception e)
        {
          throw new javax.xml.transform.TransformerException(e);
        }
      }
      else
      {
        throw new XPathProcessorException(XSLMessages.createMessage(XSLTErrorResources.ER_EXTENSION_FUNC_UNKNOWN,
                                          new Object[]{ns, extFunction.getFunctionName()}));
      }
    }
    return result;


public class ElemWithParam extends ElemTemplateElement
{
  /**
   * This is the index to the stack frame being called, <emph>not</emph> the
   * stack frame that contains this element.
   */
  int m_index;

  /**
   * The "select" attribute, which specifies the value of the
   * argument, if element content is not specified.
   * @serial
   */
  private XPath m_selectPattern = null;

  /**
   * Set the "select" attribute.
   * The "select" attribute specifies the value of the
   * argument, if element content is not specified.
   *
   * @param v Value to set for the "select" attribute.
   */
  public void setSelect(XPath v)
  {
    m_selectPattern = v;
  }

  /**
   * Get the "select" attribute.
   * The "select" attribute specifies the value of the
   * argument, if element content is not specified.
   *
   * @return Value of the "select" attribute.
   */
  public XPath getSelect()
  {
    return m_selectPattern;
  }

  /**
   * The required name attribute specifies the name of the
   * parameter (the variable the value of whose binding is
   * to be replaced). The value of the name attribute is a QName,
   * which is expanded as described in [2.4 Qualified Names].
   * @serial
   */
  private QName m_qname = null;

  int m_qnameID;

  /**
   * Set the "name" attribute.
   * DJD
   *
   * @param v Value to set for the "name" attribute.
   */
  public void setName(QName v)
  {
    m_qname = v;
  }

  /**
   * Get the "name" attribute.
   * DJD
   *
   * @return Value of the "name" attribute.
   */
  public QName getName()
  {
    return m_qname;
  }

  /**
   * Get an integer representation of the element type.
   *
   * @return An integer representation of the element, defined in the
   *     Constants class.
   * @see org.apache.xalan.templates.Constants
   */
  public int getXSLToken()
  {
    return Constants.ELEMNAME_WITHPARAM;
  }

  /**
   * Return the node name.
   *
   * @return the node name.
   */
  public String getNodeName()
  {
    return Constants.ELEMNAME_WITHPARAM_STRING;
  }

  /**
   * This function is called after everything else has been
   * recomposed, and allows the template to set remaining
   * values that may be based on some other property that
   * depends on recomposition.
   */
  public void compose(StylesheetRoot sroot) throws TransformerException
  {
    if(null == m_selectPattern
       && org.apache.xalan.processor.TransformerFactoryImpl.m_optimize)
    {
      XPath newSelect = ElemVariable.rewriteChildToExpression(this);
      if(null != newSelect)
        m_selectPattern = newSelect;
    }
    m_qnameID = sroot.getComposeState().getQNameID(m_qname);
    super.compose(sroot);

    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
    if(null != m_selectPattern)
      m_selectPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());

  }

  /**
   * Set the parent as an ElemTemplateElement.
   *
   * @param parent This node's parent as an ElemTemplateElement
   */
  public void setParentElem(ElemTemplateElement p)
  {
    super.setParentElem(p);
    p.m_hasVariableDecl = true;
  }

  /**
   * Get the XObject representation of the variable.
   *
   * @param transformer non-null reference to the the current transform-time state.
   *
   * @return the XObject representation of the variable.
   *
   * @throws TransformerException
   */
  public XObject getValue(TransformerImpl transformer, int sourceNode)
          throws TransformerException
  {

    XObject var;
    XPathContext xctxt = transformer.getXPathContext();

    xctxt.pushCurrentNode(sourceNode);

    try
    {
      if (null != m_selectPattern)
      {
        var = m_selectPattern.execute(xctxt, sourceNode, this);

        var.allowDetachToRelease(false);

        if (TransformerImpl.S_DEBUG)
          transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
                  "select", m_selectPattern, var);
      }
      else if (null == getFirstChildElem())
      {
        var = XString.EMPTYSTRING;
      }
      else
      {

        int df = transformer.transformToRTF(this);

        var = new XRTreeFrag(df, xctxt, this);
      }
    }
    finally
    {
      xctxt.popCurrentNode();
    }

    return var;
  }

  /**
   * Call the children visitors.
   * @param visitor The visitor whose appropriate method will be called.
   */
  protected void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
  {
  	if(callAttrs && (null != m_selectPattern))
  		m_selectPattern.getExpression().callVisitors(m_selectPattern, visitor);
    super.callChildVisitors(visitor, callAttrs);

FUNC_DECL RETURN TRY VAR_DECL VAR_DECL PARAM PARAM IF CALL CALL IF BINARY_OP CALL BINARY_OP IF LITERAL_ANCHOR VAR_DECL CALL LITERAL_ANCHOR CALL ASSIGN ASSIGN ASSIGN CALL LITERAL_ANCHOR CALL CALL CALL CALL LITERAL_ANCHOR


public final class ExpressionBuilder {

    /**
     * Utility classes should not have a public constructor.
     */
    private ExpressionBuilder() {
    }

    /**
     * Returns an expression for the header value with the given name
     *
     * @param headerName the name of the header the expression will return
     * @return an expression object which will return the header value
     */
    public static <E extends Exchange> Expression<E> headerExpression(final String headerName) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Object header = exchange.getIn().getHeader(headerName);
                if (header == null) {
                    header = exchange.getProperty(headerName);
                }
                return header;
            }

            @Override
            public String toString() {
                return "header(" + headerName + ")";
            }
        };
    }

    /**
     * Returns an expression for the inbound message headers
     *
     * @see Message#getHeaders()
     * @return an expression object which will return the inbound headers
     */
    public static <E extends Exchange> Expression<E> headersExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getIn().getHeaders();
            }

            @Override
            public String toString() {
                return "headers";
            }
        };
    }

    /**
     * Returns an expression for the out header value with the given name
     *
     * @param headerName the name of the header the expression will return
     * @return an expression object which will return the header value
     */
    public static <E extends Exchange> Expression<E> outHeaderExpression(final String headerName) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Message out = exchange.getOut(false);
                if (out == null) {
                    return null;
                }
                Object header = out.getHeader(headerName);
                if (header == null) {
                    header = exchange.getProperty(headerName);
                }
                return header;
            }

            @Override
            public String toString() {
                return "outHeader(" + headerName + ")";
            }
        };
    }

    /**
     * Returns an expression for the outbound message headers
     *
     * @see Message#getHeaders()
     * @return an expression object which will return the inbound headers
     */
    public static <E extends Exchange> Expression<E> outHeadersExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getOut().getHeaders();
            }

            @Override
            public String toString() {
                return "outHeaders";
            }
        };
    }

    /**
     * Returns an expression for the property value with the given name
     *
     * @see Exchange#getProperty(String)
     * @param propertyName the name of the property the expression will return
     * @return an expression object which will return the property value
     */
    public static <E extends Exchange> Expression<E> propertyExpression(final String propertyName) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getProperty(propertyName);
            }

            @Override
            public String toString() {
                return "property(" + propertyName + ")";
            }
        };
    }

    /**
     * Returns an expression for the property value with the given name
     *
     * @see Exchange#getProperties()
     * @return an expression object which will return the properties
     */
    public static <E extends Exchange> Expression<E> propertiesExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getProperties();
            }

            @Override
            public String toString() {
                return "properties";
            }
        };
    }

    /**
     * Returns an expression for a system property value with the given name
     *
     * @param propertyName the name of the system property the expression will
     *                return
     * @return an expression object which will return the system property value
     */
    public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName) {
        return systemPropertyExpression(propertyName, null);
    }

    /**
     * Returns an expression for a system property value with the given name
     *
     * @param propertyName the name of the system property the expression will
     *                return
     * @return an expression object which will return the system property value
     */
    public static <E extends Exchange> Expression<E> systemPropertyExpression(final String propertyName,
                                                                              final String defaultValue) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return System.getProperty(propertyName, defaultValue);
            }

            @Override
            public String toString() {
                return "systemProperty(" + propertyName + ")";
            }
        };
    }

    /**
     * Returns an expression for the constant value
     *
     * @param value the value the expression will return
     * @return an expression object which will return the constant value
     */
    public static <E extends Exchange> Expression<E> constantExpression(final Object value) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return value;
            }

            @Override
            public String toString() {
                return "" + value;
            }
        };
    }

    /**
     * Returns the expression for the exchanges inbound message body
     */
    public static <E extends Exchange> Expression<E> bodyExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getIn().getBody();
            }

            @Override
            public String toString() {
                return "body";
            }
        };
    }

    /**
     * Returns the expression for the exchanges inbound message body converted
     * to the given type
     */
    public static <E extends Exchange, T> Expression<E> bodyExpression(final Class<T> type) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getIn().getBody(type);
            }

            @Override
            public String toString() {
                return "bodyAs[" + type.getName() + "]";
            }
        };
    }

    /**
     * Returns the expression for the out messages body
     */
    public static <E extends Exchange> Expression<E> outBodyExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Message out = exchange.getOut(false);
                if (out == null) {
                    return null;
                }
                return out.getBody();
            }

            @Override
            public String toString() {
                return "outBody";
            }
        };
    }

    /**
     * Returns the expression for the exchanges outbound message body converted
     * to the given type
     */
    public static <E extends Exchange, T> Expression<E> outBodyExpression(final Class<T> type) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Message out = exchange.getOut(false);
                if (out == null) {
                    return null;
                }
                return out.getBody(type);
            }

            @Override
            public String toString() {
                return "outBodyAs[" + type.getName() + "]";
            }
        };
    }

    /**
     * Returns the expression for the fault messages body
     */
    public static <E extends Exchange> Expression<E> faultBodyExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getFault().getBody();
            }

            @Override
            public String toString() {
                return "faultBody";
            }
        };
    }

    /**
     * Returns the expression for the exchanges fault message body converted
     * to the given type
     */
    public static <E extends Exchange, T> Expression<E> faultBodyExpression(final Class<T> type) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getFault().getBody(type);
            }

            @Override
            public String toString() {
                return "faultBodyAs[" + type.getName() + "]";
            }
        };
    }

    /**
     * Returns the expression for the exchange
     */
    public static <E extends Exchange> Expression<E> exchangeExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange;
            }

            @Override
            public String toString() {
                return "exchange";
            }
        };
    }

    /**
     * Returns the expression for the IN message
     */
    public static <E extends Exchange> Expression<E> inMessageExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getIn();
            }

            @Override
            public String toString() {
                return "inMessage";
            }
        };
    }

    /**
     * Returns the expression for the OUT message
     */
    public static <E extends Exchange> Expression<E> outMessageExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getOut();
            }

            @Override
            public String toString() {
                return "outMessage";
            }
        };
    }

    /**
     * Returns an expression which converts the given expression to the given
     * type
     */
    public static <E extends Exchange> Expression<E> convertTo(final Expression expression, final Class type) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Object value = expression.evaluate(exchange);
                return exchange.getContext().getTypeConverter().convertTo(type, exchange, value);
            }

            @Override
            public String toString() {
                return "" + expression + ".convertTo(" + type.getName() + ".class)";
            }
        };
    }

    /**
     * Returns a tokenize expression which will tokenize the string with the
     * given token
     */
    public static <E extends Exchange> Expression<E> tokenizeExpression(final Expression<E> expression,
                                                                        final String token) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Object value = expression.evaluate(exchange);
                Scanner scanner = getScanner(exchange, value);
                scanner.useDelimiter(token);
                return scanner;
            }

            @Override
            public String toString() {
                return "tokenize(" + expression + ", " + token + ")";
            }
        };
    }

    /**
     * Returns a tokenize expression which will tokenize the string with the
     * given regex
     */
    public static <E extends Exchange> Expression<E> regexTokenize(final Expression<E> expression,
                                                                   final String regexTokenizer) {
        final Pattern pattern = Pattern.compile(regexTokenizer);
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Object value = expression.evaluate(exchange);
                Scanner scanner = getScanner(exchange, value);
                scanner.useDelimiter(regexTokenizer);
                return scanner;
            }

            @Override
            public String toString() {
                return "regexTokenize(" + expression + ", " + pattern.pattern() + ")";
            }
        };
    }

    private static Scanner getScanner(Exchange exchange, Object value) {
        String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);

        Scanner scanner = null;
        if (value instanceof Readable) {
            scanner = new Scanner((Readable)value);
        } else if (value instanceof InputStream) {
            scanner = charset == null ? new Scanner((InputStream)value)
                : new Scanner((InputStream)value, charset);
        } else if (value instanceof File) {
            try {
                scanner = charset == null ? new Scanner((File)value) : new Scanner((File)value, charset);
            } catch (FileNotFoundException e) {
                throw new RuntimeCamelException(e);
            }
        } else if (value instanceof String) {
            scanner = new Scanner((String)value);
        } else if (value instanceof ReadableByteChannel) {
            scanner = charset == null ? new Scanner((ReadableByteChannel)value)
                : new Scanner((ReadableByteChannel)value, charset);
        }

        if (scanner == null) {
            String text = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value);
            if (text != null) {
                scanner = new Scanner(text);
            }
        }

        if (scanner == null) {
            scanner = new Scanner("");
        }
        return scanner;
    }

    /**
     * Transforms the expression into a String then performs the regex
     * replaceAll to transform the String and return the result
     */
    public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression,
                                                                     final String regex, final String replacement) {
        final Pattern pattern = Pattern.compile(regex);
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                String text = evaluateStringExpression(expression, exchange);
                if (text == null) {
                    return null;
                }
                return pattern.matcher(text).replaceAll(replacement);
            }

            @Override
            public String toString() {
                return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
            }
        };
    }

    /**
     * Transforms the expression into a String then performs the regex
     * replaceAll to transform the String and return the result
     */
    public static <E extends Exchange> Expression<E> regexReplaceAll(final Expression<E> expression,
                                                                     String regex,
                                                                     final Expression<E> replacementExpression) {
        final Pattern pattern = Pattern.compile(regex);
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                String text = evaluateStringExpression(expression, exchange);
                String replacement = evaluateStringExpression(replacementExpression, exchange);
                if (text == null || replacement == null) {
                    return null;
                }
                return pattern.matcher(text).replaceAll(replacement);
            }

            @Override
            public String toString() {
                return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
            }
        };
    }

    /**
     * Appends the String evaluations of the two expressions together
     */
    public static <E extends Exchange> Expression<E> append(final Expression<E> left,
                                                            final Expression<E> right) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return evaluateStringExpression(left, exchange) + evaluateStringExpression(right, exchange);
            }

            @Override
            public String toString() {
                return "append(" + left + ", " + right + ")";
            }
        };
    }

    /**
     * Evaluates the expression on the given exchange and returns the String
     * representation
     *
     * @param expression the expression to evaluate
     * @param exchange the exchange to use to evaluate the expression
     * @return the String representation of the expression or null if it could
     *         not be evaluated
     */
    public static <E extends Exchange> String evaluateStringExpression(Expression<E> expression, E exchange) {
        Object value = expression.evaluate(exchange);
        return exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value);
    }

    /**
     * Returns an expression for the given system property
     */
    public static <E extends Exchange> Expression<E> systemProperty(final String name) {
        return systemProperty(name, null);
    }

    /**
     * Returns an expression for the given system property
     */
    public static <E extends Exchange> Expression<E> systemProperty(final String name,
                                                                    final String defaultValue) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return System.getProperty(name, defaultValue);
            }
        };
    }

    /**
     * Returns an expression which returns the string concatenation value of the various
     * expressions
     *
     * @param expressions the expression to be concatenated dynamically
     * @return an expression which when evaluated will return the concatenated values
     */
    public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions) {
        return concatExpression(expressions, null);
    }

    /**
     * Returns an expression which returns the string concatenation value of the various
     * expressions
     *
     * @param expressions the expression to be concatenated dynamically
     * @param expression the text description of the expression
     * @return an expression which when evaluated will return the concatenated values
     */
    public static <E extends Exchange> Expression<E> concatExpression(final Collection<Expression> expressions, final String expression) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                StringBuffer buffer = new StringBuffer();
                for (Expression<E> expression : expressions) {
                    String text = evaluateStringExpression(expression, exchange);
                    if (text != null) {
                        buffer.append(text);
                    }
                }
                return buffer.toString();
            }

            @Override
            public String toString() {
                if (expression != null) {
                    return expression;
                } else {
                    return "concat" + expressions;
                }
            }
        };
    }

    /**
     * Returns an Expression for the inbound message id
     */
    public static <E extends Exchange> Expression<E> messageIdExpression() {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return exchange.getIn().getMessageId();
            }

            @Override
            public String toString() {
                return "messageId";
            }
        };
    }

    public static <E extends Exchange> Expression<E> dateExpression(final String command, final String pattern) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                Date date;
                if ("now".equals(command)) {
                    date = new Date();
                } else if (command.startsWith("header.") || command.startsWith("in.header.")) {
                    String key = command.substring(command.lastIndexOf(".") + 1);
                    date = exchange.getIn().getHeader(key, Date.class);
                    if (date == null) {
                        throw new IllegalArgumentException("Could not find java.util.Date object at " + command);
                    }
                } else if (command.startsWith("out.header.")) {
                    String key = command.substring(command.lastIndexOf(".") + 1);
                    date = exchange.getOut().getHeader(key, Date.class);
                    if (date == null) {
                        throw new IllegalArgumentException("Could not find java.util.Date object at " + command);
                    }
                } else {
                    throw new IllegalArgumentException("Command not supported for dateExpression: " + command);
                }

                SimpleDateFormat df = new SimpleDateFormat(pattern);
                return df.format(date);
            }

            @Override
            public String toString() {
                return "date(" + command + ":" + pattern + ")";
            }
        };
    }

    public static <E extends Exchange> Expression<E> simpleExpression(final String simple) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return SimpleLanguage.simple(simple).evaluate(exchange);
            }

            @Override
            public String toString() {
                return "simple(" + simple + ")";
            }
        };
    }

    public static <E extends Exchange> Expression<E> beanExpression(final String bean) {
        return new Expression<E>() {
            public Object evaluate(E exchange) {
                return BeanLanguage.bean(bean).evaluate(exchange);
            }

            @Override
            public String toString() {
                return "bean(" + bean + ")";

FUNC_DECL RETURN VAR_DECL PARAM PARAM CALL CALL CALL CALL

FUNC_DECL RETURN PARAM PARAM CALL FUNC_DECL RETURN PARAM CALL


public class LatestRevisionStrategy extends ComparatorLatestStrategy {
    /**
     * Compares two ModuleRevisionId by their revision. Revisions are compared using an algorithm
     * inspired by PHP version_compare one.
     */
    final class MridComparator implements Comparator {
        public int compare(Object o1, Object o2) {
            String rev1 = ((ModuleRevisionId) o1).getRevision();
            String rev2 = ((ModuleRevisionId) o2).getRevision();

            rev1 = rev1.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
            rev1 = rev1.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
            rev2 = rev2.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
            rev2 = rev2.replaceAll("(\\d)([a-zA-Z])", "$1.$2");

            String[] parts1 = rev1.split("[\\._\\-\\+]");
            String[] parts2 = rev2.split("[\\._\\-\\+]");

            int i = 0;
            for (; i < parts1.length && i < parts2.length; i++) {
                if (parts1[i].equals(parts2[i])) {
                    continue;
                }
                boolean is1Number = isNumber(parts1[i]);
                boolean is2Number = isNumber(parts2[i]);
                if (is1Number && !is2Number) {
                    return 1;
                }
                if (is2Number && !is1Number) {
                    return -1;
                }
                if (is1Number && is2Number) {
                    return Long.valueOf(parts1[i]).compareTo(Long.valueOf(parts2[i]));
                }
                // both are strings, we compare them taking into account special meaning
                Map specialMeanings = getSpecialMeanings();
                Integer sm1 = (Integer) specialMeanings.get(parts1[i].toLowerCase(Locale.US));
                Integer sm2 = (Integer) specialMeanings.get(parts2[i].toLowerCase(Locale.US));
                if (sm1 != null) {
                    sm2 = sm2 == null ? new Integer(0) : sm2;
                    return sm1.compareTo(sm2);
                }
                if (sm2 != null) {
                    return new Integer(0).compareTo(sm2);
                }
                return parts1[i].compareTo(parts2[i]);
            }
            if (i < parts1.length) {
                return isNumber(parts1[i]) ? 1 : -1;
            }
            if (i < parts2.length) {
                return isNumber(parts2[i]) ? -1 : 1;
            }
            return 0;
        }

        private boolean isNumber(String str) {
            return str.matches("\\d+");
        }
    }

    /**
     * Compares two ArtifactInfo by their revision. Revisions are compared using an algorithm
     * inspired by PHP version_compare one, unless a dynamic revision is given, in which case the
     * version matcher is used to perform the comparison.
     */
    final class ArtifactInfoComparator implements Comparator {
        public int compare(Object o1, Object o2) {
            String rev1 = ((ArtifactInfo) o1).getRevision();
            String rev2 = ((ArtifactInfo) o2).getRevision();

            /*
             * The revisions can still be not resolved, so we use the current version matcher to
             * know if one revision is dynamic, and in this case if it should be considered greater
             * or lower than the other one. Note that if the version matcher compare method returns
             * 0, it's because it's not possible to know which revision is greater. In this case we
             * consider the dynamic one to be greater, because most of the time it will then be
             * actually resolved and a real comparison will occur.
             */
            VersionMatcher vmatcher = IvyContext.getContext().getSettings().getVersionMatcher();
            ModuleRevisionId mrid1 = ModuleRevisionId.newInstance("", "", rev1);
            ModuleRevisionId mrid2 = ModuleRevisionId.newInstance("", "", rev2);
            if (vmatcher.isDynamic(mrid1)) {
                int c = vmatcher.compare(mrid1, mrid2, mridComparator);
                return c >= 0 ? 1 : -1;
            } else if (vmatcher.isDynamic(mrid2)) {
                int c = vmatcher.compare(mrid2, mrid1, mridComparator);
                return c >= 0 ? -1 : 1;
            }

            return mridComparator.compare(mrid1, mrid2);
        }
    }

    public static class SpecialMeaning {
        private String name;

        private Integer value;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getValue() {
            return value;
        }

        public void setValue(Integer value) {
            this.value = value;
        }

        public void validate() {
            if (name == null) {
                throw new IllegalStateException("a special meaning should have a name");
            }
            if (value == null) {
                throw new IllegalStateException("a special meaning should have a value");
            }
        }
    }

    private static final Map DEFAULT_SPECIAL_MEANINGS;
    static {
        DEFAULT_SPECIAL_MEANINGS = new HashMap();
        DEFAULT_SPECIAL_MEANINGS.put("dev", new Integer(-1));
        DEFAULT_SPECIAL_MEANINGS.put("rc", new Integer(1));
        DEFAULT_SPECIAL_MEANINGS.put("final", new Integer(2));
    }

    private final Comparator mridComparator = new MridComparator();

    private final Comparator artifactInfoComparator = new ArtifactInfoComparator();

    private Map specialMeanings = null;

    private boolean usedefaultspecialmeanings = true;

    public LatestRevisionStrategy() {
        setComparator(artifactInfoComparator);
        setName("latest-revision");
    }

    public void addConfiguredSpecialMeaning(SpecialMeaning meaning) {
        meaning.validate();
        getSpecialMeanings().put(meaning.getName().toLowerCase(Locale.US), meaning.getValue());
    }

    public synchronized Map getSpecialMeanings() {
        if (specialMeanings == null) {
            specialMeanings = new HashMap();
            if (isUsedefaultspecialmeanings()) {
                specialMeanings.putAll(DEFAULT_SPECIAL_MEANINGS);
            }
        }
        return specialMeanings;
    }

    public boolean isUsedefaultspecialmeanings() {
        return usedefaultspecialmeanings;
    }

    public void setUsedefaultspecialmeanings(boolean usedefaultspecialmeanings) {
        this.usedefaultspecialmeanings = usedefaultspecialmeanings;

FUNC_DECL PARAM CALL CALL CALL CALL CALL CALL

FUNC_DECL RETURN IF BINARY_OP IF LITERAL_ANCHOR CALL ASSIGN CALL CALL