org.gjt.sp.jedit.gui.VariableGridLayout

public class VariableGridLayout implements LayoutManager2, java.io.Serializable
{

	public static final int FIXED_NUM_ROWS = 1;
	public static final int FIXED_NUM_COLUMNS = 2;

	public VariableGridLayout(int mode, int size, int hgap, int vgap) {
		if (mode != FIXED_NUM_ROWS && mode != FIXED_NUM_COLUMNS) {
			throw new IllegalArgumentException("illegal mode; value is " + mode);
		}
		if (size <= 0) {
			throw new IllegalArgumentException("size cannot be zero or less; value is " + size);
		}
		if (hgap < 0) {
			throw new IllegalArgumentException("hgap cannot be negative; value is " + hgap);
		}
		if (vgap < 0) {
			throw new IllegalArgumentException("vgap cannot be negative; value is " + vgap);
		}
		this.mode = mode;
		this.size = size;
		this.hgap = hgap;
		this.vgap = vgap;
	}

	/**
	 * Creates a variable grid layout manager with the specified mode
	 * and zero horizontal and vertical gap.
	 */
	public VariableGridLayout(int mode, int size) {
		this(mode, size, 0, 0);
	}

	/**
	 * Creates a variable grid layout manager with mode FIXED_NUM_ROWS,
	 * number of rows == 1 and zero horizontal and vertical gap.
	 */
	public VariableGridLayout() {
		this(FIXED_NUM_ROWS, 1, 0, 0);
	}

	/**
	 * Not used in this class.
	 */
	public void addLayoutComponent(String name, Component component) { }

	/**
	 * Not used in this class.
	 */
	public void addLayoutComponent(Component component, Object constraints) { }

	/**
	 * Not used in this class.
	 */
	public void removeLayoutComponent(Component component) { }

	/**
	 * Always returns 0.5.
	 */
	public float getLayoutAlignmentX(Container container) {
		return 0.5f;
	}

	/**
	 * Always returns 0.5.
	 */
	public float getLayoutAlignmentY(Container container) {
		return 0.5f;
	}

	public Dimension preferredLayoutSize(Container parent) {
		return getLayoutSize(parent, 2);
	}

	public Dimension minimumLayoutSize(Container parent) {
		return getLayoutSize(parent, 0);
	}

	public Dimension maximumLayoutSize(Container parent) {
		return getLayoutSize(parent, 1);
	}

	public void layoutContainer(Container parent) {
		synchronized (parent.getTreeLock()) {
			update(parent);

			int ncomponents = parent.getComponentCount();

			if (ncomponents == 0) {
				return;
			}

			// Pass 1: compute preferred row heights / column widths
			int total_height = 0;
			for (int r = 0, i = 0; r < nrows; r++) {
				for (int c = 0; c < ncols; c++, i++) {
					if (i < ncomponents) {
						Dimension d = parent.getComponent(i).getPreferredSize();
						row_heights[r] = Math.max(row_heights[r], d.height);
						col_widths[c] = Math.max(col_widths[c], d.width);
					} else {
						break;
					}
				}
				total_height += row_heights[r];
			}

			int total_width = 0;
			for (int c = 0; c < ncols; c++) {
				total_width += col_widths[c];
			}

			// Pass 2: redistribute free space
			Dimension parent_size = parent.getSize();
			Insets insets = parent.getInsets();
			int free_height = parent_size.height - insets.top - insets.bottom - (nrows - 1) * vgap;
			int free_width = parent_size.width - insets.left - insets.right - (ncols - 1) * hgap;

			if (total_height != free_height) {
				double dy = (double)free_height / (double)total_height;
				for (int r = 0; r < nrows; r++) {
					row_heights[r] = (int) ((double)row_heights[r] * dy);
				}
			}

			if (total_width != free_width) {
				double dx = ((double)free_width) / ((double)total_width);
				for (int c = 0; c < ncols; c++) {
					col_widths[c] = (int) ((double)col_widths[c] * dx);
				}
			}

			// Pass 3: layout components
			for (int r = 0, y = insets.top, i = 0; r < nrows; y += row_heights[r] + vgap, r++) {
				for (int c = 0, x = insets.left; c < ncols; x += col_widths[c] + hgap, c++, i++) {
					if (i < ncomponents) {
						parent.getComponent(i).setBounds(x, y, col_widths[c], row_heights[r]);
					}
				}
			}

		} // synchronized
	}

	public void invalidateLayout(Container container) {}

	/**
	 * Returns the string representation of this variable grid layout's values.
	 * @return  a string representation of this variable grid layout.
	 */
	public String toString() {
		return getClass().getName() + "[mode=" + mode + ",size=" + size
			   + ",hgap=" + hgap + ",vgap=" + vgap + "]";
	}

	/**
	 * @param  which  if 0 compute minimum layout size,
	 *				if 1 compute maximum layout size,
	 *				otherwise compute preferred layout size.
	 */
	private Dimension getLayoutSize(Container parent, int which) {
		synchronized (parent.getTreeLock()){
			update(parent);

			int ncomponents = parent.getComponentCount();
			int h = 0;
			int w = 0;

			for (int r = 0, i = 0; r < nrows; r++) {
				int row_height = 0;
				for (int c = 0; c < ncols; c++, i++) {
					if (i < ncomponents) {
						switch (which) {
							case 0:
								row_height = Math.max(row_height, parent.getComponent(i).getMinimumSize().height);
								break;
							case 1:
								row_height = Math.max(row_height, parent.getComponent(i).getMaximumSize().height);
								break;
							default:
								row_height = Math.max(row_height, parent.getComponent(i).getPreferredSize().height);
								break;
						}
					} else {
						break;
					}
				}
				h += row_height;
			}

			for (int c = 0; c < ncols; c++) {
				int col_width = 0;
				for (int r = 0; r < nrows; r++) {
					int i = r * ncols + c;
					if (i < ncomponents) {
						switch (which) {
							case 0:
								col_width = Math.max(col_width, parent.getComponent(i).getMinimumSize().width);
								break;
							case 1:
								col_width = Math.max(col_width, parent.getComponent(i).getMaximumSize().width);
								break;
							default:
								col_width = Math.max(col_width, parent.getComponent(i).getPreferredSize().width);
								break;
						}
					} else {
						break;
					}
				}
				w += col_width;
			}

			Insets insets = parent.getInsets();
			return new Dimension(w + insets.left + insets.right + ((ncols - 1) * hgap),
								 h + insets.top + insets.bottom + ((nrows - 1) * vgap));
		}
	}

	private void update(Container container) {
		int ncomponents = container.getComponentCount();
		int old_nrows = nrows;
		int old_ncols = ncols;
		if (this.mode == FIXED_NUM_ROWS) {
			nrows = this.size;
			ncols = (ncomponents + nrows - 1) / nrows;
		} else {
			ncols = this.size;
			nrows = (ncomponents + ncols - 1) / ncols;
		}
		if (old_nrows != nrows) {
			row_heights = new int[nrows];
		}
		if (old_ncols != ncols) {
			col_widths = new int[ncols];
		}
	}

	private int mode;
	private int size;
	private int hgap;
	private int vgap;
	private transient int nrows = -1;
	private transient int ncols = -1;
	private transient int[] row_heights = null;
	private transient int[] col_widths = null;


org.apache.xalan.transformer.StackGuard

public class StackGuard
{

  /**
   * Used for infinite loop check. If the value is -1, do not
   * check for infinite loops. Anyone who wants to enable that
   * check should change the value of this variable to be the
   * level of recursion that they want to check. Be careful setting
   * this variable, if the number is too low, it may report an
   * infinite loop situation, when there is none.
   * Post version 1.0.0, we'll make this a runtime feature.
   */
  public static int m_recursionLimit = -1;

  TransformerImpl m_transformer;

  /**
   * Get the recursion limit.
   * Used for infinite loop check. If the value is -1, do not
   * check for infinite loops. Anyone who wants to enable that
   * check should change the value of this variable to be the
   * level of recursion that they want to check. Be careful setting
   * this variable, if the number is too low, it may report an
   * infinite loop situation, when there is none.
   * Post version 1.0.0, we'll make this a runtime feature.
   *
   * @return The recursion limit.
   */
  public int getRecursionLimit()
  {
    return m_recursionLimit;
  }

  /**
   * Set the recursion limit.
   * Used for infinite loop check. If the value is -1, do not
   * check for infinite loops. Anyone who wants to enable that
   * check should change the value of this variable to be the
   * level of recursion that they want to check. Be careful setting
   * this variable, if the number is too low, it may report an
   * infinite loop situation, when there is none.
   * Post version 1.0.0, we'll make this a runtime feature.
   *
   * @param limit The recursion limit.
   */
  public void setRecursionLimit(int limit)
  {
    m_recursionLimit = limit;
  }

  /**
   * Constructor StackGuard
   *
   *
   * @param xslTemplate Current template node
   * @param sourceXML Source Node
   */
  public StackGuard(TransformerImpl transformerImpl)
  {
    m_transformer = transformerImpl;
  }

  /**
   * Overide equal method for StackGuard objects
   *
   *
   * @param obj StackGuard object to compare
   *
   * @return True if the given object matches this StackGuard object
   */
  public int countLikeTemplates(ElemTemplate templ, int pos)
  {
  	ObjectStack elems = m_transformer.getCurrentTemplateElements();
  	int count = 1;
    for (int i = pos-1; i >= 0; i--)
    {
    	if((ElemTemplateElement)elems.elementAt(i) == templ)
    		count++;
    }

    return count;
  }

  /**
   * Get the next named or match template down from and including
   * the given position.
   * @param pos the current index position in the stack.
   * @return null if no matched or named template found, otherwise
   * the next named or matched template at or below the position.
   */
  private ElemTemplate getNextMatchOrNamedTemplate(int pos)
  {
  	ObjectStack elems = m_transformer.getCurrentTemplateElements();
    for (int i = pos; i >= 0; i--)
    {
    	ElemTemplateElement elem = (ElemTemplateElement) elems.elementAt(i);
    	if(null != elem)
    	{
	    	if(elem.getXSLToken() == Constants.ELEMNAME_TEMPLATE)
	    	{
	    		return (ElemTemplate)elem;
	    	}
    	}
    }
  	return null;
  }

  /**
   * Check if we are in an infinite loop
   *
   *
   * @param guard Current StackGuard object (matching current template)
   *
   * @throws TransformerException
   */
  public void checkForInfinateLoop() throws TransformerException
  {
    int nTemplates = m_transformer.getCurrentTemplateElementsCount();
    if(nTemplates < m_recursionLimit)
    	return;

    if(m_recursionLimit <= 0)

    for (int i = (nTemplates - 1); i >= m_recursionLimit; i--)
    {
    	ElemTemplate template = getNextMatchOrNamedTemplate(i);

    	if(null == template)
    		break;

    	int loopCount = countLikeTemplates(template, i);

    	if (loopCount >= m_recursionLimit)
    	{

    		String idIs = XSLMessages.createMessage(((null != template.getName()) ? "nameIs" : "matchPatternIs"), null);
        	Object[] msgArgs = new Object[]{ new Integer(loopCount), idIs,
                     ((null != template.getName()) ? template.getName().toString()
    		   : template.getMatch().getPatternString()) };
        	String msg = XSLMessages.createMessage("recursionTooDeep", msgArgs);

    		throw new TransformerException(msg);


public final class RtMethodGenerator extends MethodGenerator {
    private static final int HANDLER_INDEX = 2;
    private final Instruction _astoreHandler;
    private final Instruction _aloadHandler;

    public RtMethodGenerator(int access_flags, Type return_type,
			     Type[] arg_types, String[] arg_names,
			     String method_name, String class_name,
			     InstructionList il, ConstantPoolGen cp) {
	super(access_flags, return_type, arg_types, arg_names, method_name,
	      class_name, il, cp);

	_astoreHandler = new ASTORE(HANDLER_INDEX);
	_aloadHandler  = new ALOAD(HANDLER_INDEX);
    }

    public int getIteratorIndex() {
    }

    public final Instruction storeHandler() {
	return _astoreHandler;
    }

    public final Instruction loadHandler() {
	return _aloadHandler;
    }

    public int getLocalIndex(String name) {

FUNC_DECL PARAM PARAM PARAM PARAM PARAM PARAM PARAM PARAM ASSIGN ASSIGN CALL CALL


public class TeeOutputStream extends OutputStream {
    private OutputStream left;
    private OutputStream right;

    /**
     * Constructor for TeeOutputStream.
     * @param left one of the output streams.
     * @param right the other output stream.
     */
    public TeeOutputStream(OutputStream left, OutputStream right) {
        this.left = left;
        this.right = right;
    }

    /**
     * Close both output streams.
     * @throws IOException on error.
     */
    public void close() throws IOException {
        try {
            left.close();
        } finally {
            right.close();
        }
    }

    /**
     * Flush both output streams.
     * @throws IOException on error
     */
    public void flush() throws IOException {
        left.flush();
        right.flush();
    }

    /**
     * Write a byte array to both output streams.
     * @param b an array of bytes.
     * @throws IOException on error.
     */
    public void write(byte[] b) throws IOException {
        left.write(b);
        right.write(b);
    }

    /**
     * Write a byte array to both output streams.
     * @param b     the data.
     * @param off   the start offset in the data.
     * @param len   the number of bytes to write.
     * @throws IOException on error.
     */
    public void write(byte[] b, int off, int len) throws IOException {
        left.write(b, off, len);
        right.write(b, off, len);
    }

    /**
     * Write a byte to both output streams.
     * @param b the byte to write.
     * @throws IOException on error.
     */
    public void write(int b) throws IOException {
        left.write(b);
        right.write(b);


org.gjt.sp.jedit.BufferHistory

public class BufferHistory
{
	//{{{ Entry class
	/**
	 * Recent file list entry.
	 */
	public static class Entry
	{
		public String path;
		public int caret;
		public String selection;
		public String encoding;
		public String mode;

		public Selection[] getSelection()
		{
			return stringToSelection(selection);
		}

		public Entry(String path, int caret, String selection, String encoding, String mode)
		{
			this.path = path;
			this.caret = caret;
			this.selection = selection;
			this.encoding = encoding;
			this.mode = mode;
		}

		public String toString()
		{
			return path + ": " + caret;
		}
	} //}}}

	//{{{ getEntry() method
	public static Entry getEntry(String path)
	{
		historyLock.readLock().lock();
		try
		{
			for (Entry entry : history)
			{
				if(MiscUtilities.pathsEqual(entry.path,path))
					return entry;
			}
		}
		finally
		{
			historyLock.readLock().unlock();
		}

		return null;
	} //}}}

	//{{{ setEntry() method
	public static void setEntry(String path, int caret, Selection[] selection,
		String encoding, String mode)
	{
		Entry entry = new Entry(path,caret,
			selectionToString(selection), encoding, mode);
		historyLock.writeLock().lock();
		try
		{
			removeEntry(path);
			addEntry(entry);
		}
		finally
		{
			historyLock.writeLock().unlock();
		}
		notifyChange();
	} //}}}

	//{{{ clear() method
	/**
	 * Clear the BufferHistory.
	 * @since 4.3pre6
	 */
	public static void clear()
	{
		historyLock.writeLock().lock();
		try
		{
			history.clear();
		}
		finally
		{
			historyLock.writeLock().unlock();
		}
		notifyChange();
	} //}}}

	//{{{ getHistory() method
	/**
	 * Returns the Buffer list.
	 * @return the buffer history list
	 * @since jEdit 4.2pre2
	 */
	public static List<Entry> getHistory()
	{
		// Returns a snapshot to avoid concurrent access to the
		// history. This requires O(n) time, but it should be ok
		// because this method should be used only by external
		// O(n) operation.

		historyLock.readLock().lock();
		try
		{
			return (List<Entry>)history.clone();
		}
		finally
		{
			historyLock.readLock().unlock();
		}
	} //}}}

	//{{{ load() method
	public static void load()
	{
		if(recentXML == null)
			return;

		if(!recentXML.fileExists())
			return;

		Log.log(Log.MESSAGE,BufferHistory.class,"Loading " + recentXML);

		RecentHandler handler = new RecentHandler();
		try
		{
			recentXML.load(handler);
		}
		catch(IOException e)
		{
			Log.log(Log.ERROR,BufferHistory.class,e);
		}
		trimToLimit(handler.result);
		history = handler.result;
	} //}}}

	//{{{ save() method
	public static void save()
	{
		if(recentXML == null)
			return;

		if(recentXML.hasChangedOnDisk())
		{
			Log.log(Log.WARNING,BufferHistory.class,recentXML
				+ " changed on disk; will not save recent"
				+ " files");
			return;
		}

		Log.log(Log.MESSAGE,BufferHistory.class,"Saving " + recentXML);

		String lineSep = System.getProperty("line.separator");

		SettingsXML.Saver out = null;

		try
		{
			out = recentXML.openSaver();
			out.writeXMLDeclaration();

			out.write("<!DOCTYPE RECENT SYSTEM \"recent.dtd\">");
			out.write(lineSep);
			out.write("<RECENT>");
			out.write(lineSep);

			// Make a snapshot to avoid long locking period
			// which may be required by file I/O.
			List<Entry> snapshot = getHistory();

			for (Entry entry : snapshot)
			{
				out.write("<ENTRY>");
				out.write(lineSep);

				out.write("<PATH>");
				out.write(XMLUtilities.charsToEntities(entry.path,false));
				out.write("</PATH>");
				out.write(lineSep);

				out.write("<CARET>");
				out.write(String.valueOf(entry.caret));
				out.write("</CARET>");
				out.write(lineSep);

				if(entry.selection != null
					&& entry.selection.length() > 0)
				{
					out.write("<SELECTION>");
					out.write(entry.selection);
					out.write("</SELECTION>");
					out.write(lineSep);
				}

				if(entry.encoding != null)
				{
					out.write("<ENCODING>");
					out.write(entry.encoding);
					out.write("</ENCODING>");
					out.write(lineSep);
				}

				if (entry.mode != null)
				{
					out.write("<MODE>");
					out.write(entry.mode);
					out.write("</MODE>");
					out.write(lineSep);
				}

				out.write("</ENTRY>");
				out.write(lineSep);
			}

			out.write("</RECENT>");
			out.write(lineSep);

			out.finish();
		}
		catch(Exception e)
		{
			Log.log(Log.ERROR,BufferHistory.class,e);
		}
		finally
		{
			IOUtilities.closeQuietly(out);
		}
	} //}}}

	//{{{ Private members
	private static LinkedList<Entry> history;
	private static ReentrantReadWriteLock historyLock;
	private static SettingsXML recentXML;

	//{{{ Class initializer
	static
	{
		history = new LinkedList<Entry>();
		historyLock = new ReentrantReadWriteLock();
		String settingsDirectory = jEdit.getSettingsDirectory();
		if(settingsDirectory != null)
		{
			recentXML = new SettingsXML(settingsDirectory, "recent");
		}
	} //}}}

	//{{{ addEntry() method
	private static void addEntry(Entry entry)
	{
		historyLock.writeLock().lock();
		try
		{
			history.addFirst(entry);
			trimToLimit(history);
		}
		finally
		{
			historyLock.writeLock().unlock();
		}
	} //}}}

	//{{{ removeEntry() method
	private static void removeEntry(String path)
	{
		historyLock.writeLock().lock();
		try
		{
			Iterator<Entry> iter = history.iterator();
			while(iter.hasNext())
			{
				Entry entry = iter.next();
				if(MiscUtilities.pathsEqual(path,entry.path))
				{
					iter.remove();
					return;
				}
			}
		}
		finally
		{
			historyLock.writeLock().unlock();
		}
	} //}}}

	//{{{ selectionToString() method
	private static String selectionToString(Selection[] s)
	{
		if(s == null)
			return null;

		StringBuilder buf = new StringBuilder();

		for(int i = 0; i < s.length; i++)
		{
			if(i != 0)
				buf.append(' ');

			Selection sel = s[i];
			if(sel instanceof Selection.Range)
				buf.append("range ");
			else //if(sel instanceof Selection.Rect)
				buf.append("rect ");
			buf.append(sel.getStart());
			buf.append(' ');
			buf.append(sel.getEnd());
		}

		return buf.toString();
	} //}}}

	//{{{ stringToSelection() method
	private static Selection[] stringToSelection(String s)
	{
		if(s == null)
			return null;

		List<Selection> selection = new ArrayList<Selection>();
		StringTokenizer st = new StringTokenizer(s);

		while(st.hasMoreTokens())
		{
			String type = st.nextToken();
			int start = Integer.parseInt(st.nextToken());
			int end = Integer.parseInt(st.nextToken());
			if(end < start)
			{
				// I'm not sure when this can happen,
				// but it does sometimes, witness the
				// jEdit bug tracker.
				continue;
			}

			Selection sel;
			if(type.equals("range"))
				sel = new Selection.Range(start,end);
			else //if(type.equals("rect"))
				sel = new Selection.Rect(start,end);

			selection.add(sel);
		}

		Selection[] returnValue = new Selection[selection.size()];
		returnValue = selection.toArray(returnValue);
		return returnValue;
	} //}}}

	//{{{ trimToLimit() method
	private static void trimToLimit(LinkedList<Entry> list)
	{
		int max = jEdit.getIntegerProperty("recentFiles",50);
		while(list.size() > max)
			list.removeLast();
	} //}}}

	//{{{ notifyChange() method
	private static void notifyChange()
	{
		EditBus.send(new DynamicMenuChanged("recent-files"));
	} //}}}

	//{{{ RecentHandler class
	private static class RecentHandler extends DefaultHandler
	{
		public LinkedList<Entry> result = new LinkedList<Entry>();

		public InputSource resolveEntity(String publicId, String systemId)
		{
			return XMLUtilities.findEntity(systemId, "recent.dtd", getClass());
		}

		public void endElement(String uri, String localName, String name)
		{
			if(name.equals("ENTRY"))
			{
				result.addLast(new Entry(
					path,caret,selection,
					encoding,
					mode));
				path = null;
				caret = 0;
				selection = null;
				encoding = null;
				mode = null;
			}
			else if(name.equals("PATH"))
				path = charData.toString();
			else if(name.equals("CARET"))
				caret = Integer.parseInt(charData.toString());
			else if(name.equals("SELECTION"))
				selection = charData.toString();
			else if(name.equals("ENCODING"))
				encoding = charData.toString();
			else if(name.equals("MODE"))
				mode = charData.toString();
			charData.setLength(0);
		}

		public void characters(char[] ch, int start, int length)
		{
			charData.append(ch,start,length);
		}

		// end HandlerBase implementation

		// private members
		private String path;
		private int caret;
		private String selection;
		private String encoding;
		private String mode;
		private StringBuilder charData = new StringBuilder();

FUNC_DECL RETURN TRY PARAM LITERAL_ANCHOR LOOP CALL CALL CALL CALL IF RETURN CALL

FUNC_DECL TRY VAR_DECL PARAM PARAM PARAM PARAM PARAM CALL CALL CALL CALL CALL CALL CALL CALL CALL

FUNC_DECL TRY CALL CALL CALL CALL CALL CALL

FUNC_DECL TRY RETURN CALL CALL CALL CALL CALL

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

FUNC_DECL TRY PARAM CALL CALL CALL CALL CALL CALL

FUNC_DECL TRY PARAM LOOP VAR_DECL CALL CALL CALL CALL CALL IF VAR_DECL CALL CALL RETURN CALL CALL


org.gjt.sp.jedit.bsh.Primitive

public final class Primitive implements ParserConstants, java.io.Serializable
{
	/*
	static Hashtable primitiveToWrapper = new Hashtable();
	static Hashtable wrapperToPrimitive = new Hashtable();
	static {
		primitiveToWrapper.put( Boolean.TYPE, Boolean.class );
		primitiveToWrapper.put( Byte.TYPE, Byte.class );
		primitiveToWrapper.put( Short.TYPE, Short.class );
		primitiveToWrapper.put( Character.TYPE, Character.class );
		primitiveToWrapper.put( Integer.TYPE, Integer.class );
		primitiveToWrapper.put( Long.TYPE, Long.class );
		primitiveToWrapper.put( Float.TYPE, Float.class );
		primitiveToWrapper.put( Double.TYPE, Double.class );
		wrapperToPrimitive.put( Boolean.class, Boolean.TYPE );
		wrapperToPrimitive.put( Byte.class, Byte.TYPE );
		wrapperToPrimitive.put( Short.class, Short.TYPE );
		wrapperToPrimitive.put( Character.class, Character.TYPE );
		wrapperToPrimitive.put( Integer.class, Integer.TYPE );
		wrapperToPrimitive.put( Long.class, Long.TYPE );
		wrapperToPrimitive.put( Float.class, Float.TYPE );
		wrapperToPrimitive.put( Double.class, Double.TYPE );
	}
	*/
	static Hashtable wrapperMap = new Hashtable();
	static {
		wrapperMap.put( Boolean.TYPE, Boolean.class );
		wrapperMap.put( Byte.TYPE, Byte.class );
		wrapperMap.put( Short.TYPE, Short.class );
		wrapperMap.put( Character.TYPE, Character.class );
		wrapperMap.put( Integer.TYPE, Integer.class );
		wrapperMap.put( Long.TYPE, Long.class );
		wrapperMap.put( Float.TYPE, Float.class );
		wrapperMap.put( Double.TYPE, Double.class );
		wrapperMap.put( Boolean.class, Boolean.TYPE );
		wrapperMap.put( Byte.class, Byte.TYPE );
		wrapperMap.put( Short.class, Short.TYPE );
		wrapperMap.put( Character.class, Character.TYPE );
		wrapperMap.put( Integer.class, Integer.TYPE );
		wrapperMap.put( Long.class, Long.TYPE );
		wrapperMap.put( Float.class, Float.TYPE );
		wrapperMap.put( Double.class, Double.TYPE );
	}

    /** The primitive value stored in its java.lang wrapper class */
    private Object value;

    private static class Special implements java.io.Serializable
    {
        private Special() { }

        public static final Special NULL_VALUE = new Special();
        public static final Special VOID_TYPE = new Special();
    }

    /*
        NULL means "no value".
        This ia a placeholder for primitive null value.
    */
    public static final Primitive NULL = new Primitive(Special.NULL_VALUE);

    /**
        VOID means "no type".
        Strictly speaking, this makes no sense here.  But for practical
        reasons we'll consider the lack of a type to be a special value.
    */
    public static final Primitive VOID = new Primitive(Special.VOID_TYPE);

    // private to prevent invocation with param that isn't a primitive-wrapper
    public Primitive( Object value )
    {
        if ( value == null )
            throw new InterpreterError(
				"Use Primitve.NULL instead of Primitive(null)");

		if ( value != Special.NULL_VALUE
			&& value != Special.VOID_TYPE &&
			!isWrapperType( value.getClass() )
		)
            throw new InterpreterError( "Not a wrapper type: "+value);

        this.value = value;
    }

    public Primitive(boolean value) { this(new Boolean(value)); }
    public Primitive(byte value) { this(new Byte(value)); }
    public Primitive(short value) { this(new Short(value)); }
    public Primitive(char value) { this(new Character(value)); }
    public Primitive(int value) { this(new Integer(value)); }
    public Primitive(long value) { this(new Long(value)); }
    public Primitive(float value) { this(new Float(value)); }
    public Primitive(double value) { this(new Double(value)); }

	/**
    	Return the primitive value stored in its java.lang wrapper class
	*/
    public Object getValue()
    {
        if ( value == Special.NULL_VALUE )
            return null;
        else
		if ( value == Special.VOID_TYPE )
                throw new InterpreterError("attempt to unwrap void type");
        else
            return value;
    }

    public String toString()
    {
        if(value == Special.NULL_VALUE)
            return "null";
        else if(value == Special.VOID_TYPE)
            return "void";
        else
            return value.toString();
    }

	/**
		Get the corresponding Java primitive TYPE class for this Primitive.
		@return the primitive TYPE class type of the value or Void.TYPE for
		Primitive.VOID or null value for type of Primitive.NULL
	*/
    public Class getType()
    {
		if ( this == Primitive.VOID )
			return Void.TYPE;

		// NULL return null as type... we currently use null type to indicate
		// loose typing throughout bsh.
		if ( this == Primitive.NULL )
			return null;

		return unboxType( value.getClass() );
    }

	/**
		Perform a binary operation on two Primitives or wrapper types.
		If both original args were Primitives return a Primitive result
		else it was mixed (wrapper/primitive) return the wrapper type.
		The exception is for boolean operations where we will return the
		primitive type either way.
	*/
    public static Object binaryOperation(
		Object obj1, Object obj2, int kind)
        throws UtilEvalError
    {
		// special primitive types
        if ( obj1 == NULL || obj2 == NULL )
            throw new UtilEvalError(
				"Null value or 'null' literal in binary operation");
        if ( obj1 == VOID || obj2 == VOID )
            throw new UtilEvalError(
			"Undefined variable, class, or 'void' literal in binary operation");

		// keep track of the original types
		Class lhsOrgType = obj1.getClass();
		Class rhsOrgType = obj2.getClass();

		// Unwrap primitives
        if ( obj1 instanceof Primitive )
            obj1 = ((Primitive)obj1).getValue();
        if ( obj2 instanceof Primitive )
            obj2 = ((Primitive)obj2).getValue();

        Object[] operands = promotePrimitives(obj1, obj2);
        Object lhs = operands[0];
        Object rhs = operands[1];

        if(lhs.getClass() != rhs.getClass())
            throw new UtilEvalError("Type mismatch in operator.  "
			+ lhs.getClass() + " cannot be used with " + rhs.getClass() );

		Object result;
		try {
			result = binaryOperationImpl( lhs, rhs, kind );
		} catch ( ArithmeticException e ) {
			throw new UtilTargetError( "Arithemetic Exception in binary op", e);
		}

		// If both original args were Primitives return a Primitive result
		// else it was mixed (wrapper/primitive) return the wrapper type
		// Exception is for boolean result, return the primitive
		if ( (lhsOrgType == Primitive.class && rhsOrgType == Primitive.class)
			|| result instanceof Boolean
		)
			return new Primitive( result );
		else
			return result;
    }

    static Object binaryOperationImpl( Object lhs, Object rhs, int kind )
        throws UtilEvalError
	{
        if(lhs instanceof Boolean)
            return booleanBinaryOperation((Boolean)lhs, (Boolean)rhs, kind);
        else if(lhs instanceof Integer)
            return intBinaryOperation( (Integer)lhs, (Integer)rhs, kind );
        else if(lhs instanceof Long)
            return longBinaryOperation((Long)lhs, (Long)rhs, kind);
        else if(lhs instanceof Float)
            return floatBinaryOperation((Float)lhs, (Float)rhs, kind);
        else if(lhs instanceof Double)
            return doubleBinaryOperation( (Double)lhs, (Double)rhs, kind);
        else
            throw new UtilEvalError("Invalid types in binary operator" );
	}

    static Boolean booleanBinaryOperation(Boolean B1, Boolean B2, int kind)
    {
        boolean lhs = B1.booleanValue();
        boolean rhs = B2.booleanValue();

        switch(kind)
        {
            case EQ:
                return new Boolean(lhs == rhs);

            case NE:
                return new Boolean(lhs != rhs);

            case BOOL_OR:
            case BOOL_ORX:
                return new Boolean( lhs || rhs );

            case BOOL_AND:
            case BOOL_ANDX:
                return new Boolean( lhs && rhs );

            default:
                throw new InterpreterError("unimplemented binary operator");
        }
    }

    // returns Object covering both Long and Boolean return types
    static Object longBinaryOperation(Long L1, Long L2, int kind)
    {
        long lhs = L1.longValue();
        long rhs = L2.longValue();

        switch(kind)
        {
            // boolean
            case LT:
            case LTX:
                return new Boolean(lhs < rhs);

            case GT:
            case GTX:
                return new Boolean(lhs > rhs);

            case EQ:
                return new Boolean(lhs == rhs);

            case LE:
            case LEX:
                return new Boolean(lhs <= rhs);

            case GE:
            case GEX:
                return new Boolean(lhs >= rhs);

            case NE:
                return new Boolean(lhs != rhs);

            // arithmetic
            case PLUS:
                return new Long(lhs + rhs);

            case MINUS:
                return new Long(lhs - rhs);

            case STAR:
                return new Long(lhs * rhs);

            case SLASH:
                return new Long(lhs / rhs);

            case MOD:
                return new Long(lhs % rhs);

            // bitwise
            case LSHIFT:
            case LSHIFTX:
                return new Long(lhs << rhs);

            case RSIGNEDSHIFT:
            case RSIGNEDSHIFTX:
                return new Long(lhs >> rhs);

            case RUNSIGNEDSHIFT:
            case RUNSIGNEDSHIFTX:
                return new Long(lhs >>> rhs);

            case BIT_AND:
            case BIT_ANDX:
                return new Long(lhs & rhs);

            case BIT_OR:
            case BIT_ORX:
                return new Long(lhs | rhs);

            case XOR:
                return new Long(lhs ^ rhs);

            default:
                throw new InterpreterError(
					"Unimplemented binary long operator");
        }
    }

    // returns Object covering both Integer and Boolean return types
    static Object intBinaryOperation(Integer I1, Integer I2, int kind)
    {
        int lhs = I1.intValue();
        int rhs = I2.intValue();

        switch(kind)
        {
            // boolean
            case LT:
            case LTX:
                return new Boolean(lhs < rhs);

            case GT:
            case GTX:
                return new Boolean(lhs > rhs);

            case EQ:
                return new Boolean(lhs == rhs);

            case LE:
            case LEX:
                return new Boolean(lhs <= rhs);

            case GE:
            case GEX:
                return new Boolean(lhs >= rhs);

            case NE:
                return new Boolean(lhs != rhs);

            // arithmetic
            case PLUS:
                return new Integer(lhs + rhs);

            case MINUS:
                return new Integer(lhs - rhs);

            case STAR:
                return new Integer(lhs * rhs);

            case SLASH:
                return new Integer(lhs / rhs);

            case MOD:
                return new Integer(lhs % rhs);

            // bitwise
            case LSHIFT:
            case LSHIFTX:
                return new Integer(lhs << rhs);

            case RSIGNEDSHIFT:
            case RSIGNEDSHIFTX:
                return new Integer(lhs >> rhs);

            case RUNSIGNEDSHIFT:
            case RUNSIGNEDSHIFTX:
                return new Integer(lhs >>> rhs);

            case BIT_AND:
            case BIT_ANDX:
                return new Integer(lhs & rhs);

            case BIT_OR:
            case BIT_ORX:
                return new Integer(lhs | rhs);

            case XOR:
                return new Integer(lhs ^ rhs);

            default:
                throw new InterpreterError(
					"Unimplemented binary integer operator");
        }
    }

    // returns Object covering both Double and Boolean return types
    static Object doubleBinaryOperation(Double D1, Double D2, int kind)
        throws UtilEvalError
    {
        double lhs = D1.doubleValue();
        double rhs = D2.doubleValue();

        switch(kind)
        {
            // boolean
            case LT:
            case LTX:
                return new Boolean(lhs < rhs);

            case GT:
            case GTX:
                return new Boolean(lhs > rhs);

            case EQ:
                return new Boolean(lhs == rhs);

            case LE:
            case LEX:
                return new Boolean(lhs <= rhs);

            case GE:
            case GEX:
                return new Boolean(lhs >= rhs);

            case NE:
                return new Boolean(lhs != rhs);

            // arithmetic
            case PLUS:
                return new Double(lhs + rhs);

            case MINUS:
                return new Double(lhs - rhs);

            case STAR:
                return new Double(lhs * rhs);

            case SLASH:
                return new Double(lhs / rhs);

            case MOD:
                return new Double(lhs % rhs);

            // can't shift floating-point values
            case LSHIFT:
            case LSHIFTX:
            case RSIGNEDSHIFT:
            case RSIGNEDSHIFTX:
            case RUNSIGNEDSHIFT:
            case RUNSIGNEDSHIFTX:
                throw new UtilEvalError("Can't shift doubles");

            default:
                throw new InterpreterError(
					"Unimplemented binary double operator");
        }
    }
    // returns Object covering both Long and Boolean return types
    static Object floatBinaryOperation(Float F1, Float F2, int kind)
        throws UtilEvalError
    {
        float lhs = F1.floatValue();
        float rhs = F2.floatValue();

        switch(kind)
        {
            // boolean
            case LT:
            case LTX:
                return new Boolean(lhs < rhs);

            case GT:
            case GTX:
                return new Boolean(lhs > rhs);

            case EQ:
                return new Boolean(lhs == rhs);

            case LE:
            case LEX:
                return new Boolean(lhs <= rhs);

            case GE:
            case GEX:
                return new Boolean(lhs >= rhs);

            case NE:
                return new Boolean(lhs != rhs);

            // arithmetic
            case PLUS:
                return new Float(lhs + rhs);

            case MINUS:
                return new Float(lhs - rhs);

            case STAR:
                return new Float(lhs * rhs);

            case SLASH:
                return new Float(lhs / rhs);

            case MOD:
                return new Float(lhs % rhs);

            // can't shift floats
            case LSHIFT:
            case LSHIFTX:
            case RSIGNEDSHIFT:
            case RSIGNEDSHIFTX:
            case RUNSIGNEDSHIFT:
            case RUNSIGNEDSHIFTX:
                throw new UtilEvalError("Can't shift floats ");

            default:
                throw new InterpreterError(
					"Unimplemented binary float operator");
        }
    }

	/**
		Promote primitive wrapper type to to Integer wrapper type
	*/
    static Object promoteToInteger(Object wrapper )
    {
        if(wrapper instanceof Character)
            return new Integer(((Character)wrapper).charValue());
        else if((wrapper instanceof Byte) || (wrapper instanceof Short))
            return new Integer(((Number)wrapper).intValue());

        return wrapper;
    }

	/**
		Promote the pair of primitives to the maximum type of the two.
		e.g. [int,long]->[long,long]
	*/
    static Object[] promotePrimitives(Object lhs, Object rhs)
    {
        lhs = promoteToInteger(lhs);
        rhs = promoteToInteger(rhs);

        if((lhs instanceof Number) && (rhs instanceof Number))
        {
            Number lnum = (Number)lhs;
            Number rnum = (Number)rhs;

            boolean b;

            if((b = (lnum instanceof Double)) || (rnum instanceof Double))
            {
                if(b)
                    rhs = new Double(rnum.doubleValue());
                else
                    lhs = new Double(lnum.doubleValue());
            }
            else if((b = (lnum instanceof Float)) || (rnum instanceof Float))
            {
                if(b)
                    rhs = new Float(rnum.floatValue());
                else
                    lhs = new Float(lnum.floatValue());
            }
            else if((b = (lnum instanceof Long)) || (rnum instanceof Long))
            {
                if(b)
                    rhs = new Long(rnum.longValue());
                else
                    lhs = new Long(lnum.longValue());
            }
        }

        return new Object[] { lhs, rhs };
    }

    public static Primitive unaryOperation(Primitive val, int kind)
        throws UtilEvalError
    {
        if (val == NULL)
            throw new UtilEvalError(
				"illegal use of null object or 'null' literal");
        if (val == VOID)
            throw new UtilEvalError(
				"illegal use of undefined object or 'void' literal");

        Class operandType = val.getType();
        Object operand = promoteToInteger(val.getValue());

        if ( operand instanceof Boolean )
            return new Primitive(booleanUnaryOperation((Boolean)operand, kind));
        else if(operand instanceof Integer)
        {
            int result = intUnaryOperation((Integer)operand, kind);

            // ++ and -- must be cast back the original type
            if(kind == INCR || kind == DECR)
            {
                if(operandType == Byte.TYPE)
                    return new Primitive((byte)result);
                if(operandType == Short.TYPE)
                    return new Primitive((short)result);
                if(operandType == Character.TYPE)
                    return new Primitive((char)result);
            }

            return new Primitive(result);
        }
        else if(operand instanceof Long)
            return new Primitive(longUnaryOperation((Long)operand, kind));
        else if(operand instanceof Float)
            return new Primitive(floatUnaryOperation((Float)operand, kind));
        else if(operand instanceof Double)
            return new Primitive(doubleUnaryOperation((Double)operand, kind));
        else
            throw new InterpreterError(
				"An error occurred.  Please call technical support.");
    }

    static boolean booleanUnaryOperation(Boolean B, int kind)
		throws UtilEvalError
    {
        boolean operand = B.booleanValue();
        switch(kind)
        {
            case BANG:
                return !operand;
            default:
                throw new UtilEvalError("Operator inappropriate for boolean");
        }
    }

    static int intUnaryOperation(Integer I, int kind)
    {
        int operand = I.intValue();

        switch(kind)
        {
            case PLUS:
                return operand;
            case MINUS:
                return -operand;
            case TILDE:
                return ~operand;
            case INCR:
                return operand + 1;
            case DECR:
                return operand - 1;
            default:
                throw new InterpreterError("bad integer unaryOperation");
        }
    }

    static long longUnaryOperation(Long L, int kind)
    {
        long operand = L.longValue();

        switch(kind)
        {
            case PLUS:
                return operand;
            case MINUS:
                return -operand;
            case TILDE:
                return ~operand;
            case INCR:
                return operand + 1;
            case DECR:
                return operand - 1;
            default:
                throw new InterpreterError("bad long unaryOperation");
        }
    }

    static float floatUnaryOperation(Float F, int kind)
    {
        float operand = F.floatValue();

        switch(kind)
        {
            case PLUS:
                return operand;
            case MINUS:
                return -operand;
            default:
                throw new InterpreterError("bad float unaryOperation");
        }
    }

    static double doubleUnaryOperation(Double D, int kind)
    {
        double operand = D.doubleValue();

        switch(kind)
        {
            case PLUS:
                return operand;
            case MINUS:
                return -operand;
            default:
                throw new InterpreterError("bad double unaryOperation");
        }
    }

    public int intValue() throws UtilEvalError
    {
        if(value instanceof Number)
            return((Number)value).intValue();
        else
            throw new UtilEvalError("Primitive not a number");
    }

    public boolean booleanValue() throws UtilEvalError
    {
        if(value instanceof Boolean)
            return((Boolean)value).booleanValue();
        else
            throw new UtilEvalError("Primitive not a boolean");
    }

	/**
		Determine if this primitive is a numeric type.
		i.e. not boolean, null, or void (but including char)
	*/
	public boolean isNumber() {
		return ( !(value instanceof Boolean)
			&& !(this == NULL) && !(this == VOID) );
	}

    public Number numberValue() throws UtilEvalError
    {
		Object value = this.value;

		// Promote character to Number type for these purposes
		if (value instanceof Character)
			value = new Integer(((Character)value).charValue());

        if (value instanceof Number)
            return (Number)value;
        else
            throw new UtilEvalError("Primitive not a number");
    }

	/**
		Primitives compare equal with other Primitives containing an equal
		wrapped value.
	*/
	public boolean equals( Object obj )
	{
		if ( obj instanceof Primitive )
			return ((Primitive)obj).value.equals( this.value );
		else
			return false;
	}

	/**
		The hash of the Primitive is tied to the hash of the wrapped value but
		shifted so that they are not the same.
	*/
	public int hashCode()
	{
		return this.value.hashCode() * 21; // arbitrary
	}

	/**
		Unwrap primitive values and map voids to nulls.
		Non Primitive types remain unchanged.

		@param obj object type which may be bsh.Primitive
		@return corresponding "normal" Java type, "unwrapping"
			any bsh.Primitive types to their wrapper types.
	*/
	public static Object unwrap( Object obj )
	{
        // map voids to nulls for the outside world
        if (obj == Primitive.VOID)
            return null;

        // unwrap primitives
        if (obj instanceof Primitive)
            return((Primitive)obj).getValue();
        else
            return obj;
	}

    /*
        Unwrap Primitive wrappers to their java.lang wrapper values.
		e.g. Primitive(42) becomes Integer(42)
		@see #unwrap( Object )
    */
    public static Object [] unwrap( Object[] args )
    {
		Object [] oa = new Object[ args.length ];
        for(int i=0; i<args.length; i++)
            oa[i] = unwrap( args[i] );
		return oa;
    }

    /*
    */
    public static Object [] wrap( Object[] args, Class [] paramTypes )
    {
		if ( args == null )
			return null;

		Object [] oa = new Object[ args.length ];
        for(int i=0; i<args.length; i++)
            oa[i] = wrap( args[i], paramTypes[i] );
		return oa;
    }

	/**
		Wrap primitive values (as indicated by type param) and nulls in the
		Primitive class.  Values not primitive or null are left unchanged.
		Primitive values are represented by their wrapped values in param value.
		<p/>
		The value null is mapped to Primitive.NULL.
		Any value specified with type Void.TYPE is mapped to Primitive.VOID.
	*/
    public static Object wrap(
		Object value, Class type )
    {
        if ( type == Void.TYPE )
            return Primitive.VOID;

        if ( value == null )
            return Primitive.NULL;

		if ( type.isPrimitive() )
			return new Primitive( value );

		return value;
    }

	/**
		Get the appropriate default value per JLS 4.5.4
	*/
	public static Primitive getDefaultValue( Class type )
	{
		if ( type == null || !type.isPrimitive() )
			return Primitive.NULL;
		if ( type == Boolean.TYPE )
			return new Primitive( false );

		// non boolean primitive, get appropriate flavor of zero
		try {
			return new Primitive((int)0).castToType( type, Types.CAST );
		} catch ( UtilEvalError e ) {
			throw new InterpreterError( "bad cast" );
		}
	}

	/**
		Get the corresponding java.lang wrapper class for the primitive TYPE
		class.
		e.g.  Integer.TYPE -> Integer.class
	*/
	public static Class boxType( Class primitiveType )
	{
		Class c = (Class)wrapperMap.get( primitiveType );
		if ( c != null )
			return c;
		throw new InterpreterError(
			"Not a primitive type: "+ primitiveType );
	}

	/**
		Get the corresponding primitive TYPE class for the java.lang wrapper
		class type.
		e.g.  Integer.class -> Integer.TYPE
	*/
	public static Class unboxType( Class wrapperType )
	{
		Class c = (Class)wrapperMap.get( wrapperType );
		if ( c != null )
			return c;
		throw new InterpreterError(
			"Not a primitive wrapper type: "+wrapperType );
	}

	/**
		Cast this bsh.Primitive value to a new bsh.Primitive value
		This is usually a numeric type cast.  Other cases include:
			A boolean can be cast to boolen
			null can be cast to any object type and remains null
			Attempting to cast a void causes an exception
		@param toType is the java object or primitive TYPE class
	*/
	public Primitive castToType( Class toType, int operation )
		throws UtilEvalError
	{
		return castPrimitive(
			toType, getType()/*fromType*/, this/*fromValue*/,
			false/*checkOnly*/, operation );
	}

	/*
		Cast or check a cast of a primitive type to another type.
		Normally both types are primitive (e.g. numeric), but a null value
		(no type) may be cast to any type.
		<p/>

		@param toType is the target type of the cast.  It is normally a
		java primitive TYPE, but in the case of a null cast can be any object
		type.

		@param fromType is the java primitive TYPE type of the primitive to be
		cast or null, to indicate that the fromValue was null or void.

		@param fromValue is, optionally, the value to be converted.  If
		checkOnly is true fromValue must be null.  If checkOnly is false,
		fromValue must be non-null (Primitive.NULL is of course valid).
	*/
	static Primitive castPrimitive(
		Class toType, Class fromType, Primitive fromValue,
		boolean checkOnly, int operation )
		throws UtilEvalError
	{
		/*
			Lots of preconditions checked here...
			Once things are running smoothly we might comment these out
			(That's what assertions are for).
		*/
		if ( checkOnly && fromValue != null )
			throw new InterpreterError("bad cast param 1");
		if ( !checkOnly && fromValue == null )
			throw new InterpreterError("bad cast param 2");
		if ( fromType != null && !fromType.isPrimitive() )
			throw new InterpreterError("bad fromType:" +fromType);
		if ( fromValue == Primitive.NULL && fromType != null )
			throw new InterpreterError("inconsistent args 1");
		if ( fromValue == Primitive.VOID && fromType != Void.TYPE )
			throw new InterpreterError("inconsistent args 2");

		// can't cast void to anything
		if ( fromType == Void.TYPE )
			if ( checkOnly )
				return Types.INVALID_CAST;
			else
				throw Types.castError( Reflect.normalizeClassName(toType),
					"void value", operation );

		// unwrap Primitive fromValue to its wrapper value, etc.
		Object value = null;
		if ( fromValue != null )
			value = fromValue.getValue();

		if ( toType.isPrimitive() )
		{
			// Trying to cast null to primitive type?
			if ( fromType == null )
				if ( checkOnly )
					return Types.INVALID_CAST;
				else
					throw Types.castError(
						"primitive type:" + toType, "Null value", operation );

			// fall through
		} else
		{
			// Trying to cast primitive to an object type
			// Primitive.NULL can be cast to any object type
			if ( fromType == null )
				return checkOnly ? Types.VALID_CAST :
					Primitive.NULL;

			if ( checkOnly )
				return Types.INVALID_CAST;
			else
				throw Types.castError(
						"object type:" + toType, "primitive value", operation);
		}

		// can only cast boolean to boolean
		if ( fromType == Boolean.TYPE )
		{
			if ( toType != Boolean.TYPE )
				if ( checkOnly )
					return Types.INVALID_CAST;
				else
					throw Types.castError( toType, fromType, operation );

			return checkOnly ? Types.VALID_CAST :
				fromValue;
		}

		// Do numeric cast

		// Only allow legal Java assignment unless we're a CAST operation
		if ( operation == Types.ASSIGNMENT
			&& !Types.isJavaAssignable( toType, fromType )
		) {
			if ( checkOnly )
				return Types.INVALID_CAST;
			else
				throw Types.castError( toType, fromType, operation );
		}

		return checkOnly ? Types.VALID_CAST :
			new Primitive( castWrapper(toType, value) );
	}

	public static boolean isWrapperType( Class type )
	{
		return wrapperMap.get( type ) != null && !type.isPrimitive();
	}

	/**
		Cast a primitive value represented by its java.lang wrapper type to the
		specified java.lang wrapper type.  e.g.  Byte(5) to Integer(5) or
		Integer(5) to Byte(5)
		@param toType is the java TYPE type
		@param value is the value in java.lang wrapper.
		value may not be null.
	*/
	static Object castWrapper(
		Class toType, Object value )
	{
		if ( !toType.isPrimitive() )
			throw new InterpreterError("invalid type in castWrapper: "+toType);
		if ( value == null )
			throw new InterpreterError("null value in castWrapper, guard");
		if ( value instanceof Boolean )
		{
			if ( toType != Boolean.TYPE )
				throw new InterpreterError("bad wrapper cast of boolean");
			else
				return value;
		}

		// first promote char to Number type to avoid duplicating code
		if ( value instanceof Character )
			value = new Integer(((Character)value).charValue());

		if ( !(value instanceof Number) )
			throw new InterpreterError("bad type in cast");

		Number number = (Number)value;

		if (toType == Byte.TYPE)
			return new Byte(number.byteValue());
		if (toType == Short.TYPE)
			return new Short(number.shortValue());
		if (toType == Character.TYPE)
			return new Character((char)number.intValue());
		if (toType == Integer.TYPE)
			return new Integer(number.intValue());
		if (toType == Long.TYPE)
			return new Long(number.longValue());
		if (toType == Float.TYPE)
			return new Float(number.floatValue());
		if (toType == Double.TYPE)
			return new Double(number.doubleValue());

		throw new InterpreterError("error in wrapper cast");

FUNC_DECL IF PARAM PARAM PARAM IF RETURN BINARY_OP IF RETURN BINARY_OP CALL IF RETURN BINARY_OP CALL IF RETURN BINARY_OP CALL THROW_RAISE RETURN BINARY_OP CALL CALL CALL LITERAL_ANCHOR

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

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

FUNC_DECL RETURN PARAM PARAM CALL LITERAL_ANCHOR CALL


org.apache.xpath.objects.XStringForFSB

public class XStringForFSB extends XString
{

  /** The start position in the fsb. */
  int m_start;

  /** The length of the string. */
  int m_length;

  /** If the str() function is called, the string will be cached here. */
  protected String m_strCache = null;

  /** cached hash code */
  protected int m_hash = 0;

  /**
   * Construct a XNodeSet object.
   *
   * @param val FastStringBuffer object this will wrap, must be non-null.
   * @param start The start position in the array.
   * @param length The number of characters to read from the array.
   */
  public XStringForFSB(FastStringBuffer val, int start, int length)
  {

    super(val);

    m_start = start;
    m_length = length;

    if (null == val)
      throw new IllegalArgumentException(
        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_FASTSTRINGBUFFER_CANNOT_BE_NULL, null));
  }

  /**
   * Construct a XNodeSet object.
   *
   * @param val String object this will wrap.
   */
  private XStringForFSB(String val)
  {

    super(val);

    throw new IllegalArgumentException();
  }

  /**
   * Cast result object to a string.
   *
   * @return The string this wraps or the empty string if null
   */
  public FastStringBuffer fsb()
  {
    return ((FastStringBuffer) m_obj);
  }

  /**
   * Cast result object to a string.
   *
   * @return The string this wraps or the empty string if null
   */
  public void appendToFsb(org.apache.xml.utils.FastStringBuffer fsb)
  {
    fsb.append(str());
  }

  /**
   * Tell if this object contains a java String object.
   *
   * @return true if this XMLString can return a string without creating one.
   */
  public boolean hasString()
  {
    return (null != m_strCache);
  }

  /**
   * Since this object is incomplete without the length and the offset, we
   * have to convert to a string when this function is called.
   *
   * @return The java String representation of this object.
   */
  public Object object()
  {
    return str();
  }

  /**
   * Cast result object to a string.
   *
   * @return The string this wraps or the empty string if null
   */
  public String str()
  {

    if (null == m_strCache)
    {
      m_strCache = fsb().getString(m_start, m_length);

    }

    return m_strCache;
  }

  /**
   * Directly call the
   * characters method on the passed ContentHandler for the
   * string-value. Multiple calls to the
   * ContentHandler's characters methods may well occur for a single call to
   * this method.
   *
   * @param ch A non-null reference to a ContentHandler.
   *
   * @throws org.xml.sax.SAXException
   */
  public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
          throws org.xml.sax.SAXException
  {
    fsb().sendSAXcharacters(ch, m_start, m_length);
  }

  /**
   * Directly call the
   * comment method on the passed LexicalHandler for the
   * string-value.
   *
   * @param lh A non-null reference to a LexicalHandler.
   *
   * @throws org.xml.sax.SAXException
   */
  public void dispatchAsComment(org.xml.sax.ext.LexicalHandler lh)
          throws org.xml.sax.SAXException
  {
    fsb().sendSAXComment(lh, m_start, m_length);
  }

  /**
   * Returns the length of this string.
   *
   * @return  the length of the sequence of characters represented by this
   *          object.
   */
  public int length()
  {
    return m_length;
  }

  /**
   * Returns the character at the specified index. An index ranges
   * from 0 to length() - 1. The first character
   * of the sequence is at index 0, the next at index
   * 1, and so on, as for array indexing.
   *
   * @param      index   the index of the character.
   * @return     the character at the specified index of this string.
   *             The first character is at index 0.
   * @exception  IndexOutOfBoundsException  if the index
   *             argument is negative or not less than the length of this
   *             string.
   */
  public char charAt(int index)
  {
    return fsb().charAt(m_start + index);
  }

  /**
   * Copies characters from this string into the destination character
   * array.
   *
   * @param      srcBegin   index of the first character in the string
   *                        to copy.
   * @param      srcEnd     index after the last character in the string
   *                        to copy.
   * @param      dst        the destination array.
   * @param      dstBegin   the start offset in the destination array.
   * @exception IndexOutOfBoundsException If any of the following
   *            is true:
   *

srcBegin is negative.
   *
srcBegin is greater than srcEnd
   *
srcEnd is greater than the length of this
   *                string
   *
dstBegin is negative
   *
dstBegin+(srcEnd-srcBegin) is larger than
   *                dst.length

   * @exception NullPointerException if dst is null
   */
  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
  {

    int n = srcEnd - srcBegin;

    if (n > m_length)
      n = m_length;

    if (n > (dst.length - dstBegin))
      n = (dst.length - dstBegin);

    int end = srcBegin + m_start + n;
    int d = dstBegin;
    FastStringBuffer fsb = fsb();

    for (int i = srcBegin + m_start; i < end; i++)
    {
      dst[d++] = fsb.charAt(i);
    }
  }

  /**
   * Compares this string to the specified object.
   * The result is true if and only if the argument is not
   * null and is a String object that represents
   * the same sequence of characters as this object.
   *
   * @param   anObject   the object to compare this String
   *                     against.
   *
   * NEEDSDOC @param obj2
   * @return  true if the String are equal;
   *          false otherwise.
   * @see     java.lang.String#compareTo(java.lang.String)
   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
   */
  public boolean equals(XMLString obj2)
  {

    if (this == obj2)
    {
      return true;
    }

    int n = m_length;

    if (n == obj2.length())
    {
      FastStringBuffer fsb = fsb();
      int i = m_start;
      int j = 0;

      while (n-- != 0)
      {
        if (fsb.charAt(i) != obj2.charAt(j))
        {
          return false;
        }

        i++;
        j++;
      }

      return true;
    }

    return false;
  }

  /**
   * Tell if two objects are functionally equal.
   *
   * @param obj2 Object to compare this to
   *
   * @return true if the two objects are equal
   *
   * @throws javax.xml.transform.TransformerException
   */
  public boolean equals(XObject obj2)
  {

    if (this == obj2)
    {
      return true;
    }
    if(obj2.getType() == XObject.CLASS_NUMBER)
    	return obj2.equals(this);

    String str = obj2.str();
    int n = m_length;

    if (n == str.length())
    {
      FastStringBuffer fsb = fsb();
      int i = m_start;
      int j = 0;

      while (n-- != 0)
      {
        if (fsb.charAt(i) != str.charAt(j))
        {
          return false;
        }

        i++;
        j++;
      }

      return true;
    }

    return false;
  }

  /**
   * Tell if two objects are functionally equal.
   *
   * @param obj2 Object to compare this to
   *
   * NEEDSDOC @param anotherString
   *
   * @return true if the two objects are equal
   *
   * @throws javax.xml.transform.TransformerException
   */
  public boolean equals(String anotherString)
  {

    int n = m_length;

    if (n == anotherString.length())
    {
      FastStringBuffer fsb = fsb();
      int i = m_start;
      int j = 0;

      while (n-- != 0)
      {
        if (fsb.charAt(i) != anotherString.charAt(j))
        {
          return false;
        }

        i++;
        j++;
      }

      return true;
    }

    return false;
  }

  /**
   * Compares this string to the specified object.
   * The result is true if and only if the argument is not
   * null and is a String object that represents
   * the same sequence of characters as this object.
   *
   * @param   anObject   the object to compare this String
   *                     against.
   *
   * NEEDSDOC @param obj2
   * @return  true if the String are equal;
   *          false otherwise.
   * @see     java.lang.String#compareTo(java.lang.String)
   * @see     java.lang.String#equalsIgnoreCase(java.lang.String)
   */
  public boolean equals(Object obj2)
  {

    if (null == obj2)
      return false;

    if(obj2 instanceof XNumber)
    	return obj2.equals(this);

    else if (obj2 instanceof XNodeSet)
      return obj2.equals(this);
    else if (obj2 instanceof XStringForFSB)
      return equals((XMLString) this);
    else
      return equals(obj2.toString());
  }

  /**
   * Compares this String to another String,
   * ignoring case considerations.  Two strings are considered equal
   * ignoring case if they are of the same length, and corresponding
   * characters in the two strings are equal ignoring case.
   *
   * @param   anotherString   the String to compare this
   *                          String against.
   * @return  true if the argument is not null
   *          and the Strings are equal,
   *          ignoring case; false otherwise.
   * @see     #equals(Object)
   * @see     java.lang.Character#toLowerCase(char)
   * @see java.lang.Character#toUpperCase(char)
   */
  public boolean equalsIgnoreCase(String anotherString)
  {
    return (m_length == anotherString.length())
           ? str().equalsIgnoreCase(anotherString) : false;
  }

  /**
   * Compares two strings lexicographically.
   *
   * @param   anotherString   the String to be compared.
   *
   * NEEDSDOC @param xstr
   * @return  the value 0 if the argument string is equal to
   *          this string; a value less than 0 if this string
   *          is lexicographically less than the string argument; and a
   *          value greater than 0 if this string is
   *          lexicographically greater than the string argument.
   * @exception java.lang.NullPointerException if anotherString
   *          is null.
   */
  public int compareTo(XMLString xstr)
  {

    int len1 = m_length;
    int len2 = xstr.length();
    int n = Math.min(len1, len2);
    FastStringBuffer fsb = fsb();
    int i = m_start;
    int j = 0;

    while (n-- != 0)
    {
      char c1 = fsb.charAt(i);
      char c2 = xstr.charAt(j);

      if (c1 != c2)
      {
        return c1 - c2;
      }

      i++;
      j++;
    }

    return len1 - len2;
  }

  /**
   * Compares two strings lexicographically, ignoring case considerations.
   * This method returns an integer whose sign is that of
   * this.toUpperCase().toLowerCase().compareTo(
   * str.toUpperCase().toLowerCase()).
   *

   * Note that this method does not take locale into account,
   * and will result in an unsatisfactory ordering for certain locales.
   * The java.text package provides collators to allow
   * locale-sensitive ordering.
   *
   * @param   str   the String to be compared.
   *
   * NEEDSDOC @param xstr
   * @return  a negative integer, zero, or a positive integer as the
   *          the specified String is greater than, equal to, or less
   *          than this String, ignoring case considerations.
   * @see     java.text.Collator#compare(String, String)
   * @since   1.2
   */
  public int compareToIgnoreCase(XMLString xstr)
  {

    int len1 = m_length;
    int len2 = xstr.length();
    int n = Math.min(len1, len2);
    FastStringBuffer fsb = fsb();
    int i = m_start;
    int j = 0;

    while (n-- != 0)
    {
      char c1 = Character.toLowerCase(fsb.charAt(i));
      char c2 = Character.toLowerCase(xstr.charAt(j));

      if (c1 != c2)
      {
        return c1 - c2;
      }

      i++;
      j++;
    }

    return len1 - len2;
  }

  /**
   * Returns a hashcode for this string. The hashcode for a
   * String object is computed as
   *

   * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
   *

   * using int arithmetic, where s[i] is the
   * ith character of the string, n is the length of
   * the string, and ^ indicates exponentiation.
   * (The hash value of the empty string is zero.)
   *
   * @return  a hash code value for this object.
   */
  public int hashCode()
  {

/*
    int h = m_hash;

    if (h == 0)
    {
      int off = m_start;
      int len = m_length;
      FastStringBuffer fsb = fsb();

      for (int i = 0; i < len; i++)
      {
        h = 31 * h + fsb.charAt(off);

        off++;
      }

      m_hash = h;
    }
    */

  }

  /**
   * Tests if this string starts with the specified prefix beginning
   * a specified index.
   *
   * @param   prefix    the prefix.
   * @param   toffset   where to begin looking in the string.
   * @return  true if the character sequence represented by the
   *          argument is a prefix of the substring of this object starting
   *          at index toffset; false otherwise.
   *          The result is false if toffset is
   *          negative or greater than the length of this
   *          String object; otherwise the result is the same
   *          as the result of the expression
   *

   *          this.subString(toffset).startsWith(prefix)
   *

   * @exception java.lang.NullPointerException if prefix is
   *          null.
   */
  public boolean startsWith(XMLString prefix, int toffset)
  {

    FastStringBuffer fsb = fsb();
    int to = m_start + toffset;
    int tlim = m_start + m_length;
    int po = 0;
    int pc = prefix.length();

    if ((toffset < 0) || (toffset > m_length - pc))
    {
      return false;
    }

    while (--pc >= 0)
    {
      if (fsb.charAt(to) != prefix.charAt(po))
      {
        return false;
      }

      to++;
      po++;
    }

    return true;
  }

  /**
   * Tests if this string starts with the specified prefix.
   *
   * @param   prefix   the prefix.
   * @return  true if the character sequence represented by the
   *          argument is a prefix of the character sequence represented by
   *          this string; false otherwise.
   *          Note also that true will be returned if the
   *          argument is an empty string or is equal to this
   *          String object as determined by the
   *          {@link #equals(Object)} method.
   * @exception java.lang.NullPointerException if prefix is
   *          null.
   * @since   JDK1. 0
   */
  public boolean startsWith(XMLString prefix)
  {
    return startsWith(prefix, 0);
  }

  /**
   * Returns the index within this string of the first occurrence of the
   * specified character. If a character with value ch occurs
   * in the character sequence represented by this String
   * object, then the index of the first such occurrence is returned --
   * that is, the smallest value k such that:
   *

   * this.charAt(k) == ch
   *

   * is true. If no such character occurs in this string,
   * then -1 is returned.
   *
   * @param   ch   a character.
   * @return  the index of the first occurrence of the character in the
   *          character sequence represented by this object, or
   *          -1 if the character does not occur.
   */
  public int indexOf(int ch)
  {
    return indexOf(ch, 0);
  }

  /**
   * Returns the index within this string of the first occurrence of the
   * specified character, starting the search at the specified index.
   *

   * If a character with value ch occurs in the character
   * sequence represented by this String object at an index
   * no smaller than fromIndex, then the index of the first
   * such occurrence is returned--that is, the smallest value k
   * such that:
   *

   * (this.charAt(k) == ch) && (k >= fromIndex)
   *

   * is true. If no such character occurs in this string at or after
   * position fromIndex, then -1 is returned.
   *

   * There is no restriction on the value of fromIndex. If it
   * is negative, it has the same effect as if it were zero: this entire
   * string may be searched. If it is greater than the length of this
   * string, it has the same effect as if it were equal to the length of
   * this string: -1 is returned.
   *
   * @param   ch          a character.
   * @param   fromIndex   the index to start the search from.
   * @return  the index of the first occurrence of the character in the
   *          character sequence represented by this object that is greater
   *          than or equal to fromIndex, or -1
   *          if the character does not occur.
   */
  public int indexOf(int ch, int fromIndex)
  {

    int max = m_start + m_length;
    FastStringBuffer fsb = fsb();

    if (fromIndex < 0)
    {
      fromIndex = 0;
    }
    else if (fromIndex >= m_length)
    {

      return -1;
    }

    for (int i = m_start + fromIndex; i < max; i++)
    {
      if (fsb.charAt(i) == ch)
      {
        return i - m_start;
      }
    }

    return -1;
  }

  /**
   * Returns a new string that is a substring of this string. The
   * substring begins with the character at the specified index and
   * extends to the end of this string.

   * Examples:
   *

   * "unhappy".substring(2) returns "happy"
   * "Harbison".substring(3) returns "bison"
   * "emptiness".substring(9) returns "" (an empty string)
   *

   *
   * @param      beginIndex   the beginning index, inclusive.
   * @return     the specified substring.
   * @exception  IndexOutOfBoundsException  if
   *             beginIndex is negative or larger than the
   *             length of this String object.
   */
  public XMLString substring(int beginIndex)
  {

    int len = m_length - beginIndex;

    if (len <= 0)
      return XString.EMPTYSTRING;
    else
    {
      int start = m_start + beginIndex;

      return new XStringForFSB(fsb(), start, len);
    }
  }

  /**
   * Returns a new string that is a substring of this string. The
   * substring begins at the specified beginIndex and
   * extends to the character at index endIndex - 1.
   * Thus the length of the substring is endIndex-beginIndex.
   *
   * @param      beginIndex   the beginning index, inclusive.
   * @param      endIndex     the ending index, exclusive.
   * @return     the specified substring.
   * @exception  IndexOutOfBoundsException  if the
   *             beginIndex is negative, or
   *             endIndex is larger than the length of
   *             this String object, or
   *             beginIndex is larger than
   *             endIndex.
   */
  public XMLString substring(int beginIndex, int endIndex)
  {

    int len = endIndex - beginIndex;

    if (len > m_length)
      len = m_length;

    if (len <= 0)
      return XString.EMPTYSTRING;
    else
    {
      int start = m_start + beginIndex;

      return new XStringForFSB(fsb(), start, len);
    }
  }

  /**
   * Concatenates the specified string to the end of this string.
   *
   * @param   str   the String that is concatenated to the end
   *                of this String.
   * @return  a string that represents the concatenation of this object's
   *          characters followed by the string argument's characters.
   * @exception java.lang.NullPointerException if str is
   *          null.
   */
  public XMLString concat(String str)
  {

    return new XString(str().concat(str));
  }

  /**
   * Removes white space from both ends of this string.
   *
   * @return  this string, with white space removed from the front and end.
   */
  public XMLString trim()
  {
    return fixWhiteSpace(true, true, false);
  }

  /**
   * Returns whether the specified <var>ch</var> conforms to the XML 1.0 definition
   * the definition of S for details.
   * @param   ch      Character to check as XML whitespace.
   * @return          =true if <var>ch</var> is XML whitespace; otherwise =false.
   */
  private static boolean isSpace(char ch)
  {
  }

  /**
   * Conditionally trim all leading and trailing whitespace in the specified String.
   * All strings of white space are
   * replaced by a single space character (#x20), except spaces after punctuation which
   * receive double spaces if doublePunctuationSpaces is true.
   * This function may be useful to a formatter, but to get first class
   * results, the formatter should probably do it's own white space handling
   * based on the semantics of the formatting object.
   *
   * @param   trimHead    Trim leading whitespace?
   * @param   trimTail    Trim trailing whitespace?
   * @param   doublePunctuationSpaces    Use double spaces for punctuation?
   * @return              The trimmed string.
   */
  public XMLString fixWhiteSpace(boolean trimHead, boolean trimTail,
                                 boolean doublePunctuationSpaces)
  {

    int end = m_length + m_start;
    char[] buf = new char[m_length];
    FastStringBuffer fsb = fsb();
    boolean edit = false;

    /* replace S to ' '. and ' '+ -> single ' '. */
    int d = 0;
    boolean pres = false;

    for (int s = m_start; s < end; s++)
    {
      char c = fsb.charAt(s);

      if (isSpace(c))
      {
        if (!pres)
        {
          if (' ' != c)
          {
            edit = true;
          }

          buf[d++] = ' ';

          if (doublePunctuationSpaces && (d != 0))
          {
            char prevChar = buf[d - 1];

            if (!((prevChar == '.') || (prevChar == '!')
                  || (prevChar == '?')))
            {
              pres = true;
            }
          }
          else
          {
            pres = true;
          }
        }
        else
        {
          edit = true;
          pres = true;
        }
      }
      else
      {
        buf[d++] = c;
        pres = false;
      }
    }

    if (trimTail && 1 <= d && ' ' == buf[d - 1])
    {
      edit = true;

      d--;
    }

    int start = 0;

    if (trimHead && 0 < d && ' ' == buf[0])
    {
      edit = true;

      start++;
    }

    XMLStringFactory xsf = XMLStringFactoryImpl.getFactory();

    return edit ? xsf.newstr(buf, start, d - start) : this;
  }

  /**
   * Convert a string to a double -- Allowed input is in fixed
   * notation ddd.fff.
   *
   * %OPT% CHECK PERFORMANCE against generating a Java String and
   * converting it to double. The advantage of running in native
   * machine code -- perhaps even microcode, on some systems -- may
   * more than make up for the cost of allocating and discarding the
   * additional object. We need to benchmark this.
   *
   * %OPT% More importantly, we need to decide whether we _care_ about
   * the performance of this operation. Does XString.toDouble constitute
   * any measurable percentage of our typical runtime? I suspect not!
   *
   * @return A double value representation of the string, or return Double.NaN
   * if the string can not be converted.  */
  public double toDouble()
  {
    if(m_length == 0)
      return Double.NaN;
    int i;
    char c;
    String valueString = fsb().getString(m_start,m_length);

    for (i=0;i<m_length;i++)
      if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
        break;
    if (valueString.charAt(i) == '-')
      i++;
    for (;i<m_length;i++) {
      c = valueString.charAt(i);
      if (c != '.' && (c < '0' || c > '9'))
        break;
    }
    for (;i<m_length;i++)
      if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
        break;
    if (i != m_length)
      return Double.NaN;

    try {
      return new Double(valueString).doubleValue();
    } catch (NumberFormatException nfe) {
      return Double.NaN;

  public Object object()
  {
    return str();

  public int length()
  {
    return m_length;

FUNC_DECL RETURN PARAM CALL CALL BINARY_OP

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


public class DOM2SAX implements XMLReader, Locator {

    private final static String EMPTYSTRING = "";
    private static final String XMLNS_PREFIX = "xmlns";

    private Node _dom = null;
    private ContentHandler _sax = null;
    private LexicalHandler _lex = null;
    private SAXImpl _saxImpl = null;
    private Hashtable _nsPrefixes = new Hashtable();

    public DOM2SAX(Node root) {
	_dom = root;
    }

    public ContentHandler getContentHandler() {
	return _sax;
    }

    public void setContentHandler(ContentHandler handler) throws
	NullPointerException
    {
	_sax = handler;
	if (handler instanceof LexicalHandler) {
	    _lex = (LexicalHandler) handler;
	}

	if (handler instanceof SAXImpl) {
	    _saxImpl = (SAXImpl)handler;
	}
    }

    /**
     * Begin the scope of namespace prefix. Forward the event to the
     * SAX handler only if the prefix is unknown or it is mapped to a
     * different URI.
     */
    private boolean startPrefixMapping(String prefix, String uri)
	throws SAXException
    {
	boolean pushed = true;
	Stack uriStack = (Stack) _nsPrefixes.get(prefix);

	if (uriStack != null) {
	    if (uriStack.isEmpty()) {
		_sax.startPrefixMapping(prefix, uri);
		uriStack.push(uri);
	    }
	    else {
		final String lastUri = (String) uriStack.peek();
		if (!lastUri.equals(uri)) {
		    _sax.startPrefixMapping(prefix, uri);
		    uriStack.push(uri);
		}
		else {
		    pushed = false;
		}
	    }
	}
	else {
	    _sax.startPrefixMapping(prefix, uri);
	    _nsPrefixes.put(prefix, uriStack = new Stack());
	    uriStack.push(uri);
	}
	return pushed;
    }

    /*
     * End the scope of a name prefix by popping it from the stack and
     * passing the event to the SAX Handler.
     */
    private void endPrefixMapping(String prefix)
	throws SAXException
    {
	final Stack uriStack = (Stack) _nsPrefixes.get(prefix);

	if (uriStack != null) {
	    _sax.endPrefixMapping(prefix);
	    uriStack.pop();
	}
    }

    /**
     * If the DOM was created using a DOM 1.0 API, the local name may be
     * null. If so, get the local name from the qualified name before
     * generating the SAX event.
     */
    private static String getLocalName(Node node) {
	final String localName = node.getLocalName();

	if (localName == null) {
	    final String qname = node.getNodeName();
	    final int col = qname.lastIndexOf(':');
	    return (col > 0) ? qname.substring(col + 1) : qname;
	}
	return localName;
    }

    public void parse(InputSource unused) throws IOException, SAXException {
        parse(_dom);
    }

    public void parse() throws IOException, SAXException {
	if (_dom != null) {
	    boolean isIncomplete =
		(_dom.getNodeType() != org.w3c.dom.Node.DOCUMENT_NODE);

	    if (isIncomplete) {
		_sax.startDocument();
		parse(_dom);
		_sax.endDocument();
	    }
	    else {
		parse(_dom);
	    }
	}
    }

    /**
     * Traverse the DOM and generate SAX events for a handler. A
     * startElement() event passes all attributes, including namespace
     * declarations.
     */
    private void parse(Node node) throws IOException, SAXException {
        Node first = null;
 	if (node == null) return;

        switch (node.getNodeType()) {
	case Node.DOCUMENT_FRAGMENT_NODE:
	case Node.DOCUMENT_TYPE_NODE :
	case Node.ENTITY_NODE :
	case Node.ENTITY_REFERENCE_NODE:
	case Node.NOTATION_NODE :
	    break;
	case Node.CDATA_SECTION_NODE:
	    final String cdata = node.getNodeValue();
	    if (_lex != null) {
		_lex.startCDATA();
	        _sax.characters(cdata.toCharArray(), 0, cdata.length());
		_lex.endCDATA();
 	    }
	    else {
	        _sax.characters(cdata.toCharArray(), 0, cdata.length());
	    }
	    break;

	    if (_lex != null) {
		final String value = node.getNodeValue();
		_lex.comment(value.toCharArray(), 0, value.length());
	    }
	    break;
	case Node.DOCUMENT_NODE:
	    _sax.setDocumentLocator(this);

	    _sax.startDocument();
	    Node next = node.getFirstChild();
	    while (next != null) {
		parse(next);
		next = next.getNextSibling();
	    }
	    _sax.endDocument();
	    break;

	case Node.ELEMENT_NODE:
	    String prefix;
	    Vector pushedPrefixes = new Vector();
	    final AttributesImpl attrs = new AttributesImpl();
	    final NamedNodeMap map = node.getAttributes();
	    final int length = map.getLength();

	    for (int i = 0; i < length; i++) {
		final Node attr = map.item(i);
		final String qnameAttr = attr.getNodeName();

		if (qnameAttr.startsWith(XMLNS_PREFIX)) {
		    final String uriAttr = attr.getNodeValue();
		    final int colon = qnameAttr.lastIndexOf(':');
		    prefix = (colon > 0) ? qnameAttr.substring(colon + 1) : EMPTYSTRING;
		    if (startPrefixMapping(prefix, uriAttr)) {
			pushedPrefixes.addElement(prefix);
		    }
		}
	    }

	    for (int i = 0; i < length; i++) {
		final Node attr = map.item(i);
		final String qnameAttr = attr.getNodeName();

		if (!qnameAttr.startsWith(XMLNS_PREFIX)) {
		    final String uriAttr = attr.getNamespaceURI();
		    final String localNameAttr = getLocalName(attr);

		    if (uriAttr != null) {
			final int colon = qnameAttr.lastIndexOf(':');
			prefix = (colon > 0) ? qnameAttr.substring(0, colon) : EMPTYSTRING;
			if (startPrefixMapping(prefix, uriAttr)) {
			    pushedPrefixes.addElement(prefix);
			}
		    }

		    attrs.addAttribute(attr.getNamespaceURI(), getLocalName(attr),
			qnameAttr, "CDATA", attr.getNodeValue());
		}
	    }

	    final String qname = node.getNodeName();
	    final String uri = node.getNamespaceURI();
	    final String localName = getLocalName(node);

	    if (uri != null) {
		final int colon = qname.lastIndexOf(':');
		prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING;
		if (startPrefixMapping(prefix, uri)) {
		    pushedPrefixes.addElement(prefix);
		}
	    }

	    if (_saxImpl != null) {
	        _saxImpl.startElement(uri, localName, qname, attrs, node);
	    }
	    else {
	        _sax.startElement(uri, localName, qname, attrs);
	    }

	    next = node.getFirstChild();
	    while (next != null) {
		parse(next);
		next = next.getNextSibling();
	    }

	    _sax.endElement(uri, localName, qname);

	    final int nPushedPrefixes = pushedPrefixes.size();
	    for (int i = 0; i < nPushedPrefixes; i++) {
		endPrefixMapping((String) pushedPrefixes.elementAt(i));
	    }
	    break;

	case Node.PROCESSING_INSTRUCTION_NODE:
	    _sax.processingInstruction(node.getNodeName(),
				       node.getNodeValue());
	    break;

	case Node.TEXT_NODE:
	    final String data = node.getNodeValue();
	    _sax.characters(data.toCharArray(), 0, data.length());
	    break;
	}
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public DTDHandler getDTDHandler() {
	return null;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public ErrorHandler getErrorHandler() {
	return null;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public boolean getFeature(String name) throws SAXNotRecognizedException,
	SAXNotSupportedException
    {
	return false;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public void setFeature(String name, boolean value) throws
	SAXNotRecognizedException, SAXNotSupportedException
    {
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public void parse(String sysId) throws IOException, SAXException {
	throw new IOException("This method is not yet implemented.");
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public void setDTDHandler(DTDHandler handler) throws NullPointerException {
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public void setEntityResolver(EntityResolver resolver) throws
	NullPointerException
    {
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public EntityResolver getEntityResolver() {
	return null;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public void setErrorHandler(ErrorHandler handler) throws
	NullPointerException
    {
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public void setProperty(String name, Object value) throws
	SAXNotRecognizedException, SAXNotSupportedException {
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public Object getProperty(String name) throws SAXNotRecognizedException,
	SAXNotSupportedException
    {
	return null;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public int getColumnNumber() {
	return 0;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public int getLineNumber() {
	return 0;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public String getPublicId() {
	return null;
    }

    /**
     * This class is only used internally so this method should never
     * be called.
     */
    public String getSystemId() {
	return null;
    }

    private String getNodeTypeFromCode(short code) {
	String retval = null;
	switch (code) {
	case Node.ATTRIBUTE_NODE :
	    retval = "ATTRIBUTE_NODE"; break;
	case Node.CDATA_SECTION_NODE :
	    retval = "CDATA_SECTION_NODE"; break;
	case Node.COMMENT_NODE :
	    retval = "COMMENT_NODE"; break;
	case Node.DOCUMENT_FRAGMENT_NODE :
	    retval = "DOCUMENT_FRAGMENT_NODE"; break;
	case Node.DOCUMENT_NODE :
	    retval = "DOCUMENT_NODE"; break;
	case Node.DOCUMENT_TYPE_NODE :
	    retval = "DOCUMENT_TYPE_NODE"; break;
	case Node.ELEMENT_NODE :
	    retval = "ELEMENT_NODE"; break;
	case Node.ENTITY_NODE :
	    retval = "ENTITY_NODE"; break;
	case Node.ENTITY_REFERENCE_NODE :
	    retval = "ENTITY_REFERENCE_NODE"; break;
	case Node.NOTATION_NODE :
	    retval = "NOTATION_NODE"; break;
	case Node.PROCESSING_INSTRUCTION_NODE :
	    retval = "PROCESSING_INSTRUCTION_NODE"; break;
	case Node.TEXT_NODE:
	    retval = "TEXT_NODE"; break;
        }
	return retval;

FUNC_DECL IF IF PARAM BINARY_OP BINARY_OP ASSIGN ASSIGN ASSIGN

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

    public int getLineNumber() {
	return 0;


public interface InvokingContext {

    /**
     * This method is called when the router is preparing an outbound message
     * (orignated from the router's client) to be sent to the target CXF server.
     * It sets the content in the given (out) message object.
     */
    void setRequestOutMessageContent(Message message, Map<Class, Object> contents);

    /**
     * This method is call when the CxfClient receives a response from a CXF server and needs
     * to extract the response object from the message.
     */
    Object getResponseObject(Exchange exchange, Map<String, Object> responseContext);

    /**
     * This method is called when the routing interceptor has received a response message
     * from the target CXF server and needs to set the response in the outgoing message
     * that is to be sent to the client.
     */
    void setResponseContent(Message outMessage, Object resultPayload);

    /**
     * This method is called when the routing interceptor has intercepted a message from
     * the client and needs to extract the request content from the message.  It retreives
     * and receives the request content from the incoming message.
     */
    Map<Class, Object> getRequestContent(Message inMessage);


org.gjt.sp.jedit.gui.TextAreaDialog

public class TextAreaDialog extends EnhancedDialog
{
	//{{{ TextAreaDialog constructor
	public TextAreaDialog(Frame frame, String title, String caption,
		Icon icon, String text)
	{
		super(frame,title,true);

		init(caption,icon,text);
	} //}}}

	//{{{ TextAreaDialog constructor
	public TextAreaDialog(Frame frame, String name, Throwable t)
	{
		this(frame,jEdit.getProperty(name + ".title"),
			jEdit.getProperty(name + ".message"),
			UIManager.getIcon("OptionPane.errorIcon"),
			MiscUtilities.throwableToString(t));
	} //}}}

	//{{{ TextAreaDialog constructor
	public TextAreaDialog(Dialog frame, String title, String caption,
		Icon icon, String text)
	{
		super(frame,title,true);

		init(caption,icon,text);
	} //}}}

	//{{{ TextAreaDialog constructor
	public TextAreaDialog(Dialog frame, String name, Throwable t)
	{
		this(frame,jEdit.getProperty(name + ".title"),
			jEdit.getProperty(name + ".message"),
			UIManager.getIcon("OptionPane.errorIcon"),
			MiscUtilities.throwableToString(t));
	} //}}}

	//{{{ init() method
	private void init(String caption,
		Icon icon, String text)
	{
		JPanel content = new JPanel(new BorderLayout(12,12));
		content.setBorder(new EmptyBorder(12,12,12,12));
		setContentPane(content);

		Box iconBox = new Box(BoxLayout.Y_AXIS);
		iconBox.add(new JLabel(icon));
		iconBox.add(Box.createGlue());
		content.add(BorderLayout.WEST,iconBox);

		JPanel centerPanel = new JPanel(new BorderLayout(6,6));

		centerPanel.add(BorderLayout.NORTH,
			GUIUtilities.createMultilineLabel(caption));

		JTextArea textArea = new JTextArea(10,80);

		textArea.setText(text);
		textArea.setLineWrap(true);
		textArea.setCaretPosition(0);
		centerPanel.add(BorderLayout.CENTER,new JScrollPane(textArea));

		content.add(BorderLayout.CENTER,centerPanel);

		Box buttons = new Box(BoxLayout.X_AXIS);
		buttons.add(Box.createGlue());
		JButton ok = new JButton(jEdit.getProperty("common.ok"));
		ok.addActionListener(new ActionHandler());
		buttons.add(ok);
		buttons.add(Box.createGlue());
		content.add(BorderLayout.SOUTH,buttons);

		getRootPane().setDefaultButton(ok);

		pack();
		setLocationRelativeTo(getParent());
		setVisible(true);
	} //}}}

	//{{{ ok() method
	public void ok()
	{
		dispose();
	} //}}}

	//{{{ cancel() method
	public void cancel()
	{
		dispose();
	} //}}}

	//{{{ ActionHandler class
	class ActionHandler implements ActionListener
	{
		//{{{ actionPerformed() method
		public void actionPerformed(ActionEvent evt)
		{
			dispose();

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

FUNC_DECL PARAM PARAM PARAM PARAM PARAM CALL LITERAL_ANCHOR


org.apache.poi.hssf.record.EOFRecord

public class EOFRecord
    extends Record
{
    public final static short sid = 0x0A;

    public EOFRecord()
    {
    }

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

    public EOFRecord(RecordInputStream in)
    {
        super(in);
    }

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

    protected void fillFields(RecordInputStream in)
    {
    }

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

        buffer.append("[EOF]\n");
        buffer.append("[/EOF]\n");
        return buffer.toString();
    }

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

    public int getRecordSize()
    {
        return 4;
    }

    public short getSid()
    {
        return sid;
    }

    public Object clone() {
      EOFRecord rec = new EOFRecord();
      return rec;

    public int getRecordSize()
    {
        return 4;

    public short getSid()
    {
        return sid;


bsh.BSHArrayDimensions

class BSHArrayDimensions extends SimpleNode
{
	public Class baseType;
    private int arrayDims;

	/** The Length in each dimension.  This value set by the eval() */
	// is it ok to cache this here?
	// it can't change, right?
    /*transient?why?*/
	public int [] dimensions;

    BSHArrayDimensions(int id) { super(id); }

    public void addArrayDimension() { arrayDims++; }

    public Object eval(
			Class type, CallStack callstack, Interpreter interpreter )
		throws EvalError
	{
		Interpreter.debug("array base type = "+type);
		baseType = type;
		return eval( callstack, interpreter );
	}

	/**
		Evaluate the structure of the array in one of two ways:

			a) an initializer exists, evaluate it and return
			the fully constructed array object, also record the dimensions
			of that array

			b) evaluate and record the lengths in each dimension and
			return void.

		The structure of the array dims is maintained in dimensions.
	*/
    public Object eval( CallStack callstack, Interpreter interpreter )
		throws EvalError
    {
		SimpleNode child = (SimpleNode)jjtGetChild(0);

		if (child instanceof BSHArrayInitializer)
		// evaluate the initializer and the dimensions it returns
		{
			if ( baseType == null )
				throw new EvalError(
					"Internal Array Eval err:  unknown base type", this);

			Object initValue = ((BSHArrayInitializer)child).eval(
				baseType, arrayDims, callstack, interpreter);

			Class arrayClass = initValue.getClass();
			dimensions = new int[
				Reflect.getArrayDimensions(arrayClass) ];

			// compare with number of dimensions explicitly specified
			if (dimensions.length != arrayDims)
				throw new EvalError(
				"Incompatible initializer. Allocation calls for a " +
				arrayDims + " dimensional array, but initializer is a " +
					dimensions.length + " dimensional array", this);

			// fill in dimensions[] lengths
			Object arraySlice = initValue;
			for(int i = 0; i < dimensions.length; i++) {
				dimensions[i] = Array.getLength( arraySlice );
				if ( dimensions[i] > 0 )
					arraySlice = Array.get(arraySlice, 0);
			}

			return initValue;
		}
		else
		// evaluate the dimensions of the array
		{
			dimensions = new int[ jjtGetNumChildren() ];
			for(int i = 0; i < dimensions.length; i++)
			{
				try {
					Object length = ((SimpleNode)jjtGetChild(i)).eval(
						callstack, interpreter);
					dimensions[i] = ((Primitive)length).intValue();
				}
				catch(Exception e)
				{
					throw new EvalError(
						"Array index: " + i +
						" does not evaluate to an integer", this);
				}
			}
		}

        return Primitive.VOID;

FUNC_DECL RETURN PARAM PARAM PARAM CALL ASSIGN CALL BINARY_OP LITERAL_ANCHOR