public class PanelWindowContainer implements DockableWindowContainer
{
	//{{{ PanelWindowContainer constructor
	public PanelWindowContainer(DockableWindowManager wm, String position,
		int dimension)
	{
		this.wm = wm;
		this.position = position;

		//{{{ Button box setup
		buttonPanel = new JPanel(new ButtonLayout());
		buttonPanel.setBorder(new EmptyBorder(1,1,1,1));

		closeBox = new JButton(GUIUtilities.loadIcon("closebox.gif"));
		closeBox.setRequestFocusEnabled(false);
		closeBox.setToolTipText(jEdit.getProperty("view.docking.close-tooltip"));
		if(OperatingSystem.isMacOSLF())
			closeBox.putClientProperty("JButton.buttonType","toolbar");

		closeBox.setMargin(new Insets(0,0,0,0));

		closeBox.addActionListener(new ActionHandler());

		menuBtn = new JButton(GUIUtilities.loadIcon("ToolbarMenu.gif"));
		menuBtn.setRequestFocusEnabled(false);
		menuBtn.setToolTipText(jEdit.getProperty("view.docking.menu-tooltip"));
		if(OperatingSystem.isMacOSLF())
			menuBtn.putClientProperty("JButton.buttonType","toolbar");

		menuBtn.setMargin(new Insets(0,0,0,0));

		menuBtn.addMouseListener(new MenuMouseHandler());

		buttonGroup = new ButtonGroup();
		// JDK 1.4 workaround
		buttonGroup.add(nullButton = new JToggleButton());
		//}}}

		dockables = new ArrayList();
		buttons = new ArrayList();
		dockablePanel = new DockablePanel();

		this.dimension = dimension;
	} //}}}

	//{{{ register() method
	public void register(final DockableWindowManager.Entry entry)
	{
		dockables.add(entry);

		//{{{ Create button
		int rotation;
		if(position.equals(DockableWindowManager.TOP)
			|| position.equals(DockableWindowManager.BOTTOM))
			rotation = RotatedTextIcon.NONE;
		else if(position.equals(DockableWindowManager.LEFT))
			rotation = RotatedTextIcon.CCW;
		else if(position.equals(DockableWindowManager.RIGHT))
			rotation = RotatedTextIcon.CW;
		else
			throw new InternalError("Invalid position: " + position);

		JToggleButton button = new JToggleButton();
		button.setMargin(new Insets(1,1,1,1));
		button.setRequestFocusEnabled(false);
		button.setIcon(new RotatedTextIcon(rotation,button.getFont(),
			entry.title));
		button.setActionCommand(entry.factory.name);
		button.addActionListener(new ActionHandler());
		button.addMouseListener(new MenuMouseHandler());
		if(OperatingSystem.isMacOSLF())
			button.putClientProperty("JButton.buttonType","toolbar");
		//}}}

		buttonGroup.add(button);
		buttons.add(button);
		entry.btn = button;

		wm.revalidate();
	} //}}}

	//{{{ unregister() method
	public void unregister(DockableWindowManager.Entry entry)
	{
		if(entry.factory.name.equals(mostRecent))
			mostRecent = null;

		buttonPanel.remove(entry.btn);
		buttons.remove(entry.btn);
		entry.btn = null;

		dockables.remove(entry);
		if(entry.win != null)
			dockablePanel.remove(entry.win);

		if(current == entry)
		{
			current = null;
			show(null);
		}
		else
		{
			wm.revalidate();
			dockablePanel.repaint();
			buttonPanel.repaint();
		}
	} //}}}

	//{{{ remove() method
	public void remove(final DockableWindowManager.Entry entry)
	{
		if(entry.factory.name.equals(mostRecent))
			mostRecent = null;

		if(entry.win != null)
		{
			dockablePanel.remove(entry.win);
			entry.win = null;
		}

		if(current == entry)
		{
			current = null;
			show(null);
		}
		else
		{
			wm.revalidate();
			dockablePanel.repaint();
		}
	} //}}}

	//{{{ showMostRecent() method
	public void showMostRecent()
	{
		if(dockables.size() == 0)
		{
			Toolkit.getDefaultToolkit().beep();
			return;
		}

		if(mostRecent == null)
		{
			mostRecent = ((DockableWindowManager.Entry)
				dockables.get(0)).factory.name;
		}

		wm.showDockableWindow(mostRecent);
	} //}}}

	//{{{ show() method
	public void show(final DockableWindowManager.Entry entry)
	{
		if(current == entry)
		{
			if(entry != null)
			{
				if(entry.win instanceof DefaultFocusComponent)
				{
					((DefaultFocusComponent)entry.win)
						.focusOnDefaultComponent();
				}
				else
				{
					entry.win.requestDefaultFocus();
				}
			}
			return;
		}

		if(entry != null)
		{
			if(current == null)
			{
				// we didn't have a component previously, so
				// create a border
				dockablePanel.setBorder(new DockBorder(position));
			}

			mostRecent = entry.factory.name;
			this.current = entry;

			if(entry.win.getParent() != dockablePanel)
				dockablePanel.add(entry.factory.name,entry.win);

			dockablePanel.showDockable(entry.factory.name);

			entry.btn.setSelected(true);

			if(entry.win instanceof DefaultFocusComponent)
			{
				((DefaultFocusComponent)entry.win)
					.focusOnDefaultComponent();
			}
			else
			{
				entry.win.requestDefaultFocus();
			}
		}
		else
		{
			current = null;
			nullButton.setSelected(true);
			// removing last component, so remove border
			dockablePanel.setBorder(null);

			wm.getView().getTextArea().requestFocus();
		}

		wm.revalidate();
		dockablePanel.repaint();
	} //}}}

	//{{{ isVisible() method
	public boolean isVisible(DockableWindowManager.Entry entry)
	{
		return current == entry;
	} //}}}

	//{{{ getCurrent() method
	/**
	 * Returns the name of the dockable in this container.
	 * @since jEdit 4.2pre1
	 */
	public String getCurrent()
	{
		if(current == null)
			return null;
		else
			return current.factory.name;
	} //}}}

	//{{{ getDimension() method
	/**
	 * Returns the width or height (depending on position) of the dockable
	 * window container.
	 * @since jEdit 4.2pre1
	 */
	public int getDimension()
	{
		return dimension;
	} //}}}

	//{{{ getDockables() method
	public String[] getDockables()
	{
		String[] retVal = new String[dockables.size()];
		for(int i = 0; i < dockables.size(); i++)
		{
			DockableWindowManager.Entry entry =
				(DockableWindowManager.Entry) dockables.get(i);
			retVal[i] = entry.factory.name;
		}
		return retVal;
	} //}}}

	//{{{ Package-private members
	static final int SPLITTER_WIDTH = 10;
	DockablePanel dockablePanel;
	JPanel buttonPanel;

	//{{{ save() method
	void save()
	{
		jEdit.setIntegerProperty("view.dock." + position + ".dimension",
			dimension);
		if(current == null)
			jEdit.unsetProperty("view.dock." + position + ".last");
		else
		{
			jEdit.setProperty("view.dock." + position + ".last",
				current.factory.name);
		}
	} //}}}

	//{{{ setDimension() method
	void setDimension(int dimension)
	{
		if(dimension != 0)
			this.dimension = dimension - SPLITTER_WIDTH;
	} //}}}

	//{{{ sortDockables() method
	void sortDockables()
	{
		buttonPanel.removeAll();
		buttonPanel.add(closeBox);
		buttonPanel.add(menuBtn);
		Collections.sort(buttons,new DockableWindowCompare());
		for(int i = 0; i < buttons.size(); i++)
		{
			buttonPanel.add((AbstractButton)buttons.get(i));
		}
	} //}}}

	//{{{ getWrappedDimension() method
	/**
	 * Returns the width or height of wrapped rows or columns.
	 */
	int getWrappedDimension(int dimension)
	{
		return ((ButtonLayout)buttonPanel.getLayout())
			.getWrappedDimension(buttonPanel,dimension);
	} //}}}

	//}}}

	//{{{ Private members
	private DockableWindowManager wm;
	private String position;
	private JButton closeBox;
	private JButton menuBtn;
	private ButtonGroup buttonGroup;
	private JToggleButton nullButton;
	private int dimension;
	private ArrayList dockables;
	private ArrayList buttons;
	private DockableWindowManager.Entry current;
	private JPopupMenu popup;

	// remember the most recent dockable
	private String mostRecent;
	//}}}

	//{{{ Inner classes

	//{{{ DockableWindowCompare class
	static class DockableWindowCompare implements Comparator
	{
		public int compare(Object o1, Object o2)
		{
			String name1 = ((AbstractButton)o1).getActionCommand();
			String name2 = ((AbstractButton)o2).getActionCommand();
			return MiscUtilities.compareStrings(
				jEdit.getProperty(name1 + ".title",""),
				jEdit.getProperty(name2 + ".title",""),
				true);
		}
	} //}}}

	//{{{ ActionHandler class
	class ActionHandler implements ActionListener
	{
		public void actionPerformed(ActionEvent evt)
		{
			if(popup != null && popup.isVisible())
				popup.setVisible(false);

			if(evt.getSource() == closeBox)
				show(null);
			else
			{
				if(wm.isDockableWindowVisible(evt.getActionCommand()))
					show(null);
				else
					wm.showDockableWindow(evt.getActionCommand());
			}
		}
	} //}}}

	//{{{ MenuMouseHandler class
	class MenuMouseHandler extends MouseAdapter
	{
		public void mousePressed(MouseEvent evt)
		{
			if(popup != null && popup.isVisible())
			{
				popup.setVisible(false);
				return;
			}

			Component comp = (Component)evt.getSource();
			String dockable;
			if(comp instanceof JToggleButton)
				dockable = ((JToggleButton)comp).getActionCommand();
			else
				dockable = getCurrent();

			if(comp == menuBtn || GUIUtilities.isPopupTrigger(evt))
			{
				if(dockable == null)
				{
					popup = wm.createPopupMenu(PanelWindowContainer.this,null,false);
				}
				else
				{
					popup = wm.createPopupMenu(PanelWindowContainer.this,dockable,false);
				}

				int x, y;
				boolean point;
				if(comp == menuBtn)
				{
					x = 0;
					y = menuBtn.getHeight();
					point = false;
				}
				else
				{
					x = evt.getX();
					y = evt.getY();
					point = true;
				}
				GUIUtilities.showPopupMenu(popup,
					comp,x,y,point);
			}
		}
	} //}}}

	//{{{ DockBorder class
	static class DockBorder implements Border
	{
		String position;
		Insets insets;
		Color color1;
		Color color2;
		Color color3;

		//{{{ DockBorder constructor
		DockBorder(String position)
		{
			this.position = position;
			insets = new Insets(
				position.equals(DockableWindowManager.BOTTOM)
					? SPLITTER_WIDTH : 0,
				position.equals(DockableWindowManager.RIGHT)
					? SPLITTER_WIDTH : 0,
				position.equals(DockableWindowManager.TOP)
					? SPLITTER_WIDTH : 0,
				position.equals(DockableWindowManager.LEFT)
					? SPLITTER_WIDTH : 0);
		} //}}}

		//{{{ paintBorder() method
		public void paintBorder(Component c, Graphics g,
			int x, int y, int width, int height)
		{
			updateColors();

			if(color1 == null || color2 == null || color3 == null)
				return;

			if(position.equals(DockableWindowManager.BOTTOM))
				paintHorizBorder(g,x,y,width);
			else if(position.equals(DockableWindowManager.RIGHT))
				paintVertBorder(g,x,y,height);
			else if(position.equals(DockableWindowManager.TOP))
			{
				paintHorizBorder(g,x,y + height
					- SPLITTER_WIDTH,width);
			}
			else if(position.equals(DockableWindowManager.LEFT))
			{
				paintVertBorder(g,x + width
					- SPLITTER_WIDTH,y,height);
			}
		} //}}}

		//{{{ getBorderInsets() method
		public Insets getBorderInsets(Component c)
		{
			return insets;
		} //}}}

		//{{{ isBorderOpaque() method
		public boolean isBorderOpaque()
		{
			return false;
		} //}}}

		//{{{ paintHorizBorder() method
		private void paintHorizBorder(Graphics g, int x, int y, int width)
		{
			g.setColor(color3);
			g.fillRect(x,y,width,SPLITTER_WIDTH);

			for(int i = 0; i < width / 4 - 1; i++)
			{
				g.setColor(color1);
				g.drawLine(x + i * 4 + 2,y + 3,
					x + i * 4 + 2,y + 3);
				g.setColor(color2);
				g.drawLine(x + i * 4 + 3,y + 4,
					x + i * 4 + 3,y + 4);
				g.setColor(color1);
				g.drawLine(x + i * 4 + 4,y + 5,
					x + i * 4 + 4,y + 5);
				g.setColor(color2);
				g.drawLine(x + i * 4 + 5,y + 6,
					x + i * 4 + 5,y + 6);
			}
		} //}}}

		//{{{ paintVertBorder() method
		private void paintVertBorder(Graphics g, int x, int y, int height)
		{
			g.setColor(color3);
			g.fillRect(x,y,SPLITTER_WIDTH,height);

			for(int i = 0; i < height / 4 - 1; i++)
			{
				g.setColor(color1);
				g.drawLine(x + 3,y + i * 4 + 2,
					x + 3,y + i * 4 + 2);
				g.setColor(color2);
				g.drawLine(x + 4,y + i * 4 + 3,
					x + 4,y + i * 4 + 3);
				g.setColor(color1);
				g.drawLine(x + 5,y + i * 4 + 4,
					x + 5,y + i * 4 + 4);
				g.setColor(color2);
				g.drawLine(x + 6,y + i * 4 + 5,
					x + 6,y + i * 4 + 5);
			}
		} //}}}

		//{{{ updateColors() method
		private void updateColors()
		{
			if(UIManager.getLookAndFeel() instanceof MetalLookAndFeel)
			{
				color1 = MetalLookAndFeel.getControlHighlight();
				color2 = MetalLookAndFeel.getControlDarkShadow();
				color3 = MetalLookAndFeel.getControl();
			}
			else
			{
				color1 = color2 = color3 = null;
			}
		} //}}}
	} //}}}

	//{{{ RotatedTextIcon class
	public static class RotatedTextIcon implements Icon
	{
		public static final int NONE = 0;
		public static final int CW = 1;
		public static final int CCW = 2;

		//{{{ RotatedTextIcon constructor
		public RotatedTextIcon(int rotate, Font font, String text)
		{
			this.rotate = rotate;
			this.font = font;

			FontRenderContext fontRenderContext
				= new FontRenderContext(null,true,true);
			this.text = text;
			glyphs = font.createGlyphVector(fontRenderContext,text);
			width = (int)glyphs.getLogicalBounds().getWidth() + 4;
			//height = (int)glyphs.getLogicalBounds().getHeight();

			LineMetrics lineMetrics = font.getLineMetrics(text,fontRenderContext);
			ascent = lineMetrics.getAscent();
			height = (int)lineMetrics.getHeight();

			renderHints = new RenderingHints(
				RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
			renderHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
				RenderingHints.VALUE_FRACTIONALMETRICS_ON);
			renderHints.put(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		} //}}}

		//{{{ getIconWidth() method
		public int getIconWidth()
		{
			return (int)(rotate == RotatedTextIcon.CW
				|| rotate == RotatedTextIcon.CCW
				? height : width);
		} //}}}

		//{{{ getIconHeight() method
		public int getIconHeight()
		{
			return (int)(rotate == RotatedTextIcon.CW
				|| rotate == RotatedTextIcon.CCW
				? width : height);
		} //}}}

		//{{{ paintIcon() method
		public void paintIcon(Component c, Graphics g, int x, int y)
		{
			Graphics2D g2d = (Graphics2D)g;
			g2d.setFont(font);
			AffineTransform oldTransform = g2d.getTransform();
			RenderingHints oldHints = g2d.getRenderingHints();

			g2d.setRenderingHints(renderHints);
			g2d.setColor(c.getForeground());

			//{{{ No rotation
			if(rotate == RotatedTextIcon.NONE)
			{
				g2d.drawGlyphVector(glyphs,x + 2,y + ascent);
			} //}}}
			//{{{ Clockwise rotation
			else if(rotate == RotatedTextIcon.CW)
			{
				AffineTransform trans = new AffineTransform();
				trans.concatenate(oldTransform);
				trans.translate(x,y + 2);
				trans.rotate(Math.PI / 2,
					height / 2, width / 2);
				g2d.setTransform(trans);
				g2d.drawGlyphVector(glyphs,(height - width) / 2,
					(width - height) / 2
					+ ascent);
			} //}}}
			//{{{ Counterclockwise rotation
			else if(rotate == RotatedTextIcon.CCW)
			{
				AffineTransform trans = new AffineTransform();
				trans.concatenate(oldTransform);
				trans.translate(x,y - 2);
				trans.rotate(Math.PI * 3 / 2,
					height / 2, width / 2);
				g2d.setTransform(trans);
				g2d.drawGlyphVector(glyphs,(height - width) / 2,
					(width - height) / 2
					+ ascent);
			} //}}}

			g2d.setTransform(oldTransform);
			g2d.setRenderingHints(oldHints);
		} //}}}

		//{{{ Private members
		private int rotate;
		private Font font;
		private String text;
		private GlyphVector glyphs;
		private float width;
		private float height;
		private float ascent;
		private RenderingHints renderHints;
		//}}}
	} //}}}

	//{{{ ButtonLayout class
	class ButtonLayout implements LayoutManager
	{
		//{{{ addLayoutComponent() method
		public void addLayoutComponent(String name, Component comp) {} //}}}

		//{{{ removeLayoutComponent() method
		public void removeLayoutComponent(Component comp) {} //}}}

		//{{{ getWrappedDimension() method
		/**
		 * Returns the width or height of wrapped rows or columns.
		 */
		int getWrappedDimension(JComponent parent, int dimension)
		{
			Insets insets = ((JComponent)parent).getBorder()
				.getBorderInsets((JComponent)parent);

			Component[] comp = parent.getComponents();
			if(comp.length <= 2)
				return 0;

			Dimension dim = comp[2].getPreferredSize();

			if(position.equals(DockableWindowManager.TOP)
				|| position.equals(DockableWindowManager.BOTTOM))
			{
				int width = dimension - insets.right;
				int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
				int x = rowHeight * 2 + insets.left;
				Dimension returnValue = new Dimension(0,rowHeight
					+ insets.top + insets.bottom);

				for(int i = 2; i < comp.length; i++)
				{
					int btnWidth = comp[i].getPreferredSize().width;
					if(btnWidth + x > width)
					{
						returnValue.height += rowHeight;
						x = insets.left;
					}

					x += btnWidth;
				}
				return returnValue.height;
			}
			else
			{
				int height = dimension - insets.bottom;
				int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
				int y = colWidth * 2 + insets.top;
				Dimension returnValue = new Dimension(colWidth
					+ insets.left + insets.right,0);

				for(int i = 2; i < comp.length; i++)
				{
					int btnHeight = comp[i].getPreferredSize().height;
					if(btnHeight + y > height)
					{
						returnValue.width += colWidth;
						y = insets.top;
					}

					y += btnHeight;
				}
				return returnValue.width;
			}
		} //}}}

		//{{{ preferredLayoutSize() method
		public Dimension preferredLayoutSize(Container parent)
		{
			Insets insets = ((JComponent)parent).getBorder()
				.getBorderInsets((JComponent)parent);

			Component[] comp = parent.getComponents();
			if(comp.length <= 2)
			{
				// nothing 'cept close box
				return new Dimension(0,0);
			}

			Dimension dim = comp[2].getPreferredSize();

			if(position.equals(DockableWindowManager.TOP)
				|| position.equals(DockableWindowManager.BOTTOM))
			{
				int width = parent.getWidth() - insets.right;
				int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
				int x = rowHeight * 2 + insets.left;
				Dimension returnValue = new Dimension(0,rowHeight
					+ insets.top + insets.bottom);

				for(int i = 2; i < comp.length; i++)
				{
					int btnWidth = comp[i].getPreferredSize().width;
					if(btnWidth + x > width)
					{
						returnValue.height += rowHeight;
						x = insets.left;
					}

					x += btnWidth;
				}
				return returnValue;
			}
			else
			{
				int height = parent.getHeight() - insets.bottom;
				int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
				int y = colWidth * 2 + insets.top;
				Dimension returnValue = new Dimension(colWidth
					+ insets.left + insets.right,0);

				for(int i = 2; i < comp.length; i++)
				{
					int btnHeight = comp[i].getPreferredSize().height;
					if(btnHeight + y > height)
					{
						returnValue.width += colWidth;
						y = insets.top;
					}

					y += btnHeight;
				}
				return returnValue;
			}
		} //}}}

		//{{{ minimumLayoutSize() method
		public Dimension minimumLayoutSize(Container parent)
		{
			return preferredLayoutSize(parent);
		} //}}}

		//{{{ layoutContainer() method
		public void layoutContainer(Container parent)
		{
			Insets insets = ((JComponent)parent).getBorder()
				.getBorderInsets((JComponent)parent);

			Component[] comp = parent.getComponents();
			if(comp.length <= 2)
			{
				for(int i = 0; i < comp.length; i++)
				{
					comp[i].setVisible(false);
				}
				return;
			}

			comp[0].setVisible(true);
			comp[1].setVisible(true);

			Dimension dim = comp[2].getPreferredSize();

			if(position.equals(DockableWindowManager.TOP)
				|| position.equals(DockableWindowManager.BOTTOM))
			{
				int width = parent.getWidth() - insets.right;
				int rowHeight = Math.max(dim.height,closeBox.getPreferredSize().width);
				int x = rowHeight * 2 + insets.left;
				int y = insets.top;
				closeBox.setBounds(insets.left,insets.top,rowHeight,rowHeight);
				menuBtn.setBounds(insets.left + rowHeight,insets.top,rowHeight,rowHeight);

				for(int i = 2; i < comp.length; i++)
				{
					int btnWidth = comp[i].getPreferredSize().width;
					if(btnWidth + x > width)
					{
						x = insets.left;
						y += rowHeight;
					}
					comp[i].setBounds(x,y,btnWidth,rowHeight);
					x += btnWidth;
				}

				/* if(y + rowHeight != parent.getHeight())
				{
					parent.setSize(
						parent.getWidth(),
						y + rowHeight);
					((JComponent)parent).revalidate();
				} */
			}
			else
			{
				int height = parent.getHeight() - insets.bottom;
				int colWidth = Math.max(dim.width,closeBox.getPreferredSize().height);
				int x = insets.left;
				int y = colWidth * 2 + insets.top;
				closeBox.setBounds(insets.left,insets.top,colWidth,colWidth);
				menuBtn.setBounds(insets.left,insets.top + colWidth,colWidth,colWidth);

				for(int i = 2; i < comp.length; i++)
				{
					int btnHeight = comp[i].getPreferredSize().height;
					if(btnHeight + y > height)
					{
						x += colWidth;
						y = insets.top;
					}
					comp[i].setBounds(x,y,colWidth,btnHeight);
					y += btnHeight;
				}

				/* if(x + colWidth != parent.getWidth())
				{
					parent.setSize(x + colWidth,
						parent.getHeight());
					((JComponent)parent).revalidate();
				} */
			}
		} //}}}
	} //}}}

	//{{{ DockablePanel class
	class DockablePanel extends JPanel
	{
		//{{{ DockablePanel constructor
		DockablePanel()
		{
			super(new CardLayout());

			ResizeMouseHandler resizeMouseHandler = new ResizeMouseHandler();
			addMouseListener(resizeMouseHandler);
			addMouseMotionListener(resizeMouseHandler);
		} //}}}

		//{{{ getWindowContainer() method
		PanelWindowContainer getWindowContainer()
		{
			return PanelWindowContainer.this;
		} //}}}

		//{{{ showDockable() method
		void showDockable(String name)
		{
			((CardLayout)getLayout()).show(this,name);
		} //}}}

		//{{{ getMinimumSize() method
		public Dimension getMinimumSize()
		{
			return new Dimension(0,0);
		} //}}}

		//{{{ getPreferredSize() method
		public Dimension getPreferredSize()
		{
			if(current == null)
				return new Dimension(0,0);
			else
			{
				if(position.equals(DockableWindowManager.TOP)
					|| position.equals(DockableWindowManager.BOTTOM))
				{
					if(dimension <= 0)
					{
						int height = super.getPreferredSize().height;
						dimension = height - SPLITTER_WIDTH;
					}
					return new Dimension(0,
						dimension + SPLITTER_WIDTH);
				}
				else
				{
					if(dimension <= 0)
					{
						int width = super.getPreferredSize().width;
						dimension = width - SPLITTER_WIDTH;
					}
					return new Dimension(dimension + SPLITTER_WIDTH,
						0);
				}
			}
		} //}}}

		//{{{ setBounds() method
		public void setBounds(int x, int y, int width, int height)
		{
			if(position.equals(DockableWindowManager.TOP) ||
				position.equals(DockableWindowManager.BOTTOM))
			{
				if(dimension != 0 && height <= SPLITTER_WIDTH)
					PanelWindowContainer.this.show(null);
				else
					dimension = height - SPLITTER_WIDTH;
			}
			else
			{
				if(dimension != 0 && width <= SPLITTER_WIDTH)
					PanelWindowContainer.this.show(null);
				else
					dimension = width - SPLITTER_WIDTH;
			}

			super.setBounds(x,y,width,height);
		} //}}}

		//{{{ ResizeMouseHandler class
		class ResizeMouseHandler extends MouseAdapter implements MouseMotionListener
		{
			boolean canDrag;
			Point dragStart;

			//{{{ mousePressed() method
			public void mousePressed(MouseEvent evt)
			{
				if(canDrag)
				{
					wm.setResizePos(dimension,PanelWindowContainer.this);
					dragStart = evt.getPoint();
				}
			} //}}}

			//{{{ mouseReleased() method
			public void mouseReleased(MouseEvent evt)
			{
				if(canDrag)
				{
					dimension = wm.resizePos;
					wm.finishResizing();
					dragStart = null;
					wm.revalidate();
				}
			} //}}}

			//{{{ mouseMoved() method
			public void mouseMoved(MouseEvent evt)
			{
				Border border = getBorder();
				if(border == null)
				{
					// collapsed
					return;
				}

				Insets insets = border.getBorderInsets(DockablePanel.this);
				canDrag = false;
				//{{{ Top...
				if(position.equals(DockableWindowManager.TOP))
				{
					if(evt.getY() >= getHeight() - insets.bottom)
						canDrag = true;
				} //}}}
				//{{{ Left...
				else if(position.equals(DockableWindowManager.LEFT))
				{
					if(evt.getX() >= getWidth() - insets.right)
						canDrag = true;
				} //}}}
				//{{{ Bottom...
				else if(position.equals(DockableWindowManager.BOTTOM))
				{
					if(evt.getY() <= insets.top)
						canDrag = true;
				} //}}}
				//{{{ Right...
				else if(position.equals(DockableWindowManager.RIGHT))
				{
					if(evt.getX() <= insets.left)
						canDrag = true;
				} //}}}

				if(canDrag)
				{
					wm.setCursor(Cursor.getPredefinedCursor(
						getAppropriateCursor()));
				}
				else
				{
					wm.setCursor(Cursor.getPredefinedCursor(
						Cursor.DEFAULT_CURSOR));
				}
			} //}}}

			//{{{ mouseDragged() method
			public void mouseDragged(MouseEvent evt)
			{
				if(!canDrag)
					return;

				if(dragStart == null) // can't happen?
					return;

				wm.setCursor(Cursor.getPredefinedCursor(
					getAppropriateCursor()));

				//{{{ Top...
				if(position.equals(DockableWindowManager.TOP))
				{
					wm.setResizePos(
						evt.getY() - dragStart.y
						+ dimension,
						PanelWindowContainer.this);
				} //}}}
				//{{{ Left...
				else if(position.equals(DockableWindowManager.LEFT))
				{
					wm.setResizePos(evt.getX() - dragStart.x
						+ dimension,
						PanelWindowContainer.this);
				} //}}}
				//{{{ Bottom...
				else if(position.equals(DockableWindowManager.BOTTOM))
				{
					wm.setResizePos(dimension - evt.getY()
						+ dragStart.y,
						PanelWindowContainer.this);
				} //}}}
				//{{{ Right...
				else if(position.equals(DockableWindowManager.RIGHT))
				{
					wm.setResizePos(dimension - evt.getX()
						+ dragStart.x,
						PanelWindowContainer.this);
				} //}}}
			} //}}}

			//{{{ mouseExited() method
			public void mouseExited(MouseEvent evt)
			{
				wm.setCursor(Cursor.getPredefinedCursor(
					Cursor.DEFAULT_CURSOR));
			} //}}}

			//{{{ getCursor() method
			private int getAppropriateCursor()
			{
				if(position.equals(DockableWindowManager.TOP))
					return Cursor.N_RESIZE_CURSOR;
				else if(position.equals(DockableWindowManager.LEFT))
					return Cursor.W_RESIZE_CURSOR;
				else if(position.equals(DockableWindowManager.BOTTOM))
					return Cursor.S_RESIZE_CURSOR;
				else if(position.equals(DockableWindowManager.RIGHT))
					return Cursor.E_RESIZE_CURSOR;
				else
					throw new InternalError();

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

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

FUNC_DECL LOOP BINARY_OP CALL CALL CALL CALL CALL CALL CALL LITERAL_ANCHOR CALL

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


public class JikesOutputParser implements ExecuteStreamHandler {
    protected Task task;
    protected int errors;
    protected int warnings;
    protected boolean error = false;
    protected boolean emacsMode;

    protected BufferedReader br;

    /**
     * Ignore.
     */
    public void setProcessInputStream(OutputStream os) {}

    /**
     * Ignore.
     */
    public void setProcessErrorStream(InputStream is) {}

    /**
     * Set the inputstream
     */
    public void setProcessOutputStream(InputStream is) throws IOException {
        br = new BufferedReader(new InputStreamReader(is));
    }

    /**
     * Invokes parseOutput.
     */
    public void start() throws IOException {
        parseOutput(br);
    }

    /**
     * Ignore.
     */
    public void stop() {}

    /**
     * Construct a new Parser object
     * @param task - task in whichs context we are called
     */
    protected JikesOutputParser(Task task, boolean emacsMode) {
        super();

        System.err.println("As of Ant 1.2 released in October 2000, the "
            + "JikesOutputParser class");
        System.err.println("is considered to be dead code by the Ant "
            + "developers and is unmaintained.");
        System.err.println("Don\'t use it!");

        this.task = task;
        this.emacsMode = emacsMode;
    }

    /**
     * Parse the output of a jikes compiler
     * @param reader - Reader used to read jikes's output
     */
    protected void parseOutput(BufferedReader reader) throws IOException {
       if (emacsMode) {
           parseEmacsOutput(reader);
       } else {
           parseStandardOutput(reader);
       }
    }

    private void parseStandardOutput(BufferedReader reader) throws IOException {
        String line;
        String lower;

        while ((line = reader.readLine()) != null) {
            lower = line.toLowerCase();
            if (line.trim().equals("")) {
                continue;
            }
            if (lower.indexOf("error") != -1) {
                setError(true);
            } else if (lower.indexOf("warning") != -1) {
                setError(false);
                   } else {
                if (emacsMode) {
                    setError(true);
                }
            }
            log(line);
        }
    }

    private void parseEmacsOutput(BufferedReader reader) throws IOException {
       parseStandardOutput(reader);
    }

    private void setError(boolean err) {
        error = err;
        if (error) {
            errorFlag = true;
        }
    }

    private void log(String line) {
       if (!emacsMode) {
           task.log("", (error ? Project.MSG_ERR : Project.MSG_WARN));
       }
       task.log(line, (error ? Project.MSG_ERR : Project.MSG_WARN));
    }

    /**
     * Indicate if there were errors during the compile
     * @return if errors ocured
     */
    protected boolean getErrorFlag() {
        return errorFlag;

FUNC_DECL IF PARAM ASSIGN ASSIGN LITERAL_ANCHOR


org.gjt.sp.jedit.gui.BufferOptions

public class BufferOptions extends EnhancedDialog
{
	//{{{ BufferOptions constructor

	public BufferOptions(View view, Buffer buffer)
	{
		super(view,jEdit.getProperty("buffer-options.title"),true);
		this.view = view;
		this.buffer = buffer;

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

		ActionHandler actionListener = new ActionHandler();
		panel = new BufferOptionPane();

		content.add(BorderLayout.NORTH,panel);

		//{{{ Buttons

		JPanel buttons = new JPanel();
		buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS));
		buttons.setBorder(new EmptyBorder(12,0,0,0));
		buttons.add(Box.createGlue());

		ok = new JButton(jEdit.getProperty("common.ok"));
		ok.addActionListener(actionListener);
		getRootPane().setDefaultButton(ok);
		buttons.add(ok);

		buttons.add(Box.createHorizontalStrut(6));

		cancel = new JButton(jEdit.getProperty("common.cancel"));
		cancel.addActionListener(actionListener);
		buttons.add(cancel);

		buttons.add(Box.createGlue());
		content.add(BorderLayout.SOUTH,buttons);

		//}}}

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

	//{{{ ok() method

	public void ok()
	{
		panel.save();
		dispose();
	} //}}}

	//{{{ cancel() method

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

	//{{{ Private members

	private View view;
	private Buffer buffer;
	private BufferOptionPane panel;
	private JButton ok;
	private JButton cancel;

	//{{{ ActionHandler class

	class ActionHandler implements ActionListener
	{
		//{{{ actionPerformed() method
		public void actionPerformed(ActionEvent evt)
		{
			Object source = evt.getSource();
			if(source == ok)
				ok();
			else if(source == cancel)
				cancel();

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


public class LeadPipeInputStream extends PipedInputStream {
    private static final int BYTE_MASK = 0xFF;
    private ProjectComponent managingPc;

    /**
     * Construct a new LeadPipeInputStream.
     */
    public LeadPipeInputStream() {
        super();
    }

    /**
     * Construct a new LeadPipeInputStream
     * with the specified buffer size.
     * @param size   the size of the circular buffer.
     */
    public LeadPipeInputStream(int size) {
        super();
        setBufferSize(size);
    }

    /**
     * Construct a new LeadPipeInputStream to pull
     * from the specified PipedOutputStream.
     * @param src   the PipedOutputStream source.
     * @throws IOException if unable to construct the stream.
     */
    public LeadPipeInputStream(PipedOutputStream src) throws IOException {
        super(src);
    }

    /**
     * Construct a new LeadPipeInputStream to pull
     * from the specified PipedOutputStream, using a
     * circular buffer of the specified size.
     * @param src    the PipedOutputStream source.
     * @param size   the size of the circular buffer.
     * @throws IOException if there is an error.
     */
    public LeadPipeInputStream(PipedOutputStream src, int size) throws IOException {
        super(src);
        setBufferSize(size);
    }

    /**
     * Read a byte from the stream.
     * @return the byte (0 to 255) or -1 if there are no more.
     * @throws IOException if there is an error.
     */
    public synchronized int read() throws IOException {
        int result = -1;
        try {
            result = super.read();
        } catch (IOException eyeOhEx) {
            if ("write end dead".equalsIgnoreCase(eyeOhEx.getMessage())) {
                if (super.in > 0 && super.out < super.buffer.length
                    && super.out > super.in) {
                    result = super.buffer[super.out++] & BYTE_MASK;
                }
            } else {
                log("error at LeadPipeInputStream.read():  "
                    + eyeOhEx.getMessage(), Project.MSG_INFO);
            }
        }
        return result;
    }

    /**
     * Set the size of the buffer.
     * @param size   the new buffer size.  Ignored if <= current size.
     */
    public synchronized void setBufferSize(int size) {
        if (size > buffer.length) {
            byte[] newBuffer = new byte[size];
            if (in >= 0) {
                if (in > out) {
                    System.arraycopy(buffer, out, newBuffer, out, in - out);
                } else {
                    int outlen = buffer.length - out;
                    System.arraycopy(buffer, out, newBuffer, 0, outlen);
                    System.arraycopy(buffer, 0, newBuffer, outlen, in);
                    in += outlen;
                    out = 0;
                }
            }
            buffer = newBuffer;
        }
    }

    /**
     * Set a managing Task for
     * this LeadPipeInputStream.
     * @param task   the managing Task.
     */
    public void setManagingTask(Task task) {
        setManagingComponent(task);
    }

    /**
     * Set a managing ProjectComponent for
     * this LeadPipeInputStream.
     * @param pc   the managing ProjectComponent.
     */
    public void setManagingComponent(ProjectComponent pc) {
        this.managingPc = pc;
    }

    /**
     * Log a message with the specified logging level.
     * @param message    the String message.
     * @param loglevel   the int logging level.
     */
    public void log(String message, int loglevel) {
        if (managingPc != null) {
            managingPc.log(message, loglevel);
        } else {
            if (loglevel > Project.MSG_WARN) {
                System.out.println(message);
            } else {
                System.err.println(message);

    public LeadPipeInputStream() {
        super();


org.apache.xalan.templates.ElemWhen

public class ElemWhen extends ElemTemplateElement
{
    static final long serialVersionUID = 5984065730262071360L;

  /**
   * Each xsl:when element has a single attribute, test,
   * which specifies an expression.
   * @serial
   */
  private XPath m_test;

  /**
   * Set the "test" attribute.
   * Each xsl:when element has a single attribute, test,
   * which specifies an expression.
   *
   * @param v Value to set for the "test" attribute.
   */
  public void setTest(XPath v)
  {
    m_test = v;
  }

  /**
   * Get the "test" attribute.
   * Each xsl:when element has a single attribute, test,
   * which specifies an expression.
   *
   * @return Value of the "test" attribute.
   */
  public XPath getTest()
  {
    return m_test;
  }

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

  /**
   * This function is called after everything else has been
   * recomposed, and allows the template to set remaining
   * values that may be based on some other property that
   * depends on recomposition.
   */
  public void compose(StylesheetRoot sroot)
    throws javax.xml.transform.TransformerException
  {
    super.compose(sroot);
    java.util.Vector vnames = sroot.getComposeState().getVariableNames();
    if(null != m_test)
      m_test.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
  }

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

  /**
   * Constructor ElemWhen
   *
   */
  public ElemWhen(){}

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

  public XPath getTest()
  {
    return m_test;


public class ElemAttribute extends ElemElement
{

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

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

  /**
   * Create an attribute in the result tree.
   *
   * @param transformer non-null reference to the the current transform-time state.
   *
   * @throws TransformerException
   */
  public void execute(
          TransformerImpl transformer)
            throws TransformerException
  {
    ResultTreeHandler rhandler = transformer.getResultTreeHandler();

    if (!rhandler.isElementPending())
    {
      if (TransformerImpl.S_DEBUG)
        transformer.getTraceManager().fireTraceEvent(this);

      XPathContext xctxt = transformer.getXPathContext();
      int sourceNode = xctxt.getCurrentNode();
      String attrName = m_name_avt.evaluate(xctxt, sourceNode, this);
      transformer.getMsgMgr().warn(this,
                                   XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE,
                                   new Object[]{ attrName });

      if (TransformerImpl.S_DEBUG)
        transformer.getTraceManager().fireTraceEndEvent(this);
      return;

    }

    super.execute(transformer);

  }

  /**
   * Resolve the namespace into a prefix.  At this level, if no prefix exists,
   * then return a manufactured prefix.
   *
   * @param rhandler The current result tree handler.
   * @param prefix The probable prefix if already known.
   * @param nodeNamespace  The namespace, which should not be null.
   *
   * @return The prefix to be used.
   */
  protected String resolvePrefix(ResultTreeHandler rhandler,
                                 String prefix, String nodeNamespace)
    throws TransformerException
  {

    if (null != prefix && (prefix.length() == 0 || prefix.equals("xmlns")))
    {
      prefix = rhandler.getPrefix(nodeNamespace);

      if (null == prefix || prefix.length() == 0 || prefix.equals("xmlns"))
      {
        if(nodeNamespace.length() > 0)
        {
          prefix = rhandler.getNewUniqueNSPrefix();
        }
        else
          prefix = "";
      }
    }
    return prefix;
  }

  /**
   * Validate that the node name is good.
   *
   * @param nodeName Name of the node being constructed, which may be null.
   *
   * @return true if the node name is valid, false otherwise.
   */
   protected boolean validateNodeName(String nodeName)
   {
      if(null == nodeName)
        return false;
      if(nodeName.equals("xmlns"))
        return false;
      return super.validateNodeName(nodeName);
   }

  /**
   * Construct a node in the result tree.  This method is overloaded by
   * xsl:attribute. At this class level, this method creates an element.
   *
   * @param nodeName The name of the node, which may be null.
   * @param prefix The prefix for the namespace, which may be null.
   * @param nodeNamespace The namespace of the node, which may be null.
   * @param transformer non-null reference to the the current transform-time state.
   *
   * @throws TransformerException
   */
  void constructNode(
          String nodeName, String prefix, String nodeNamespace, TransformerImpl transformer)
            throws TransformerException
  {

    if(null != nodeName && nodeName.length() > 0)
    {
      ResultTreeHandler rhandler = transformer.getResultTreeHandler();
      if(prefix != null && prefix.length() > 0)
      {
        try
        {
          rhandler.startPrefixMapping(prefix, nodeNamespace, false);
        }
        catch(SAXException se)
        {
          throw new TransformerException(se);
        }
      }
      String val = transformer.transformToString(this);
      String localName = QName.getLocalPart(nodeName);
      rhandler.addAttribute(nodeNamespace, localName, nodeName, "CDATA", val);
    }
  }

  /**
   * Add a child to the child list.
   * <!ELEMENT xsl:attribute %char-template;>
   * <!ATTLIST xsl:attribute
   *   name %avt; #REQUIRED
   *   namespace %avt; #IMPLIED
   *   %space-att;
   * >
   *
   * @param newChild Child to append to the list of this node's children
   *
   * @return The node we just appended to the children list
   *
   * @throws DOMException
   */
  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
  {

    int type = ((ElemTemplateElement) newChild).getXSLToken();

    switch (type)
    {

    case Constants.ELEMNAME_TEXTLITERALRESULT :
    case Constants.ELEMNAME_APPLY_TEMPLATES :
    case Constants.ELEMNAME_APPLY_IMPORTS :
    case Constants.ELEMNAME_CALLTEMPLATE :
    case Constants.ELEMNAME_FOREACH :
    case Constants.ELEMNAME_VALUEOF :
    case Constants.ELEMNAME_COPY_OF :
    case Constants.ELEMNAME_NUMBER :
    case Constants.ELEMNAME_CHOOSE :
    case Constants.ELEMNAME_IF :
    case Constants.ELEMNAME_TEXT :
    case Constants.ELEMNAME_COPY :
    case Constants.ELEMNAME_VARIABLE :
    case Constants.ELEMNAME_MESSAGE :

      break;
    default :
      error(XSLTErrorResources.ER_CANNOT_ADD,
            new Object[]{ newChild.getNodeName()});

    }

    return super.appendChild(newChild);
  }
	/**
	 * @see ElemElement#setName(AVT)
	 */
	public void setName(AVT v) {
        if (v.isSimple())
        {
            if (v.getSimpleString().equals("xmlns"))
            {
                throw new IllegalArgumentException();
            }
        }
		super.setName(v);

FUNC_DECL IF VAR_DECL PARAM CALL RETURN IF VAR_DECL VAR_DECL VAR_DECL IF CALL CALL CALL CALL CALL CALL CALL CALL CALL CALL

FUNC_DECL IF PARAM CALL IF CALL THROW_RAISE CALL CALL LITERAL_ANCHOR


org.gjt.sp.jedit.gui.EnhancedDialog

public abstract class EnhancedDialog extends JDialog
{
	public EnhancedDialog(Frame parent, String title, boolean modal)
	{
		super(parent,title,modal);

		((Container)getLayeredPane()).addContainerListener(
			new ContainerHandler());
		getContentPane().addContainerListener(new ContainerHandler());

		keyHandler = new KeyHandler();
		addKeyListener(keyHandler);
		addWindowListener(new WindowHandler());

		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
	}

	public abstract void ok();
	public abstract void cancel();

	// protected members
	protected KeyHandler keyHandler;

	// Recursively adds our key listener to sub-components
	class ContainerHandler extends ContainerAdapter
	{
		public void componentAdded(ContainerEvent evt)
		{
			componentAdded(evt.getChild());
		}

		public void componentRemoved(ContainerEvent evt)
		{
			componentRemoved(evt.getChild());
		}

		private void componentAdded(Component comp)
		{
			comp.addKeyListener(keyHandler);
			if(comp instanceof Container)
			{
				Container cont = (Container)comp;
				cont.addContainerListener(this);
				Component[] comps = cont.getComponents();
				for(int i = 0; i < comps.length; i++)
				{
					componentAdded(comps[i]);
				}
			}
		}

		private void componentRemoved(Component comp)
		{
			comp.removeKeyListener(keyHandler);
			if(comp instanceof Container)
			{
				Container cont = (Container)comp;
				cont.removeContainerListener(this);
				Component[] comps = cont.getComponents();
				for(int i = 0; i < comps.length; i++)
				{
					componentRemoved(comps[i]);
				}
			}
		}
	}

	class KeyHandler extends KeyAdapter
	{
		public void keyPressed(KeyEvent evt)
		{
			if(evt.isConsumed())
				return;

			if(evt.getKeyCode() == KeyEvent.VK_ENTER)
			{
				// crusty workaround
				Component comp = getFocusOwner();
				while(comp != null)
				{
					if(comp instanceof JComboBox)
					{
						JComboBox combo = (JComboBox)comp;
						if(combo.isEditable())
						{
							Object selected = combo.getEditor().getItem();
							if(selected != null)
								combo.setSelectedItem(selected);
						}
						break;
					}

					comp = comp.getParent();
				}

				ok();
				evt.consume();
			}
			else if(evt.getKeyCode() == KeyEvent.VK_ESCAPE)
			{
				cancel();
				evt.consume();
			}
		}
	}

	class WindowHandler extends WindowAdapter
	{
		public void windowClosing(WindowEvent evt)
		{
			cancel();

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


public class FilterSetCollection {

    private Vector filterSets = new Vector();

    public FilterSetCollection() {
    }

    public FilterSetCollection(FilterSet filterSet) {
        addFilterSet(filterSet);
    }

    public void addFilterSet(FilterSet filterSet) {
        filterSets.addElement(filterSet);
    }

    /**
     * Does replacement on the given string with token matching.
     * This uses the defined begintoken and endtoken values which default to @ for both.
     *
     * @param line  The line to process the tokens in.
     * @return      The string with the tokens replaced.
     */
    public String replaceTokens(String line) {
        String replacedLine = line;
        for (Enumeration e = filterSets.elements(); e.hasMoreElements();) {
            FilterSet filterSet = (FilterSet)e.nextElement();
            replacedLine = filterSet.replaceTokens(replacedLine);
        }
        return replacedLine;
    }

    /**
    * Test to see if this filter set it empty.
    *
    * @return   Return true if there are filter in this set otherwise false.
    */
    public boolean hasFilters() {
        for (Enumeration e = filterSets.elements(); e.hasMoreElements();) {
            FilterSet filterSet = (FilterSet)e.nextElement();
            if (filterSet.hasFilters()) {
                return true;
            }
        }
        return false;

FUNC_DECL RETURN LOOP VAR_DECL PARAM CALL VAR_DECL ASSIGN CALL CALL CALL

FUNC_DECL RETURN LOOP LITERAL_ANCHOR CALL IF VAR_DECL CALL CALL RETURN LITERAL_ANCHOR CALL


public abstract class ExtensionHandler
{

  /** uri of the extension namespace */
  protected String m_namespaceUri;

  /** scripting language of implementation */
  protected String m_scriptLang;

  /**
   * This method loads a class using the context class loader if we're
   * running under Java2 or higher.
   *
   * @param className Name of the class to load
   */
  static Class getClassForName(String className)
      throws ClassNotFoundException
  {
    if(className.equals("org.apache.xalan.xslt.extensions.Redirect")) {
      className = "org.apache.xalan.lib.Redirect";
    }

    return ObjectFactory.findProviderClass(
        className, ObjectFactory.findClassLoader(), true);
  }

  /**
   * Construct a new extension namespace handler given all the information
   * needed.
   *
   * @param namespaceUri the extension namespace URI that I'm implementing
   * @param scriptLang   language of code implementing the extension
   */
  protected ExtensionHandler(String namespaceUri, String scriptLang)
  {
    m_namespaceUri = namespaceUri;
    m_scriptLang = scriptLang;
  }

  /**
   * Tests whether a certain function name is known within this namespace.
   * @param function name of the function being tested
   * @return true if its known, false if not.
   */
  public abstract boolean isFunctionAvailable(String function);

  /**
   * Tests whether a certain element name is known within this namespace.
   * @param element Name of element to check
   * @return true if its known, false if not.
   */
  public abstract boolean isElementAvailable(String element);

  /**
   * Process a call to a function.
   *
   * @param funcName Function name.
   * @param args     The arguments of the function call.
   * @param methodKey A key that uniquely identifies this class and method call.
   * @param exprContext The context in which this expression is being executed.
   *
   * @return the return value of the function evaluation.
   *
   * @throws TransformerException          if parsing trouble
   */
  public abstract Object callFunction(
    String funcName, Vector args, Object methodKey,
      ExpressionContext exprContext) throws TransformerException;

  /**
   * Process a call to a function.
   *
   * @param extFunction The XPath extension function.
   * @param args     The arguments of the function call.
   * @param exprContext The context in which this expression is being executed.
   *
   * @return the return value of the function evaluation.
   *
   * @throws TransformerException          if parsing trouble
   */
  public abstract Object callFunction(
    FuncExtFunction extFunction, Vector args,
      ExpressionContext exprContext) throws TransformerException;

  /**
   * Process a call to this extension namespace via an element. As a side
   * effect, the results are sent to the TransformerImpl's result tree.
   *
   * @param localPart      Element name's local part.
   * @param element        The extension element being processed.
   * @param transformer    Handle to TransformerImpl.
   * @param stylesheetTree The compiled stylesheet tree.
   * @param methodKey      A key that uniquely identifies this class and method call.
   *
   * @throws XSLProcessorException thrown if something goes wrong
   *            while running the extension handler.
   * @throws MalformedURLException if loading trouble
   * @throws FileNotFoundException if loading trouble
   * @throws IOException           if loading trouble
   * @throws TransformerException  if parsing trouble
   */
  public abstract void processElement(
    String localPart, ElemTemplateElement element, TransformerImpl transformer,
      Stylesheet stylesheetTree, Object methodKey) throws TransformerException, IOException;


org.apache.xpath.XPath

public class XPath implements Serializable, ExpressionOwner
{

  /** The top of the expression tree.
   *  @serial */
  private Expression m_mainExp;

  /**
   * Get the raw Expression object that this class wraps.
   *
   *
   * @return the raw Expression object, which should not normally be null.
   */
  public Expression getExpression()
  {
    return m_mainExp;
  }

  /**
   * This function is used to fixup variables from QNames to stack frame
   * indexes at stylesheet build time.
   * @param vars List of QNames that correspond to variables.  This list
   * should be searched backwards for the first qualified name that
   * corresponds to the variable reference qname.  The position of the
   * QName in the vector from the start of the vector will be its position
   * in the stack frame (but variables above the globalsTop value will need
   * to be offset to the current stack frame).
   */
  public void fixupVariables(java.util.Vector vars, int globalsSize)
  {
    m_mainExp.fixupVariables(vars, globalsSize);
  }

  /**
   * Set the raw expression object for this object.
   *
   *
   * @param exp the raw Expression object, which should not normally be null.
   */
  public void setExpression(Expression exp)
  {
  	if(null != m_mainExp)
    m_mainExp = exp;
  }

  /**
   * Get the SourceLocator on the expression object.
   *
   *
   * @return the SourceLocator on the expression object, which may be null.
   */
  public SourceLocator getLocator()
  {
    return m_mainExp;
  }

  /** The pattern string, mainly kept around for diagnostic purposes.
   *  @serial  */
  String m_patternString;

  /**
   * Return the XPath string associated with this object.
   *
   *
   * @return the XPath string associated with this object.
   */
  public String getPatternString()
  {
    return m_patternString;
  }

  /** Represents a select type expression. */
  public static final int SELECT = 0;

  /** Represents a match type expression.  */
  public static final int MATCH = 1;

  /**
   * Construct an XPath object.
   *
   * (Needs review -sc) This method initializes an XPathParser/
   * Compiler and compiles the expression.
   * @param exprString The XPath expression.
   * @param locator The location of the expression, may be null.
   * @param prefixResolver A prefix resolver to use to resolve prefixes to
   *                       namespace URIs.
   * @param type one of {@link #SELECT} or {@link #MATCH}.
   * @param errorListener The error listener, or null if default should be used.
   *
   * @throws javax.xml.transform.TransformerException if syntax or other error.
   */
  public XPath(
          String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type,
          ErrorListener errorListener)
            throws javax.xml.transform.TransformerException
  {
    if(null == errorListener)
      errorListener = new org.apache.xml.utils.DefaultErrorHandler();

    m_patternString = exprString;

    XPathParser parser = new XPathParser(errorListener, locator);
    Compiler compiler = new Compiler(errorListener, locator);

    if (SELECT == type)
      parser.initXPath(compiler, exprString, prefixResolver);
    else if (MATCH == type)
      parser.initMatchPattern(compiler, exprString, prefixResolver);
    else{}

    Expression expr = compiler.compile(0);

    this.setExpression(expr);

    if((null != locator) && locator instanceof ExpressionNode)
    {
    	expr.exprSetParent((ExpressionNode)locator);
    }

  }

  /**
   * Construct an XPath object.
   *
   * (Needs review -sc) This method initializes an XPathParser/
   * Compiler and compiles the expression.
   * @param exprString The XPath expression.
   * @param locator The location of the expression, may be null.
   * @param prefixResolver A prefix resolver to use to resolve prefixes to
   *                       namespace URIs.
   * @param type one of {@link #SELECT} or {@link #MATCH}.
   *
   * @throws javax.xml.transform.TransformerException if syntax or other error.
   */
  public XPath(
          String exprString, SourceLocator locator, PrefixResolver prefixResolver, int type)
            throws javax.xml.transform.TransformerException
  {
    this(exprString, locator, prefixResolver, type, null);
  }

  /**
   * Construct an XPath object.
   *
   * @param expr The Expression object.
   *
   * @throws javax.xml.transform.TransformerException if syntax or other error.
   */
  public XPath(Expression expr)
  {
    this.setExpression(expr);
  }

  /**
   * Given an expression and a context, evaluate the XPath
   * and return the result.
   *
   * @param xctxt The execution context.
   * @param contextNode The node that "." expresses.
   * @param namespaceContext The context in which namespaces in the
   * XPath are supposed to be expanded.
   *
   * @return The result of the XPath or null if callbacks are used.
   * @throws TransformerException thrown if
   * the error condition is severe enough to halt processing.
   *
   * @throws javax.xml.transform.TransformerException
   * @xsl.usage experimental
   */
  public XObject execute(
          XPathContext xctxt, org.w3c.dom.Node contextNode,
          PrefixResolver namespaceContext)
            throws javax.xml.transform.TransformerException
  {
    return execute(
          xctxt, xctxt.getDTMHandleFromNode(contextNode),
          namespaceContext);
  }

  /**
   * Given an expression and a context, evaluate the XPath
   * and return the result.
   *
   * @param xctxt The execution context.
   * @param contextNode The node that "." expresses.
   * @param namespaceContext The context in which namespaces in the
   * XPath are supposed to be expanded.
   *
   * @throws TransformerException thrown if the active ProblemListener decides
   * the error condition is severe enough to halt processing.
   *
   * @throws javax.xml.transform.TransformerException
   * @xsl.usage experimental
   */
  public XObject execute(
          XPathContext xctxt, int contextNode, PrefixResolver namespaceContext)
            throws javax.xml.transform.TransformerException
  {

    xctxt.pushNamespaceContext(namespaceContext);

    xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);

    XObject xobj = null;

    try
    {
      xobj = m_mainExp.execute(xctxt);
    }
    catch (TransformerException te)
    {
      te.setLocator(this.getLocator());
      ErrorListener el = xctxt.getErrorListener();
      if(true){
        el.error(te);
      }
      else
        throw te;
    }
    catch (Exception e)
    {
      while (e instanceof org.apache.xml.utils.WrappedRuntimeException)
      {
        e = ((org.apache.xml.utils.WrappedRuntimeException) e).getException();
      }

      String msg = e.getMessage();

      if (msg == null || msg.length() == 0) {
           msg = XSLMessages.createXPATHMessage(
               XPATHErrorResources.ER_XPATH_ERROR, null);

      }
      TransformerException te = new TransformerException(msg,
              getLocator(), e);
      ErrorListener el = xctxt.getErrorListener();
      if(true){
        el.fatalError(te);
      }
      else
        throw te;
    }
    finally
    {
      xctxt.popNamespaceContext();

      xctxt.popCurrentNodeAndExpression();
    }

    return xobj;
  }

  /**
   * Given an expression and a context, evaluate the XPath
   * and return the result.
   *
   * @param xctxt The execution context.
   * @param contextNode The node that "." expresses.
   * @param namespaceContext The context in which namespaces in the
   * XPath are supposed to be expanded.
   *
   * @throws TransformerException thrown if the active ProblemListener decides
   * the error condition is severe enough to halt processing.
   *
   * @throws javax.xml.transform.TransformerException
   * @xsl.usage experimental
   */
  public boolean bool(
          XPathContext xctxt, int contextNode, PrefixResolver namespaceContext)
            throws javax.xml.transform.TransformerException
  {

    xctxt.pushNamespaceContext(namespaceContext);

    xctxt.pushCurrentNodeAndExpression(contextNode, contextNode);

    try
    {
      return m_mainExp.bool(xctxt);
    }
    catch (TransformerException te)
    {
      te.setLocator(this.getLocator());
      ErrorListener el = xctxt.getErrorListener();
      if(true){
        el.error(te);
      }
      else
        throw te;
    }
    catch (Exception e)
    {
      while (e instanceof org.apache.xml.utils.WrappedRuntimeException)
      {
        e = ((org.apache.xml.utils.WrappedRuntimeException) e).getException();
      }

      String msg = e.getMessage();

      if (msg == null || msg.length() == 0) {
           msg = XSLMessages.createXPATHMessage(
               XPATHErrorResources.ER_XPATH_ERROR, null);

      }

      TransformerException te = new TransformerException(msg,
              getLocator(), e);
      ErrorListener el = xctxt.getErrorListener();
      if(true){
        el.fatalError(te);
      }
      else
        throw te;
    }
    finally
    {
      xctxt.popNamespaceContext();

      xctxt.popCurrentNodeAndExpression();
    }

    return false;
  }

  /** Set to true to get diagnostic messages about the result of
   *  match pattern testing.  */
  private static final boolean DEBUG_MATCHES = false;

  /**
   * Get the match score of the given node.
   *
   * @param xctxt XPath runtime context.
   * @param context The current source tree context node.
   *
   * @return score, one of {@link #MATCH_SCORE_NODETEST},
   * {@link #MATCH_SCORE_NONE}, {@link #MATCH_SCORE_OTHER},
   * or {@link #MATCH_SCORE_QNAME}.
   *
   * @throws javax.xml.transform.TransformerException
   */
  public double getMatchScore(XPathContext xctxt, int context)
          throws javax.xml.transform.TransformerException
  {

    xctxt.pushCurrentNode(context);
    xctxt.pushCurrentExpressionNode(context);

    try
    {
      XObject score = m_mainExp.execute(xctxt);

      if (DEBUG_MATCHES)
      {
        DTM dtm = xctxt.getDTM(context);
        System.out.println("score: " + score.num() + " for "
                           + dtm.getNodeName(context) + " for xpath "
                           + this.getPatternString());
      }

      return score.num();
    }
    finally
    {
      xctxt.popCurrentNode();
      xctxt.popCurrentExpressionNode();
    }

  }

  /**
   * Install a built-in function.
   * @param name The unqualified name of the function; not currently used.
   * @param funcIndex The index of the function in the table.
   * @param func An Implementation of an XPath Function object.
   * @return the position of the function in the internal index.
   */
  public void installFunction(String name, int funcIndex, Function func)
  {
    FunctionTable.installFunction(func, funcIndex);
  }

  /**
   * Warn the user of an problem.
   *
   * @param xctxt The XPath runtime context.
   * @param sourceNode Not used.
   * @param msg An error msgkey that corresponds to one of the constants found
   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is
   *            a key for a format string.
   * @param args An array of arguments represented in the format string, which
   *             may be null.
   *
   * @throws TransformerException if the current ErrorListoner determines to
   *                              throw an exception.
   */
  public void warn(
          XPathContext xctxt, int sourceNode, String msg, Object[] args)
            throws javax.xml.transform.TransformerException
  {

    String fmsg = XSLMessages.createXPATHWarning(msg, args);
    ErrorListener ehandler = xctxt.getErrorListener();

    if (null != ehandler)
    {

      ehandler.warning(new TransformerException(fmsg, (SAXSourceLocator)xctxt.getSAXLocator()));
    }
  }

  /**
   * Tell the user of an assertion error, and probably throw an
   * exception.
   *
   * @param b  If false, a runtime exception will be thrown.
   * @param msg The assertion message, which should be informative.
   *
   * @throws RuntimeException if the b argument is false.
   */
  public void assertion(boolean b, String msg)
  {

    if (!b)
    {
      String fMsg = XSLMessages.createXPATHMessage(
        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
        new Object[]{ msg });

      throw new RuntimeException(fMsg);
    }
  }

  /**
   * Tell the user of an error, and probably throw an
   * exception.
   *
   * @param xctxt The XPath runtime context.
   * @param sourceNode Not used.
   * @param msg An error msgkey that corresponds to one of the constants found
   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is
   *            a key for a format string.
   * @param args An array of arguments represented in the format string, which
   *             may be null.
   *
   * @throws TransformerException if the current ErrorListoner determines to
   *                              throw an exception.
   */
  public void error(
          XPathContext xctxt, int sourceNode, String msg, Object[] args)
            throws javax.xml.transform.TransformerException
  {

    String fmsg = XSLMessages.createXPATHMessage(msg, args);
    ErrorListener ehandler = xctxt.getErrorListener();

    if (null != ehandler)
    {
      ehandler.fatalError(new TransformerException(fmsg,
                              (SAXSourceLocator)xctxt.getSAXLocator()));
    }
    else
    {
      SourceLocator slocator = xctxt.getSAXLocator();
      System.out.println(fmsg + "; file " + slocator.getSystemId()
                         + "; line " + slocator.getLineNumber() + "; column "
                         + slocator.getColumnNumber());
    }
  }

  /**
   * This will traverse the heararchy, calling the visitor for
   * each member.  If the called visitor method returns
   * false, the subtree should not be called.
   *
   * @param owner The owner of the visitor, where that path may be
   *              rewritten if needed.
   * @param visitor The visitor whose appropriate method will be called.
   */
  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
  {
  	m_mainExp.callVisitors(this, visitor);
  }

  /**
   * The match score if no match is made.
   * @xsl.usage advanced
   */
  public static final double MATCH_SCORE_NONE = Double.NEGATIVE_INFINITY;

  /**
   * The match score if the pattern has the form
   * of a QName optionally preceded by an @ character.
   * @xsl.usage advanced
   */
  public static final double MATCH_SCORE_QNAME = 0.0;

  /**
   * The match score if the pattern pattern has the form NCName:*.
   * @xsl.usage advanced
   */
  public static final double MATCH_SCORE_NSWILD = -0.25;

  /**
   * The match score if the pattern consists of just a NodeTest.
   * @xsl.usage advanced
   */
  public static final double MATCH_SCORE_NODETEST = -0.5;

  /**
   * The match score if the pattern consists of something
   * other than just a NodeTest or just a qname.
   * @xsl.usage advanced
   */
  public static final double MATCH_SCORE_OTHER = 0.5;

FUNC_DECL RETURN PARAM PARAM PARAM CALL CALL

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

FUNC_DECL PARAM PARAM PARAM PARAM LITERAL_ANCHOR


org.gjt.sp.jedit.gui.JEditMetalTheme

public class JEditMetalTheme extends DefaultMetalTheme
{
	public String getName()
	{
		return "jEdit";
	}

	public ColorUIResource getSystemTextColor()
	{
		return getBlack();
	}

	public FontUIResource getControlTextFont()
	{
		return primaryFont;
	}

	public FontUIResource getSystemTextFont()
	{
		return secondaryFont;
	}

	public FontUIResource getUserTextFont()
	{
		return secondaryFont;
	}

	public FontUIResource getMenuTextFont()
	{
		return primaryFont;
	}

	public void propertiesChanged()
	{
		primaryFont = new FontUIResource(
			jEdit.getFontProperty("metal.primary.font",
			super.getControlTextFont()));
		secondaryFont = new FontUIResource(
			jEdit.getFontProperty("metal.secondary.font",
			super.getSystemTextFont()));
	}

	// private members
	private FontUIResource primaryFont;
	private FontUIResource secondaryFont;

FUNC_DECL ASSIGN ASSIGN CALL CALL CALL CALL LITERAL_ANCHOR LITERAL_ANCHOR


org.apache.poi.poifs.property.Parent

public interface Parent
    extends Child
{

    /**
     * Get an iterator over the children of this Parent; all elements
     * are instances of Property.
     *
     * @return Iterator of children; may refer to an empty collection
     */

    public Iterator getChildren();

    /**
     * Add a new child to the collection of children
     *
     * @param property the new child to be added; must not be null
     *
     * @exception IOException if the Parent already has a child with
     *                        the same name
     */

    public void addChild(final Property property)
        throws IOException;

    /**
     * Set the previous Child
     *
     * @param child the new 'previous' child; may be null, which has
     *              the effect of saying there is no 'previous' child
     */

    public void setPreviousChild(final Child child);

    /**
     * Set the next Child
     *
     * @param child the new 'next' child; may be null, which has the
     *              effect of saying there is no 'next' child
     */

    public void setNextChild(final Child child);


org.apache.camel.model.OtherwiseType

@XmlRootElement(name = "otherwise")
@XmlAccessorType(XmlAccessType.FIELD)
public class OtherwiseType extends OutputType<ProcessorType> implements Block {

    @Override
    public String toString() {
        return "Otherwise[" + getOutputs() + "]";
    }

    @Override
    public Processor createProcessor(RouteContext routeContext) throws Exception {
        return routeContext.createProcessor(this);
    }

    @Override
    public String getShortName() {
        return "otherwise";
    }

    @Override
    public String getLabel() {
        return "otherwise";


public class XmlSettingsParser extends DefaultHandler {
    /**
     * Wraps an {@link IvyVariableContainer} delegating most method calls to the wrapped instance,
     * except for a set of variables which are only stored locally in the wrapper, and not
     * propagated to the wrapped instance.
     */
    private static final class IvyVariableContainerWrapper implements IvyVariableContainer {
        private static final Collection SETTINGS_VARIABLES = Arrays.asList(new String[] {
                "ivy.settings.dir", "ivy.settings.url", "ivy.settings.file",
                "ivy.conf.dir", "ivy.conf.url", "ivy.conf.file"});

        private final IvyVariableContainer variables;

        private Map localVariables = new HashMap();

        private IvyVariableContainerWrapper(IvyVariableContainer variables) {
            this.variables = variables;
        }

        public void setVariable(String varName, String value, boolean overwrite) {
            if (SETTINGS_VARIABLES.contains(varName)) {
                if (!localVariables.containsKey(varName) || overwrite) {
                    localVariables.put(varName, value);
                }
            } else {
                variables.setVariable(varName, value, overwrite);
            }
        }

        public void setEnvironmentPrefix(String prefix) {
            variables.setEnvironmentPrefix(prefix);
        }

        public String getVariable(String name) {
            if (localVariables.containsKey(name)) {
                return (String) localVariables.get(name);
            }
            return variables.getVariable(name);
        }

        public Object clone() {
            throw new UnsupportedOperationException();
        }
    }

    private Configurator configurator;

    private List configuratorTags = Arrays.asList(new String[] {"resolvers", "namespaces",
            "parsers", "latest-strategies", "conflict-managers", "outputters", "version-matchers",
            "statuses", "circular-dependency-strategies", "triggers", "lock-strategies",
            "caches"});

    private IvySettings ivy;

    private String defaultResolver;

    private String defaultCM;

    private String defaultLatest;

    private String defaultCacheManager;

    private String defaultCircular;

    private String defaultLock;

    private String currentConfiguratorTag;

    private URL settings;

    private boolean deprecatedMessagePrinted = false;

    public XmlSettingsParser(IvySettings ivy) {
        this.ivy = ivy;
    }

    public void parse(URL settings) throws ParseException, IOException {
        configurator = new Configurator();
        configurator.setFileResolver(new FileResolver() {
            public File resolveFile(String path, String filename) {
                return Checks.checkAbsolute(path, filename);
            }
        });
        // put every type definition from ivy to configurator
        Map typeDefs = ivy.getTypeDefs();
        for (Iterator iter = typeDefs.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            configurator.typeDef(name, (Class) typeDefs.get(name));
        }

        doParse(settings);
    }

    private void doParse(URL settingsUrl) throws IOException, ParseException {
        this.settings = settingsUrl;
        InputStream stream = null;
        try {
            stream = URLHandlerRegistry.getDefault().openStream(settingsUrl);
            InputSource inSrc = new InputSource(stream);
            inSrc.setSystemId(settingsUrl.toExternalForm());
            SAXParserFactory.newInstance().newSAXParser().parse(settingsUrl.toExternalForm(), this);
            ivy.validate();
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            ParseException pe = new ParseException("failed to load settings from " + settingsUrl
                    + ": " + e.getMessage(), 0);
            pe.initCause(e);
            throw pe;
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    // ingnored
                }
            }
        }
    }

    private void parse(Configurator configurator, URL configuration) throws IOException,
            ParseException {
        this.configurator = configurator;
        doParse(configuration);
    }

    public void startElement(String uri, String localName, String qName, Attributes att)
            throws SAXException {
        // we first copy attributes in a Map to be able to modify them
        Map attributes = new HashMap();
        for (int i = 0; i < att.getLength(); i++) {
            attributes.put(att.getQName(i), ivy.substitute(att.getValue(i)));
        }

        try {
            if ("ivyconf".equals(qName)) {
                deprecatedMessagePrinted = true;
                Message.deprecated("'ivyconf' element is deprecated, use 'ivysettings' instead ("
                        + settings + ")");
            }
            if (configurator.getCurrent() != null) {
                inConfiguratorStarted(qName, attributes);
            } else if ("classpath".equals(qName)) {
                classpathStarted(attributes);
            } else if ("typedef".equals(qName)) {
                typedefStarted(attributes);
            } else if ("property".equals(qName)) {
                propertyStarted(attributes);
            } else if ("properties".equals(qName)) {
                propertiesStarted(attributes);
            } else if ("include".equals(qName)) {
                includeStarted(attributes);
            } else if ("settings".equals(qName) || "conf".equals(qName)) {
                settingsStarted(qName, attributes);
            } else if ("caches".equals(qName)) {
                cachesStarted(qName, attributes);
            } else if ("version-matchers".equals(qName)) {
                versionMatchersStarted(qName, attributes);
            } else if ("statuses".equals(qName)) {
                statusesStarted(qName, attributes);
            } else if (configuratorTags.contains(qName)) {
                anyConfiguratorStarted(qName);
            } else if ("macrodef".equals(qName)) {
                macrodefStarted(qName, attributes);
            } else if ("module".equals(qName)) {
                moduleStarted(attributes);
            } else if ("credentials".equals(qName)) {
                credentialsStarted(attributes);
            }
        } catch (ParseException ex) {
            SAXException sax = new SAXException("problem in config file: " + ex.getMessage(), ex);
            sax.initCause(ex);
            throw sax;
        } catch (IOException ex) {
            SAXException sax = new SAXException("io problem while parsing config file: "
                        + ex.getMessage(), ex);
            sax.initCause(ex);
            throw sax;
        }
    }

    private void credentialsStarted(Map attributes) {
        String realm = (String) attributes.remove("realm");
        String host = (String) attributes.remove("host");
        String userName = (String) attributes.remove("username");
        String passwd = (String) attributes.remove("passwd");
        CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd);
    }

    private void moduleStarted(Map attributes) {
        attributes.put(IvyPatternHelper.MODULE_KEY, attributes.remove("name"));
        String resolver = (String) attributes.remove("resolver");
        String branch = (String) attributes.remove("branch");
        String cm = (String) attributes.remove("conflict-manager");
        String resolveMode = (String) attributes.remove("resolveMode");
        String matcher = (String) attributes.remove("matcher");
        matcher = matcher == null ? PatternMatcher.EXACT_OR_REGEXP : matcher;
        ivy.addModuleConfiguration(attributes, ivy
                .getMatcher(matcher), resolver, branch, cm, resolveMode);
    }

    private void macrodefStarted(String qName, Map attributes) {
        currentConfiguratorTag = qName;
        Configurator.MacroDef macrodef = configurator.startMacroDef((String) attributes
                .get("name"));
        macrodef.addAttribute("name", null);
    }

    private void anyConfiguratorStarted(String qName) {
        currentConfiguratorTag = qName;
        configurator.setRoot(ivy);
    }

    private void statusesStarted(String qName, Map attributes) {
        currentConfiguratorTag = qName;
        StatusManager m = new StatusManager();
        String defaultStatus = (String) attributes.get("default");
        if (defaultStatus != null) {
            m.setDefaultStatus(defaultStatus);
        }
        ivy.setStatusManager(m);
        configurator.setRoot(m);
    }

    private void versionMatchersStarted(String qName, Map attributes) {
        anyConfiguratorStarted(qName);
        if ("true".equals((String) attributes.get("usedefaults"))) {
            ivy.configureDefaultVersionMatcher();
        }
    }

    private void cachesStarted(String qName, Map attributes) {
        anyConfiguratorStarted(qName);
        defaultLock = (String) attributes.get("lockStrategy");
        defaultCacheManager = (String) attributes.get("default");

        String cache = (String) attributes.get("defaultCacheDir");
        if (cache != null) {
            ivy.setDefaultCache(Checks.checkAbsolute(cache, "defaultCacheDir"));
        }
        String up2d = (String) attributes.get("checkUpToDate");
        if (up2d != null) {
            ivy.setCheckUpToDate(Boolean.valueOf(up2d).booleanValue());
        }
        String resolutionDir = (String) attributes.get("resolutionCacheDir");
        if (resolutionDir != null) {
            ivy.setDefaultResolutionCacheBasedir(resolutionDir);
        }
        String useOrigin = (String) attributes.get("useOrigin");
        if (useOrigin != null) {
            ivy.setDefaultUseOrigin(Boolean.valueOf(useOrigin).booleanValue());
        }
        String cacheIvyPattern = (String) attributes.get("ivyPattern");
        if (cacheIvyPattern != null) {
            ivy.setDefaultCacheIvyPattern(cacheIvyPattern);
        }
        String cacheArtPattern = (String) attributes.get("artifactPattern");
        if (cacheArtPattern != null) {
            ivy.setDefaultCacheArtifactPattern(cacheArtPattern);
        }
        String repositoryDir = (String) attributes.get("repositoryCacheDir");
        if (repositoryDir != null) {
            ivy.setDefaultRepositoryCacheBasedir(repositoryDir);
        }
    }

    private void settingsStarted(String qName, Map attributes) {
        if ("conf".equals(qName) && !deprecatedMessagePrinted) {
            Message.deprecated(
                "'conf' is deprecated, use 'settings' instead (" + settings + ")");
        }
        String cache = (String) attributes.get("defaultCache");
        if (cache != null) {
            Message.deprecated("'defaultCache' is deprecated, "
                + "use 'caches[@defaultCacheDir]' instead (" + settings + ")");
            ivy.setDefaultCache(Checks.checkAbsolute(cache, "defaultCache"));
        }
        String defaultBranch = (String) attributes.get("defaultBranch");
        if (defaultBranch != null) {
            ivy.setDefaultBranch(defaultBranch);
        }
        String defaultResolveMode = (String) attributes.get("defaultResolveMode");
        if (defaultResolveMode != null) {
            ivy.setDefaultResolveMode(defaultResolveMode);
        }
        String validate = (String) attributes.get("validate");
        if (validate != null) {
            ivy.setValidate(Boolean.valueOf(validate).booleanValue());
        }
        String up2d = (String) attributes.get("checkUpToDate");
        if (up2d != null) {
            Message.deprecated("'checkUpToDate' is deprecated, "
                + "use 'caches[@checkUpToDate]' instead (" + settings + ")");
            ivy.setCheckUpToDate(Boolean.valueOf(up2d).booleanValue());
        }
        String useRemoteConfig = (String) attributes.get("useRemoteConfig");
        if (useRemoteConfig != null) {
            ivy.setUseRemoteConfig(Boolean.valueOf(useRemoteConfig)
                    .booleanValue());
        }
        String cacheIvyPattern = (String) attributes.get("cacheIvyPattern");
        if (cacheIvyPattern != null) {
            Message.deprecated(
                "'cacheIvyPattern' is deprecated, use 'caches[@ivyPattern]' instead"
                + " (" + settings + ")");
            ivy.setDefaultCacheIvyPattern(cacheIvyPattern);
        }
        String cacheArtPattern = (String) attributes.get("cacheArtifactPattern");
        if (cacheArtPattern != null) {
            Message.deprecated(
                "'cacheArtifactPattern' is deprecated, "
                + "use 'caches[@artifactPattern]' instead (" + settings + ")");
            ivy.setDefaultCacheArtifactPattern(cacheArtPattern);
        }

        // we do not set following defaults here since no instances has been registered yet
        defaultResolver = (String) attributes.get("defaultResolver");
        defaultCM = (String) attributes.get("defaultConflictManager");
        defaultLatest = (String) attributes.get("defaultLatestStrategy");
        defaultCircular = (String) attributes.get("circularDependencyStrategy");

        String requestMethod = (String) attributes.get("httpRequestMethod");
        if ("head".equalsIgnoreCase(requestMethod)) {
            URLHandlerRegistry.getHttp().setRequestMethod(URLHandler.REQUEST_METHOD_HEAD);
        } else if ("get".equalsIgnoreCase(requestMethod)) {
            URLHandlerRegistry.getHttp().setRequestMethod(URLHandler.REQUEST_METHOD_GET);
        } else if ((requestMethod != null) && (requestMethod.trim().length() > 0)) {
            throw new IllegalArgumentException("Invalid httpRequestMethod specified, must be "
                + "one of {'HEAD', 'GET'}");
        }
    }

    private void includeStarted(Map attributes) throws IOException, ParseException {
        final IvyVariableContainer variables = (IvyVariableContainer) ivy.getVariableContainer();
        ivy.setVariableContainer(new IvyVariableContainerWrapper(variables));
        try {
            String propFilePath = (String) attributes.get("file");
            URL settingsURL = null;
            if (propFilePath == null) {
                propFilePath = (String) attributes.get("url");
                if (propFilePath == null) {
                    throw new IllegalArgumentException(
                        "bad include tag: specify file or url to include");
                } else {
                    try {
                        //First asume that it is an absolute URL
                        settingsURL = new URL(propFilePath);
                    } catch (MalformedURLException e) {
                        //If that fail, it may be because it is a relative one.
                        settingsURL = new URL(this.settings , propFilePath);
                    }
                    Message.verbose("including url: " + settingsURL.toString());
                    ivy.setSettingsVariables(settingsURL);
                }
            } else {
                settingsURL = urlFromFileAttribute(propFilePath);
                Message.verbose("including file: " + settingsURL);
                if ("file".equals(settingsURL.getProtocol())) {
                    ivy.setSettingsVariables(
                        Checks.checkAbsolute(settingsURL.getPath(),
                        "settings include path"));
                } else {
                    ivy.setSettingsVariables(settingsURL);
                }
            }
            new XmlSettingsParser(ivy).parse(configurator, settingsURL);
        } finally {
            ivy.setVariableContainer(variables);
        }
    }

    /** Provide an URL referencing the given filepath.  If filePath is an absolute path, then
     * the resulting URL point to a local file, otherwise, the filepath is evaluated relatively
     * to the URL of the current settings file (can be local file or remote URL).
     */
    private URL urlFromFileAttribute(String filePath) throws MalformedURLException {
        try {
            return new URL(filePath);
        } catch (MalformedURLException e) {
            // ignore, we'll try to create a correct URL below
        }

        File incFile = new File(filePath);
        if (incFile.isAbsolute()) {
            return incFile.toURI().toURL();
        } else if ("file".equals(this.settings.getProtocol())) {
            try {
                File settingsFile = new File(new URI(this.settings.toExternalForm()));
                return new File(settingsFile.getParentFile(), filePath).toURI().toURL();
            } catch (URISyntaxException e) {
                return new URL(this.settings , filePath);
            }
        } else {
            return new URL(this.settings , filePath);
        }
    }

    private void propertiesStarted(Map attributes) throws IOException {
        String propFilePath = (String) attributes.get("file");
        String environmentPrefix = (String) attributes.get("environment");
        if (propFilePath != null) {
            String overrideStr = (String) attributes.get("override");
            boolean override = overrideStr == null ? true
                                                   : Boolean.valueOf(overrideStr).booleanValue();
            Message.verbose("loading properties: " + propFilePath);
            URL fileUrl = urlFromFileAttribute(propFilePath);
            ivy.loadProperties(fileUrl, override);
        } else if (environmentPrefix != null) {
            ivy.getVariableContainer().setEnvironmentPrefix(environmentPrefix);
        } else {
            throw new IllegalArgumentException(
                "Didn't find a 'file' or 'environment' attribute "
                + "on the 'properties' element");
        }
    }

    private void propertyStarted(Map attributes) {
        String name = (String) attributes.get("name");
        String value = (String) attributes.get("value");
        String override = (String) attributes.get("override");
        if (name == null) {
            throw new IllegalArgumentException("missing attribute name on property tag");
        }
        if (value == null) {
            throw new IllegalArgumentException("missing attribute value on property tag");
        }
        ivy.setVariable(name, value, override == null ? true : Boolean.valueOf(override)
                .booleanValue());
    }

    private void typedefStarted(Map attributes) {
        String name = (String) attributes.get("name");
        String className = (String) attributes.get("classname");
        Class clazz = ivy.typeDef(name, className);
        configurator.typeDef(name, clazz);
    }

    private void classpathStarted(Map attributes) throws MalformedURLException {
        String urlStr = (String) attributes.get("url");
        URL url = null;
        if (urlStr == null) {
            String file = (String) attributes.get("file");
            if (file == null) {
                throw new IllegalArgumentException(
                        "either url or file should be given for classpath element");
            } else {
                url = Checks.checkAbsolute(file, "classpath").toURI().toURL();
            }
        } else {
            url = new URL(urlStr);
        }
        ivy.addClasspathURL(url);
    }

    private void inConfiguratorStarted(String qName, Map attributes) {
        if ("macrodef".equals(currentConfiguratorTag)
                && configurator.getTypeDef(qName) != null) {
            String name = (String) attributes.get("name");
            if (name == null) {
                attributes.put("name", "@{name}");
            } else if (name.indexOf("@{name}") != -1) {
                attributes.put("name", name);
            } else {
                attributes.put("name", "@{name}-" + name);
            }
        }
        if (attributes.get("ref") != null) {
            if (attributes.size() != 1) {
                throw new IllegalArgumentException(
                        "ref attribute should be the only one ! found " + attributes.size()
                                + " in " + qName);
            }
            String name = (String) attributes.get("ref");
            Object child = null;
            if ("resolvers".equals(currentConfiguratorTag) || "resolver".equals(qName)) {
                child = ivy.getResolver(name);
                if (child == null) {
                    throw new IllegalArgumentException("unknown resolver " + name
                            + ": resolver should be defined before being referenced");
                }
            } else if ("latest-strategies".equals(currentConfiguratorTag)) {
                child = ivy.getLatestStrategy(name);
                if (child == null) {
                    throw new IllegalArgumentException("unknown latest strategy " + name
                           + ": latest strategy should be defined before being referenced");
                }
            } else if ("conflict-managers".equals(currentConfiguratorTag)) {
                child = ivy.getConflictManager(name);
                if (child == null) {
                    throw new IllegalArgumentException(
                         "unknown conflict manager " + name
                         + ": conflict manager should be defined before being referenced");
                }
            }
            if (child == null) {
                throw new IllegalArgumentException("bad reference " + name);
            }
            configurator.addChild(qName, child);
        } else {
            configurator.startCreateChild(qName);
            for (Iterator iter = attributes.keySet().iterator(); iter.hasNext();) {
                String attName = (String) iter.next();
                configurator.setAttribute(attName, (String) attributes
                        .get(attName));
            }
        }
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (configurator.getCurrent() != null) {
            if (configuratorTags.contains(qName) && configurator.getDepth() == 1) {
                configurator.clear();
                currentConfiguratorTag = null;
            } else if ("macrodef".equals(qName) && configurator.getDepth() == 1) {
                configurator.endMacroDef();
                currentConfiguratorTag = null;
            } else {
                configurator.endCreateChild();
            }
        }
    }

    public void endDocument() throws SAXException {
        if (defaultResolver != null) {
            ivy.setDefaultResolver(ivy.substitute(defaultResolver));
        }
        if (defaultCM != null) {
            ConflictManager conflictManager = ivy.getConflictManager(ivy.substitute(defaultCM));
            if (conflictManager == null) {
                throw new IllegalArgumentException("unknown conflict manager "
                        + ivy.substitute(defaultCM));
            }
            ivy.setDefaultConflictManager(conflictManager);
        }
        if (defaultLatest != null) {
            LatestStrategy latestStrategy = ivy.getLatestStrategy(ivy.substitute(defaultLatest));
            if (latestStrategy == null) {
                throw new IllegalArgumentException("unknown latest strategy "
                        + ivy.substitute(defaultLatest));
            }
            ivy.setDefaultLatestStrategy(latestStrategy);
        }
        if (defaultCacheManager != null) {
            RepositoryCacheManager cache = ivy.getRepositoryCacheManager(
                                                ivy.substitute(defaultCacheManager));
            if (cache == null) {
                throw new IllegalArgumentException("unknown cache manager "
                        + ivy.substitute(defaultCacheManager));
            }
            ivy.setDefaultRepositoryCacheManager(cache);
        }
        if (defaultCircular != null) {
            CircularDependencyStrategy strategy = ivy.getCircularDependencyStrategy(ivy
                    .substitute(defaultCircular));
            if (strategy == null) {
                throw new IllegalArgumentException("unknown circular dependency strategy "
                        + ivy.substitute(defaultCircular));
            }
            ivy.setCircularDependencyStrategy(strategy);
        }
        if (defaultLock != null) {
            LockStrategy strategy = ivy.getLockStrategy(ivy.substitute(defaultLock));
            if (strategy == null) {
                throw new IllegalArgumentException("unknown lock strategy "
                        + ivy.substitute(defaultLock));
            }
            ivy.setDefaultLockStrategy(strategy);

FUNC_DECL LOOP VAR_DECL PARAM CALL CALL CALL ASSIGN VAR_DECL CALL CALL CALL CALL CALL FUNC_DECL CALL RETURN PARAM PARAM CALL CALL CALL

FUNC_DECL IF PARAM PARAM LITERAL_ANCHOR CALL CALL CALL CALL LITERAL_ANCHOR

FUNC_DECL IF VAR_DECL TRY PARAM IF CALL CATCH RETURN LITERAL_ANCHOR RETURN CALL CALL RETURN TRY CALL CALL CALL CATCH RETURN VAR_DECL CALL RETURN CALL CALL CALL CALL CALL CALL CALL CALL CALL


public class MDArtifact extends AbstractArtifact {

    public static Artifact newIvyArtifact(ModuleDescriptor md) {
        return new MDArtifact(md, "ivy", "ivy", "xml", true);
    }

    private ModuleDescriptor md;

    private String name;

    private String type;

    private String ext;

    private List confs = new ArrayList();

    private Map extraAttributes = null;

    private URL url;

    private boolean isMetadata = false;

    public MDArtifact(ModuleDescriptor md, String name, String type, String ext) {
        this(md, name, type, ext, null, null);
    }

    public MDArtifact(ModuleDescriptor md,
            String name, String type, String ext, boolean isMetadata) {
        this(md, name, type, ext, null, null);
        this.isMetadata = isMetadata;
    }

    public MDArtifact(ModuleDescriptor md, String name, String type, String ext, URL url,
            Map extraAttributes) {
        if (md == null) {
            throw new NullPointerException("null module descriptor not allowed");
        }
        if (name == null) {
            throw new NullPointerException("null name not allowed");
        }
        if (type == null) {
            throw new NullPointerException("null type not allowed");
        }
        if (ext == null) {
            throw new NullPointerException("null ext not allowed");
        }
        this.md = md;
        this.name = name;
        this.type = type;
        this.ext = ext;
        this.url = url;
        this.extraAttributes = extraAttributes;
    }

    public ModuleRevisionId getModuleRevisionId() {
        return md.getResolvedModuleRevisionId();
    }

    public Date getPublicationDate() {
        return md.getResolvedPublicationDate();
    }

    public ArtifactRevisionId getId() {
        // do not cache the result because the resolvedModuleRevisionId can change!
        return ArtifactRevisionId.newInstance(md.getResolvedModuleRevisionId(), name, type,
                ext, extraAttributes);
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return type;
    }

    public String getExt() {
        return ext;
    }

    public String[] getConfigurations() {
        return (String[]) confs.toArray(new String[confs.size()]);
    }

    public void addConfiguration(String conf) {
        confs.add(conf);
    }

    public URL getUrl() {
        return url;
    }

    public boolean isMetadata() {
        return isMetadata;

    public String getName() {
        return name;

    public String getType() {
        return type;

    public String getExt() {
        return ext;

    public URL getUrl() {
        return url;

FUNC_DECL PARAM PARAM PARAM PARAM PARAM ASSIGN LITERAL_ANCHOR LITERAL_ANCHOR