/*******************************************************************************
 * Copyright (c) 2000, 2008 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 - derived implementation
 *     Martin Karpisek - bug 195840
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor.utils;
  
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.RuntimeConfigurable;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.UnknownElement;
import org.apache.tools.ant.helper.AntXMLContext;
import org.apache.tools.ant.helper.ProjectHelper2;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JAXPUtils;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.jface.text.BadLocationException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;

/**
 * Derived from the original Ant ProjectHelper2 with help from the JAXPUtils class.
 * This class provides parsing for using a String as a source and provides
 * handlers that will continue parsing to completion upon hitting errors.
 */
public class ProjectHelper extends ProjectHelper2 {

	/**
	 * helper for path -> URI and URI -> path conversions.
	 */
	private static FileUtils fu= null;
    
	/**
	 * The buildfile that is to be parsed. Must be set if parsing is to
	 * be successful.
	 */
	private File buildFile= null;
	
	private static String currentEntityName= null;
	private static String currentEntityPath= null;
	
	private static int currentImportStackSize= 1;
	
	/**
	 * The Ant Model
	 */
	private static IAntModel fgAntModel;

	/**
	 * The current Ant parsing context
	 */
	private static AntXMLContext fgAntContext;
	
	private static AntHandler elementHandler= new ElementHandler();
	private static AntHandler projectHandler= new ProjectHandler();
	private static AntHandler targetHandler= new TargetHandler();
	private static AntHandler mainHandler= new MainHandler();
	private static LexicalHandler lexicalHandler= new LexHandler();
    
    private static XMLReader fgXMLReader= null;
	
	public static class ElementHandler extends ProjectHelper2.ElementHandler {
		
		private UnknownElement task= null;
		private Task currentTask= null;
        
        private Map fNormalizedFileNames= new HashMap();
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) {
			return ProjectHelper.elementHandler;
		}
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void onStartElement(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) {
			try {
				RuntimeConfigurable wrapper= context.currentWrapper();
				currentTask= null;
				task= null;
				if (wrapper != null) {
					currentTask= (Task)wrapper.getProxy();
				}
				onStartElement0(uri, tag, qname, attrs, context);
				
				Locator locator= context.getLocator();
				getAntModel().addTask(task, currentTask, attrs, locator.getLineNumber(), locator.getColumnNumber());
				
			} catch (BuildException be) {
				Locator locator= context.getLocator();
				getAntModel().addTask(task, currentTask, attrs, locator.getLineNumber(), locator.getColumnNumber());
				getAntModel().error(be);
			}
		}

		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onEndElement(java.lang.String, java.lang.String, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void onEndElement(String uri, String tag, AntXMLContext context) {
			super.onEndElement(uri, tag, context);
			
			Locator locator= context.getLocator();
			if (getAntModel().canGetTaskInfo()) {
			    getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber());
			}
		}
		
		private void onStartElement0(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) {
			
			RuntimeConfigurable parentWrapper = context.currentWrapper();
            Object parent = null;

            if (parentWrapper != null) {
                parent = parentWrapper.getProxy();
            }

            /* UnknownElement is used for tasks and data types - with
               delayed eval */
            task = new UnknownElement(tag);
            task.setProject(context.getProject());
            task.setNamespace(uri);
            task.setQName(qname);
            task.setTaskType(org.apache.tools.ant.ProjectHelper.genComponentName(task.getNamespace(), tag));
            task.setTaskName(qname);

            Locator contextLocator= context.getLocator();
            String fileName= contextLocator.getSystemId();
            String normalizedFileName= (String) fNormalizedFileNames.get(fileName);
            if (normalizedFileName == null) {
                if (fileName.startsWith("file:")) { //$NON-NLS-1$
                    normalizedFileName= getFileUtils().fromURI(fileName);
                    fNormalizedFileNames.put(fileName, normalizedFileName);
                } else {
                    normalizedFileName= fileName;
                }
            }
            
            Target currentTarget= context.getCurrentTarget();
            Location location = new Location(normalizedFileName,
                    contextLocator.getLineNumber(),
                    contextLocator.getColumnNumber());
            task.setLocation(location);
            task.setOwningTarget(currentTarget);

            context.configureId(task, attrs);

            if (parent != null) {
                // Nested element
                ((UnknownElement) parent).addChild(task);
            }  else {
                // Task included in a target ( including the default one ).
                currentTarget.addTask(task);
            }

            // container.addTask(task);
            // This is a nop in UE: task.init();

            RuntimeConfigurable wrapper
                = new RuntimeConfigurable(task, task.getTaskName());

            for (int i = 0; i < attrs.getLength(); i++) {
                String attrUri = attrs.getURI(i);
                if (attrUri != null
                    && attrUri.length() != 0 
                    && !attrUri.equals(uri)) {
                    continue; // Ignore attributes from unknown uris
                }
                String name = attrs.getLocalName(i);
                String value = attrs.getValue(i);
                // PR: Hack for ant-type value
                //  an ant-type is a component name which can
                // be namespaced, need to extract the name
                // and convert from qualified name to uri/name
                if (name.equals("ant-type")) { //$NON-NLS-1$
                    int index = value.indexOf(':');
                    if (index != -1) {
                        String prefix = value.substring(0, index);
                        String mappedUri = context.getPrefixMapping(prefix);
                        if (mappedUri == null) {
                            throw new BuildException(
                                "Unable to find XML NS prefix " + prefix); //$NON-NLS-1$
                        }
                        value = org.apache.tools.ant.ProjectHelper.genComponentName(mappedUri, value.substring(index + 1));
                    }
                }
                wrapper.setAttribute(name, value);
            }

            if (parentWrapper != null) {
                parentWrapper.addChild(wrapper);
            }

            context.pushWrapper(wrapper);
		}
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#characters(char[], int, int, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void characters(char[] buf, int start, int count, AntXMLContext context) {
			try {
				super.characters(buf, start, count, context);
			} catch (SAXParseException e) {
				ErrorHelper.handleErrorFromElementText(start, count, context, e);
			} catch (BuildException be) {
				ErrorHelper.handleErrorFromElementText(start, count, context, be);
			}
		}
		
		public void reset() {
			task= null;
			currentTask= null;
            fNormalizedFileNames.clear();
		}
	}
	
	public static class MainHandler extends ProjectHelper2.MainHandler {
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXMLContext context) throws SAXParseException {
			if (name.equals("project") //$NON-NLS-1$
					&& (uri.length() == 0 || uri.equals(ANT_CORE_URI))) {
				return ProjectHelper.projectHandler;
			} 
			try {
				return super.onStartChild(uri, name, qname, attrs, context);
			} catch (SAXParseException e) {
				getAntModel().error(e);
				throw e;
			}
		}
	}
	
	public static class ProjectHandler extends ProjectHelper2.ProjectHandler {
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXMLContext context) {
			if (name.equals("target") //$NON-NLS-1$
					&& (uri.length() == 0 || uri.equals(ANT_CORE_URI))) {
				return ProjectHelper.targetHandler;
			} 
			return ProjectHelper.elementHandler;
		}
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onEndElement(java.lang.String, java.lang.String, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void onEndElement(String uri, String tag, AntXMLContext context) {
			super.onEndElement(uri, tag, context);
			if (currentImportStackSize == 1) {
				Locator locator= context.getLocator();
				getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber());
			}
		}
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void onStartElement(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) {
			try {
				super.onStartElement(uri, tag, qname, attrs, context);
			} catch (SAXParseException e) {
				getAntModel().error(e);
			} catch (BuildException be) {
				getAntModel().error(be);
			}
            if (context.getCurrentTarget() == null) {
                //exception occurred creating the project
                context.getProject().addTarget("", context.getImplicitTarget()); //$NON-NLS-1$
                context.setCurrentTarget(context.getImplicitTarget());
            }
			if (currentImportStackSize == 1) {
				Locator locator= context.getLocator();
				getAntModel().addProject(context.getProject(), locator.getLineNumber(), locator.getColumnNumber());
			}
		}
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#characters(char[], int, int, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void characters(char[] buf, int start, int count, AntXMLContext context) {
			try {
				super.characters(buf, start, count, context);
			} catch (SAXParseException e) {
				ErrorHelper.handleErrorFromElementText(start, count, context, e);
			} catch (BuildException be) {
				ErrorHelper.handleErrorFromElementText(start, count, context, be);
			}
		}
	}
	
	public static class TargetHandler extends ProjectHelper2.TargetHandler {
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartChild(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs, AntXMLContext context) {
			return ProjectHelper.elementHandler;
		}
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onStartElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void onStartElement(String uri, String tag, String qname, Attributes attrs, AntXMLContext context) {
			try {
				super.onStartElement(uri, tag, qname, attrs, context);
				Target newTarget= context.getCurrentTarget();
				Locator locator= context.getLocator();
				getAntModel().addTarget(newTarget, locator.getLineNumber(), locator.getColumnNumber());
			} catch (SAXParseException e) {
				handleErrorInTarget(context, e);
			} catch (BuildException be) {
				handleErrorInTarget(context, be);
			}
		}
		
		private void handleErrorInTarget(AntXMLContext context, Exception e) {
			Target newTarget= context.getCurrentTarget();
			Locator locator= context.getLocator();
			getAntModel().addTarget(newTarget, locator.getLineNumber(), locator.getColumnNumber());
			getAntModel().errorFromElement(e, null, locator.getLineNumber(), locator.getColumnNumber());
		}
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#onEndElement(java.lang.String, java.lang.String, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void onEndElement(String uri, String tag, AntXMLContext context) {
			super.onEndElement(uri, tag, context);
			Locator locator= context.getLocator();
			getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber());
		}
		
		/* (non-Javadoc)
		 * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler#characters(char[], int, int, org.apache.tools.ant.helper.AntXMLContext)
		 */
		public void characters(char[] buf, int start, int count, AntXMLContext context) {
			try {
				super.characters(buf, start, count, context);
			} catch (SAXParseException e) {
				ErrorHelper.handleErrorFromElementText(start, count, context, e);
			} catch (BuildException be) {
				ErrorHelper.handleErrorFromElementText(start, count, context, be);
			}
		}
	}
	
	 public static class RootHandler extends ProjectHelper2.RootHandler {

		public RootHandler(AntXMLContext context, AntHandler rootHandler) {
			super(context, rootHandler);
		}
	
		/* (non-Javadoc)
		 * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
		 */
		public void error(SAXParseException e) {
			getAntModel().error(e);
		}
		/* (non-Javadoc)
		 * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
		 */
		public void fatalError(SAXParseException e) {
			getAntModel().fatalError(e);
		}
		/* (non-Javadoc)
		 * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
		 */
		public void warning(SAXParseException e) {
			getAntModel().warning(e);
		}
		/* (non-Javadoc)
		 * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
		 */
		public InputSource resolveEntity(String publicId, String systemId) {
			InputSource source= super.resolveEntity(publicId, systemId);
			if (source != null) {
				String path = getFileUtils().fromURI(source.getSystemId());
				if (currentEntityName == null) {
					currentEntityPath= path;
				} else {
					getAntModel().addEntity(currentEntityName, path);
					currentEntityName= null;
				}
			}
			return source;
		}
        
        /* (non-Javadoc)
         * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
         */
        public void startPrefixMapping(String prefix, String uri) {
       
            super.startPrefixMapping(prefix, uri);
            getAntModel().addPrefixMapping(prefix, uri);
        }
	 }
	 
	 private static class ErrorHelper {
 		public static void handleErrorFromElementText(int start, int count, AntXMLContext context, Exception e) {
 			Locator locator= context.getLocator();
			int columnNumber= locator.getColumnNumber();
			if (columnNumber > -1) {
				int offset= start;
				try {
					offset= getAntModel().getOffset(locator.getLineNumber(), 1);
				} catch (BadLocationException e1) {
				}
				getAntModel().errorFromElementText(e, offset, locator.getColumnNumber());
			} else {
				getAntModel().errorFromElementText(e, start, count);
			}
		}
	 }
	 
	 private static class LexHandler implements LexicalHandler {
	 	/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#endCDATA()
		 */
		public void endCDATA() throws SAXException {
		}

		/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#endDTD()
		 */
		public void endDTD() throws SAXException {
		    if (getAntModel().canGetLexicalInfo()) {
				AntXMLContext context= getContext();
				Locator locator= context.getLocator();
				getAntModel().setCurrentElementLength(locator.getLineNumber(), locator.getColumnNumber());
		    }
		}

		/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#startCDATA()
		 */
		public void startCDATA() throws SAXException {
		}

		/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
		 */
		public void comment(char[] ch, int start, int length) throws SAXException {
		    if (getAntModel().canGetLexicalInfo()) {
				AntXMLContext context= getContext();
				Locator locator= context.getLocator();
				if (locator != null) {
					getAntModel().addComment(locator.getLineNumber(), locator.getColumnNumber(), length);
				}
		    }
		}

		/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
		 */
		public void endEntity(String name) throws SAXException {
		}

		/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
		 */
		public void startEntity(String name) throws SAXException {
			if (currentEntityPath == null) {
				currentEntityName= name;
			} else {
				getAntModel().addEntity(name, currentEntityPath);
				currentEntityPath= null;
			}
		}

		/* (non-Javadoc)
		 * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
		 */
		public void startDTD(String name, String publicId, String systemId) throws SAXException {
		    if (getAntModel().canGetLexicalInfo()) {
		        AntXMLContext context= getContext();
		        Locator locator= context.getLocator();
		        getAntModel().addDTD(name, locator.getLineNumber(), locator.getColumnNumber());
		    }
		}
	 }
	
	public ProjectHelper(IAntModel model) {
		setAntModel(model);
	}
	
	/**
     * Parses the project file, configuring the project as it goes.
     *
     * @param project the current project
     * @param source  the xml source or a java.io.File
     * @param handler the root handler to use (contains the current context)
     * @exception BuildException if the configuration is invalid or cannot
     *                           be read
     */
    public void parse(Project project, Object source, org.apache.tools.ant.helper.ProjectHelper2.RootHandler handler) throws BuildException {
    	
    	if (!(source instanceof String) && !(source instanceof File)) {
    		//this should only occur with a source URL and that should not be possible currently
    		//as Antlib hard codes using ProjectHelper2 (bug 152793)
    		super.parse(project, source, handler);
    		return;
    	}
    	
    	AntXMLContext context = (AntXMLContext)project.getReference("ant.parsing.context"); //$NON-NLS-1$
		//switch to using "our" handler so parsing will continue on hitting errors.
    	handler = new RootHandler(context, mainHandler);
    	InputStream stream = null;
		try {
        	InputSource inputSource= null;
        	if ((source instanceof File)) {
        		buildFile = (File) source;
                buildFile = getFileUtils().normalize(buildFile.getAbsolutePath());
                stream = new FileInputStream(buildFile);
                inputSource = new InputSource(stream);
        	} else if (source instanceof String) {
        		stream = new ByteArrayInputStream(((String)source).getBytes("UTF-8")); //$NON-NLS-1$
        		inputSource = new InputSource(stream);
        	}
        	
            /**
             * SAX 2 style parser used to parse the given file.
             */
        	//We cannot use the JAXPUtils support here as the underlying parser factory is cached and 
        	//will not reflect classpath changes that effect which XML parser will be returned.
        	//see bug 59764
        	//XMLReader parser = JAXPUtils.getNamespaceXMLReader();
        	XMLReader parser = getNamespaceXMLReader();
        	if (parser == null) {
        		throw new BuildException(ProjectHelperMessages.ProjectHelper_0);
        	}
            String uri = null;
            if (buildFile != null) {
                uri = getFileUtils().toURI(buildFile.getAbsolutePath());
            }

            if (uri != null) {
                inputSource.setSystemId(uri);
            }

            context.setBuildFile(buildFile);
            
            parser.setContentHandler(handler);
            parser.setEntityResolver(handler);
            parser.setErrorHandler(handler);
            parser.setDTDHandler(handler);
            parser.setProperty("http://xml.org/sax/properties/lexical-handler", lexicalHandler); //$NON-NLS-1$
          
            parser.parse(inputSource);
        } catch (SAXParseException exc) {
        	getAntModel().fatalError(exc);
        } catch (SAXException exc) {
        	//ignore as we will be parsing incomplete source
        } catch (FileNotFoundException exc) {
            throw new BuildException(exc);
        } catch (UnsupportedEncodingException exc) {
              throw new BuildException(exc);
        } catch (IOException exc) {
            throw new BuildException(exc);
        } finally {
            try {
            	if (stream != null) {
            		stream.close();
            	}
            } catch (IOException ioe) {
                // ignore this
            }
        }
    }

	/**
	 * Sets the buildfile that is about to be parsed or <code>null</code> if
	 * parsing has completed.
	 * 
	 * @param file The buildfile about to be parsed
	 */
	public void setBuildFile(File file) {
		buildFile= file;
		currentImportStackSize= 1;
	}
	
	/* (non-Javadoc)
	 * We override this method from ProjectHelper2 as we do not want to execute the implicit target or
	 * any other target for that matter as it could hang Eclipse.
	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=50795 for more details.
	 * 
	 * @see org.apache.tools.ant.ProjectHelper#parse(org.apache.tools.ant.Project, java.lang.Object)
	 */
	public void parse(Project project, Object source) throws BuildException {
		AntXMLContext context = (AntXMLContext) project.getReference("ant.parsing.context"); //$NON-NLS-1$
        if (context == null) {
        	getImportStack().removeAllElements();
            context = new AntXMLContext(project);
            project.addReference("ant.parsing.context", context); //$NON-NLS-1$
            project.addReference("ant.targets", context.getTargets()); //$NON-NLS-1$
            fgAntContext= context;
        }
        getImportStack().addElement(source);
		currentImportStackSize= getImportStack().size();
        if (getImportStack().size() > 1) {
            // we are in an imported file.
            context.setIgnoreProjectTag(true);
            Target currentTarget = context.getCurrentTarget();
            Target currentImplicit = context.getImplicitTarget();
            Map currentTargets = context.getCurrentTargets();
            
            try {
                Target newCurrent = new Target();
                newCurrent.setProject(project);
                newCurrent.setName(""); //$NON-NLS-1$
                context.setCurrentTarget(newCurrent);
                context.setCurrentTargets(new HashMap());
                context.setImplicitTarget(newCurrent);
                parse(project, source, new RootHandler(context, mainHandler));
            } finally {
                context.setCurrentTarget(currentTarget);
                context.setImplicitTarget(currentImplicit);
                context.setCurrentTargets(currentTargets);
            }
        } else {
            // top level file
            context.setCurrentTargets(new HashMap());
            parse(project, source, new RootHandler(context, mainHandler));
        }
	}

    public static void reset() {
        fgXMLReader= null;
        fu= null;
    }
    
	public static void setAntModel(IAntModel antModel) {
		fgAntModel= antModel;
		((ProjectHelper.ElementHandler)elementHandler).reset();
		fu= null;
		fgAntContext= null;
	}
    
	public static IAntModel getAntModel() {
		return fgAntModel;
	}
	
	public static AntXMLContext getContext() {
		return fgAntContext;
	}
	
	private static FileUtils getFileUtils() {
		if (fu == null) {
			fu= FileUtils.getFileUtils();
		}
		return fu;
	}
	
	 /**
     * Returns a newly created SAX 2 XMLReader, which is namespace aware
     *
     * @return a SAX 2 XMLReader.
     * @since Ant 1.6 from org.apache.tools.ant.util.JAXPUtils
     */
    private XMLReader getNamespaceXMLReader() throws BuildException {
        if (fgXMLReader == null) {
            try {
                fgXMLReader= newSAXParser(getNSParserFactory()).getXMLReader();
            } catch (SAXException e) {
            }
        }
        return fgXMLReader;
    }
    
    /**
     * Returns the parser factory to use to create namespace aware parsers.
     *
     * @return a SAXParserFactory to use which supports manufacture of
     * namespace aware parsers
     *
     * @since Ant 1.6 from org.apache.tools.ant.util.JAXPUtils
     */
    private SAXParserFactory getNSParserFactory() throws BuildException {

    	SAXParserFactory nsParserFactory = JAXPUtils.newParserFactory();
        nsParserFactory.setNamespaceAware(true);
        
        return nsParserFactory;
    }
    
    /**
     * @return a new SAXParser instance as helper for getParser and
     * getXMLReader.
     *
     * @since Ant 1.5 from org.apache.tools.ant.util.JAXPUtils
     */
    private SAXParser newSAXParser(SAXParserFactory factory) {
        try {
            return factory.newSAXParser();
        } catch (ParserConfigurationException e) {
        } catch (SAXException e) {
        }
        return null;
    }
}
