/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.part.MultiPageEditorSite;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.wst.sse.ui.internal.extension.ActionDescriptor;
import org.eclipse.wst.sse.ui.internal.extension.RegistryReader;


/**
 * This class reads the registry for extensions that plug into 'editorActions'
 * extension point.
 */

public class ExtendedEditorActionBuilder extends RegistryReader {

	public class ExtendedContributor implements IExtendedContributor, IMenuListener {
		private IExtendedSimpleEditor activeExtendedEditor = null;

		private List cache;
		private Map map = new HashMap();
		private IMenuManager menuBar = null;

		private Set menus = new HashSet();

		public ExtendedContributor(List cache) {
			this.cache = cache;
		}

		public void contributeToMenu(IMenuManager menu) {
			menuBar = menu;
			long time0 = System.currentTimeMillis();
			for (int i = 0; i < cache.size(); i++) {
				Object obj = cache.get(i);
				if (obj instanceof IConfigurationElement) {
					IConfigurationElement menuElement = (IConfigurationElement) obj;
					if ((menuElement.getName()).equals(TAG_MENU)) {
						contributeMenu(menuElement, menu, true);
						if (debugMenu)
							System.out.println(getClass().getName() + "#contributeToMenu() added: " + menuElement.getAttribute(ATT_ID)); //$NON-NLS-1$
					}
				} else if (obj instanceof ActionDescriptor) {
					try {
						ActionDescriptor ad = (ActionDescriptor) obj;
						IMenuManager mm = contributeMenuAction(ad, menu, true, false);
						if (mm != null) {
							map.put(ad.getContributionItem(), mm);
							mm.addMenuListener(this);
							menus.add(mm);
							if (debugMenu)
								System.out.println(getClass().getName() + "#contributeToMenu() added: " + ad.getId()); //$NON-NLS-1$
						}
					} catch (Exception e) {
						Logger.logException("contributing to menu", e); //$NON-NLS-1$
					}
				}
			}
			if (debugContributeTime)
				System.out.println(getClass().getName() + "#contributeToMenu(): ran in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		public void contributeToPopupMenu(IMenuManager menu) {
			long time0 = System.currentTimeMillis();
			for (int i = 0; i < cache.size(); i++) {
				Object obj = cache.get(i);
				if (obj instanceof IConfigurationElement) {
					IConfigurationElement menuElement = (IConfigurationElement) obj;
					if ((menuElement.getName()).equals(TAG_POPUPMENU)) {
						contributeMenu(menuElement, menu, true);
					}
				} else if (obj instanceof ActionDescriptor) {
					try {
						ActionDescriptor ad = (ActionDescriptor) obj;
						IAction a = ad.getAction();
						if (a instanceof IExtendedEditorAction) {
							// uncaught exceptions could cause the menu to not
							// be shown
							try {

								IExtendedEditorAction eea = (IExtendedEditorAction) a;
								eea.setActiveExtendedEditor(activeExtendedEditor);
								eea.update();
								if (eea.isVisible()) {
									IMenuManager parent = contributeMenuAction(ad, menu, true, true);
									if (debugPopup && parent != null)
										System.out.println(getClass().getName() + "#contributeToPopupMenu() added: " + ad.getId()); //$NON-NLS-1$
								}
							} catch (Exception e) {
								Logger.logException(e);
							}

						} else {
							IMenuManager parent = contributeMenuAction(ad, menu, true, true);
							if (debugPopup && parent != null)
								System.out.println(getClass().getName() + "#contributeToPopupMenu() added: " + ad.getId()); //$NON-NLS-1$
						}
					} catch (Exception e) {
						Logger.logException("contributing to popup", e); //$NON-NLS-1$
					}
				}
			}
			if (debugContributeTime)
				System.out.println(getClass().getName() + "#contributeToPopupMenu(): ran in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		public void contributeToStatusLine(IStatusLineManager manager) {
			// nothing from here
		}

		public void contributeToToolBar(IToolBarManager manager) {
			long time0 = System.currentTimeMillis();
			for (int i = 0; i < cache.size(); i++) {
				Object obj = cache.get(i);
				if (obj instanceof ActionDescriptor) {
					try {
						ActionDescriptor ad = (ActionDescriptor) obj;
						IAction a = ad.getAction();
						if (a instanceof IExtendedEditorAction) {
							IExtendedEditorAction eea = (IExtendedEditorAction) a;
							eea.setActiveExtendedEditor(activeExtendedEditor);
							eea.update();
							if (eea.isVisible()) {
								boolean contributed = contributeToolbarAction(ad, manager, true);
								if (debugToolbar && contributed)
									System.out.println(getClass().getName() + "#contributeToToolBar() added: " + ad.getId()); //$NON-NLS-1$
							} else {
								if (debugToolbar)
									System.out.println(getClass().getName() + "#contributeToToolBar(): [skipped] " + ad.getId()); //$NON-NLS-1$
							}
						} else {
							boolean contributed = contributeToolbarAction(ad, manager, true);
							if (debugToolbar && contributed)
								System.out.println(getClass().getName() + "#contributeToToolBar() added: " + ad.getId()); //$NON-NLS-1$
						}
					} catch (Exception e) {
						Logger.logException("contributing to toolbar", e); //$NON-NLS-1$
					}
				}
			}
			if (debugContributeTime)
				System.out.println(getClass().getName() + "#contributeToToolBar(): ran in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
		}

		public void dispose() {
			Iterator it = menus.iterator();
			while (it.hasNext()) {
				Object o = it.next();
				if (o instanceof IMenuManager) {
					((IMenuManager) o).removeMenuListener(this);
				}
			}
		}

		public void init(IActionBars bars, IWorkbenchPage page) {
			// nothing from here
		}

		public void menuAboutToShow(IMenuManager menu) {
			// slows down the menu and interferes with it for other editors;
			// optimize on visibility
			IEditorSite site = null;
			boolean activeEditorIsVisible = false;

			if (activeExtendedEditor != null && activeExtendedEditor.getEditorPart() != null)
				site = activeExtendedEditor.getEditorPart().getEditorSite();
			if (site == null)
				return;

			// Eclipse bug 48784 - [MPE] ClassCast exception Workbench page
			// isPartVisiable for MultiPageSite
			if (site instanceof MultiPageEditorSite) {
				Object multiPageEditor = ((MultiPageEditorSite) site).getMultiPageEditor();
				activeEditorIsVisible = multiPageEditor.equals(site.getPage().getActiveEditor()) || multiPageEditor.equals(site.getPage().getActivePart());
			} else {
				activeEditorIsVisible = site.getWorkbenchWindow().getPartService().getActivePart().equals(activeExtendedEditor.getEditorPart());
			}
			if (!activeEditorIsVisible)
				return;

			IContributionItem[] items = menu.getItems();
			if (items == null || items.length == 0)
				return;

			for (int i = 0; i < items.length; ++i) {
				// add menu listener to submenu
				if (items[i] instanceof IMenuManager) {
					((IMenuManager) items[i]).addMenuListener(this);
					menus.add(items[i]);
				}
			}

			Set keys = map.keySet();
			Iterator it = keys.iterator();
			while (it.hasNext()) {
				IContributionItem item = (IContributionItem) it.next();
				IMenuManager mm = (IMenuManager) map.get(item);
				if (menu.getId() != null && menu.getId().equals(mm.getId()) && item instanceof ActionContributionItem) {
					try {
						IAction action = ((ActionContributionItem) item).getAction();

						if (action instanceof IUpdate) {
							((IUpdate) action).update();
						}

						boolean visible = true;
						if (action instanceof IExtendedEditorAction) {
							visible = ((IExtendedEditorAction) action).isVisible();
						}
						item.setVisible(visible);
					} catch (Exception e) {
						Logger.logException("updating actions", e); //$NON-NLS-1$
					}
				}
			}
			menu.update(false);
		}

		public void setActiveEditor(IEditorPart editor) {
			activeExtendedEditor = (editor instanceof IExtendedSimpleEditor) ? (IExtendedSimpleEditor) editor : null;
			IKeyBindingService svc = (editor != null) ? editor.getEditorSite().getKeyBindingService() : null;
			for (int i = 0; i < cache.size(); i++) {
				Object obj = cache.get(i);
				if (obj instanceof ActionDescriptor) {
					ActionDescriptor ad = (ActionDescriptor) obj;
					try {
						IAction action = ad.getAction();
						if (action instanceof IExtendedEditorAction) {
							((IExtendedEditorAction) action).setActiveExtendedEditor(activeExtendedEditor);
							((IExtendedEditorAction) action).update();
							// update visibility right now so that the menu
							// will show/hide properly
							if (!((IExtendedEditorAction) action).isVisible() && ad.getContributionItem() != null)
								ad.getContributionItem().setVisible(false);
							if (svc != null && action.getActionDefinitionId() != null) {
								svc.registerAction(action);
							}
						}
					} catch (Exception e) {
						Logger.logException("setting active editor on actions", e); //$NON-NLS-1$
					}
				}
			}

			if (menuBar != null && editor != null) {
				//				Class clz = editor.getClass();
				//				while (clz != null) {
				//					if (clz.getName().equals(targetID)) {
				//						contributeToMenu(menuBar);
				//						break;
				//					}
				//					clz = clz.getSuperclass();
				//				}
				if (targetIDs.contains(editor.getEditorSite().getId())) {
					contributeToMenu(menuBar);
				}
			}

			updateToolbarActions();
		}

		public void updateToolbarActions() {
			for (int i = 0; i < cache.size(); i++) {
				Object obj = cache.get(i);
				if (obj instanceof ActionDescriptor) {
					try {
						ActionDescriptor ad = (ActionDescriptor) obj;
						if (ad.getToolbarPath() != null) {
							IAction action = ad.getAction();
							if (action instanceof IUpdate) {
								((IUpdate) action).update();
							}
						}
					} catch (Exception e) {
						Logger.logException("updating toolbar actions", e); //$NON-NLS-1$
					}
				}
			}
		}
	}

	public static final String ATT_ID = "id"; //$NON-NLS-1$
	public static final String ATT_LABEL = "label"; //$NON-NLS-1$
	public static final String ATT_NAME = "name"; //$NON-NLS-1$
	public static final String ATT_PATH = "path"; //$NON-NLS-1$

	public static final String ATT_TARGET_ID = "targetID"; //$NON-NLS-1$
	protected final static boolean debugContributeTime = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/extendededitoractionbuilder/contributetime")); //$NON-NLS-1$  //$NON-NLS-2$

	protected final static boolean debugMenu = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/extendededitoractionbuilder/debugmenu")); //$NON-NLS-1$  //$NON-NLS-2$;
	protected final static boolean debugPopup = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/extendededitoractionbuilder/debugpopup")); //$NON-NLS-1$  //$NON-NLS-2$;
	protected final static boolean debugReadTime = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/extendededitoractionbuilder/readtime")); //$NON-NLS-1$  //$NON-NLS-2$
	protected final static boolean debugToolbar = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/extendededitoractionbuilder/debugtoolbar")); //$NON-NLS-1$  //$NON-NLS-2$;

	private static final String EXTENDED_EDITOR = "extendedEditor"; //$NON-NLS-1$

	public static final String PL_EXTENDED_EDITOR_ACTIONS = "extendedEditorActions"; //$NON-NLS-1$

	public static final String PLUGIN_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$
	public static final String TAG_ACTION = "action"; //$NON-NLS-1$

	public static final String TAG_CONTRIBUTION_TYPE = "editorContribution"; //$NON-NLS-1$

	public static final String TAG_MENU = "menu"; //$NON-NLS-1$
	public static final String TAG_POPUPMENU = "popupmenu"; //$NON-NLS-1$
	public static final String TAG_RULERMENU = "rulermenu"; //$NON-NLS-1$
	public static final String TAG_SEPARATOR = "separator"; //$NON-NLS-1$

	protected List readingCache;

	protected String targetContributionTag;
	protected List targetIDs;

	/**
	 * The constructor.
	 */
	public ExtendedEditorActionBuilder() {
		super();
	}

	/**
	 * Creates a menu from the information in the menu configuration element
	 * and adds it into the provided menu manager. If 'appendIfMissing' is
	 * true, and menu path slot is not found, it will be created and menu will
	 * be added into it. Otherwise, add operation will fail.
	 */
	protected void contributeMenu(IConfigurationElement menuElement, IMenuManager mng, boolean appendIfMissing) {
		// Get config data.
		String id = menuElement.getAttribute(ATT_ID);
		String label = menuElement.getAttribute(ATT_LABEL);
		String path = menuElement.getAttribute(ATT_PATH);
		if (label == null) {
			Logger.log(Logger.ERROR, "Invalid Menu Extension (label == null): " + id); //$NON-NLS-1$
			return;
		}

		// Calculate menu path and group.
		String group = null;
		if (path != null) {
			int loc = path.lastIndexOf('/');
			if (loc != -1) {
				group = path.substring(loc + 1);
				path = path.substring(0, loc);
			} else {
				// assume that path represents a slot
				// so actual path portion should be null
				group = path;
				path = null;
			}
		}

		// Find parent menu.
		IMenuManager parent = mng;
		if (path != null) {
			parent = mng.findMenuUsingPath(path);
			if (parent == null) {
				//Logger.log("Invalid Menu Extension (Path is invalid): " +
				// id);//$NON-NLS-1$
				return;
			}
			// IMenuManager.findMenuUsingPath() returns invisible menu item if
			// the manager can't find
			// the specified path and create new MenuManager for it.
			// I don't know this is a specification or bug.
			// Anyway, to ensure the menu can be visible, setVisible(true)
			// needs to be called.
			parent.setVisible(true);
		}

		// Find reference group.
		if (group == null)
			group = IWorkbenchActionConstants.MB_ADDITIONS;
		IContributionItem sep = parent.find(group);
		if (sep == null) {
			if (appendIfMissing)
				parent.add(new Separator(group));
			else {
				Logger.log(Logger.ERROR, "Invalid Menu Extension (Group is invalid): " + id); //$NON-NLS-1$
				return;
			}
		}

		// If the menu does not exist create it.
		IMenuManager newMenu = parent.findMenuUsingPath(id);
		if (newMenu == null)
			newMenu = new MenuManager(label, id);

		// Create separators.
		IConfigurationElement[] children = menuElement.getChildren(TAG_SEPARATOR);
		for (int i = 0; i < children.length; i++) {
			contributeSeparator(newMenu, children[i]);
		}

		// Add new menu
		try {
			parent.insertAfter(group, newMenu);
		} catch (IllegalArgumentException e) {
			Logger.log(Logger.ERROR, "Invalid Menu Extension (Group is missing): " + id); //$NON-NLS-1$
		}
	}

	/**
	 * Contributes action from action descriptor into the provided menu
	 * manager.
	 */
	protected IMenuManager contributeMenuAction(ActionDescriptor ad, IMenuManager menu, boolean appendIfMissing, boolean popupmenu) {
		if (ad.getContributionItem() == null || ad.getAction() == null)
			return null;

		// Get config data.
		String mpath = popupmenu ? ad.getPopupMenuPath() : ad.getMenuPath();
		String mgroup = popupmenu ? ad.getPopupMenuGroup() : ad.getMenuGroup();
		if (mpath == null && mgroup == null)
			return null;

		// Find parent menu.
		IMenuManager parent = menu;
		if (mpath != null) {
			parent = parent.findMenuUsingPath(mpath);
			if (parent == null) {
				//Logger.log("Invalid Menu Extension (Path is invalid): " +
				// ad.getId()); //$NON-NLS-1$
				return null;
			}
			// IMenuManager.findMenuUsingPath() returns invisible menu item if
			// the manager can't find
			// the specified path and create new MenuManager for it.
			// I don't know this is a specification or bug.
			// Anyway, to ensure the menu can be visible, setVisible(true)
			// needs to be called.
			parent.setVisible(true);
		}

		// First remove existing menu item
		IContributionItem item = parent.find(ad.getId());
		if (item != null) {
			parent.remove(ad.getId());
		}

		// Find reference group.
		if (mgroup == null)
			mgroup = IWorkbenchActionConstants.MB_ADDITIONS;
		IContributionItem sep = parent.find(mgroup);
		if (sep == null) {
			if (appendIfMissing)
				parent.add(sep = new Separator(mgroup));
			else {
				Logger.log(Logger.ERROR, "Invalid Menu Extension (Group is invalid): " + ad.getId()); //$NON-NLS-1$
				return null;
			}
		}

		// Add action.
		try {
			if (popupmenu) {
				// Context menu need a newly created contribution item
				if (sep != null && sep.isGroupMarker())
					parent.appendToGroup(sep.getId(), ad.getAction());
				else
					parent.insertAfter(mgroup, ad.getAction());
			} else {
				// Normal menu need to add existing contribution item to
				// remove it from menu listener
				if (sep != null && sep.isGroupMarker())
					parent.appendToGroup(sep.getId(), ad.getContributionItem());
				else
					parent.insertAfter(mgroup, ad.getContributionItem());
			}
		} catch (IllegalArgumentException e) {
			Logger.log(Logger.ERROR, "Invalid Menu Extension (Group is missing): " + ad.getId()); //$NON-NLS-1$
			parent = null;
		}

		return parent;
	}

	/**
	 * Creates a named menu separator from the information in the
	 * configuration element. If the separator already exists do not create a
	 * second.
	 */
	protected boolean contributeSeparator(IMenuManager menu, IConfigurationElement element) {
		String id = element.getAttribute(ATT_NAME);
		if (id == null || id.length() <= 0)
			return false;
		IContributionItem sep = menu.find(id);
		if (sep != null)
			return false;
		menu.add(new Separator(id));
		return true;
	}

	/**
	 * Contributes action from the action descriptor into the provided tool
	 * bar manager.
	 */
	protected boolean contributeToolbarAction(ActionDescriptor ad, IToolBarManager toolbar, boolean appendIfMissing) {
		if (ad.getContributionItem() == null || ad.getAction() == null)
			return false;

		// Get config data.
		String tpath = ad.getToolbarPath();
		String tgroup = ad.getToolbarGroup();
		if (tpath == null && tgroup == null)
			return false;

		// First remove existing toolbar item
		IContributionItem item = toolbar.find(ad.getId());
		if (item != null) {
			toolbar.remove(ad.getId());
		}

		// Find reference group.
		if (tgroup == null)
			tgroup = IWorkbenchActionConstants.MB_ADDITIONS;
		IContributionItem sep = toolbar.find(tgroup);
		if (sep == null) {
			if (appendIfMissing)
				toolbar.add(new Separator(tgroup));
			else {
				Logger.log(Logger.ERROR, "Invalid Toolbar Extension (Group is invalid): " + ad.getId()); //$NON-NLS-1$
				return false;
			}
		}

		// Add action to tool bar.
		try {
			if (sep != null && sep.isGroupMarker())
				toolbar.appendToGroup(sep.getId(), ad.getAction());
			else
				toolbar.insertAfter(tgroup, ad.getAction());
		} catch (IllegalArgumentException e) {
			Logger.log(Logger.ERROR, "Invalid Toolbar Extension (Group is missing): " + ad.getId()); //$NON-NLS-1$
			return false;
		}
		return true;
	}

	/**
	 * This factory method returns a new ActionDescriptor for the
	 * configuration element. It should be implemented by subclasses.
	 */
	protected ActionDescriptor createActionDescriptor(IConfigurationElement element) {
		ActionDescriptor ad = null;
		try {
			ad = new ActionDescriptor(element);
			// these cases like "class not found" are handled
			// at lower level, so no action if formed. In that
			// case, we also don't want to form an action descriptor.
			if ((ad != null) && (ad.getAction() == null)) {
				ad = null;
			}
		} catch (Exception e) {
			Logger.traceException(EXTENDED_EDITOR, e);
			ad = null;
		}
		return ad;
	}

	/**
	 * Returns the name of the part ID attribute that is expected in the
	 * target extension.
	 */
	protected String getTargetID(IConfigurationElement element) {
		String value = element.getAttribute(ATT_TARGET_ID);
		return value != null ? value : "???"; //$NON-NLS-1$
	}

	/**
	 * Reads editor contributor if specified directly in the 'editor'
	 * extension point, and all external contributions for this editor's ID
	 * registered in 'editorActions' extension point.
	 */
	public IExtendedContributor readActionExtensions(String editorId) {
		return readActionExtensions(new String[]{editorId});
	}

	/**
	 * Reads editor contributor if specified directly in the 'editor'
	 * extension point, and all external contributions for this editor's ID
	 * registered in 'editorActions' extension point.
	 */
	public IExtendedContributor readActionExtensions(String[] ids) {
		long time0 = System.currentTimeMillis();
		ExtendedContributor ext = null;
		readContributions(ids, TAG_CONTRIBUTION_TYPE, PL_EXTENDED_EDITOR_ACTIONS);
		if (debugReadTime) {
			String idlist = ""; //$NON-NLS-1$
			if (ids.length > 0) {
				for (int i = 0; i < ids.length; i++) {
					idlist += ids[i];
					if (i < ids.length - 1)
						idlist += ","; //$NON-NLS-1$
				}
			}
			System.out.println(getClass().getName() + "#readActionExtensions(" + idlist + "): read in " + (System.currentTimeMillis() - time0) + "ms [" + (readingCache != null ? readingCache.size() : 0) + " contributions]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		}
		if (readingCache != null) {
			ext = new ExtendedContributor(readingCache);
			readingCache = null;
		}
		return ext;
	}

	/**
	 * Reads the contributions from the registry for the provided workbench
	 * part and the provided extension point IDs.
	 */
	protected void readContributions(String[] ids, String tag, String extensionPoint) {
		readingCache = null;
		targetIDs = Arrays.asList(ids);
		targetContributionTag = tag;
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		readRegistry(registry, PLUGIN_ID, extensionPoint);
	}

	/**
	 * Implements abstract method to handle the provided XML element in the
	 * registry.
	 */
	protected boolean readElement(IConfigurationElement element) {
		String tag = element.getName();
		if (tag.equals(targetContributionTag)) {
			String id = getTargetID(element);
			if (id == null || !targetIDs.contains(id)) {
				// This is not of interest to us - don't go deeper
				return true;
			}
		} else if (tag.equals(TAG_MENU)) {
			if (readingCache == null)
				readingCache = new ArrayList();
			readingCache.add(element);
			return true; // just cache the element - don't go into it
		} else if (tag.equals(TAG_POPUPMENU)) {
			if (readingCache == null)
				readingCache = new ArrayList();
			readingCache.add(element);
			return true; // just cache the element - don't go into it
		} else if (tag.equals(TAG_RULERMENU)) {
			if (readingCache == null)
				readingCache = new ArrayList();
			readingCache.add(element);
			return true; // just cache the element - don't go into it
		} else if (tag.equals(TAG_ACTION)) {
			if (readingCache == null)
				readingCache = new ArrayList();
			ActionDescriptor ad = createActionDescriptor(element);
			if (ad != null)
				readingCache.add(ad);
			return true; // just cache the action - don't go into
		} else {
			return false;
		}

		readElementChildren(element);
		return true;
	}
}
