public class MethodResolver
{

  /**
   * Specifies a search for static methods only.
   */
  public static final int STATIC_ONLY         = 1;

  /**
   * Specifies a search for instance methods only.
   */
  public static final int INSTANCE_ONLY       = 2;

  /**
   * Specifies a search for both static and instance methods.
   */
  public static final int STATIC_AND_INSTANCE = 3;

  /**
   * Specifies a Dynamic method search.  If the method being
   * evaluated is a static method, all arguments are used.
   * Otherwise, it is an instance method and only arguments
   * beginning with the second argument are used.
   */
  public static final int DYNAMIC             = 4;

  /**
   * Given a class, figure out the resolution of
   * the Java Constructor from the XSLT argument types, and perform the
   * conversion of the arguments.
   * @param classObj the Class of the object to be constructed.
   * @param argsIn An array of XSLT/XPath arguments.
   * @param argsOut An array of the exact size as argsIn, which will be
   * populated with converted arguments if a suitable method is found.
   * @return A constructor that will work with the argsOut array.
   * @throws TransformerException may be thrown for Xalan conversion
   * exceptions.
   */
  public static Constructor getConstructor(Class classObj,
                                           Object[] argsIn,
                                           Object[][] argsOut,
                                           ExpressionContext exprContext)
    throws NoSuchMethodException,
           SecurityException,
           TransformerException
  {
    Constructor bestConstructor = null;
    Class[] bestParamTypes = null;
    Constructor[] constructors = classObj.getConstructors();
    int nMethods = constructors.length;
    int bestScore = Integer.MAX_VALUE;
    int bestScoreCount = 0;
    for(int i = 0; i < nMethods; i++)
    {
      Constructor ctor = constructors[i];
      Class[] paramTypes = ctor.getParameterTypes();
      int numberMethodParams = paramTypes.length;
      int paramStart = 0;
      boolean isFirstExpressionContext = false;
      int scoreStart;
      if(numberMethodParams == (argsIn.length+1))
      {
        Class javaClass = paramTypes[0];
        if(ExpressionContext.class.isAssignableFrom(javaClass))
        {
          isFirstExpressionContext = true;
          scoreStart = 0;
          paramStart++;
        }
        else
          continue;
      }
      else
          scoreStart = 1000;

      if(argsIn.length == (numberMethodParams - paramStart))
      {
        int score = scoreMatch(paramTypes, paramStart, argsIn, scoreStart);
        if(-1 == score)
          continue;
        if(score < bestScore)
        {
          bestConstructor = ctor;
          bestParamTypes = paramTypes;
          bestScore = score;
          bestScoreCount = 1;
        }
        else if (score == bestScore)
          bestScoreCount++;
      }
    }

    if(null == bestConstructor)
    {
      throw new NoSuchMethodException(errString("function", "constructor", classObj,
                                                                        "", 0, argsIn));
    }
    /*** This is commented out until we can do a better object -> object scoring
    else if (bestScoreCount > 1)
                                                                   + classObj.getName());
    ***/
    else
      convertParams(argsIn, argsOut, bestParamTypes, exprContext);

    return bestConstructor;
  }

  /**
   * Given the name of a method, figure out the resolution of
   * the Java Method from the XSLT argument types, and perform the
   * conversion of the arguments.
   * @param classObj The Class of the object that should have the method.
   * @param name The name of the method to be invoked.
   * @param argsIn An array of XSLT/XPath arguments.
   * @param argsOut An array of the exact size as argsIn, which will be
   * populated with converted arguments if a suitable method is found.
   * @return A method that will work with the argsOut array.
   * @throws TransformerException may be thrown for Xalan conversion
   * exceptions.
   */
  public static Method getMethod(Class classObj,
                                 String name,
                                 Object[] argsIn,
                                 Object[][] argsOut,
                                 ExpressionContext exprContext,
                                 int searchMethod)
    throws NoSuchMethodException,
           SecurityException,
           TransformerException
  {
    if (name.indexOf("-")>0)
      name = replaceDash(name);
    Method bestMethod = null;
    Class[] bestParamTypes = null;
    Method[] methods = classObj.getMethods();
    int nMethods = methods.length;
    int bestScore = Integer.MAX_VALUE;
    int bestScoreCount = 0;
    boolean isStatic;
    for(int i = 0; i < nMethods; i++)
    {
      Method method = methods[i];
      int xsltParamStart = 0;
      if(method.getName().equals(name))
      {
        isStatic = Modifier.isStatic(method.getModifiers());
        switch(searchMethod)
        {
          case STATIC_ONLY:
            if (!isStatic)
            {
              continue;
            }
            break;

          case INSTANCE_ONLY:
            if (isStatic)
            {
              continue;
            }
            break;

          case STATIC_AND_INSTANCE:
            break;

          case DYNAMIC:
            if (!isStatic)
              xsltParamStart = 1;
        }
        int javaParamStart = 0;
        Class[] paramTypes = method.getParameterTypes();
        int numberMethodParams = paramTypes.length;
        boolean isFirstExpressionContext = false;
        int scoreStart;
        int argsLen = (null != argsIn) ? argsIn.length : 0;
        if(numberMethodParams == (argsLen-xsltParamStart+1))
        {
          Class javaClass = paramTypes[0];
          if(ExpressionContext.class.isAssignableFrom(javaClass))
          {
            isFirstExpressionContext = true;
            scoreStart = 0;
            javaParamStart++;
          }
          else
          {
            continue;
          }
        }
        else
            scoreStart = 1000;

        if((argsLen - xsltParamStart) == (numberMethodParams - javaParamStart))
        {
          int score = scoreMatch(paramTypes, javaParamStart, argsIn, scoreStart);
          if(-1 == score)
            continue;
          if(score < bestScore)
          {
            bestMethod = method;
            bestParamTypes = paramTypes;
            bestScore = score;
            bestScoreCount = 1;
          }
          else if (score == bestScore)
            bestScoreCount++;
        }
      }
    }

    if (null == bestMethod)
    {
      throw new NoSuchMethodException(errString("function", "method", classObj,
                                                                name, searchMethod, argsIn));
    }
    /*** This is commented out until we can do a better object -> object scoring
    else if (bestScoreCount > 1)
    ***/
    else
      convertParams(argsIn, argsOut, bestParamTypes, exprContext);

    return bestMethod;
  }

  /**
   * To support EXSLT extensions, convert names with dash to allowable Java names:
   * e.g., convert abc-xyz to abcXyz.
   * Note: dashes only appear in middle of an EXSLT function or element name.
   */
  private static String replaceDash(String name)
  {
    char dash = '-';
    StringBuffer buff = new StringBuffer("");
    for (int i=0; i<name.length(); i++)
    {
      if (name.charAt(i) == dash)
      {}
      else if (i > 0 && name.charAt(i-1) == dash)
        buff.append(Character.toUpperCase(name.charAt(i)));
      else
        buff.append(name.charAt(i));
    }
    return buff.toString();
  }

  /**
   * Given the name of a method, figure out the resolution of
   * the Java Method
   * @param classObj The Class of the object that should have the method.
   * @param name The name of the method to be invoked.
   * @return A method that will work to be called as an element.
   * @throws TransformerException may be thrown for Xalan conversion
   * exceptions.
   */
  public static Method getElementMethod(Class classObj,
                                        String name)
    throws NoSuchMethodException,
           SecurityException,
           TransformerException
  {
    Method bestMethod = null;
    Method[] methods = classObj.getMethods();
    int nMethods = methods.length;
    int bestScoreCount = 0;
    for(int i = 0; i < nMethods; i++)
    {
      Method method = methods[i];
      if(method.getName().equals(name))
      {
        Class[] paramTypes = method.getParameterTypes();
        if ( (paramTypes.length == 2)
           && paramTypes[1].isAssignableFrom(org.apache.xalan.templates.ElemExtensionCall.class)
                                         && paramTypes[0].isAssignableFrom(org.apache.xalan.extensions.XSLProcessorContext.class) )
        {
          if ( ++bestScoreCount == 1 )
            bestMethod = method;
          else
            break;
        }
      }
    }

    if (null == bestMethod)
    {
      throw new NoSuchMethodException(errString("element", "method", classObj,
                                                                        name, 0, null));
    }
    else if (bestScoreCount > 1)

    return bestMethod;
  }

  /**
   * Convert a set of parameters based on a set of paramTypes.
   * @param argsIn An array of XSLT/XPath arguments.
   * @param argsOut An array of the exact size as argsIn, which will be
   * populated with converted arguments.
   * @param paramTypes An array of class objects, of the exact same
   * size as argsIn and argsOut.
   * @throws TransformerException may be thrown for Xalan conversion
   * exceptions.
   */
  public static void convertParams(Object[] argsIn,
                                   Object[][] argsOut, Class[] paramTypes,
                                   ExpressionContext exprContext)
    throws javax.xml.transform.TransformerException
  {
    if (paramTypes == null)
      argsOut[0] = null;
    else
    {
      int nParams = paramTypes.length;
      argsOut[0] = new Object[nParams];
      int paramIndex = 0;
      if((nParams > 0)
         && ExpressionContext.class.isAssignableFrom(paramTypes[0]))
      {
        argsOut[0][0] = exprContext;
        paramIndex++;
      }

      if (argsIn != null)
      {
        for(int i = argsIn.length - nParams + paramIndex ; paramIndex < nParams; i++, paramIndex++)
        {
          argsOut[0][paramIndex] = convert(argsIn[i], paramTypes[paramIndex]);
        }
      }
    }
  }

  /**
   * Simple class to hold information about allowed conversions
   * and their relative scores, for use by the table below.
   */
  static class ConversionInfo
  {
    ConversionInfo(Class cl, int score)
    {
      m_class = cl;
      m_score = score;
    }

  }

  private static final int SCOREBASE=1;

  /**
   * Specification of conversions from XSLT type CLASS_UNKNOWN
   * (i.e. some unknown Java object) to allowed Java types.
   */
  static ConversionInfo[] m_javaObjConversions = {
    new ConversionInfo(Double.TYPE, 11),
    new ConversionInfo(Float.TYPE, 12),
    new ConversionInfo(Long.TYPE, 13),
    new ConversionInfo(Integer.TYPE, 14),
    new ConversionInfo(Short.TYPE, 15),
    new ConversionInfo(Character.TYPE, 16),
    new ConversionInfo(Byte.TYPE, 17),
    new ConversionInfo(java.lang.String.class, 18)
  };

  /**
   * Specification of conversions from XSLT type CLASS_BOOLEAN
   * to allowed Java types.
   */
  static ConversionInfo[] m_booleanConversions = {
    new ConversionInfo(Boolean.TYPE, 0),
    new ConversionInfo(java.lang.Boolean.class, 1),
    new ConversionInfo(java.lang.Object.class, 2),
    new ConversionInfo(java.lang.String.class, 3)
  };

  /**
   * Specification of conversions from XSLT type CLASS_NUMBER
   * to allowed Java types.
   */
  static ConversionInfo[] m_numberConversions = {
    new ConversionInfo(Double.TYPE, 0),
    new ConversionInfo(java.lang.Double.class, 1),
    new ConversionInfo(Float.TYPE, 3),
    new ConversionInfo(Long.TYPE, 4),
    new ConversionInfo(Integer.TYPE, 5),
    new ConversionInfo(Short.TYPE, 6),
    new ConversionInfo(Character.TYPE, 7),
    new ConversionInfo(Byte.TYPE, 8),
    new ConversionInfo(Boolean.TYPE, 9),
    new ConversionInfo(java.lang.String.class, 10),
    new ConversionInfo(java.lang.Object.class, 11)
  };

  /**
   * Specification of conversions from XSLT type CLASS_STRING
   * to allowed Java types.
   */
  static ConversionInfo[] m_stringConversions = {
    new ConversionInfo(java.lang.String.class, 0),
    new ConversionInfo(java.lang.Object.class, 1),
    new ConversionInfo(Character.TYPE, 2),
    new ConversionInfo(Double.TYPE, 3),
    new ConversionInfo(Float.TYPE, 3),
    new ConversionInfo(Long.TYPE, 3),
    new ConversionInfo(Integer.TYPE, 3),
    new ConversionInfo(Short.TYPE, 3),
    new ConversionInfo(Byte.TYPE, 3),
    new ConversionInfo(Boolean.TYPE, 4)
  };

  /**
   * Specification of conversions from XSLT type CLASS_RTREEFRAG
   * to allowed Java types.
   */
  static ConversionInfo[] m_rtfConversions = {
    new ConversionInfo(org.w3c.dom.traversal.NodeIterator.class, 0),
    new ConversionInfo(org.w3c.dom.NodeList.class, 1),
    new ConversionInfo(org.w3c.dom.Node.class, 2),
    new ConversionInfo(java.lang.String.class, 3),
    new ConversionInfo(java.lang.Object.class, 5),
    new ConversionInfo(Character.TYPE, 6),
    new ConversionInfo(Double.TYPE, 7),
    new ConversionInfo(Float.TYPE, 7),
    new ConversionInfo(Long.TYPE, 7),
    new ConversionInfo(Integer.TYPE, 7),
    new ConversionInfo(Short.TYPE, 7),
    new ConversionInfo(Byte.TYPE, 7),
    new ConversionInfo(Boolean.TYPE, 8)
  };

  /**
   * Specification of conversions from XSLT type CLASS_NODESET
   * to allowed Java types.  (This is the same as for CLASS_RTREEFRAG)
   */
  static ConversionInfo[] m_nodesetConversions = {
    new ConversionInfo(org.w3c.dom.traversal.NodeIterator.class, 0),
    new ConversionInfo(org.w3c.dom.NodeList.class, 1),
    new ConversionInfo(org.w3c.dom.Node.class, 2),
    new ConversionInfo(java.lang.String.class, 3),
    new ConversionInfo(java.lang.Object.class, 5),
    new ConversionInfo(Character.TYPE, 6),
    new ConversionInfo(Double.TYPE, 7),
    new ConversionInfo(Float.TYPE, 7),
    new ConversionInfo(Long.TYPE, 7),
    new ConversionInfo(Integer.TYPE, 7),
    new ConversionInfo(Short.TYPE, 7),
    new ConversionInfo(Byte.TYPE, 7),
    new ConversionInfo(Boolean.TYPE, 8)
  };

  /**
   * Order is significant in the list below, based on
   * XObject.CLASS_XXX values.
   */
  static ConversionInfo[][] m_conversions =
  {
  };

  /**
   * Score the conversion of a set of XSLT arguments to a
   * given set of Java parameters.
   * If any invocations of this function for a method with
   * the same name return the same positive value, then a conflict
   * has occured, and an error should be signaled.
   * @param javaParamTypes Must be filled with valid class names, and
   * of the same length as xsltArgs.
   * @param xsltArgs Must be filled with valid object instances, and
   * of the same length as javeParamTypes.
   * @return -1 for no allowed conversion, or a positive score
   * that is closer to zero for more preferred, or further from
   * zero for less preferred.
   */
  public static int scoreMatch(Class[] javaParamTypes, int javaParamsStart,
                               Object[] xsltArgs, int score)
  {
    if ((xsltArgs == null) || (javaParamTypes == null))
      return score;
    int nParams = xsltArgs.length;
    for(int i = nParams - javaParamTypes.length + javaParamsStart, javaParamTypesIndex = javaParamsStart;
        i < nParams;
        i++, javaParamTypesIndex++)
    {
      Object xsltObj = xsltArgs[i];
      int xsltClassType = (xsltObj instanceof XObject)
                          ? ((XObject)xsltObj).getType()
                            : XObject.CLASS_UNKNOWN;
      Class javaClass = javaParamTypes[javaParamTypesIndex];

      if(xsltClassType == XObject.CLASS_NULL)
      {
        if(!javaClass.isPrimitive())
        {
          score += 10;
          continue;
        }

      }

      ConversionInfo[] convInfo = m_conversions[xsltClassType];
      int nConversions = convInfo.length;
      int k;
      for(k = 0; k < nConversions; k++)
      {
        ConversionInfo cinfo = convInfo[k];
        if(javaClass.isAssignableFrom(cinfo.m_class))
        {
          score += cinfo.m_score;
        }
      }

      if (k == nConversions)
      {

        if (XObject.CLASS_UNKNOWN == xsltClassType)
        {
          Class realClass = null;

          if (xsltObj instanceof XObject)
          {
            Object realObj = ((XObject) xsltObj).object();
            if (null != realObj)
            {
              realClass = realObj.getClass();
            }
            else
            {
              score += 10;
              continue;
            }
          }
          else
          {
            realClass = xsltObj.getClass();
          }

          if (javaClass.isAssignableFrom(realClass))
          {
          }
          else
            return -1;
        }
        else
          return -1;
      }
    }
    return score;
  }

  /**
   * Convert the given XSLT object to an object of
   * the given class.
   * @param xsltObj The XSLT object that needs conversion.
   * @param javaClass The type of object to convert to.
   * @returns An object suitable for passing to the Method.invoke
   * function in the args array, which may be null in some cases.
   * @throws TransformerException may be thrown for Xalan conversion
   * exceptions.
   */
  static Object convert(Object xsltObj, Class javaClass)
    throws javax.xml.transform.TransformerException
  {
    if(xsltObj instanceof XObject)
    {
      XObject xobj = ((XObject)xsltObj);
      int xsltClassType = xobj.getType();

      switch(xsltClassType)
      {
      case XObject.CLASS_NULL:
        return null;

      case XObject.CLASS_BOOLEAN:
        {
          if(javaClass == java.lang.String.class)
            return xobj.str();
          else
            return new Boolean(xobj.bool());
        }
      case XObject.CLASS_NUMBER:
        {
          if(javaClass == java.lang.String.class)
            return xobj.str();
          else if(javaClass == Boolean.TYPE)
            return new Boolean(xobj.bool());
          else
          {
            return convertDoubleToNumber(xobj.num(), javaClass);
          }
        }

      case XObject.CLASS_STRING:
        {
          if((javaClass == java.lang.String.class) ||
             (javaClass == java.lang.Object.class))
            return xobj.str();
          else if(javaClass == Character.TYPE)
          {
            String str = xobj.str();
            if(str.length() > 0)
              return new Character(str.charAt(0));

          }
          else if(javaClass == Boolean.TYPE)
            return new Boolean(xobj.bool());
          else
          {
            return convertDoubleToNumber(xobj.num(), javaClass);
          }
        }

      case XObject.CLASS_RTREEFRAG:
        {
          if ( (javaClass == NodeIterator.class) ||
               (javaClass == java.lang.Object.class) )
          {
            DTMIterator dtmIter = ((XRTreeFrag) xobj).asNodeIterator();
            return new DTMNodeIterator(dtmIter);
          }
          else if (javaClass == NodeList.class)
          {
            return ((XRTreeFrag) xobj).convertToNodeset();
          }
          else if(javaClass == Node.class)
          {
            DTMIterator iter = ((XRTreeFrag) xobj).asNodeIterator();
            int rootHandle = iter.nextNode();
            DTM dtm = iter.getDTM(rootHandle);
            return dtm.getNode(dtm.getFirstChild(rootHandle));
          }
          else if(javaClass == java.lang.String.class)
          {
            return xobj.str();
          }
          else if(javaClass == Boolean.TYPE)
          {
            return new Boolean(xobj.bool());
          }
          else if(javaClass.isPrimitive())
          {
            return convertDoubleToNumber(xobj.num(), javaClass);
          }
          else
          {
            DTMIterator iter = ((XRTreeFrag) xobj).asNodeIterator();
            int rootHandle = iter.nextNode();
            DTM dtm = iter.getDTM(rootHandle);
            Node child = dtm.getNode(dtm.getFirstChild(rootHandle));

            if(javaClass.isAssignableFrom(child.getClass()))
              return child;
            else
              return null;
          }
        }

      case XObject.CLASS_NODESET:
        {
          if ( (javaClass == NodeIterator.class) ||
               (javaClass == java.lang.Object.class) )
          {
            return xobj.nodeset();
          }
          else if(javaClass == NodeList.class)
          {
            return xobj.nodelist();
          }
          else if(javaClass == Node.class)
          {
            DTMIterator ni = xobj.iter();
            int handle = ni.nextNode();
          }
          else if(javaClass == java.lang.String.class)
          {
            return xobj.str();
          }
          else if(javaClass == Boolean.TYPE)
          {
            return new Boolean(xobj.bool());
          }
          else if(javaClass.isPrimitive())
          {
            return convertDoubleToNumber(xobj.num(), javaClass);
          }
          else
          {
            DTMIterator iter = xobj.iter();
            int childHandle = iter.nextNode();
            DTM dtm = iter.getDTM(childHandle);
            Node child = dtm.getNode(childHandle);
            if(javaClass.isAssignableFrom(child.getClass()))
              return child;
            else
              return null;
          }
        }
	  }
      xsltObj = xobj.object();
	}

    if (null != xsltObj)
    {
      if(javaClass == java.lang.String.class)
      {
        return xsltObj.toString();
      }
      else if(javaClass.isPrimitive())
      {
        XString xstr = new XString(xsltObj.toString());
        double num = xstr.num();
        return convertDoubleToNumber(num, javaClass);
      }
      else if(javaClass == java.lang.Class.class)
      {
        return xsltObj.getClass();
      }
      else
      {
        return xsltObj;
      }
                }
    else
    {
      return xsltObj;
    }
  }

  /**
   * Do a standard conversion of a double to the specified type.
   * @param num The number to be converted.
   * @param javaClass The class type to be converted to.
   * @return An object specified by javaClass, or a Double instance.
   */
  static Object convertDoubleToNumber(double num, Class javaClass)
  {
    if((javaClass == Double.TYPE) ||
       (javaClass == java.lang.Double.class))
      return new Double(num);
    else if(javaClass == Float.TYPE)
      return new Float(num);
    else if(javaClass == Long.TYPE)
    {
      return new Long((long)num);
    }
    else if(javaClass == Integer.TYPE)
    {
      return new Integer((int)num);
    }
    else if(javaClass == Short.TYPE)
    {
      return new Short((short)num);
    }
    else if(javaClass == Character.TYPE)
    {
      return new Character((char)num);
    }
    else if(javaClass == Byte.TYPE)
    {
      return new Byte((byte)num);
    }
    {
      return new Double(num);
    }
  }

  private static String errArgs(Object[] xsltArgs, int startingArg)
  {
    StringBuffer returnArgs = new StringBuffer();
    for (int i = startingArg; i < xsltArgs.length; i++)
    {
      if (i != startingArg)
        returnArgs.append(", ");
      if (xsltArgs[i] instanceof XObject)
        returnArgs.append(((XObject) xsltArgs[i]).getTypeString());
      else
        returnArgs.append(xsltArgs[i].getClass().getName());
    }
    return returnArgs.toString();

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

FUNC_DECL IF PARAM PARAM RETURN IF RETURN BINARY_OP CALL IF RETURN BINARY_OP CALL BINARY_OP BINARY_OP IF BINARY_OP CALL IF BINARY_OP RETURN IF BINARY_OP RETURN CALL IF BINARY_OP RETURN CALL BINARY_OP RETURN CALL RETURN CALL CALL

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


org.apache.tools.ant.util.DOMUtils

public class DOMUtils {

    /**
     * Get a new Document instance,
     * @return the document.
     * @since Ant 1.6.3
     */
    public static Document newDocument() {
        return JAXPUtils.getDocumentBuilder().newDocument();
    }

    /**
     * Creates a named Element and appends it to the given element,
     * returns it.
     *
     *
This means
     *
createChildElement(<a>, "b")

     * creates
     *

     * <a>
     *   <b/>
     * </a>
     *

     * and returns <b>.

     *
     * @param parent element that will receive the new element as child.
     * @param name name of the new element.
     * @return the new element.
     *
     * @since Ant 1.6.3
     */
    public static Element createChildElement(Element parent, String name) {
        Document doc = parent.getOwnerDocument();
        Element e = doc.createElement(name);
        parent.appendChild(e);
        return e;
    }

    /**
     * Adds nested text.
     *
     *
This means
     *
appendText(<a>, "b")

     * creates
     *

     * <a>b</a>
     *

     *

     *
     * @param parent element that will receive the new element as child.
     * @param content text content.
     *
     * @since Ant 1.6.3
     */
    public static void appendText(Element parent, String content) {
        Document doc = parent.getOwnerDocument();
        Text t = doc.createTextNode(content);
        parent.appendChild(t);
    }

    /**
     * Adds a nested CDATA section.
     *
     *
This means
     *
appendCDATA(<a>, "b")

     * creates
     *

     * <a><[!CDATA[b]]></a>
     *

     *

     *
     * @param parent element that will receive the new element as child.
     * @param content text content.
     *
     * @since Ant 1.6.3
     */
    public static void appendCDATA(Element parent, String content) {
        Document doc = parent.getOwnerDocument();
        CDATASection c = doc.createCDATASection(content);
        parent.appendChild(c);
    }

    /**
     * Adds nested text in a new child element.
     *
     *
This means
     *
appendTextElement(<a>, "b", "c")

     * creates
     *

     * <a>
     *   <b>c</b>
     * </a>
     *

     *

     *
     * @param parent element that will receive the new element as child.
     * @param name of the child element.
     * @param content text content.
     *
     * @since Ant 1.6.3
     */
    public static void appendTextElement(Element parent, String name,
                                         String content) {
        Element e = createChildElement(parent, name);
        appendText(e, content);
    }

    /**
     * Adds a nested CDATA section in a new child element.
     *
     *
This means
     *
appendCDATAElement(<a>, "b", "c")

     * creates
     *

     * <a>
     *   <b><![CDATA[c]]></b>
     * </a>
     *

     *

     *

     *
     * @param parent element that will receive the new element as child.
     * @param name of the child element.
     * @param content text content.
     *
     * @since Ant 1.6.3
     */
    public static void appendCDATAElement(Element parent, String name,
                                          String content) {
        Element e = createChildElement(parent, name);
        appendCDATA(e, content);

FUNC_DECL RETURN VAR_DECL VAR_DECL PARAM PARAM CALL CALL CALL

FUNC_DECL VAR_DECL PARAM PARAM PARAM CALL CALL


public class ThrowableInformation implements java.io.Serializable {

  static final long serialVersionUID = -4748765566864322735L;

  private transient Throwable throwable;
  private transient Category category;
  private String[] rep;

  public
  ThrowableInformation(Throwable throwable) {
    this.throwable = throwable;
  }

    /**
     * Create a new instance.
     * @param throwable throwable, may not be null.
     * @param category category used to obtain ThrowableRenderer, may be null.
     * @since 1.2.16
     */
  public ThrowableInformation(Throwable throwable, Category category) {
      this.throwable = throwable;
      this.category = category;
  }

    /**
     * Create new instance.
     * @since 1.2.15
     * @param r String representation of throwable.
     */
  public ThrowableInformation(final String[] r) {
      if (r != null) {
        rep = (String[]) r.clone();
      }
  }

  public
  Throwable getThrowable() {
    return throwable;
  }

  public synchronized String[] getThrowableStrRep() {
    if(rep == null) {
      ThrowableRenderer renderer = null;
      if (category != null) {
          LoggerRepository repo = category.getLoggerRepository();
          if (repo instanceof ThrowableRendererSupport) {
              renderer = ((ThrowableRendererSupport) repo).getThrowableRenderer();
          }
      }
      if (renderer == null) {
          rep = DefaultThrowableRenderer.render(throwable);
      } else {
          rep = renderer.doRender(throwable);
      }
    }
    return (String[]) rep.clone();


org.apache.xalan.lib.ExsltStrings

public class ExsltStrings extends ExsltBase
{
  /**
   * The str:align function aligns a string within another string.
   *

   * The first argument gives the target string to be aligned. The second argument gives
   * the padding string within which it is to be aligned.
   *

   * If the target string is shorter than the padding string then a range of characters
   * in the padding string are repaced with those in the target string. Which characters
   * are replaced depends on the value of the third argument, which gives the type of
   * alignment. It can be one of 'left', 'right' or 'center'. If no third argument is
   * given or if it is not one of these values, then it defaults to left alignment.
   *

   * With left alignment, the range of characters replaced by the target string begins
   * with the first character in the padding string. With right alignment, the range of
   * characters replaced by the target string ends with the last character in the padding
   * string. With center alignment, the range of characters replaced by the target string
   * is in the middle of the padding string, such that either the number of unreplaced
   * characters on either side of the range is the same or there is one less on the left
   * than there is on the right.
   *

   * If the target string is longer than the padding string, then it is truncated to be
   * the same length as the padding string and returned.
   *
   * @param targetStr The target string
   * @param paddingStr The padding string
   * @param type The type of alignment
   *
   * @return The string after alignment
   */
  public static String align(String targetStr, String paddingStr, String type)
  {
    if (targetStr.length() >= paddingStr.length())
      return targetStr.substring(0, paddingStr.length());

    if (type.equals("right"))
    {
      return paddingStr.substring(0, paddingStr.length() - targetStr.length()) + targetStr;
    }
    else if (type.equals("center"))
    {
      int startIndex = (paddingStr.length() - targetStr.length()) / 2;
      return paddingStr.substring(0, startIndex) + targetStr + paddingStr.substring(startIndex + targetStr.length());
    }
    else
    {
      return targetStr + paddingStr.substring(targetStr.length());
    }
  }

  /**
   * See above
   */
  public static String align(String targetStr, String paddingStr)
  {
    return align(targetStr, paddingStr, "left");
  }

  /**
   * The str:concat function takes a node set and returns the concatenation of the
   * string values of the nodes in that node set. If the node set is empty, it returns
   * an empty string.
   *
   * @param nl A node set
   * @return The concatenation of the string values of the nodes in that node set
   */
  public static String concat(NodeList nl)
  {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < nl.getLength(); i++)
    {
      Node node = nl.item(i);
      String value = toString(node);

      if (value != null && value.length() > 0)
        sb.append(value);
    }

    return sb.toString();
  }

  /**
   * The str:padding function creates a padding string of a certain length.
   * The first argument gives the length of the padding string to be created.
   * The second argument gives a string to be used to create the padding. This
   * string is repeated as many times as is necessary to create a string of the
   * length specified by the first argument; if the string is more than a character
   * long, it may have to be truncated to produce the required length. If no second
   * argument is specified, it defaults to a space (' '). If the second argument is
   * an empty string, str:padding returns an empty string.
   *
   * @param length The length of the padding string to be created
   * @param pattern The string to be used as pattern
   *
   * @return A padding string of the given length
   */
  public static String padding(double length, String pattern)
  {
    if (pattern == null || pattern.length() == 0)
      return "";

    StringBuffer sb = new StringBuffer();
    int len = (int)length;
    int numAdded = 0;
    int index = 0;
    while (numAdded < len)
    {
      if (index == pattern.length())
        index = 0;

      sb.append(pattern.charAt(index));
      index++;
      numAdded++;
    }

    return sb.toString();
  }

  /**
   * See above
   */
  public static String padding(double length)
  {
    return padding(length, " ");
  }

  /**
   * The str:split function splits up a string and returns a node set of token
   * elements, each containing one token from the string.
   *

   * The first argument is the string to be split. The second argument is a pattern
   * string. The string given by the first argument is split at any occurrence of
   * this pattern. For example:
   *

   * str:split('a, simple, list', ', ') gives the node set consisting of:
   *
   * <token>a</token>
   * <token>simple</token>
   * <token>list</token>
   *

   * If the second argument is omitted, the default is the string ' ' (i.e. a space).
   *
   * @param str The string to be split
   * @param pattern The pattern
   *
   * @return A node set of split tokens
   */
  public static NodeList split(String str, String pattern)
  {

    NodeSet resultSet = new NodeSet();
    resultSet.setShouldCacheNodes(true);

    boolean done = false;
    int fromIndex = 0;
    int matchIndex = 0;
    String token = null;

    while (!done && fromIndex < str.length())
    {
      matchIndex = str.indexOf(pattern, fromIndex);
      if (matchIndex >= 0)
      {
	token = str.substring(fromIndex, matchIndex);
	fromIndex = matchIndex + pattern.length();
      }
      else
      {
        done = true;
        token = str.substring(fromIndex);
      }

      Document doc = DocumentHolder.m_doc;
      synchronized (doc)
      {
        Element element = doc.createElement("token");
        Text text = doc.createTextNode(token);
        element.appendChild(text);
        resultSet.addNode(element);
      }
    }

    return resultSet;
  }

  /**
   * See above
   */
  public static NodeList split(String str)
  {
    return split(str, " ");
  }

  /**
   * The str:tokenize function splits up a string and returns a node set of token
   * elements, each containing one token from the string.
   *

   * The first argument is the string to be tokenized. The second argument is a
   * string consisting of a number of characters. Each character in this string is
   * taken as a delimiting character. The string given by the first argument is split
   * at any occurrence of any of these characters. For example:
   *

   * str:tokenize('2001-06-03T11:40:23', '-T:') gives the node set consisting of:
   *
   * <token>2001</token>
   * <token>06</token>
   * <token>03</token>
   * <token>11</token>
   * <token>40</token>
   * <token>23</token>
   *

   * If the second argument is omitted, the default is the string '

 '
   * (i.e. whitespace characters).
   *

   * If the second argument is an empty string, the function returns a set of token
   * elements, each of which holds a single character.
   *

   * Note: This one is different from the tokenize extension function in the Xalan
   * namespace. The one in Xalan returns a set of Text nodes, while this one wraps
   * the Text nodes inside the token Element nodes.
   *
   * @param toTokenize The string to be tokenized
   * @param delims The delimiter string
   *
   * @return A node set of split token elements
   */
  public static NodeList tokenize(String toTokenize, String delims)
  {

    NodeSet resultSet = new NodeSet();

    if (delims != null && delims.length() > 0)
    {
      StringTokenizer lTokenizer = new StringTokenizer(toTokenize, delims);

      Document doc = DocumentHolder.m_doc;
      synchronized (doc)
      {
        while (lTokenizer.hasMoreTokens())
        {
          Element element = doc.createElement("token");
          element.appendChild(doc.createTextNode(lTokenizer.nextToken()));
          resultSet.addNode(element);
        }
      }
    }
    else
    {

      Document doc = DocumentHolder.m_doc;
      synchronized (doc)
      {
        for (int i = 0; i < toTokenize.length(); i++)
        {
          Element element = doc.createElement("token");
          element.appendChild(doc.createTextNode(toTokenize.substring(i, i+1)));
          resultSet.addNode(element);
        }
      }
    }

    return resultSet;
  }

  /**
   * See above
   */
  public static NodeList tokenize(String toTokenize)
  {
    return tokenize(toTokenize, " \t\n\r");
  }
    /**
     * This class is not loaded until first referenced (see Java Language
     * Specification by Gosling/Joy/Steele, section 12.4.1)
     *
     * The static members are created when this class is first referenced, as a
     * lazy initialization not needing checking against null or any
     * synchronization.
     *
     */
    private static class DocumentHolder
    {
        private static final Document m_doc;

FUNC_DECL RETURN PARAM PARAM CALL LITERAL_ANCHOR


public class TransactionInterceptor extends DelegateProcessor {
    public static final ExchangeProperty<Boolean> TRANSACTED =
        new ExchangeProperty<Boolean>("transacted", "org.apache.camel.transacted", Boolean.class);
    private static final transient Log LOG = LogFactory.getLog(TransactionInterceptor.class);
    private final TransactionTemplate transactionTemplate;
    private RedeliveryPolicy redeliveryPolicy;
    private DelayPolicy delayPolicy;

    public TransactionInterceptor(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public TransactionInterceptor(Processor processor, TransactionTemplate transactionTemplate) {
        super(processor);
        this.transactionTemplate = transactionTemplate;
    }

    /**
     * @deprecated use DelayPolicy. Will be removed in Camel 2.0
     */
    public TransactionInterceptor(Processor processor, TransactionTemplate transactionTemplate, RedeliveryPolicy redeliveryPolicy) {
        this(processor, transactionTemplate);
        this.redeliveryPolicy = redeliveryPolicy;
        this.delayPolicy = redeliveryPolicy;
    }

    public TransactionInterceptor(Processor processor, TransactionTemplate transactionTemplate, DelayPolicy delayPolicy) {
        this(processor, transactionTemplate);
        this.delayPolicy = delayPolicy;
    }

    @Override
    public String toString() {
        return "TransactionInterceptor:"
            + propagationBehaviorToString(transactionTemplate.getPropagationBehavior())
            + "[" + getProcessor() + "]";
    }

    public void process(final Exchange exchange) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            protected void doInTransactionWithoutResult(TransactionStatus status) {

                RuntimeCamelException rce = null;

                boolean activeTx = false;
                try {
                    activeTx = TransactionSynchronizationManager.isActualTransactionActive();
                    if (!activeTx) {
                        activeTx = status.isNewTransaction() && !status.isCompleted();
                        if (!activeTx) {
                            if (DefaultTransactionStatus.class.isAssignableFrom(status.getClass())) {
                                DefaultTransactionStatus defStatus =
                                        DefaultTransactionStatus.class.cast(status);
                                activeTx = defStatus.hasTransaction() && !status.isCompleted();
                            }
                        }
                    }
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Is actual transaction active: " + activeTx);
                    }

                    if (activeTx) {
                        TRANSACTED.set(exchange, Boolean.TRUE);
                    }

                    processNext(exchange);

                    if (exchange.getException() != null) {
                        rce = wrapRuntimeCamelException(exchange.getException());
                    }
                } catch (Exception e) {
                    rce = wrapRuntimeCamelException(e);
                }

                if (rce != null) {
                    delayBeforeRedelivery();
                    if (activeTx) {
                        status.setRollbackOnly();
                        LOG.debug("Setting transaction to rollbackOnly due to exception being thrown: " + rce.getMessage());
                    }
                    throw rce;
                }
            }
        });
    }

    /**
     * Sleeps before the transaction is set as rollback and the caused exception is rethrown to let the
     * Spring TransactionManager handle the rollback.
     */
    protected void delayBeforeRedelivery() {
        long delay = 0;
        if (redeliveryPolicy != null) {
            delay = redeliveryPolicy.getDelay();
        } else if (delayPolicy != null) {
            delay = delayPolicy.getDelay();
        }

        if (delay > 0) {
            try {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Sleeping for: " + delay + " millis until attempting redelivery");
                }
                Thread.sleep(delay);
            } catch (InterruptedException e) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Thread interrupted: " + e, e);
                }
            }
        }
    }

    /**
     * @deprecated use DelayPolicy. Will be removed in Camel 2.0
     */
    public RedeliveryPolicy getRedeliveryPolicy() {
        return redeliveryPolicy;
    }

    /**
     * @deprecated use DelayPolicy. Will be removed in Camel 2.0
     */
    public void setRedeliveryPolicy(RedeliveryPolicy redeliveryPolicy) {
        this.redeliveryPolicy = redeliveryPolicy;
    }

    public DelayPolicy getDelayPolicy() {
        return delayPolicy;
    }

    public void setDelayPolicy(DelayPolicy delayPolicy) {
        this.delayPolicy = delayPolicy;
    }

    protected String propagationBehaviorToString(int propagationBehavior) {
        String rc;
        switch (propagationBehavior) {
        case TransactionDefinition.PROPAGATION_MANDATORY:
            rc = "PROPAGATION_MANDATORY";
            break;
        case TransactionDefinition.PROPAGATION_NESTED:
            rc = "PROPAGATION_NESTED";
            break;
        case TransactionDefinition.PROPAGATION_NEVER:
            rc = "PROPAGATION_NEVER";
            break;
        case TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
            rc = "PROPAGATION_NOT_SUPPORTED";
            break;
        case TransactionDefinition.PROPAGATION_REQUIRED:
            rc = "PROPAGATION_REQUIRED";
            break;
        case TransactionDefinition.PROPAGATION_REQUIRES_NEW:
            rc = "PROPAGATION_REQUIRES_NEW";
            break;
        case TransactionDefinition.PROPAGATION_SUPPORTS:
            rc = "PROPAGATION_SUPPORTS";
            break;
        default:
            rc = "UNKNOWN";
        }
        return rc;

FUNC_DECL PARAM CALL CALL FUNC_DECL IF TRY VAR_DECL VAR_DECL PARAM BINARY_OP CATCH IF IF IF IF THROW_RAISE IF LITERAL_ANCHOR BINARY_OP CALL CALL ASSIGN LITERAL_ANCHOR LITERAL_ANCHOR CALL ASSIGN LITERAL_ANCHOR CALL IF CALL CALL ASSIGN CALL CALL ASSIGN CALL CALL CALL BINARY_OP IF BINARY_OP BINARY_OP CALL LITERAL_ANCHOR CALL CALL CALL CALL LITERAL_ANCHOR VAR_DECL CALL ASSIGN BINARY_OP CALL CALL CALL

FUNC_DECL PARAM PARAM PARAM ASSIGN ASSIGN


org.apache.xalan.templates.ElemFallback

public class ElemFallback extends ElemTemplateElement
{

  /**
   * Get an int constant identifying the type of element.
   * @see org.apache.xalan.templates.Constants
   *
   * @return The token ID for this element
   */
  public int getXSLToken()
  {
    return Constants.ELEMNAME_FALLBACK;
  }

  /**
   * Return the node name.
   *
   * @return The Element's name
   */
  public String getNodeName()
  {
    return Constants.ELEMNAME_FALLBACK_STRING;
  }

  /**
   * This is the normal call when xsl:fallback is instantiated.
   * In accordance with the XSLT 1.0 Recommendation, chapter 15,
   * "Normally, instantiating an xsl:fallback element does nothing."
   *
   * @param transformer non-null reference to the the current transform-time state.
   *
   * @throws TransformerException
   */
  public void execute(
          TransformerImpl transformer)
            throws TransformerException
  {
  }

  /**
   * Execute the fallback elements.  This must be explicitly called to
   * instantiate the content of an xsl:fallback element.
   * When an XSLT transformer performs fallback for an instruction
   * element, if the instruction element has one or more xsl:fallback
   * children, then the content of each of the xsl:fallback children
   * must be instantiated in sequence; otherwise, an error must
   * be signaled. The content of an xsl:fallback element is a template.
   *
   * @param transformer non-null reference to the the current transform-time state.
   *
   * @throws TransformerException
   */
  public void executeFallback(
          TransformerImpl transformer)
            throws TransformerException
  {

    if (Constants.ELEMNAME_EXTENSIONCALL == m_parentNode.getXSLToken())
    {

      if (TransformerImpl.S_DEBUG)
        transformer.getTraceManager().fireTraceEvent(this);

      transformer.executeChildTemplates(this, true);

      if (TransformerImpl.S_DEBUG)
	    transformer.getTraceManager().fireTraceEndEvent(this);
    }
    else
    {

      System.out.println(
        "Error!  parent of xsl:fallback must be an extension element!");

FUNC_DECL IF PARAM BINARY_OP IF IF CALL CALL CALL LITERAL_ANCHOR CALL LITERAL_ANCHOR CALL CALL CALL


public final class ReplaceTokens
    extends BaseParamFilterReader
    implements ChainableReader {
    /** Default "begin token" character. */
    private static final char DEFAULT_BEGIN_TOKEN = '@';

    /** Default "end token" character. */
    private static final char DEFAULT_END_TOKEN = '@';

    /** Data to be used before reading from stream again */
    private String queuedData = null;

    /** replacement test from a token */
    private String replaceData = null;

    /** Index into replacement data */
    private int replaceIndex = -1;

    /** Index into queue data */
    private int queueIndex = -1;

    /** Hashtable to hold the replacee-replacer pairs (String to String). */
    private Hashtable hash = new Hashtable();

    /** Character marking the beginning of a token. */
    private char beginToken = DEFAULT_BEGIN_TOKEN;

    /** Character marking the end of a token. */
    private char endToken = DEFAULT_END_TOKEN;

    /**
     * Constructor for "dummy" instances.
     *
     * @see BaseFilterReader#BaseFilterReader()
     */
    public ReplaceTokens() {
        super();
    }

    /**
     * Creates a new filtered reader.
     *
     * @param in A Reader object providing the underlying stream.
     *           Must not be null.
     */
    public ReplaceTokens(final Reader in) {
        super(in);
    }

    private int getNextChar() throws IOException {
        if (queueIndex != -1) {
            final int ch = queuedData.charAt(queueIndex++);
            if (queueIndex >= queuedData.length()) {
                queueIndex = -1;
            }
            return ch;
        }

        return in.read();
    }

    /**
     * Returns the next character in the filtered stream, replacing tokens
     * from the original stream.
     *
     * @return the next character in the resulting stream, or -1
     * if the end of the resulting stream has been reached
     *
     * @exception IOException if the underlying stream throws an IOException
     * during reading
     */
    public final int read() throws IOException {
        if (!getInitialized()) {
            initialize();
            setInitialized(true);
        }

        if (replaceIndex != -1) {
            final int ch = replaceData.charAt(replaceIndex++);
            if (replaceIndex >= replaceData.length()) {
                replaceIndex = -1;
            }
            return ch;
        }

        int ch = getNextChar();

        if (ch == beginToken) {
            final StringBuffer key = new StringBuffer("");
            do  {
                ch = getNextChar();
                if (ch != -1) {
                    key.append((char) ch);
                } else {
                    break;
                }
            } while (ch != endToken);

            if (ch == -1) {
                if (queuedData == null || queueIndex == -1) {
                    queuedData = key.toString();
                } else {
                    queuedData
                        = key.toString() + queuedData.substring(queueIndex);
                }
                queueIndex = 0;
                return beginToken;
            } else {
                key.setLength(key.length() - 1);

                final String replaceWith = (String) hash.get(key.toString());
                if (replaceWith != null) {
                    replaceData = replaceWith;
                    replaceIndex = 0;
                    return read();
                } else {
                    String newData = key.toString() + endToken;
                    if (queuedData == null || queueIndex == -1) {
                        queuedData = newData;
                    } else {
                        queuedData = newData + queuedData.substring(queueIndex);
                    }
                    queueIndex = 0;
                    return beginToken;
                }
            }
        }
        return ch;
    }

    /**
     * Sets the "begin token" character.
     *
     * @param beginToken the character used to denote the beginning of a token
     */
    public final void setBeginToken(final char beginToken) {
        this.beginToken = beginToken;
    }

    /**
     * Returns the "begin token" character.
     *
     * @return the character used to denote the beginning of a token
     */
    private final char getBeginToken() {
        return beginToken;
    }

    /**
     * Sets the "end token" character.
     *
     * @param endToken the character used to denote the end of a token
     */
    public final void setEndToken(final char endToken) {
        this.endToken = endToken;
    }

    /**
     * Returns the "end token" character.
     *
     * @return the character used to denote the end of a token
     */
    private final char getEndToken() {
        return endToken;
    }

    /**
     * Adds a token element to the map of tokens to replace.
     *
     * @param token The token to add to the map of replacements.
     *              Must not be null.
     */
    public final void addConfiguredToken(final Token token) {
        hash.put(token.getKey(), token.getValue());
    }

    /**
     * Sets the map of tokens to replace.
     *
     * @param hash A map (String->String) of token keys to replacement
     * values. Must not be null.
     */
    private void setTokens(final Hashtable hash) {
        this.hash = hash;
    }

    /**
     * Returns the map of tokens which will be replaced.
     *
     * @return a map (String->String) of token keys to replacement
     * values
     */
    private final Hashtable getTokens() {
        return hash;
    }

    /**
     * Creates a new ReplaceTokens using the passed in
     * Reader for instantiation.
     *
     * @param rdr A Reader object providing the underlying stream.
     *            Must not be null.
     *
     * @return a new filter based on this configuration, but filtering
     *         the specified reader
     */
    public final Reader chain(final Reader rdr) {
        ReplaceTokens newFilter = new ReplaceTokens(rdr);
        newFilter.setBeginToken(getBeginToken());
        newFilter.setEndToken(getEndToken());
        newFilter.setTokens(getTokens());
        newFilter.setInitialized(true);
        return newFilter;
    }

    /**
     * Initializes tokens and loads the replacee-replacer hashtable.
     */
    private final void initialize() {
        Parameter[] params = getParameters();
        if (params != null) {
            for (int i = 0; i < params.length; i++) {
                if (params[i] != null) {
                    final String type = params[i].getType();
                    if ("tokenchar".equals(type)) {
                        final String name = params[i].getName();
                        String value = params[i].getValue();
                        if ("begintoken".equals(name)) {
                            if (value.length() == 0) {
                                throw new BuildException("Begin token cannot "
                                    + "be empty");
                            }
                            beginToken = params[i].getValue().charAt(0);
                        } else if ("endtoken".equals(name)) {
                            if (value.length() == 0) {
                                throw new BuildException("End token cannot "
                                    + "be empty");
                            }
                            endToken = params[i].getValue().charAt(0);
                        }
                    } else if ("token".equals(type)) {
                        final String name = params[i].getName();
                        final String value = params[i].getValue();
                        hash.put(name, value);
                    }
                }
            }
        }
    }

    /**
     * Holds a token
     */
    public static class Token {

        /** Token key */
        private String key;

        /** Token value */
        private String value;

        /**
         * Sets the token key
         *
         * @param key The key for this token. Must not be null.
         */
        public final void setKey(String key) {
            this.key = key;
        }

        /**
         * Sets the token value
         *
         * @param value The value for this token. Must not be null.
         */
        public final void setValue(String value) {
            this.value = value;
        }

        /**
         * Returns the key for this token.
         *
         * @return the key for this token
         */
        public final String getKey() {
            return key;
        }

        /**
         * Returns the value for this token.
         *
         * @return the value for this token
         */
        public final String getValue() {
            return value;

FUNC_DECL RETURN VAR_DECL PARAM CALL CALL CALL CALL LITERAL_ANCHOR CALL CALL CALL CALL

    public ReplaceTokens() {
        super();


org.gjt.sp.jedit.search.SearchDialog

public class SearchDialog extends EnhancedDialog implements EBComponent
{
	//{{{ Constants
	/**
	 * Default file set.
	 * @since jEdit 3.2pre2
	 */
	public static final int CURRENT_BUFFER = 0;
	public static final int ALL_BUFFERS = 1;
	public static final int DIRECTORY = 2;
	//}}}

	//{{{ showSearchDialog() method
	/**
	 * Displays a search and replace dialog box, reusing an existing one
	 * if necessary.
	 * @param view The view
	 * @param searchString The search string
	 * @param searchIn One of CURRENT_BUFFER, ALL_BUFFERS, or DIRECTORY
	 * @since jEdit 4.0pre6
	 */
	public static void showSearchDialog(View view, String searchString,
		int searchIn)
	{
		SearchDialog dialog = (SearchDialog)viewHash.get(view);
		if(dialog != null)
		{
			// ugly workaround
			if(OperatingSystem.isUnix() && !OperatingSystem.isMacOS())
			{
				dialog.setVisible(false);
				dialog.setVisible(true);
			}

			dialog.setSearchString(searchString,searchIn);
			GUIUtilities.requestFocus(dialog,dialog.find);
			dialog.toFront();
			dialog.requestFocus();
		}
		else
		{
			dialog = new SearchDialog(view,searchString,searchIn);
			viewHash.put(view,dialog);
		}
	} //}}}

	//{{{ SearchDialog constructor
	/**
	 * Creates a new search and replace dialog box.
	 * @param view The view
	 * @param searchString The search string
	 */
	public SearchDialog(View view, String searchString)
	{
		this(view,searchString,CURRENT_BUFFER);
	} //}}}

	//{{{ SearchDialog constructor
	/**
	 * Creates a new search and replace dialog box.
	 * @param view The view
	 * @param searchString The search string
	 * @param searchIn One of CURRENT_BUFFER, ALL_BUFFERS, or DIRECTORY
	 * @since jEdit 3.2pre2
	 */
	public SearchDialog(View view, String searchString, int searchIn)
	{
		super(view,jEdit.getProperty("search.title"),false);

		this.view = view;

		JPanel content = new JPanel(new BorderLayout());
		content.setBorder(new EmptyBorder(0,12,12,12));
		setContentPane(content);

		JPanel centerPanel = new JPanel(new BorderLayout());
		centerPanel.add(BorderLayout.NORTH,createFieldPanel());
		centerPanel.add(BorderLayout.CENTER,createSearchSettingsPanel());
		content.add(BorderLayout.CENTER,centerPanel);
		content.add(BorderLayout.SOUTH,createMultiFilePanel());

		content.add(BorderLayout.EAST,createButtonsPanel());

		ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
		regexp.setSelected(SearchAndReplace.getRegexp());
		wrap.setSelected(SearchAndReplace.getAutoWrapAround());

		if(SearchAndReplace.getReverseSearch())
			searchBack.setSelected(true);
		else
			searchForward.setSelected(true);

		if(SearchAndReplace.getBeanShellReplace())
		{
			replace.setModel("replace.script");
			beanShellReplace.setSelected(true);
		}
		else
		{
			replace.setModel("replace");
			stringReplace.setSelected(true);
		}

		SearchFileSet fileset = SearchAndReplace.getSearchFileSet();

		if(fileset instanceof DirectoryListSet)
		{
			filter.setText(((DirectoryListSet)fileset)
				.getFileFilter());
			directory.setText(((DirectoryListSet)fileset)
				.getDirectory());
			searchSubDirectories.setSelected(((DirectoryListSet)fileset)
				.isRecursive());
		}
		else
		{
			String path;
			if(view.getBuffer().getVFS() instanceof FileVFS)
			{
				path = MiscUtilities.getParentOfPath(
					view.getBuffer().getPath());
			}
			else
				path = System.getProperty("user.dir");
			directory.setText(path);

			if(fileset instanceof AllBufferSet)
			{
				filter.setText(((AllBufferSet)fileset)
					.getFileFilter());
			}
			else
			{
				filter.setText("*" + MiscUtilities
					.getFileExtension(view.getBuffer()
					.getName()));
			}

			searchSubDirectories.setSelected(true);
		}

		directory.addCurrentToHistory();

		keepDialog.setSelected(jEdit.getBooleanProperty(
			"search.keepDialog.toggle"));

		setSearchString(searchString,searchIn);

		pack();
		jEdit.unsetProperty("search.width");
		jEdit.unsetProperty("search.d-width");
		jEdit.unsetProperty("search.height");
		jEdit.unsetProperty("search.d-height");
		GUIUtilities.loadGeometry(this,"search");
		show();

		EditBus.addToBus(this);

		GUIUtilities.requestFocus(this,find);
	} //}}}

	//{{{ setSearchString() method
	/**
	 * Sets the search string.
	 * @since jEdit 4.0pre5
	 */
	public void setSearchString(String searchString, int searchIn)
	{
		if(searchString == null)
			find.setText(null);
		else
		{
			if(searchString.indexOf('\n') == -1)
			{
				find.setText(searchString);
				find.selectAll();
			}
			else if(searchIn == CURRENT_BUFFER)
			{
				searchSelection.setSelected(true);
				hyperSearch.setSelected(true);
			}
		}

		if(searchIn == CURRENT_BUFFER)
		{
			if(!searchSelection.isSelected())
			{
				// might be already selected, see above.
				searchCurrentBuffer.setSelected(true);

				/* this property is only loaded and saved if
				 * the 'current buffer' file set is selected.
				 * otherwise, it defaults to on. */
				hyperSearch.setSelected(jEdit.getBooleanProperty(
					"search.hypersearch.toggle"));
			}
		}
		else if(searchIn == ALL_BUFFERS)
		{
			searchAllBuffers.setSelected(true);
			hyperSearch.setSelected(true);
		}
		else if(searchIn == DIRECTORY)
		{
			hyperSearch.setSelected(true);
			searchDirectory.setSelected(true);
		}

		updateEnabled();
	} //}}}

	//{{{ ok() method
	public void ok()
	{
		try
		{
			setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

			if(!save())
				return;

			if(hyperSearch.isSelected() || searchSelection.isSelected())
			{
				if(SearchAndReplace.hyperSearch(view,
					searchSelection.isSelected()));
					closeOrKeepDialog();
			}
			else
			{
				if(SearchAndReplace.find(view))
					closeOrKeepDialog();
			}
		}
		finally
		{
			setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		}
	} //}}}

	//{{{ cancel() method
	public void cancel()
	{
		save();
		GUIUtilities.saveGeometry(this,"search");
		dispose();
	} //}}}

	//{{{ handleMessage() method
	public void handleMessage(EBMessage msg)
	{
		if(msg instanceof SearchSettingsChanged)
		{
			ignoreCase.setSelected(SearchAndReplace.getIgnoreCase());
			regexp.setSelected(SearchAndReplace.getRegexp());
		}
		else if(msg instanceof ViewUpdate)
		{
			ViewUpdate vmsg = (ViewUpdate)msg;
			if(vmsg.getView() == view
				&& vmsg.getWhat() == ViewUpdate.CLOSED)
			{
				viewHash.remove(view);
			}
		}
	} //}}}

	//{{{ dispose() method
	public void dispose()
	{
		EditBus.removeFromBus(this);
		viewHash.remove(view);
		super.dispose();
	} //}}}

	//{{{ Private members

	private static HashMap viewHash = new HashMap();

	//{{{ Instance variables
	private View view;

	// fields
	private HistoryTextField find, replace;

	private JRadioButton stringReplace, beanShellReplace;

	// search settings
	private JCheckBox keepDialog, ignoreCase, regexp, hyperSearch,
		wrap;
	private JRadioButton searchBack, searchForward;
	private JRadioButton searchSelection, searchCurrentBuffer, searchAllBuffers,
		searchDirectory;

	// multifile settings
	private HistoryTextField filter, directory;
	private JCheckBox searchSubDirectories;
	private JButton choose;

	// buttons
	private JButton findBtn, /* replaceBtn, */ replaceAndFindBtn, replaceAllBtn,
		closeBtn;
	//}}}

	//{{{ createFieldPanel() method
	private JPanel createFieldPanel()
	{
		ButtonActionHandler actionHandler = new ButtonActionHandler();

		JPanel fieldPanel = new JPanel(new VariableGridLayout(
			VariableGridLayout.FIXED_NUM_COLUMNS,1));
		fieldPanel.setBorder(new EmptyBorder(0,0,12,12));

		JLabel label = new JLabel(jEdit.getProperty("search.find"));
		label.setDisplayedMnemonic(jEdit.getProperty("search.find.mnemonic")
			.charAt(0));
		find = new HistoryTextField("find");

		// don't want it to be too wide due to long strings
		Dimension size = find.getPreferredSize();
		size.width = find.getFontMetrics(find.getFont())
			.charWidth('a') * 25;
		find.setPreferredSize(size);

		find.addActionListener(actionHandler);
		label.setLabelFor(find);
		label.setBorder(new EmptyBorder(12,0,2,0));
		fieldPanel.add(label);
		fieldPanel.add(find);

		label = new JLabel(jEdit.getProperty("search.replace"));
		label.setDisplayedMnemonic(jEdit.getProperty("search.replace.mnemonic")
			.charAt(0));
		label.setBorder(new EmptyBorder(12,0,0,0));
		fieldPanel.add(label);

		ButtonGroup grp = new ButtonGroup();
		ReplaceActionHandler replaceActionHandler = new ReplaceActionHandler();

		// we use a custom JRadioButton subclass that returns
		// false for isFocusTraversable() so that the user can
		// tab from the search field to the replace field with
		// one keystroke

		Box replaceModeBox = new Box(BoxLayout.X_AXIS);
		stringReplace = new MyJRadioButton(jEdit.getProperty(
			"search.string-replace-btn"));
		stringReplace.addActionListener(replaceActionHandler);
		grp.add(stringReplace);
		replaceModeBox.add(stringReplace);

		replaceModeBox.add(Box.createHorizontalStrut(12));

		beanShellReplace = new MyJRadioButton(jEdit.getProperty(
			"search.beanshell-replace-btn"));
		beanShellReplace.addActionListener(replaceActionHandler);
		grp.add(beanShellReplace);
		replaceModeBox.add(beanShellReplace);

		fieldPanel.add(replaceModeBox);

		fieldPanel.add(Box.createVerticalStrut(3));

		replace = new HistoryTextField("replace");
		replace.addActionListener(actionHandler);
		label.setLabelFor(replace);
		fieldPanel.add(replace);

		return fieldPanel;
	} //}}}

	//{{{ createSearchSettingsPanel() method
	private JPanel createSearchSettingsPanel()
	{
		JPanel searchSettings = new JPanel(new VariableGridLayout(
			VariableGridLayout.FIXED_NUM_COLUMNS,3));
		searchSettings.setBorder(new EmptyBorder(0,0,12,12));

		SettingsActionHandler actionHandler = new SettingsActionHandler();
		ButtonGroup fileset = new ButtonGroup();
		ButtonGroup direction = new ButtonGroup();

		searchSettings.add(new JLabel(jEdit.getProperty("search.fileset")));

		searchSettings.add(new JLabel(jEdit.getProperty("search.settings")));

		searchSettings.add(new JLabel(jEdit.getProperty("search.direction")));

		searchSelection = new JRadioButton(jEdit.getProperty("search.selection"));
		searchSelection.setMnemonic(jEdit.getProperty("search.selection.mnemonic")
			.charAt(0));
		fileset.add(searchSelection);
		searchSettings.add(searchSelection);
		searchSelection.addActionListener(actionHandler);

		keepDialog = new JCheckBox(jEdit.getProperty("search.keep"));
		keepDialog.setMnemonic(jEdit.getProperty("search.keep.mnemonic")
			.charAt(0));
		searchSettings.add(keepDialog);

		searchBack = new JRadioButton(jEdit.getProperty("search.back"));
		searchBack.setMnemonic(jEdit.getProperty("search.back.mnemonic")
			.charAt(0));
		direction.add(searchBack);
		searchSettings.add(searchBack);
		searchBack.addActionListener(actionHandler);

		searchCurrentBuffer = new JRadioButton(jEdit.getProperty("search.current"));
		searchCurrentBuffer.setMnemonic(jEdit.getProperty("search.current.mnemonic")
			.charAt(0));
		fileset.add(searchCurrentBuffer);
		searchSettings.add(searchCurrentBuffer);
		searchCurrentBuffer.addActionListener(actionHandler);

		ignoreCase = new JCheckBox(jEdit.getProperty("search.case"));
		ignoreCase.setMnemonic(jEdit.getProperty("search.case.mnemonic")
			.charAt(0));
		searchSettings.add(ignoreCase);
		ignoreCase.addActionListener(actionHandler);

		searchForward = new JRadioButton(jEdit.getProperty("search.forward"));
		searchForward.setMnemonic(jEdit.getProperty("search.forward.mnemonic")
			.charAt(0));
		direction.add(searchForward);
		searchSettings.add(searchForward);
		searchForward.addActionListener(actionHandler);

		searchAllBuffers = new JRadioButton(jEdit.getProperty("search.all"));
		searchAllBuffers.setMnemonic(jEdit.getProperty("search.all.mnemonic")
			.charAt(0));
		fileset.add(searchAllBuffers);
		searchSettings.add(searchAllBuffers);
		searchAllBuffers.addActionListener(actionHandler);

		regexp = new JCheckBox(jEdit.getProperty("search.regexp"));
		regexp.setMnemonic(jEdit.getProperty("search.regexp.mnemonic")
			.charAt(0));
		searchSettings.add(regexp);
		regexp.addActionListener(actionHandler);

		wrap = new JCheckBox(jEdit.getProperty("search.wrap"));
		wrap.setMnemonic(jEdit.getProperty("search.wrap.mnemonic")
			.charAt(0));
		searchSettings.add(wrap);
		wrap.addActionListener(actionHandler);

		searchDirectory = new JRadioButton(jEdit.getProperty("search.directory"));
		searchDirectory.setMnemonic(jEdit.getProperty("search.directory.mnemonic")
			.charAt(0));
		fileset.add(searchDirectory);
		searchSettings.add(searchDirectory);
		searchDirectory.addActionListener(actionHandler);

		hyperSearch = new JCheckBox(jEdit.getProperty("search.hypersearch"));
		hyperSearch.setMnemonic(jEdit.getProperty("search.hypersearch.mnemonic")
			.charAt(0));
		searchSettings.add(hyperSearch);
		hyperSearch.addActionListener(actionHandler);

		return searchSettings;
	} //}}}

	//{{{ createMultiFilePanel() method
	private JPanel createMultiFilePanel()
	{
		JPanel multifile = new JPanel();

		GridBagLayout layout = new GridBagLayout();
		multifile.setLayout(layout);

		GridBagConstraints cons = new GridBagConstraints();
		cons.gridy = cons.gridwidth = cons.gridheight = 1;
		cons.anchor = GridBagConstraints.WEST;
		cons.fill = GridBagConstraints.HORIZONTAL;

		MultiFileActionHandler actionListener = new MultiFileActionHandler();
		filter = new HistoryTextField("search.filter");
		filter.addActionListener(actionListener);

		cons.insets = new Insets(0,0,3,0);

		JLabel label = new JLabel(jEdit.getProperty("search.filterField"),
			SwingConstants.RIGHT);
		label.setBorder(new EmptyBorder(0,0,0,12));
		label.setDisplayedMnemonic(jEdit.getProperty("search.filterField.mnemonic")
			.charAt(0));
		label.setLabelFor(filter);
		cons.weightx = 0.0f;
		layout.setConstraints(label,cons);
		multifile.add(label);

		cons.insets = new Insets(0,0,3,6);
		cons.weightx = 1.0f;
		layout.setConstraints(filter,cons);
		multifile.add(filter);

		cons.gridy++;

		directory = new HistoryTextField("search.directory");
		directory.addActionListener(actionListener);

		label = new JLabel(jEdit.getProperty("search.directoryField"),
			SwingConstants.RIGHT);
		label.setBorder(new EmptyBorder(0,0,0,12));

		label.setDisplayedMnemonic(jEdit.getProperty("search.directoryField.mnemonic")
			.charAt(0));
		label.setLabelFor(directory);
		cons.insets = new Insets(0,0,3,0);
		cons.weightx = 0.0f;
		layout.setConstraints(label,cons);
		multifile.add(label);

		cons.insets = new Insets(0,0,3,6);
		cons.weightx = 1.0f;
		cons.gridwidth = 2;
		layout.setConstraints(directory,cons);
		multifile.add(directory);

		choose = new JButton(jEdit.getProperty("search.choose"));
		choose.setMnemonic(jEdit.getProperty("search.choose.mnemonic")
			.charAt(0));
		cons.insets = new Insets(0,0,3,0);
		cons.weightx = 0.0f;
		cons.gridwidth = 1;
		layout.setConstraints(choose,cons);
		multifile.add(choose);
		choose.addActionListener(actionListener);

		cons.insets = new Insets(0,0,0,0);
		cons.gridy++;
		cons.gridwidth = 4;

		searchSubDirectories = new JCheckBox(jEdit.getProperty(
			"search.subdirs"));
		searchSubDirectories.setMnemonic(jEdit.getProperty("search.subdirs.mnemonic")
			.charAt(0));
		layout.setConstraints(searchSubDirectories,cons);
		multifile.add(searchSubDirectories);

		return multifile;
	} //}}}

	//{{{ createButtonsPanel() method
	private Box createButtonsPanel()
	{
		Box box = new Box(BoxLayout.Y_AXIS);

		ButtonActionHandler actionHandler = new ButtonActionHandler();

		box.add(Box.createVerticalStrut(12));

		JPanel grid = new JPanel(new GridLayout(5,1,0,12));

		findBtn = new JButton(jEdit.getProperty("search.findBtn"));
		getRootPane().setDefaultButton(findBtn);
		grid.add(findBtn);
		findBtn.addActionListener(actionHandler);

		/* replaceBtn = new JButton(jEdit.getProperty("search.replaceBtn"));
		replaceBtn.setMnemonic(jEdit.getProperty("search.replaceBtn.mnemonic")
			.charAt(0));
		grid.add(replaceBtn);
		replaceBtn.addActionListener(actionHandler); */

		replaceAndFindBtn = new JButton(jEdit.getProperty("search.replaceAndFindBtn"));
		replaceAndFindBtn.setMnemonic(jEdit.getProperty("search.replaceAndFindBtn.mnemonic")
			.charAt(0));
		grid.add(replaceAndFindBtn);
		replaceAndFindBtn.addActionListener(actionHandler);

		replaceAllBtn = new JButton(jEdit.getProperty("search.replaceAllBtn"));
		replaceAllBtn.setMnemonic(jEdit.getProperty("search.replaceAllBtn.mnemonic")
			.charAt(0));
		grid.add(replaceAllBtn);
		replaceAllBtn.addActionListener(actionHandler);

		closeBtn = new JButton(jEdit.getProperty("common.close"));
		grid.add(closeBtn);
		closeBtn.addActionListener(actionHandler);

		grid.setMaximumSize(grid.getPreferredSize());

		box.add(grid);
		box.add(Box.createGlue());

		return box;
	} //}}}

	//{{{ updateEnabled() method
	private void updateEnabled()
	{
		wrap.setEnabled(!hyperSearch.isSelected()
			&& !searchSelection.isSelected());

		boolean reverseEnabled = !hyperSearch.isSelected()
			&& searchCurrentBuffer.isSelected();
		searchBack.setEnabled(reverseEnabled && !regexp.isSelected());
		searchForward.setEnabled(reverseEnabled);
		if(!reverseEnabled)
			searchForward.setSelected(true);

		filter.setEnabled(searchAllBuffers.isSelected()
			|| searchDirectory.isSelected());

		boolean directoryEnabled = searchDirectory.isSelected();

		directory.setEnabled(directoryEnabled);
		choose.setEnabled(directoryEnabled);
		searchSubDirectories.setEnabled(directoryEnabled);

		findBtn.setEnabled(!searchSelection.isSelected()
			|| hyperSearch.isSelected());
		replaceAndFindBtn.setEnabled(!hyperSearch.isSelected()
			&& !searchSelection.isSelected());
	} //}}}

	//{{{ save() method
	private boolean save()
	{
		String filter = this.filter.getText();
		this.filter.addCurrentToHistory();
		if(filter.length() == 0)
			filter = "*";

		SearchFileSet fileset = SearchAndReplace.getSearchFileSet();

		if(searchSelection.isSelected())
			fileset = new CurrentBufferSet();
		else if(searchCurrentBuffer.isSelected())
		{
			fileset = new CurrentBufferSet();

			jEdit.setBooleanProperty("search.hypersearch.toggle",
				hyperSearch.isSelected());
		}
		else if(searchAllBuffers.isSelected())
			fileset = new AllBufferSet(filter);
		else if(searchDirectory.isSelected())
		{
			String directory = this.directory.getText();
			this.directory.addCurrentToHistory();
			boolean recurse = searchSubDirectories.isSelected();

			if(fileset instanceof DirectoryListSet)
			{
				DirectoryListSet dset = (DirectoryListSet)fileset;
				if(!dset.getDirectory().equals(directory)
					|| !dset.getFileFilter().equals(filter)
					|| !dset.isRecursive() == recurse)
					fileset = new DirectoryListSet(directory,filter,recurse);
			}
			else
				fileset = new DirectoryListSet(directory,filter,recurse);
		}
		else
		{
			// can't happen
			fileset = null;
		}

		jEdit.setBooleanProperty("search.keepDialog.toggle",
			keepDialog.isSelected());

		boolean ok = true;

		if(fileset.getFileCount() == 0)
		{
			// oops
			GUIUtilities.error(this,"empty-fileset",null);
			ok = false;
		}
		else
			SearchAndReplace.setSearchFileSet(fileset);

		if(find.getText().length() != 0)
		{
			find.addCurrentToHistory();
			SearchAndReplace.setSearchString(find.getText());
			replace.addCurrentToHistory();

			SearchAndReplace.setReplaceString(replace.getText());
		}
		else
			ok = false;

		return ok;
	} //}}}

	//{{{ closeOrKeepDialog() method
	private void closeOrKeepDialog()
	{
		if(keepDialog.isSelected())
		{
			// Windows bug workaround in case a YES/NO confirm
			// was shown

			// ... but if HyperSearch results window is floating,
			// the workaround causes problems!
			if(!hyperSearch.isSelected())
			{
				toFront();
				requestFocus();
				find.requestFocus();
			}
			return;
		}
		else
		{
			GUIUtilities.saveGeometry(this,"search");
			dispose();
		}
	} //}}}

	//}}}

	//{{{ Inner classes

	//{{{ MyJRadioButton class

	// used for the stringReplace and beanShell replace radio buttons,
	// so that the user can press tab to go from the find field to the
	// replace field in one go
	class MyJRadioButton extends JRadioButton
	{
		MyJRadioButton(String label)
		{
			super(label);
		}

		public boolean isFocusTraversable()
		{
			return false;
		}
	} //}}}

	//{{{ ReplaceActionHandler class
	class ReplaceActionHandler implements ActionListener
	{
		public void actionPerformed(ActionEvent evt)
		{
			replace.setModel(beanShellReplace.isSelected()
				? "replace.script"
				: "replace");
			SearchAndReplace.setBeanShellReplace(
				beanShellReplace.isSelected());
		}
	} //}}}

	//{{{ SettingsActionHandler class
	class SettingsActionHandler implements ActionListener
	{
		public void actionPerformed(ActionEvent evt)
		{
			Object source = evt.getSource();

			if(source == ignoreCase)
				SearchAndReplace.setIgnoreCase(ignoreCase.isSelected());
			else if(source == regexp)
				SearchAndReplace.setRegexp(regexp.isSelected());
			else if(source == searchBack || source == searchForward)
				SearchAndReplace.setReverseSearch(searchBack.isSelected());
			else if(source == wrap)
				SearchAndReplace.setAutoWrapAround(wrap.isSelected());
			else if(source == searchCurrentBuffer)
				hyperSearch.setSelected(false);
			else if(source == searchSelection
				|| source == searchAllBuffers
				|| source == searchDirectory)
				hyperSearch.setSelected(true);

			updateEnabled();
		}
	} //}}}

	//{{{ MultiFileActionHandler class
	class MultiFileActionHandler implements ActionListener
	{
		public void actionPerformed(ActionEvent evt)
		{
			if(evt.getSource() == choose)
			{
				File dir = new File(directory.getText());
				JFileChooser chooser = new JFileChooser(dir.getParent());
				chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				chooser.setSelectedFile(dir);

				if(chooser.showOpenDialog(SearchDialog.this)
					== JFileChooser.APPROVE_OPTION)
					directory.setText(chooser.getSelectedFile().getPath());
			}
			else // source is directory or filter field
			{
				// just as if Enter was pressed in another
				// text field
				ok();
			}
		}
	} //}}}

	//{{{ ButtonActionHandler class
	class ButtonActionHandler implements ActionListener
	{
		public void actionPerformed(ActionEvent evt)
		{
			Object source = evt.getSource();

			if(source == closeBtn)
				cancel();
			else if(source == findBtn || source == find
				|| source == replace)
			{
				ok();
			}
			else if(source == replaceAndFindBtn)
			{
				save();
				if(SearchAndReplace.replace(view))
					ok();
				else
					getToolkit().beep();
			}
			else if(source == replaceAllBtn)
			{
				setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

				save();

				if(searchSelection.isSelected())
				{
					if(SearchAndReplace.replace(view))
						closeOrKeepDialog();
					else
						getToolkit().beep();
				}
				else
				{
					if(SearchAndReplace.replaceAll(view))
						closeOrKeepDialog();
					else
						getToolkit().beep();
				}

				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

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

FUNC_DECL TRY IF IF CALL BINARY_OP RETURN CALL CALL CALL IF IF CALL CALL CALL CALL CALL CALL CALL CALL

FUNC_DECL RETURN VAR_DECL VAR_DECL VAR_DECL VAR_DECL CALL CALL CALL ASSIGN CALL CALL CALL CALL ASSIGN CALL CALL CALL ASSIGN CALL CALL CALL ASSIGN CALL CALL CALL CALL ASSIGN CALL CALL CALL CALL ASSIGN CALL CALL CALL ASSIGN CALL CALL CALL CALL ASSIGN CALL CALL CALL CALL ASSIGN CALL CALL ASSIGN CALL CALL CALL CALL ASSIGN CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL CALL CALL CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR

FUNC_DECL RETURN VAR_DECL VAR_DECL VAR_DECL CALL CALL CALL CALL CALL ASSIGN CALL CALL CALL ASSIGN CALL CALL CALL ASSIGN CALL CALL CALL ASSIGN CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL LITERAL_ANCHOR CALL CALL LITERAL_ANCHOR CALL CALL CALL CALL LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR LITERAL_ANCHOR

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

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

FUNC_DECL IF CALL RETURN IF CALL CALL CALL LITERAL_ANCHOR CALL CALL CALL

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


public class GeneralOptionPane extends AbstractOptionPane
{
	public GeneralOptionPane()
	{
		super("general");
	}

	// protected members
	protected void _init()
	{
		/* History count */
		history = new JTextField(jEdit.getProperty("history"));
		addComponent(jEdit.getProperty("options.general.history"),history);

		/* Save caret positions */
		saveCaret = new JCheckBox(jEdit.getProperty(
			"options.general.saveCaret"));
		saveCaret.setSelected(jEdit.getBooleanProperty("saveCaret"));
		addComponent(saveCaret);

		/* Sort buffers */
		sortBuffers = new JCheckBox(jEdit.getProperty(
			"options.general.sortBuffers"));
		sortBuffers.setSelected(jEdit.getBooleanProperty("sortBuffers"));
		sortBuffers.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent evt)
			{
				sortByName.setEnabled(sortBuffers.isSelected());
			}
		});

		addComponent(sortBuffers);

		/* Sort buffers by names */
		sortByName = new JCheckBox(jEdit.getProperty(
			"options.general.sortByName"));
		sortByName.setSelected(jEdit.getBooleanProperty("sortByName"));
		sortByName.setEnabled(sortBuffers.isSelected());
		addComponent(sortByName);

		/* Sort recent file list */
		sortRecent = new JCheckBox(jEdit.getProperty(
			"options.general.sortRecent"));
		sortRecent.setSelected(jEdit.getBooleanProperty("sortRecent"));
		addComponent(sortRecent);

		/* Check mod status on focus */
		checkModStatus = new JCheckBox(jEdit.getProperty(
			"options.general.checkModStatus"));
		checkModStatus.setSelected(jEdit.getBooleanProperty(
			"view.checkModStatus"));
		addComponent(checkModStatus);

		/* Show full path */
		showFullPath = new JCheckBox(jEdit.getProperty(
			"options.general.showFullPath"));
		showFullPath.setSelected(jEdit.getBooleanProperty(
			"view.showFullPath"));
		addComponent(showFullPath);

		/* Show search bar */
		showSearchbar = new JCheckBox(jEdit.getProperty(
			"options.general.showSearchbar"));
		showSearchbar.setSelected(jEdit.getBooleanProperty(
			"view.showSearchbar"));
		addComponent(showSearchbar);

		/* Beep on search auto wrap */
		beepOnSearchAutoWrap = new JCheckBox(jEdit.getProperty(
			"options.general.beepOnSearchAutoWrap"));
		beepOnSearchAutoWrap.setSelected(jEdit.getBooleanProperty(
			"search.beepOnSearchAutoWrap"));
		addComponent(beepOnSearchAutoWrap);

		/* Show buffer switcher */
		showBufferSwitcher = new JCheckBox(jEdit.getProperty(
			"options.general.showBufferSwitcher"));
		showBufferSwitcher.setSelected(jEdit.getBooleanProperty(
			"view.showBufferSwitcher"));
		addComponent(showBufferSwitcher);

		/* Show tip of the day */
		showTips = new JCheckBox(jEdit.getProperty(
			"options.general.showTips"));
		showTips.setSelected(jEdit.getBooleanProperty("tip.show"));
		addComponent(showTips);

		/* Show splash screen */
		showSplash = new JCheckBox(jEdit.getProperty(
			"options.general.showSplash"));
		String settingsDirectory = jEdit.getSettingsDirectory();
		if(settingsDirectory == null)
			showSplash.setSelected(true);
		else
			showSplash.setSelected(!new File(settingsDirectory,"nosplash").exists());
		addComponent(showSplash);
	}

	protected void _save()
	{
		jEdit.setProperty("history",history.getText());
		jEdit.setBooleanProperty("saveCaret",saveCaret.isSelected());
		jEdit.setBooleanProperty("sortBuffers",sortBuffers.isSelected());
		jEdit.setBooleanProperty("sortByName",sortByName.isSelected());
		jEdit.setBooleanProperty("sortRecent",sortRecent.isSelected());
		jEdit.setBooleanProperty("view.checkModStatus",checkModStatus
			.isSelected());
		jEdit.setBooleanProperty("view.showFullPath",showFullPath
			.isSelected());
		jEdit.setBooleanProperty("view.showSearchbar",showSearchbar
			.isSelected());
		jEdit.setBooleanProperty("search.beepOnSearchAutoWrap",beepOnSearchAutoWrap
			.isSelected());
		jEdit.setBooleanProperty("view.showBufferSwitcher",
			showBufferSwitcher.isSelected());
		jEdit.setBooleanProperty("tip.show",showTips.isSelected());

		// this is handled a little differently from other jEdit settings
		// as the splash screen flag needs to be known very early in the
		// startup sequence, before the user properties have been loaded
		String settingsDirectory = jEdit.getSettingsDirectory();
		if(settingsDirectory != null)
		{
			File file = new File(settingsDirectory,"nosplash");
			if(showSplash.isSelected())
				file.delete();
			else
			{
				try
				{
					FileOutputStream out = new FileOutputStream(file);
					out.write('\n');
					out.close();
				}
				catch(IOException io)
				{
					Log.log(Log.ERROR,this,io);
				}
			}
		}
	}

	// private members
	private JTextField history;
	private JCheckBox saveCaret;
	private JCheckBox sortBuffers;
	private JCheckBox sortByName;
	private JCheckBox sortRecent;
	private JCheckBox checkModStatus;
	private JCheckBox showFullPath;
	private JCheckBox showSearchbar;
  private JCheckBox beepOnSearchAutoWrap;
	private JCheckBox showBufferSwitcher;
	private JCheckBox showTips;
	private JCheckBox showSplash;

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


@XmlRootElement(name = "xstream")
@XmlAccessorType(XmlAccessType.FIELD)
public class XStreamDataFormat extends DataFormatType {
    @XmlAttribute(required = false)
    private Boolean prettyPrint;

    public XStreamDataFormat() {
        super("org.apache.camel.dataformat.xstream.XStreamDataFormat");
    }

    public Boolean getPrettyPrint() {
        return prettyPrint;
    }

    public void setPrettyPrint(Boolean prettyPrint) {
        this.prettyPrint = prettyPrint;


public abstract class AbstractConflictManager implements ConflictManager, IvySettingsAware {
    private String name;

    private IvySettings settings;

    public IvySettings getSettings() {
        return settings;
    }

    public void setSettings(IvySettings settings) {
        this.settings = settings;
    }

    public String getName() {
        return name;
    }

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

    public String toString() {
        return name;
    }

    public void handleAllBlacklistedRevisions(
            DependencyDescriptor dd, Collection foundBlacklisted) {

    public String getName() {
        return name;

    public String toString() {
        return name;


public class DockingLayoutManager implements EBComponent
{

	private static final String NO_SETTINGS_MESSAGE = "no-settings.message";
	private static final String SAVE_LAYOUT_FAILED = "save-layout-failed.message";
	private static final String LOAD_LAYOUT_TITLE = "load-layout.title";
	private static final String LOAD_LAYOUT_MESSAGE = "load-layout.message";
	private static final String SAVE_LAYOUT_TITLE = "save-layout.title";
	private static final String SAVE_LAYOUT_MESSAGE = "save-layout.message";
	private static ActionSet actions;
	private static DockingLayoutManager instance;
	private Map<View, String> currentMode;

	private DockingLayoutManager()
	{
		currentMode = new HashMap<View, String>();
	}
	private static boolean save(View view, String layoutName)
	{
		DockingLayout docking = view.getViewConfig().docking;
		if (docking != null)
		{
			boolean ret = docking.saveLayout(layoutName, DockingLayout.NO_VIEW_INDEX);
			if (! ret)
				return false;
			addAction(layoutName);
		}
		return true;
	}

	public static void saveAs(View view)
	{
		if (jEdit.getSettingsDirectory() == null)
		{
			JOptionPane.showMessageDialog(view, jEdit.getProperty(NO_SETTINGS_MESSAGE));
			return;
		}
		String layoutName = JOptionPane.showInputDialog(view,
			jEdit.getProperty(SAVE_LAYOUT_MESSAGE),
			jEdit.getProperty(SAVE_LAYOUT_TITLE),
			JOptionPane.QUESTION_MESSAGE);
		if (layoutName == null)
			return;
		if (! save(view, layoutName))
			JOptionPane.showMessageDialog(view, jEdit.getProperty(SAVE_LAYOUT_FAILED));
	}

	private static void load(View view, String layoutName)
	{
		DockingLayout docking = View.getDockingFrameworkProvider().createDockingLayout();
		if (docking.loadLayout(layoutName, DockingLayout.NO_VIEW_INDEX))
			view.getDockableWindowManager().setDockingLayout(docking);
	}

	public static void load(View view)
	{
		if (jEdit.getSettingsDirectory() == null)
		{
			JOptionPane.showMessageDialog(view, jEdit.getProperty(NO_SETTINGS_MESSAGE));
			return;
		}
		String layoutName = (String) JOptionPane.showInputDialog(view,
			jEdit.getProperty(LOAD_LAYOUT_MESSAGE),
			jEdit.getProperty(LOAD_LAYOUT_TITLE),
			JOptionPane.QUESTION_MESSAGE,
			null,
			getSavedLayouts(),
			null);
		if (layoutName == null)
			return;
		load(view, layoutName);
	}

	private static String[] getSavedLayouts()
	{
		DockingLayout docking = View.getDockingFrameworkProvider().createDockingLayout();
		String[] layouts = null;
		if (docking != null)
			layouts = docking.getSavedLayouts();
		if (layouts == null)
			return new String[0];
		return layouts;
	}

	private static void addAction(String layoutName)
	{
		if ((actions != null) && (! actions.contains(layoutName)))
			actions.addAction(new LoadPerspectiveAction(layoutName));
	}

	public static void init()
	{
		createActions();
		instance = new DockingLayoutManager();
		EditBus.addToBus(instance);
	}

	private static void createActions()
	{
		actions = new ActionSet("Docking Layouts");
		String[] layouts = getSavedLayouts();
		for (String layout: layouts)
			addAction(layout);
		jEdit.addActionSet(actions);
		actions.initKeyBindings();
	}

	public static void removeActions()
	{
		jEdit.removeActionSet(actions);
	}

	private static class LoadPerspectiveAction extends EditAction
	{
		private static final String LOAD_PREFIX = "load-";

		public LoadPerspectiveAction(String layoutName)
		{
			super(LOAD_PREFIX + layoutName, new String[] { layoutName });
			jEdit.setTemporaryProperty(LOAD_PREFIX + layoutName + ".label", LOAD_PREFIX + layoutName);
		}

		@Override
		public void invoke(View view)
		{
			DockingLayoutManager.load(view, (String) args[0]);
		}
	}

	private boolean canChangeEditMode(EBMessage message)
	{
		if (message instanceof BufferUpdate)
		{
			BufferUpdate bu = (BufferUpdate) message;
			Object what = bu.getWhat();
			if ((what == BufferUpdate.CLOSED) ||
				(what == BufferUpdate.CREATED) ||
				(what == BufferUpdate.PROPERTIES_CHANGED))
			{
				return true;
			}
		}
		else if (message instanceof EditPaneUpdate)
		{
			EditPaneUpdate ep = (EditPaneUpdate) message;
			Object what = ep.getWhat();
			if ((what == EditPaneUpdate.BUFFER_CHANGED) ||
				(what == EditPaneUpdate.CREATED))
			{
				return true;
			}
		}
		return false;
	}

	public void handleMessage(EBMessage message)
	{
		boolean autoLoadModeLayout = jEdit.getBooleanProperty(
			DockingOptionPane.AUTO_LOAD_MODE_LAYOUT_PROP, false);
		if (! autoLoadModeLayout)
			return;
		if (message instanceof ViewUpdate)
		{
			ViewUpdate vu = (ViewUpdate) message;
			if (vu.getWhat() == ViewUpdate.CLOSED)
			{
				View view = jEdit.getActiveView();
				String mode = currentMode.get(view);
				saveModeLayout(view, mode);
				return;
			}
		}
		// Check for a change in the edit mode
		View view = jEdit.getActiveView();
		if (view == null)
			return;
		if (! canChangeEditMode(message))
			return;
		String newMode = getCurrentEditMode(view);
		String mode = currentMode.get(view);
		boolean sameMode =
			(mode == null && newMode == null) ||
			(mode != null && mode.equals(newMode));
		if (! sameMode)
		{
			boolean autoSaveModeLayout = jEdit.getBooleanProperty(
				DockingOptionPane.AUTO_SAVE_MODE_LAYOUT_PROP, false);
			if (autoSaveModeLayout)
				saveModeLayout(view, mode);
			currentMode.put(view, newMode);
			loadModeLayout(view, newMode);
		}
	}

	private String getCurrentEditMode(View view)
	{
		Buffer buffer = view.getBuffer();
		if (buffer == null)
			return null;
		Mode bufferMode = buffer.getMode();
		if (bufferMode == null)
			return null;
		return bufferMode.getName();
	}

	private static final String GLOBAL_MODE = "DEFAULT";

	private void saveModeLayout(View view, String mode)
	{
		String modeLayout = getModePerspective(mode);
		if (modeLayout == null)
			return;
		save(view, modeLayout);
	}

	private void loadModeLayout(View view, String mode)
	{
		String modeLayout = getModePerspective(mode);
		if (modeLayout == null)
			return;
		load(view, modeLayout);
	}

	public static void loadCurrentModeLayout(View view)
	{
		if (view == null)
			return;
		String mode = instance.getCurrentEditMode(view);
		instance.loadModeLayout(view, mode);
	}

	public static void saveCurrentModeLayout(View view)
	{
		if (view == null)
			return;
		String mode = instance.getCurrentEditMode(view);
		instance.saveModeLayout(view, mode);
	}

	private String getModePerspective(String mode)
	{
		if (mode == null)
			mode = GLOBAL_MODE;
		return "mode-" + mode;

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

FUNC_DECL IF VAR_DECL PARAM PARAM CALL CALL CALL CALL CALL

FUNC_DECL LOOP VAR_DECL CALL CALL ASSIGN CALL CALL CALL LITERAL_ANCHOR


public class FileComponent extends DefaultComponent<FileExchange> {
    public FileComponent() {
    }

    public FileComponent(CamelContext context) {
        super(context);
    }

    protected Endpoint<FileExchange> createEndpoint(String uri, String remaining, Map parameters) throws Exception {
        File file = new File(remaining);
        FileEndpoint result = new FileEndpoint(file, remaining, this);
        IntrospectionSupport.setProperties(result, parameters);
        return result;

FUNC_DECL RETURN VAR_DECL VAR_DECL PARAM PARAM PARAM CALL CALL CALL