/*******************************************************************************
 * Copyright (c) 2002, 2011 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) 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:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug fixes
 *     John-Mason P. Shackelford (john-mason.shackelford@pearson.com) - bug 49383, 56299, 59024
 *     Brock Janiczak (brockj_eclipse@ihug.com.au ) - bug 78028, 78030 
 *     Remy Chi Jian Suen - bug 277587
 *******************************************************************************/

package org.eclipse.ant.internal.ui.editor;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ComponentHelper;
import org.apache.tools.ant.ExtensionPoint;
import org.apache.tools.ant.IntrospectionHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.taskdefs.MacroDef;
import org.apache.tools.ant.taskdefs.MacroInstance;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Reference;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIImages;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.dtd.IAttribute;
import org.eclipse.ant.internal.ui.dtd.IDfm;
import org.eclipse.ant.internal.ui.dtd.IElement;
import org.eclipse.ant.internal.ui.dtd.ISchema;
import org.eclipse.ant.internal.ui.dtd.ParseError;
import org.eclipse.ant.internal.ui.dtd.Parser;
import org.eclipse.ant.internal.ui.editor.TaskDescriptionProvider.ProposalNode;
import org.eclipse.ant.internal.ui.editor.templates.AntContext;
import org.eclipse.ant.internal.ui.editor.templates.AntTemplateAccess;
import org.eclipse.ant.internal.ui.editor.templates.AntTemplateInformationControlCreator;
import org.eclipse.ant.internal.ui.editor.templates.AntTemplateProposal;
import org.eclipse.ant.internal.ui.editor.templates.BuildFileContextType;
import org.eclipse.ant.internal.ui.editor.templates.TargetContextType;
import org.eclipse.ant.internal.ui.editor.templates.TaskContextType;
import org.eclipse.ant.internal.ui.model.AntDefiningTaskNode;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.AntTaskNode;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ContentAssistEvent;
import org.eclipse.jface.text.contentassist.ICompletionListener;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistantExtension2;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateProposal;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.ibm.icu.text.MessageFormat;

/**
 * The completion processor for the Ant Editor.
 */
public class AntEditorCompletionProcessor  extends TemplateCompletionProcessor implements ICompletionListener  {       
 
	private static final class ProposalComparator implements Comparator {
		public int compare(Object o1, Object o2) {
			return ((TemplateProposal) o2).getRelevance() - ((TemplateProposal) o1).getRelevance();
		}
	}

	private static final Comparator fgProposalComparator= new ProposalComparator();
	
 	private Comparator proposalComparator= new Comparator() {
		public int compare(Object o1, Object o2) {
		    
			int type1= getProposalType(o1);
			int type2= getProposalType(o2);
			if (type1 != type2) {
				if (type1 > type2) {
					return 1;
				}  
				return -1;
			}
			String string1 = ((ICompletionProposal)o1).getDisplayString();
			String string2 = ((ICompletionProposal)o2).getDisplayString();
			return string1.compareToIgnoreCase(string2);
		}
		private int getProposalType(Object o){
		    if(o instanceof AntCompletionProposal){
		        return ((AntCompletionProposal) o).getType();
		    } 
		    return AntCompletionProposal.TASK_PROPOSAL;    
		}
 	};
	
	protected final static int PROPOSAL_MODE_NONE = 0;
	protected final static int PROPOSAL_MODE_BUILDFILE = 1;
	protected final static int PROPOSAL_MODE_TASK_PROPOSAL = 2;
	protected final static int PROPOSAL_MODE_PROPERTY_PROPOSAL = 3;
	protected final static int PROPOSAL_MODE_ATTRIBUTE_PROPOSAL = 4;
	protected final static int PROPOSAL_MODE_TASK_PROPOSAL_CLOSING = 5;
	protected final static int PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL = 6;
	protected final static int PROPOSAL_MODE_NESTED_ELEMENT_PROPOSAL = 7;
	
	private final static ICompletionProposal[] NO_PROPOSALS= new ICompletionProposal[0];
	
    /**
     * The line where the cursor sits now.
     * <P>
     * The first line has index '1'.
     */
	protected int lineNumber = -1;

    /**
     * The startingColumn where the cursor sits now.
     * <P>
     * The first startingColumn has index '1'.
     */
	protected int columnNumber = -1;
    
	/**
	 * The additional offset required from a required attribute to
	 * place the cursor for the current proposal
	 */
	private int additionalProposalOffset = -1;
    
    private static final String ANT_DTD_FILENAME = "/org/eclipse/ant/internal/ui/editor/ant1.6.2.dtd"; //$NON-NLS-1$

    /**
     * The dtd.
     */
	private static ISchema fgDtd;

    /**
     * Cursor position, counted from the beginning of the document.
     * <P>
     * The first position has index '0'.
     */
	protected int cursorPosition = -1;
	
    /**
     * The text viewer.
     */
	private ITextViewer viewer;
	
	/**
	 * The set of characters that will trigger the activation of the
	 * completion proposal computation.
	 */
	private char[] autoActivationChars= null; 
	
	private String errorMessage;
	
	protected AntModel antModel;
	
	/**
	 * The proposal mode for the current content assist
     * @see #determineProposalMode(IDocument, int, String)
     */
	private int currentProposalMode= -1;
	
	/**
	 * The prefix for the current content assist
     */
	protected String currentPrefix= null;
	
	/**
	 * The current task string for content assist
	 * @see #determineProposalMode(IDocument, int, String)
	 */
	protected String currentTaskString= null;

    private boolean fTemplatesOnly= false;
    protected IContentAssistantExtension2 fContentAssistant;
	
	public AntEditorCompletionProcessor(AntModel model) {
		super();
		antModel= model;
	}

    /**
     * Parses the dtd.
     */
    private ISchema parseDtd() throws ParseError, IOException {
        InputStream stream= null;
        Reader reader= null;
        try {
        	stream= getClass().getResourceAsStream(ANT_DTD_FILENAME);
        	reader=new InputStreamReader(stream, "UTF-8"); //$NON-NLS-1$
        	Parser parser = new Parser();
        	ISchema schema= parser.parseDTD(reader, "project"); //$NON-NLS-1$
        	return schema;
        } finally {
        	if (reader != null) {
        		reader.close();
        	}
        	if (stream != null) {
        		stream.close();
        	}
        }
    }
    
	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
	 */
	public ICompletionProposal[] computeCompletionProposals(ITextViewer refViewer, int documentOffset) {
	    this.viewer = refViewer;   
	    try {
            if (fTemplatesOnly) {
                fContentAssistant.setStatusMessage(getIterationGestureMessage(AntEditorMessages.getString("AntEditorCompletionProcessor.0"))); //$NON-NLS-1$
                fContentAssistant.setEmptyMessage(AntEditorMessages.getString("AntEditorCompletionProcessor.60")); //$NON-NLS-1$
                ICompletionProposal[] templates= determineTemplateProposals(refViewer, documentOffset);
                Arrays.sort(templates, proposalComparator);
                return templates;
	        }
            fContentAssistant.setStatusMessage(getIterationGestureMessage(AntEditorMessages.getString("AntEditorCompletionProcessor.61"))); //$NON-NLS-1$
            fContentAssistant.setEmptyMessage(AntEditorMessages.getString("AntEditorCompletionProcessor.62")); //$NON-NLS-1$
            ICompletionProposal[] matchingProposals= determineProposals();
            ICompletionProposal[] matchingTemplateProposals = determineTemplateProposals(refViewer, documentOffset);
            return mergeProposals(matchingProposals, matchingTemplateProposals);
	    } finally {
	        currentPrefix= null;
	        currentProposalMode= -1;
            fTemplatesOnly= !fTemplatesOnly;
	    }
    }
	
	protected ICompletionProposal[] determineTemplateProposals(ITextViewer refViewer, int documentOffset) {
		this.viewer= refViewer;
        String prefix = getCurrentPrefix();
        ICompletionProposal[] matchingTemplateProposals;
        if (prefix.length() == 0) {
            matchingTemplateProposals = determineTemplateProposalsForContext(documentOffset);
        } else {
            ICompletionProposal[] templateProposals = determineTemplateProposalsForContext(documentOffset);
            List templateProposalList = new ArrayList(templateProposals.length);
            for (int i = 0; i < templateProposals.length; i++) {
                if (templateProposals[i].getDisplayString().toLowerCase().startsWith(prefix)) {
                    templateProposalList.add(templateProposals[i]);
                }
            }
            matchingTemplateProposals = 
                (ICompletionProposal[]) templateProposalList.toArray(new ICompletionProposal[templateProposalList.size()]);
        }
		return matchingTemplateProposals;
	}

	//essentially a copy of super.computeCompletionProposals but we need to have both context types work
	//for target (task and target) context type in a backwards compatible way
	private ICompletionProposal[] determineTemplateProposalsForContext(int offset) {
		ITextSelection selection= (ITextSelection) viewer.getSelectionProvider().getSelection();

		// adjust offset to end of normalized selection
		int newoffset = offset;
		if (selection.getOffset() == newoffset) {
			newoffset= selection.getOffset() + selection.getLength();
		}

		String prefix= extractPrefix(viewer, newoffset);
		Region region= new Region(newoffset - prefix.length(), prefix.length());
		TemplateContext context= createContext(viewer, region);
		if (context == null) {
			return new ICompletionProposal[0];
		}
		
		context.setVariable("selection", selection.getText()); // name of the selection variables {line, word}_selection //$NON-NLS-1$

		Template[] templates;
		String contextTypeId = context.getContextType().getId();
		boolean isTargetContextType = contextTypeId.equals(TargetContextType.TARGET_CONTEXT_TYPE);
		if (isTargetContextType) {
			Template[] tasks = AntTemplateAccess.getDefault().getTemplateStore().getTemplates(TaskContextType.TASK_CONTEXT_TYPE);
			Template[] targets = getTemplates(contextTypeId);
			templates = new Template[tasks.length + targets.length];
			System.arraycopy(tasks, 0, templates, 0, tasks.length);
			System.arraycopy(targets, 0, templates, tasks.length, targets.length);
		} else {
			templates = getTemplates(contextTypeId);
		}

		List matches= new ArrayList();
		for (int i= 0; i < templates.length; i++) {
			Template template= templates[i];
			try {
				context.getContextType().validate(template.getPattern());
			} catch (TemplateException e) {
				continue;
			}
			if (template.matches(prefix, contextTypeId) || (isTargetContextType && template.matches(prefix, TaskContextType.TASK_CONTEXT_TYPE))) {
				matches.add(createProposal(template, context, (IRegion) region, getRelevance(template, prefix)));
			}
		}

		Collections.sort(matches, fgProposalComparator);

		return (ICompletionProposal[]) matches.toArray(new ICompletionProposal[matches.size()]);
	}
	
	private ICompletionProposal[] mergeProposals(ICompletionProposal[] proposals1, ICompletionProposal[] proposals2) {

        ICompletionProposal[] combinedProposals = new ICompletionProposal[proposals1.length + proposals2.length];
                
		System.arraycopy(proposals1, 0, combinedProposals, 0, proposals1.length);
		System.arraycopy(proposals2, 0, combinedProposals, proposals1.length, proposals2.length);		                

		Arrays.sort(combinedProposals, proposalComparator);
        return combinedProposals;
    }

    /**
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(ITextViewer, int)
	 */
	public IContextInformation[] computeContextInformation(ITextViewer refViewer, int documentOffset) {
		return new IContextInformation[0];
	}

	/**
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
	 */
	public char[] getCompletionProposalAutoActivationCharacters() {
        return autoActivationChars;
	}

	/**
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
	 */
	public char[] getContextInformationAutoActivationCharacters() {
        return null;
	}

	/**
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
	 */
	public IContextInformationValidator getContextInformationValidator() {
		return null;
	}

	/**
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
	 */
	public String getErrorMessage() {
		return errorMessage;
	}
	
    /**
     * Returns the new determined proposals.
     */ 
	private ICompletionProposal[] determineProposals() {
		ITextSelection selection= (ITextSelection)viewer.getSelectionProvider().getSelection();
		cursorPosition = selection.getOffset() + selection.getLength();
        
        IDocument doc = viewer.getDocument();
        try {
            lineNumber = doc.getLineOfOffset(cursorPosition);
            columnNumber = cursorPosition - doc.getLineOffset(lineNumber);
        } catch (BadLocationException e) {
            AntUIPlugin.log(e);
        }
		
		String prefix = getCurrentPrefix();
		if (prefix == null || cursorPosition == -1) {
			AntUIPlugin.getStandardDisplay().beep();
			return NO_PROPOSALS;
		}
	
		ICompletionProposal[] proposals = getProposalsFromDocument(doc, prefix);
		currentTaskString= null;
		return proposals;
	}

    /**
     * Returns the proposals for the specified document.
     */
    protected ICompletionProposal[] getProposalsFromDocument(IDocument document, String prefix) {
		ICompletionProposal[] proposals= null;
		currentProposalMode= determineProposalMode(document, cursorPosition, prefix);
        switch (currentProposalMode) {
            case PROPOSAL_MODE_ATTRIBUTE_PROPOSAL:
                proposals= getAttributeProposals(currentTaskString, prefix);
                if (proposals.length == 0) {
                	errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.28"); //$NON-NLS-1$
                }
                break;
            case PROPOSAL_MODE_TASK_PROPOSAL:
            	String parentName= getParentName(document, lineNumber, columnNumber);
            	if (parentName == null || parentName.length() == 0) { //outside of any parent element
            		 proposals= NO_PROPOSALS;
            		 currentProposalMode= PROPOSAL_MODE_NONE;
            	} else {
            		proposals= getTaskProposals(document, parentName, prefix);
            	}
            	if (proposals.length == 0) {
        			errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.29"); //$NON-NLS-1$
        		}
				break;
            case PROPOSAL_MODE_BUILDFILE:
				proposals= getBuildFileProposals(document, prefix);
            	if (proposals.length == 0) {
				   errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.29"); //$NON-NLS-1$
            	}
				break;
            case PROPOSAL_MODE_TASK_PROPOSAL_CLOSING:
                ICompletionProposal proposal= getClosingTaskProposal(getOpenElementName(), prefix, true);
            	if (proposal == null) {
				   errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.30"); //$NON-NLS-1$
				   proposals= NO_PROPOSALS;
            	} else {
	            	proposals= new ICompletionProposal[]{proposal};
            	}
                break;
            case PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL:
            	String textToSearch= document.get().substring(0, cursorPosition-prefix.length());
                String attributeString = getAttributeStringFromDocumentStringToPrefix(textToSearch);
                if ("target".equalsIgnoreCase(currentTaskString) || "extension-point".equalsIgnoreCase(currentTaskString)) { //$NON-NLS-1$ //$NON-NLS-2$
                	proposals= getTargetAttributeValueProposals(document, textToSearch, prefix, attributeString);
                } else if ("antcall".equalsIgnoreCase(currentTaskString)) {  //$NON-NLS-1$
                    proposals= getAntCallAttributeValueProposals(document, prefix, attributeString);
                } else if ("project".equalsIgnoreCase(currentTaskString)) { //$NON-NLS-1$
                	proposals= getProjectAttributeValueProposals(prefix, attributeString);
                } else if ("refid".equalsIgnoreCase(attributeString) || "classpathref".equalsIgnoreCase(attributeString)   //$NON-NLS-1$//$NON-NLS-2$
                        || "sourcepathref".equalsIgnoreCase(attributeString) || "bootpathref".equalsIgnoreCase(attributeString)) { //$NON-NLS-1$ //$NON-NLS-2$
                	proposals= getReferencesValueProposals(prefix);
                } else {
                	proposals= getAttributeValueProposals(currentTaskString, attributeString, prefix);
                }
				if (proposals.length == 0) {
				   errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.31"); //$NON-NLS-1$
				}
				break;
            case PROPOSAL_MODE_PROPERTY_PROPOSAL:
				proposals= getPropertyProposals(document, prefix, cursorPosition);
            	if (proposals.length == 0) {
				   errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.32"); //$NON-NLS-1$
            	}
				break;
			case PROPOSAL_MODE_NONE :
            default :
                proposals= NO_PROPOSALS;
				errorMessage= AntEditorMessages.getString("AntEditorCompletionProcessor.33"); //$NON-NLS-1$
        }
        
        if (proposals.length > 0) {
        	errorMessage= IAntCoreConstants.EMPTY_STRING;
        }
        return proposals;

    }
    
    private ICompletionProposal[] getProjectAttributeValueProposals(String prefix, String attributeName) {
		if (attributeName.equalsIgnoreCase(IAntCoreConstants.DEFAULT)) {
			return getDefaultValueProposals(prefix);
		}

		return NO_PROPOSALS;
	}

	private ICompletionProposal[] getDefaultValueProposals(String prefix) {
		Map targets = getTargets();
		List defaultProposals = new ArrayList(targets.size());
		Iterator itr = targets.values().iterator();

		Target target;
		String targetName;
		while (itr.hasNext()) {
			target = (Target) itr.next();
			targetName= target.getName();
			if (targetName.toLowerCase().startsWith(prefix) && targetName.length() > 0) {
				defaultProposals.add(new AntCompletionProposal(targetName, cursorPosition - prefix.length(), prefix.length(), targetName.length(), getTargetImage(targetName), targetName, target.getDescription(), AntCompletionProposal.TASK_PROPOSAL));
			}
		}

		ICompletionProposal[] proposals = new ICompletionProposal[defaultProposals.size()];
		return (ICompletionProposal[])defaultProposals.toArray(proposals);
	}
    
	private ICompletionProposal[] getReferencesValueProposals(String prefix) {
		Project project= antModel.getProjectNode().getProject();
		Map references= project.getReferences();
		if (references.isEmpty()) {
			return NO_PROPOSALS;
		}
		Set refIds= references.keySet();
		AntElementNode node= antModel.getNode(cursorPosition, false);
		if (node == null) {
			return NO_PROPOSALS;
		}
		while (node.getParentNode() instanceof AntTaskNode) {
			node= node.getParentNode();
		}
		String id= null;
		if (node instanceof AntTaskNode) {
			id= ((AntTaskNode)node).getId();
		}
		List proposals= new ArrayList(refIds.size());
		String refId;
		ICompletionProposal proposal;
		int prefixLength= prefix.length();
		int replacementOffset= cursorPosition - prefixLength;
		Iterator iter= refIds.iterator();
		while (iter.hasNext()) {
			refId= (String) iter.next();
			if (!refId.equals(id) && (prefixLength == 0 || refId.toLowerCase().startsWith(prefix))) {
				proposal= new AntCompletionProposal(refId, replacementOffset, prefixLength, refId.length(), null, refId, null, AntCompletionProposal.TASK_PROPOSAL);
				proposals.add(proposal);
			}
		}
		return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);      
	}

	protected ICompletionProposal[] getTargetAttributeValueProposals(IDocument document, String textToSearch, String prefix, String attributeName) {
		if (attributeName.equalsIgnoreCase("depends")) { //$NON-NLS-1$
			return getDependsValueProposals(document, prefix);
		} else if (attributeName.equalsIgnoreCase("if") || attributeName.equalsIgnoreCase("unless")) { //$NON-NLS-1$ //$NON-NLS-2$
			if (!textToSearch.trim().endsWith(",")) { //$NON-NLS-1$
				return getPropertyProposals(document, prefix, cursorPosition);
			}
		} else if (attributeName.equalsIgnoreCase("extensionOf")) {//$NON-NLS-1$
			return getExtensionOfValueProposals(document, prefix);
		}
		
		return NO_PROPOSALS;
	}
    
    private ICompletionProposal[] getExtensionOfValueProposals(IDocument document, String prefix) {
    	List extensions = new ArrayList();
		
		Map targets= getTargets();
		Set targetNames= targets.keySet();
		Iterator itr= targetNames.iterator();
		while (itr.hasNext()) {
			String targetName = (String) itr.next();
			Target currentTarget= (Target)targets.get(targetName);
			if (currentTarget instanceof ExtensionPoint) {
				extensions.add(targetName);
			}
		}
		
		ICompletionProposal[] proposals= new ICompletionProposal[extensions.size()];
		int i= 0;
		for (Iterator iter = extensions.iterator(); iter.hasNext(); i++) {
			String targetName = (String) iter.next();
			ICompletionProposal proposal = new AntCompletionProposal(targetName, cursorPosition - prefix.length(), prefix.length(), targetName.length(), getTargetImage(targetName), targetName, ((Target)targets.get(targetName)).getDescription(), AntCompletionProposal.TASK_PROPOSAL);
			proposals[i]= proposal;
		}
		return proposals;
	}

	protected ICompletionProposal[] getAntCallAttributeValueProposals(IDocument document, String prefix, String attributeName) {
        if (attributeName.equalsIgnoreCase("target")) { //$NON-NLS-1$
            return getTargetProposals(document, prefix);
        }
        
        return NO_PROPOSALS;
    }
    
    private ICompletionProposal[] getTargetProposals(IDocument document, String prefix) {
        String currentTargetName= getEnclosingTargetName(document, lineNumber, columnNumber);
        if(currentTargetName == null) {
            return NO_PROPOSALS;
        }
            
        Map targets= getTargets();
        Set targetNames= targets.keySet();
        List proposals= new ArrayList(targets.size() - 2); //current target and implicit target
        Iterator itr= targetNames.iterator();
        while (itr.hasNext()) {
            String targetName = (String) itr.next();
            if (targetName.equals(currentTargetName)) {
                continue;
            }
            if (targetName.toLowerCase().startsWith(prefix) && targetName.length() > 0){
                ICompletionProposal proposal = new AntCompletionProposal(targetName, cursorPosition - prefix.length(), prefix.length(), targetName.length(), getTargetImage(targetName), targetName, ((Target)targets.get(targetName)).getDescription(), AntCompletionProposal.TASK_PROPOSAL);
                proposals.add(proposal);
            }
        }
        return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);      
    }
    
    /**
     * Retrieves the representative image of a target of the given name. If the
     * target cannot be found, <code>null</code> will be returned. 
     * 
     * @param targetName the target's name
     * @return an image suitable for representing the target, or <code>null</code> if the target cannot be found
     * @since 3.6
     */
    private Image getTargetImage(String targetName) {
		AntTargetNode targetNode = antModel.getTargetNode(targetName);
		if (targetNode == null) {
			return null;
		} else if (targetNode.isInternal()) {
			return AntUIImages.getImage(IAntUIConstants.IMG_ANT_TARGET_INTERNAL);
		} else if (targetNode.isDefaultTarget()) {
			return AntUIImages.getImage(IAntUIConstants.IMG_ANT_DEFAULT_TARGET);
		} else {
			return AntUIImages.getImage(IAntUIConstants.IMG_ANT_TARGET);
		}
    }

	private ICompletionProposal[] getDependsValueProposals(IDocument document, String prefix) {
		List possibleDependencies = new ArrayList();
		String currentTargetName= getEnclosingTargetName(document, lineNumber, columnNumber);
		if(currentTargetName == null) {
			return NO_PROPOSALS;
		}
			
		Map targets= getTargets();
		Set targetNames= targets.keySet();
		Iterator itr= targetNames.iterator();
		Enumeration dependencies= null;
		while (itr.hasNext()) {
			String targetName = (String) itr.next();
			if (targetName.equals(currentTargetName)) {
				Target currentTarget= (Target)targets.get(targetName);
				dependencies= currentTarget.getDependencies();
				continue;
			}
			if (targetName.toLowerCase().startsWith(prefix) && targetName.length() > 0){
				possibleDependencies.add(targetName);
			}
		}
		
		if (dependencies != null) {
			while (dependencies.hasMoreElements()) {
				possibleDependencies.remove(dependencies.nextElement());
			}
		}
		
		ICompletionProposal[] proposals= new ICompletionProposal[possibleDependencies.size()];
		int i= 0;
		for (Iterator iter = possibleDependencies.iterator(); iter.hasNext(); i++) {
			String targetName = (String) iter.next();
			ICompletionProposal proposal = new AntCompletionProposal(targetName, cursorPosition - prefix.length(), prefix.length(), targetName.length(), getTargetImage(targetName), targetName, ((Target)targets.get(targetName)).getDescription(), AntCompletionProposal.TASK_PROPOSAL);
			proposals[i]= proposal;
		}
		return proposals;
	}

	/**
     * Returns all possible attributes for the specified task.
     * 
     * @param taskName the name of the task for that the attribute shall be 
     * completed
     * @param prefix prefix, that all proposals should start with. The prefix
     * may be an empty string.
     */
    protected ICompletionProposal[] getAttributeProposals(String taskName, String prefix) {
        List proposals = new ArrayList();
        IElement element = getDtd().getElement(taskName);
        if (element != null) {
        	Iterator keys = element.getAttributes().keySet().iterator();
        	while (keys.hasNext()) {
        		String attrName = (String) keys.next();
        		if (prefix.length() == 0 || attrName.toLowerCase().startsWith(prefix)) {
        			IAttribute dtdAttributes = (IAttribute) element.getAttributes().get(attrName);
					String replacementString = attrName+"=\"\""; //$NON-NLS-1$
					String displayString = attrName;
					String[] items = dtdAttributes.getEnum();
					if (items != null) {					        			
                        if(items.length > 1) {
                            displayString += " - ("; //$NON-NLS-1$
                        }
                        for (int i = 0; i < items.length; i++) {
                            displayString += items[i];
                            if(i+1 < items.length) {
                                displayString += " | "; //$NON-NLS-1$
                            } else {
                                displayString += ")"; //$NON-NLS-1$
                            }
                        }
                    }
                    
                    addAttributeProposal(taskName, prefix, proposals, attrName, replacementString, displayString, true);
                }       
            }
        } else { //possibly a user defined task or type
        	Class taskClass= getTaskClass(taskName);
        	if (taskClass != null) {
        		if (taskClass == MacroInstance.class) {
        			addMacroDefAttributeProposals(taskName, prefix, proposals);
        		} else {
	        		IntrospectionHelper helper= getIntrospectionHelper(taskClass);
	        		if (helper != null) {
		        		addAttributeProposals(helper, taskName, prefix, proposals);
	        		}
        		}
        	} else { //nested user defined element
        		Class nestedType= getNestedType();
        		if (nestedType != null) {
	    			IntrospectionHelper helper= getIntrospectionHelper(nestedType);
	    			if (helper != null) {
	    				addAttributeProposals(helper, taskName, prefix, proposals);
	    			}
	    		}
        	}
        }
        return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);
    }
    
	private void addAttributeProposals(IntrospectionHelper helper, String taskName, String prefix, List proposals) {
		Enumeration attributes= helper.getAttributes();
		while (attributes.hasMoreElements()) {
			String attribute = (String) attributes.nextElement();
			if (prefix.length() == 0 || attribute.toLowerCase().startsWith(prefix)) {
				String replacementString = attribute + "=\"\""; //$NON-NLS-1$
				addAttributeProposal(taskName, prefix, proposals, attribute, replacementString, attribute, false);
			}
		}
	}

	private Class getNestedType() {
    	AntElementNode currentNode= antModel.getNode(cursorPosition, false);
    	if (currentNode == null) {
    		return null;
    	}
		AntElementNode parent= currentNode.getParentNode();
		if (parent instanceof AntTaskNode) {
			String parentName= parent.getName();
			if (hasNestedElements(parentName)) {
				Class taskClass= getTaskClass(parentName);
		    	if (taskClass != null) {
		    		IntrospectionHelper helper= getIntrospectionHelper(taskClass);
		    		if (helper != null) {
		    			Class nestedType= null;
		    			try {
		    				nestedType= helper.getElementType(currentNode.getName());
		    			} catch (BuildException be) {
		    			}
		    			return nestedType;
		    		}
				}
			}
		}
		return null;
    }
    
    private IntrospectionHelper getIntrospectionHelper(Class taskClass) {
    	IntrospectionHelper helper= null;
    	try {
    		helper= IntrospectionHelper.getHelper(antModel.getProjectNode().getProject(), taskClass);
    	} catch (NoClassDefFoundError e) {
    		//ignore as a task may require additional classpath components
		}
    	return helper;
    }

    private void addMacroDefAttributeProposals(String taskName, String prefix, List proposals) {
    	currentProposalMode= PROPOSAL_MODE_ATTRIBUTE_PROPOSAL;
		AntDefiningTaskNode node= antModel.getDefininingTaskNode(taskName);
		Object task= node.getRealTask();
		if (!(task instanceof MacroDef)) {
			return;
		}
		List attributes= ((MacroDef)task).getAttributes();
		Iterator itr= attributes.iterator();
		while (itr.hasNext()) {
			MacroDef.Attribute attribute = (MacroDef.Attribute) itr.next();
			String attributeName= attribute.getName();
			if (!(prefix.length() == 0 || attributeName.toLowerCase().startsWith(prefix))) {
				continue;
			}
			String replacementString = attributeName + "=\"\""; //$NON-NLS-1$
			String proposalInfo = null;
			
			String description = attribute.getDescription();
			if(description != null) {
			    proposalInfo= description;
			}
			String deflt = attribute.getDefault();
			if(deflt != null && deflt.length() > 0) {
				proposalInfo= (proposalInfo == null ?  "<BR><BR>" : (proposalInfo += "<BR><BR>")); //$NON-NLS-1$ //$NON-NLS-2$
				proposalInfo+= MessageFormat.format(AntEditorMessages.getString("AntEditorCompletionProcessor.59"), new String[]{deflt}); //$NON-NLS-1$
			}
			
			ICompletionProposal proposal = new AntCompletionProposal(replacementString, cursorPosition - prefix.length(), prefix.length(), attributeName.length() + 2, null, attributeName, proposalInfo, AntCompletionProposal.TASK_PROPOSAL);
			proposals.add(proposal);
		}
	}
    
    private void addMacroDefElementProposals(String taskName, String prefix, List proposals) {
		AntDefiningTaskNode node= antModel.getDefininingTaskNode(taskName);
		Object task= node.getRealTask();
		if (!(task instanceof MacroDef)) {
			return;
		}
		Map elements= ((MacroDef)task).getElements();
		Iterator itr= elements.keySet().iterator();
		int prefixLength= prefix.length();
		int replacementOffset= cursorPosition - prefixLength;
		while (itr.hasNext()) {
			String elementName = (String) itr.next();
			if (!(prefixLength == 0 || elementName.toLowerCase().startsWith(prefix))) {
				continue;
			}
			MacroDef.TemplateElement element = (MacroDef.TemplateElement) elements.get(elementName);
			String replacementString = MessageFormat.format("<{0}>\n</{1}>", new String[]{elementName, elementName}); //$NON-NLS-1$
			String proposalInfo = null;
			
			String description = element.getDescription();
			if(description != null) {
			    proposalInfo= description;
			}
			proposalInfo= (proposalInfo == null ?  "<BR><BR>" : (proposalInfo += "<BR><BR>")); //$NON-NLS-1$ //$NON-NLS-2$
			
			if(element.isOptional()) {
				proposalInfo+= AntEditorMessages.getString("AntEditorCompletionProcessor.1"); //$NON-NLS-1$
			} else {
				proposalInfo+= AntEditorMessages.getString("AntEditorCompletionProcessor.2"); //$NON-NLS-1$
			}
			
			ICompletionProposal proposal = new AntCompletionProposal(replacementString, replacementOffset, prefixLength, elementName.length() + 2, null, elementName, proposalInfo, AntCompletionProposal.TASK_PROPOSAL);
			proposals.add(proposal);
		}
	}

	private void addAttributeProposal(String taskName, String prefix, List proposals, String attrName, String replacementString, String displayString, boolean lookupDescription) {
    	
		String proposalInfo = null;
		if (lookupDescription) {
			String required = getDescriptionProvider().getRequiredAttributeForTaskAttribute(taskName, attrName);
			if(required != null && required.length() > 0) {
			    proposalInfo = AntEditorMessages.getString("AntEditorCompletionProcessor.Required___4") + required; //$NON-NLS-1$
			    proposalInfo += "<BR><BR>"; //$NON-NLS-1$
			}
			String description = getDescriptionProvider().getDescriptionForTaskAttribute(taskName, attrName);
			if(description != null) {
			    proposalInfo = (proposalInfo == null ? IAntCoreConstants.EMPTY_STRING : proposalInfo);
			    proposalInfo += description;
			}
		}
		
		ICompletionProposal proposal = new AntCompletionProposal(replacementString, cursorPosition - prefix.length(), prefix.length(), attrName.length()+2, null, displayString, proposalInfo, AntCompletionProposal.TASK_PROPOSAL);
		proposals.add(proposal);
	}

	/**
     * Returns all possible values for the specified attribute of the specified 
     * task.
     * 
     * @param aTaskName the name of the task that the specified attribute 
     * belongs to.
     * 
     * @param anAttributeName the name of the attribute for that the value
     * shall be completed
     * 
     * @param prefix the prefix that all proposals should start with. The prefix
     * may be an empty string.
     */
    private ICompletionProposal[] getAttributeValueProposals(String taskName, String attributeName, String prefix) {
        List proposals = new ArrayList();
        IElement taskElement = getDtd().getElement(taskName);
        if (taskElement != null) {
        	IAttribute attribute = (IAttribute) taskElement.getAttributes().get(attributeName);
        	if (attribute != null) {
        		String[] items = attribute.getEnum();
        		if (items != null) {
					String item;
                    for (int i = 0; i < items.length; i++) {
                        item= items[i];
                        if(prefix.length() ==0 || item.toLowerCase().startsWith(prefix)) { 
                            proposals.add(
                            	new AntCompletionProposal(item, cursorPosition - prefix.length(), prefix.length(), item.length(), null, item, null, AntCompletionProposal.TASK_PROPOSAL));
                        }
                    }
        		}
            }
        } else { //possibly a user defined task or type
        	Class taskClass= getTaskClass(taskName);
        	if (taskClass != null) {
        		IntrospectionHelper helper= getIntrospectionHelper(taskClass);
        		if (helper != null) {
        			addAttributeValueProposals(helper, attributeName, prefix, proposals);
        		}
        	} else { //nested user defined element
        		Class nestedType= getNestedType();
        		if (nestedType != null) {
	    			IntrospectionHelper helper= getIntrospectionHelper(nestedType);
	    			if (helper != null) {
	    				addAttributeValueProposals(helper, attributeName, prefix, proposals);
	    			}
        		}
        	}
        }
        return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);
    }

	private void addAttributeValueProposals(IntrospectionHelper helper, String attributeName, String prefix, List proposals) {
		Enumeration attributes= helper.getAttributes();
		while (attributes.hasMoreElements()) {
			String attribute= (String) attributes.nextElement();
			if (attribute.equals(attributeName)) {
				Class attributeType= helper.getAttributeType(attribute);
				addAttributeValueProposalsForAttributeType(attributeType, prefix, proposals);
				break;
			}
		}
	}

	private void addAttributeValueProposalsForAttributeType(Class attributeType, String prefix, List proposals) {
		if ((attributeType == Boolean.TYPE || attributeType == Boolean.class) && prefix.length() <= 5) {
			addBooleanAttributeValueProposals(prefix, proposals);
		} else if (EnumeratedAttribute.class.isAssignableFrom(attributeType)) {
			try {
				addEnumeratedAttributeValueProposals(attributeType, prefix, proposals);
			} catch (InstantiationException e) {
			} catch (IllegalAccessException e) {
			}
		} else if (Reference.class == attributeType) {
			proposals.addAll(Arrays.asList(getReferencesValueProposals(prefix)));
		}
	}
	
	private void addEnumeratedAttributeValueProposals(Class type, String prefix, List proposals) throws InstantiationException, IllegalAccessException { 
		EnumeratedAttribute ea= (EnumeratedAttribute) type.newInstance();
		String[] values = ea.getValues();
		String enumerated;
		for (int i = 0; i < values.length; i++) {
			enumerated= values[i].toLowerCase();
			if (prefix.length() == 0 || enumerated.startsWith(prefix)) {
				proposals.add(new AntCompletionProposal(enumerated, cursorPosition - prefix.length(), prefix.length(), enumerated.length(), null, enumerated, null, AntCompletionProposal.TASK_PROPOSAL));
			}
		}
	}

	private void addBooleanAttributeValueProposals(String prefix, List proposals) {
		String[] booleanValues = new String[]{"true","false","on","off","yes","no"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
		String booleanAssist;
		for (int i = 0; i < booleanValues.length; i++) {
			booleanAssist= booleanValues[i].toLowerCase();
			if (prefix.length() == 0 || booleanAssist.startsWith(prefix)) {
				proposals.add(new AntCompletionProposal(booleanAssist, cursorPosition -prefix.length(),
						prefix.length(), booleanAssist.length(), null, booleanAssist,
						null, AntCompletionProposal.TASK_PROPOSAL));
			}
		}	    
	}

	/**
     * Returns all possible properties for the specified prefix.
     * <P>
     * Note that the completion mode must be property mode, otherwise it is not
     * safe to call this method.
     */
    protected ICompletionProposal[] getPropertyProposals(IDocument document, String prefix, int aCursorPosition) {
        List proposals = new ArrayList();
        Map displayStringToProposals= new HashMap();
        Map properties = findPropertiesFromDocument();
		
		Image image = AntUIImages.getImage(IAntUIConstants.IMG_PROPERTY);
		// Determine replacement length and offset
	    // String from beginning to the beginning of the prefix
	   int replacementLength = prefix.length();
	   int replacementOffset = 0;
	   String text= document.get();
	   String stringToPrefix = text.substring(0, aCursorPosition - prefix.length());
	   // Property proposal
	   String lastTwoCharacters = stringToPrefix.substring(stringToPrefix.length()-2, stringToPrefix.length());
	   boolean appendBraces= true;
	   if(lastTwoCharacters.equals("${")) { //$NON-NLS-1$
		   replacementLength += 2;
		   replacementOffset = aCursorPosition - prefix.length() - 2;
	   } else if(lastTwoCharacters.endsWith("$")) { //$NON-NLS-1$
		   replacementLength += 1;
		   replacementOffset = aCursorPosition - prefix.length() - 1;                
	   } else {
			//support for property proposals for the if/unless attributes of targets
	   		replacementOffset= aCursorPosition - prefix.length();
	   		appendBraces= false;
	   }
	   
	   if(text.length() > aCursorPosition && text.charAt(aCursorPosition) == '}') {
		   replacementLength += 1;
	   }
	   String propertyName;
       for(Iterator i=properties.keySet().iterator(); i.hasNext(); ) {
            propertyName= (String)i.next();
            if(prefix.length() == 0 || propertyName.toLowerCase().startsWith(prefix)) {
                String additionalPropertyInfo = (String)properties.get(propertyName);
                
                StringBuffer replacementString = new StringBuffer();
                if (appendBraces) {
                	replacementString.append("${"); //$NON-NLS-1$
                }
                replacementString.append(propertyName);
                if (appendBraces) {
                	replacementString.append('}');
                }
                
				if (displayStringToProposals.get(propertyName) == null) {
                	ICompletionProposal proposal = 
		                new AntCompletionProposal(
		                    replacementString.toString(), replacementOffset, replacementLength, 
		                    replacementString.length(), image, propertyName,
		                    additionalPropertyInfo, AntCompletionProposal.PROPERTY_PROPOSAL);
					proposals.add(proposal);
					displayStringToProposals.put(propertyName, proposal);
				}
            }
        }      
		return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);          
    }


    /**
     * Returns all possible proposals for the specified parent name.
     * <P>
     * No completions will be returned if <code>parentName</code> is 
     * not known.
     * 
     * @param document the entire document 
     * @param parentName name of the parent (surrounding) element.
     * @param prefix the prefix that all proposals should start with. The prefix
     * may be an empty string.
     */
    protected ICompletionProposal[] getTaskProposals(IDocument document, String parentName, String prefix) {
       List proposals = new ArrayList(250);
       ICompletionProposal proposal;
       if (areTasksOrTypesValidChildren(parentName)) {
        	//use the definitions in the project as that includes more than what is defined in the DTD
			Project project= antModel.getProjectNode().getProject();
			Map tasksAndTypes= ComponentHelper.getComponentHelper(project).getAntTypeTable();
			createProposals(document, prefix, proposals, tasksAndTypes);
			if (parentName.equals("project")) { //$NON-NLS-1$
				if ("target".startsWith(prefix)) { //$NON-NLS-1$
					proposals.add(newCompletionProposal(document, prefix, "target")); //$NON-NLS-1$
				} 
				if ("extension-point".startsWith(prefix)) { //$NON-NLS-1$
					proposals.add(newCompletionProposal(document, prefix, "extension-point")); //$NON-NLS-1$
				}
			}
		} else {
			IElement parent = getDtd().getElement(parentName);
			if (parent != null) {
				IDfm dfm = parent.getDfm();
				String[] accepts = dfm.getAccepts();
				if (accepts.length == 0) {
					currentProposalMode= PROPOSAL_MODE_NONE;
				}
				String elementName;
				for (int i = 0; i < accepts.length; i++) {
					elementName = accepts[i];
					if(prefix.length() == 0 || elementName.toLowerCase().startsWith(prefix)) {
						proposal = newCompletionProposal(document, prefix, elementName);
						proposals.add(proposal);
					}
				}
			} else {
				//a nested element of a user defined task/type?
				Class taskClass= getTaskClass(parentName);
	        	if (taskClass != null) {
	        		if (taskClass == MacroInstance.class) {
	        			currentProposalMode= PROPOSAL_MODE_ATTRIBUTE_PROPOSAL;
	        			addMacroDefElementProposals(parentName, prefix, proposals);
	        		} else {
	        			currentProposalMode= PROPOSAL_MODE_NESTED_ELEMENT_PROPOSAL;
		        		IntrospectionHelper helper= getIntrospectionHelper(taskClass);
		        		if (helper != null) {
			        		Enumeration nested= helper.getNestedElements();
			        		String nestedElement;
				        	while (nested.hasMoreElements()) {
								nestedElement = (String) nested.nextElement();
								if (prefix.length() == 0 || nestedElement.toLowerCase().startsWith(prefix)) {
									proposal = newCompletionProposal(document, prefix, nestedElement);
									proposals.add(proposal);
								}
					        }
		        		}
	        		}
	        	}
			}
        }
        
        proposal= getClosingTaskProposal(getOpenElementName(), prefix, false);
        if (proposal != null) {
        	proposals.add(proposal);
        }
        
        return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]);
   }
    
    private boolean areTasksOrTypesValidChildren(String parentName) {
		return parentName == "project" || parentName == "target" || parentName == "sequential" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			|| parentName == "presetdef" || parentName == "parallel" || parentName == "daemons" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			|| parentName == "extension-point"; //$NON-NLS-1$
	}

	/** 
    * Returns proposals that define the structure of a build file.
    * 
    * Note that template proposals which define the structure of a build file 
    * are handled by {@link #determineTemplateProposals(ITextViewer, int)} 
    * which limits proposals by context type.

    * @param document the entire document 
    * @param prefix the prefix that all proposals should start with. The prefix
    * may be an empty string.
    */
   protected ICompletionProposal[] getBuildFileProposals(IDocument document, String prefix) {
       String rootElementName= "project"; //$NON-NLS-1$
       IElement rootElement = getDtd().getElement(rootElementName);
       if (rootElement != null && rootElementName.toLowerCase().startsWith(prefix)) {
       		ICompletionProposal proposal = newCompletionProposal(document, prefix, rootElementName);
			return new ICompletionProposal[] {proposal};
		}
       
       return NO_PROPOSALS;
   } 

    private void createProposals(IDocument document, String prefix, List proposals, Map tasks) {
		Iterator keys= tasks.keySet().iterator();
		ICompletionProposal proposal;
		String key;
		while (keys.hasNext()) {
			key= antModel.getUserNamespaceCorrectName((String) keys.next());
			if (prefix.length() == 0 || key.toLowerCase().startsWith(prefix)) {
				proposal = newCompletionProposal(document, prefix, key);
				proposals.add(proposal);
			}
		}
	}
    
    private ICompletionProposal newCompletionProposal(IDocument document, String aPrefix, String elementName) {
		additionalProposalOffset= 0;
		Image proposalImage = AntUIImages.getImage(IAntUIConstants.IMG_TASK_PROPOSAL);
		String proposalInfo = getDescriptionProvider().getDescriptionForTask(elementName);
		boolean hasNestedElements= hasNestedElements(elementName);
		String replacementString = getTaskProposalReplacementString(elementName, hasNestedElements);
		int replacementOffset = cursorPosition - aPrefix.length();
		int replacementLength = aPrefix.length();
		if (replacementOffset > 0 && document.get().charAt(replacementOffset - 1) == '<') {
			replacementOffset--;
			replacementLength++;
		}
		int proposalCursorPosition;
		if (hasNestedElements) {
			proposalCursorPosition= elementName.length() + 2 + additionalProposalOffset;
		} else {
			if (additionalProposalOffset > 0) {
				additionalProposalOffset+=2; //<antstructure output="|"/>
			} else {
				additionalProposalOffset+=1; //<arg|/>
			}
			proposalCursorPosition= elementName.length() + additionalProposalOffset;
		}
		return new AntCompletionProposal(replacementString, replacementOffset, 
			replacementLength, proposalCursorPosition, proposalImage, elementName, proposalInfo, AntCompletionProposal.TASK_PROPOSAL);
	}

	/**
     * Returns the one possible completion for the specified unclosed task .
     * 
     * @param openElementName the task that hasn't been closed 
     * last
     * @param prefix The prefix that the one possible proposal should start 
     * with. The prefix may be an empty string.
     * @return the proposal or <code>null</code> if no closing proposal available
     */
    private ICompletionProposal getClosingTaskProposal(String openElementName, String prefix, boolean closingMode) {
    	char previousChar = getPreviousChar();
		ICompletionProposal proposal= null;
        if(openElementName != null) {
            if(prefix.length() == 0 || openElementName.toLowerCase().startsWith(prefix)) {
                StringBuffer replaceString = new StringBuffer();
                if (!closingMode) {
                	if (previousChar != '/') {
	                	if (previousChar != '<') {
	                		replaceString.append('<');
	                	}
	                	replaceString.append('/');
                	}
                }
                replaceString.append(openElementName);
                replaceString.append('>');
                StringBuffer displayString= new StringBuffer("</"); //$NON-NLS-1$
                displayString.append(openElementName);
                displayString.append('>');
                proposal= new AntCompletionProposal(replaceString.toString(), cursorPosition - prefix.length(), prefix.length(), replaceString.length(), null, displayString.toString(), AntEditorMessages.getString("AntEditorCompletionProcessor.39"), AntCompletionProposal.TAG_CLOSING_PROPOSAL); //$NON-NLS-1$
    		}
        }

        return proposal;
    }

	protected char getPreviousChar() {
		ITextSelection selection = (ITextSelection)viewer.getSelectionProvider().getSelection();
    	int offset= selection.getOffset();
    	char previousChar= '?';
    	try {
			previousChar= viewer.getDocument().getChar(offset-1);
		} catch (BadLocationException e) {
			
		}
		return previousChar;
	}

    /**
     * Returns the replacement string for the specified task name.
     */
    private String getTaskProposalReplacementString(String aTaskName, boolean hasNested) {
        StringBuffer replacement = new StringBuffer("<"); //$NON-NLS-1$
        replacement.append(aTaskName); 
        ProposalNode task = getDescriptionProvider().getTaskNode(aTaskName);
        if(task != null) {
        	appendRequiredAttributes(replacement,task);
        }
        if (hasNested) {
        	replacement.append("></"); //$NON-NLS-1$
            replacement.append(aTaskName);
            replacement.append('>');
        } else {
        	replacement.append("/>"); //$NON-NLS-1$
        }
        return replacement.toString();               
    }

    private void appendRequiredAttributes(StringBuffer replacement, ProposalNode task) {
    	if(task.nodes != null) {
			boolean requiredAdded = false;
			Entry entry = null;
			for (Iterator i = task.nodes.entrySet().iterator();i.hasNext();) {
				entry = (Entry) i.next();
				String name = (String) entry.getKey();
				ProposalNode att = (ProposalNode) entry.getValue();
				if ("yes".equalsIgnoreCase(att.required)) { //$NON-NLS-1$
					replacement.append(' ');
					replacement.append(name);
					replacement.append("=\"\""); //$NON-NLS-1$
					if (!requiredAdded){
						additionalProposalOffset = name.length() + 2;
						requiredAdded = true;
					}	
				}
			}
    	}
	}

	/**
     * Returns whether the named element supports nested elements.
     */
    private boolean hasNestedElements(String elementName) {
        IElement element = getDtd().getElement(elementName);
        if (element != null) {
        	return !element.isEmpty();
        } 
        Class taskClass= getTaskClass(elementName);
    	if (taskClass != null) {
    		IntrospectionHelper helper= getIntrospectionHelper(taskClass);
    		if (helper != null) {
    			Enumeration nested= helper.getNestedElements();
    			return nested.hasMoreElements();
    		}
		}
        return false;
    }
    
    /**
     * Finds a direct child element with <code>aChildElementName</code> of 
     * <code>anElement</code>.
     * <P>
     * The child will not be searched for in the whole hierarchy but only in
     * the hierarchy step below.
     * 
     * @return the found child or <code>null</code> if not found.
     */
    protected Element findChildElementNamedOf(Element anElement, String aChildElementName) {
        NodeList nodeList = anElement.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node childNode = nodeList.item(i);
            if(childNode.getNodeType() == Node.ELEMENT_NODE) {
                if(childNode.getNodeName().equals(aChildElementName)) {
                    return (Element)childNode;
                }
            }   
        }
        return null;
    }

	/**
     * Determines the current prefix that should be used for completion.
     */
	private String getCurrentPrefix() {
		if (currentPrefix != null) {
        	return currentPrefix;
        }
		ITextSelection selection = (ITextSelection)viewer.getSelectionProvider().getSelection();
		IDocument doc = viewer.getDocument();
        return getPrefixFromDocument(doc.get(), selection.getOffset() + selection.getLength()).toLowerCase();
	}


    /**
     * Returns the prefix in the specified document text with respect to the 
     * specified offset.
     * 
     * @param aDocumentText the whole content of the edited file as String
     * @param anOffset the cursor position
     */
    protected String getPrefixFromDocument(String aDocumentText, int anOffset) {
        if (currentPrefix != null) {
        	return currentPrefix;
        }
        int startOfWordToken = anOffset;
        
        char token= 'a';
        if (startOfWordToken > 0) {
			token= aDocumentText.charAt(startOfWordToken - 1);
        }
        
        while (startOfWordToken > 0 
                && (Character.isJavaIdentifierPart(token) 
                    || '.' == token
					|| '-' == token
        			|| ';' == token)
                && !('$' == token)) {
            startOfWordToken--;
            if (startOfWordToken == 0) {
            	break; //word goes right to the beginning of the doc
            }
			token= aDocumentText.charAt(startOfWordToken - 1);
        }
        
        if (startOfWordToken != anOffset) {
            currentPrefix= aDocumentText.substring(startOfWordToken, anOffset).toLowerCase();
        } else {
            currentPrefix= IAntCoreConstants.EMPTY_STRING;
        }
        return currentPrefix;
    }
 
 
    /**
     * Returns the current proposal mode.
     */
    protected int determineProposalMode(IDocument document, int aCursorPosition, String aPrefix) {
    	if (currentProposalMode != -1) {
    		return currentProposalMode;
    	}
    	if (document.getLength() == 0 || (document.getLength() == 1 && document.get().equals("<"))) { //$NON-NLS-1$
    		return PROPOSAL_MODE_BUILDFILE;
    	}
    	
    	//String from beginning of document to the beginning of the prefix
    	String text= document.get();
        String stringToPrefix = text.substring(0, aCursorPosition - aPrefix.length());
        if (stringToPrefix.length() == 0) {
        	return PROPOSAL_MODE_BUILDFILE;
        }
        //Is trimmable from behind
        String trimmedString = stringToPrefix.trim();
    	if (antModel != null && antModel.getProjectNode() == null) {
    		currentTaskString= getTaskStringFromDocumentStringToPrefix(trimmedString);
    		if ("project".equals(currentTaskString)) { //$NON-NLS-1$
    			return PROPOSAL_MODE_ATTRIBUTE_PROPOSAL;
    		}
    		return PROPOSAL_MODE_BUILDFILE;
    	}
    	
        char lastChar = 0;
        if(trimmedString.length() > 0) {
	        lastChar = trimmedString.charAt(trimmedString.length()-1);
        } else {
        	return PROPOSAL_MODE_TASK_PROPOSAL;
        }
        if(stringToPrefix.charAt(stringToPrefix.length()-1) != lastChar && lastChar != '>' && lastChar != ',') {
            /*
             * Substring must be trimmable from behind in case of attribute 
             * proposal because a space or a new line must be used as delimiter 
             * between task name and attribute or attribute and attribute.
             * Example: '<property id="bla" name="hups"'
             */
             
            // Attribute proposal
            if(lastChar != '>' && lastChar != '<') {
               currentTaskString= getTaskStringFromDocumentStringToPrefix(trimmedString);
                if(currentTaskString != null && isKnownElement(currentTaskString)) {
                    return PROPOSAL_MODE_ATTRIBUTE_PROPOSAL;
                }
            }                
        } else if(stringToPrefix.charAt(stringToPrefix.length() - 1) == '"' || trimmedString.charAt(trimmedString.length() - 1) == ',') {
			// Attribute value proposal
        	currentTaskString= getTaskStringFromDocumentStringToPrefix(trimmedString);
            if (currentTaskString != null && isKnownElement(currentTaskString)) {
                return PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL;
            }
        } else {  // Possibly a Task proposal
            int spaceIndex = stringToPrefix.lastIndexOf(' ');
            int lessThanIndex = stringToPrefix.lastIndexOf('<');
            int greaterThanIndex = stringToPrefix.lastIndexOf('>');
            // Task proposal
            if(greaterThanIndex < lessThanIndex) {
            	//we are inside an open element
            	if(lastChar == '$') {
            		return PROPOSAL_MODE_PROPERTY_PROPOSAL;
            	}
            	if(lessThanIndex > spaceIndex) {
	                int slashIndex = stringToPrefix.lastIndexOf('/');
	                if(slashIndex == lessThanIndex +1) {
	                    return PROPOSAL_MODE_TASK_PROPOSAL_CLOSING; // ... </
	                }
	                return PROPOSAL_MODE_TASK_PROPOSAL;
            	}
            }
            if(lessThanIndex < greaterThanIndex) {
            	if (isPropertyProposalMode(stringToPrefix)) {
				   return PROPOSAL_MODE_PROPERTY_PROPOSAL;
			   }
               return PROPOSAL_MODE_TASK_PROPOSAL;
            }
        }

        // Property proposal
		if (isPropertyProposalMode(stringToPrefix)) {
			return PROPOSAL_MODE_PROPERTY_PROPOSAL;
        }
        	            
        return PROPOSAL_MODE_NONE;
    }


	private boolean isPropertyProposalMode(String stringToPrefix) {
		if(stringToPrefix.length() >= 2) {
			String lastTwoChars = stringToPrefix.substring(stringToPrefix.length()-2, stringToPrefix.length());
			if(lastTwoChars.equals("${") || //$NON-NLS-1$
				stringToPrefix.charAt(stringToPrefix.length()-1) == '$') {
					return true;
			}
		}
		return false;
	}
    /**
     * Returns the last occurring task string in the specified string.
     * <P>
     * The returned string must not necessarily be a valid Ant task string.
     * This can be tested with the method <code>inNamedTaskKnown(String)</code>
     * after invoking this method.
     * 
     * @param aDocumentStringToPrefix the String that contains the whole string
     * of the currently edited file from the beginning up to the prefix for code
     * completion. Example: '<project default="name"><property '.
     * 
     * @return the extracted task string or <code>null</code> if no string could
     * be extracted.
     */
    private String getTaskStringFromDocumentStringToPrefix(String aDocumentStringToPrefix) {
            
        int lessThanIndex = aDocumentStringToPrefix.lastIndexOf('<');

        if(lessThanIndex > -1) {
            String taskString = aDocumentStringToPrefix.trim();
            taskString = taskString.substring(lessThanIndex+1, taskString.length());
            int index = taskString.indexOf(' ');
            if(index > 0) {
                taskString = taskString.substring(0, index);
            }
            index = taskString.indexOf('\n');
            if(index > 0) {
                taskString = taskString.substring(0, index);
            }
            index = taskString.indexOf('\r');
            if(index > 0) {
                taskString = taskString.substring(0, index);
            }
            return taskString;
        }
        
        return null;
    }
    

    /**
     * Returns the last occurring attribute string in the specified string.
     * <code>null</code> is returned if no attribute string is available.
     * <P>
     * Calling this method is only safe if the current proposal mode is really
     * <code>PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL</code>.
     */
    public static String getAttributeStringFromDocumentStringToPrefix(String docStringToPrefix) {
        int index = docStringToPrefix.lastIndexOf('=');
        if (index == -1) {
        	return null;
        }
        String subString = docStringToPrefix.substring(0, index);
        subString = subString.trim();
        
        index = subString.lastIndexOf(' ');
        if(index > 0) {
            subString = subString.substring(index+1, subString.length());
        }
        index = subString.lastIndexOf('\n');
        if(index > 0) {
            subString = subString.substring(index+1, subString.length());
        }
        index = subString.lastIndexOf('\r');
        if(index > 0) {
            subString = subString.substring(index+1, subString.length());
        }
        return trimBeginning(subString);
    }
    
    private static String trimBeginning(String toBeTrimmed) {
		int i= 0;
		while ((i != toBeTrimmed.length()) && Character.isWhitespace(toBeTrimmed.charAt(i))) {
			i++;
		}
		return toBeTrimmed.substring(i);
	}


    /**
     * Returns whether the specified element name is known
     */
    protected boolean isKnownElement(String elementName) {
    	if (elementName.equals("target") || elementName.equals("project") || elementName.equals("extension-point")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    		return true;
    	} 
		AntProjectNode node= antModel.getProjectNode();
    	if (node != null) {
    		Project antProject= node.getProject();
            ComponentHelper helper= ComponentHelper.getComponentHelper(antProject);
    		if (helper.getDefinition(elementName) != null) {
    			return true;
    		}
            if (helper.getDefinition(antModel.getNamespaceCorrectName(elementName)) != null) {
                return true;
            }
    		//not everything is a task or type (nested elements)
    		if (getDtd().getElement(elementName) != null) {
    			return true;
    		}
    		
    		if (getNestedType() != null) {
    			return true;
    		}
    	}
    	
        return false;
    }

    private Class getTaskClass(String taskName) {
        Class clss= null;
    	AntProjectNode node= antModel.getProjectNode();
    	if (node != null) {
    		Project antProject= node.getProject();
    		Map tasksAndTypes= ComponentHelper.getComponentHelper(antProject).getAntTypeTable();
    		clss= (Class)tasksAndTypes.get(taskName);
            if (clss == null) {
                clss= (Class)tasksAndTypes.get(antModel.getNamespaceCorrectName(taskName));
            }
    	}
    	return clss;
    }

    /**
     * Finds the parent task element in respect to the cursor position.
     * 
     * @return the parent task element or <code>null</code> if not found.
     */
    protected String getParentName(IDocument document, int aLineNumber, int aColumnNumber) {
    	if (document.getLength() == 0) {
    		return null;
    	}
    	AntProjectNode project= antModel.getProjectNode();
    	if (project == null) {
    		return null;
    	}
    	int offset= getOffset(document, aLineNumber, aColumnNumber);
    	if (offset == -1) {
    		return null;
    	}
    	AntElementNode node= project.getNode(offset);
    	if (node == null) {
    		node= antModel.getOpenElement();
    	}
    	if (node == null) {
    		return IAntCoreConstants.EMPTY_STRING;
    	} else if (node instanceof AntTaskNode) {
    		String name= node.getName();
    		if (offset <= node.getOffset() + name.length() - 1) {
    			//not really the enclosing node as the offset is within the name of the node
    			node= node.getParentNode();
    		} else {
    			return name;
    		}
    	}
    	if (node instanceof AntTaskNode) {
    		return node.getName();
    	} else if (node instanceof AntTargetNode) {
    		return "target"; //$NON-NLS-1$
    	} else {
    		return "project"; //$NON-NLS-1$
    	}
    }

    /**
     * Return the properties as defined in the entire buildfile
     * 
     * @return a map with all the found properties
     */
    private Map findPropertiesFromDocument() {
    	Project project= antModel.getProjectNode().getProject();
        return project.getProperties();
    }
    
    private Map getTargets() {
    	Project project = antModel.getProjectNode().getProject();  
    	return project.getTargets();
    }

    protected File getEditedFile() {
    	IWorkbenchPage page= AntUIPlugin.getActivePage();
    	if (page == null) {
    		return null;
    	}
		IEditorPart editor= page.getActiveEditor();
		if (editor == null) {
			return null;
		}
        FileEditorInput input = (FileEditorInput) editor.getEditorInput();
        String projectPath = input.getFile().getProject().getLocation().toFile().getAbsolutePath();
        String  projectRelativeFilePath = input.getFile().getFullPath().removeFirstSegments(1).makeRelative().toString();
        return new File(projectPath + File.separator + projectRelativeFilePath);
    }
    
    private String getOpenElementName() {
    	AntElementNode node= antModel.getOpenElement();
    	if (node == null) {
    		return null;
    	}
    	return node.getName();
    }

    /**
     * Finds the enclosing target in respect to the cursor position and returns its name  
     * 
     * @return the name of the enclosing target or <code>null</code> if not found 
	 * or the element is not contained in a target.
     */
 	private String getEnclosingTargetName(IDocument document, int aLineNumber, int aColumnNumber) {

       AntProjectNode project= antModel.getProjectNode();
       int offset= getOffset(document, aLineNumber, aColumnNumber);
       if(offset == -1) {
       		return null;
       }
       AntElementNode node= project.getNode(offset);
       if (node instanceof AntTaskNode) {
       		node= node.getParentNode();
       		if (!(node instanceof AntTargetNode)) {
       			//top level task
       			node= null;
       		}
       } else if (node instanceof AntProjectNode) {
       		node= null;
       }
       String targetName = null;
       if(node == null 
       		|| (targetName = ((AntTargetNode)node).getTarget().getName()) == null
			|| targetName.length() == 0) {
       		return null;
       }
       return targetName;
 	}
 	
 	private int getOffset(IDocument document, int line, int column) {
 		try {
			return document.getLineOffset(line ) + column - 1;
		} catch (BadLocationException e) {
			return -1;
		}
 	}
	
	/**
	 * Sets this processor's set of characters triggering the activation of the
	 * completion proposal computation.
	 * 
	 * @param activationSet the activation set
	 */
	public void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
		autoActivationChars= activationSet;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#extractPrefix(org.eclipse.jface.text.ITextViewer, int)
	 */
	protected String extractPrefix(ITextViewer textViewer, int offset) {
		return getPrefixFromDocument(textViewer.getDocument().get(), offset);
	}

	/**
	 * Cut out angular brackets for relevance sorting, since the template name
	 * does not contain the brackets.
	 */
	protected int getRelevance(Template template, String prefix) {
		String newprefix = prefix;
		if (newprefix.startsWith("<")) {//$NON-NLS-1$
			newprefix= prefix.substring(1);
		}
		if (template.getName().startsWith(newprefix)) {
			return 90; 
		}
		return 0;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getTemplates(java.lang.String)
	 */
	protected Template[] getTemplates(String contextTypeId) {
		return AntTemplateAccess.getDefault().getTemplateStore().getTemplates(contextTypeId);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getContextType(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
	 */
	protected TemplateContextType getContextType(ITextViewer textViewer, IRegion region) {
		 switch (determineProposalMode(textViewer.getDocument(), cursorPosition, getCurrentPrefix())) {
            case PROPOSAL_MODE_TASK_PROPOSAL:
            	if (getEnclosingTargetName(textViewer.getDocument(), lineNumber, columnNumber) == null) {
            		return AntTemplateAccess.getDefault().getContextTypeRegistry().getContextType(TargetContextType.TARGET_CONTEXT_TYPE);
            	}
            	return AntTemplateAccess.getDefault().getContextTypeRegistry().getContextType(TaskContextType.TASK_CONTEXT_TYPE);
            case PROPOSAL_MODE_BUILDFILE:
            	return AntTemplateAccess.getDefault().getContextTypeRegistry().getContextType(BuildFileContextType.BUILDFILE_CONTEXT_TYPE);
			case PROPOSAL_MODE_NONE:
            case PROPOSAL_MODE_ATTRIBUTE_PROPOSAL:
            case PROPOSAL_MODE_TASK_PROPOSAL_CLOSING:
            case PROPOSAL_MODE_ATTRIBUTE_VALUE_PROPOSAL:
            case PROPOSAL_MODE_PROPERTY_PROPOSAL:
            case PROPOSAL_MODE_NESTED_ELEMENT_PROPOSAL:
            default :
            	return null;
        }
	}

    /* (non-Javadoc)
     * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#getImage(org.eclipse.jface.text.templates.Template)
     */
    protected Image getImage(Template template) {
        return AntUIImages.getImage(IAntUIConstants.IMG_TEMPLATE_PROPOSAL);
    }
    
	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#createContext(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
	 */
	protected TemplateContext createContext(ITextViewer contextViewer, IRegion region) {
		TemplateContextType contextType= getContextType(contextViewer, region);
		if (contextType != null) {
            Point selection= contextViewer.getSelectedRange();
            Position position;
            if (selection.y > 0) {
                position= new Position(selection.x, selection.y);    
            } else {
                position= new Position(region.getOffset(), region.getLength());
            }
            
			IDocument document= contextViewer.getDocument();
			return new AntContext(contextType, document, antModel, position);
		}
		return null;
	}
    
	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.templates.TemplateCompletionProcessor#createProposal(org.eclipse.jface.text.templates.Template, org.eclipse.jface.text.templates.TemplateContext, org.eclipse.jface.text.Region, int)
	 */
	protected ICompletionProposal createProposal(Template template,TemplateContext context, IRegion region, int relevance) {
		AntTemplateProposal proposal= new AntTemplateProposal(template, context, region, getImage(template), relevance);
		proposal.setInformationControlCreator(new AntTemplateInformationControlCreator());
		return proposal;
	}

	protected ISchema getDtd() {
		if (fgDtd == null) {
			IRunnableWithProgress runnable= new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor)
						throws InvocationTargetException, InterruptedException {
					try {
						fgDtd= parseDtd();
					} catch (IOException e) {
			        	AntUIPlugin.log(e);
			        } catch (ParseError e) {
						AntUIPlugin.log(e);
					}
				}
			};
			
			IProgressService service= PlatformUI.getWorkbench().getProgressService();
			try {
				service.busyCursorWhile(runnable);
			} catch (InvocationTargetException e) {
			} catch (InterruptedException e) {
			}
		}
		return fgDtd;
	}

    /**
     * The provider for all task and attribute descriptions.
     */
	private TaskDescriptionProvider getDescriptionProvider() {
		return TaskDescriptionProvider.getDefault();
	}
	
	protected static void resetCodeCompletionDataStructures() {
		fgDtd= null;
		TaskDescriptionProvider.reset();
	}

    /* (non-Javadoc)
     * @see org.eclipse.jface.text.contentassist.ICompletionListener#assistSessionStarted(org.eclipse.jface.text.contentassist.ContentAssistEvent)
     */
    public void assistSessionStarted(ContentAssistEvent event) {
        IContentAssistant assistant= event.assistant;
        if (assistant instanceof IContentAssistantExtension2) {
            fContentAssistant= (IContentAssistantExtension2) assistant;
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.text.contentassist.ICompletionListener#assistSessionEnded(org.eclipse.jface.text.contentassist.ContentAssistEvent)
     */
    public void assistSessionEnded(ContentAssistEvent event) {
        fContentAssistant= null;
        fTemplatesOnly= false;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.text.contentassist.ICompletionListener#selectionChanged(org.eclipse.jface.text.contentassist.ICompletionProposal, boolean)
     */
    public void selectionChanged(ICompletionProposal proposal, boolean smartToggle) {
    }
    
    private String getIterationGestureMessage(String showMessage) {
        final IBindingService bindingSvc= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
        TriggerSequence[] triggers= bindingSvc.getActiveBindingsFor(getContentAssistCommand());
        String message;
        if (triggers.length > 0) { 
            message= MessageFormat.format(AntEditorMessages.getString("AntEditorCompletionProcessor.63"), new Object[] { triggers[0].format(), showMessage }); //$NON-NLS-1$
        } else {
            message= MessageFormat.format(AntEditorMessages.getString("AntEditorCompletionProcessor.64"), new String[] {showMessage}); //$NON-NLS-1$
        }
        return message;
    }

    private ParameterizedCommand getContentAssistCommand() {
        final ICommandService commandSvc= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class);
        final Command command= commandSvc.getCommand(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
        ParameterizedCommand pCmd= new ParameterizedCommand(command, null);
        return pCmd;
    }
}