/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant.taskdefs;

import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.util.CollectionUtils;

/**
 * Class to manage Manifest information
 *
 * @author Conor MacNeill
 * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
 * @author <a href="mailto:j_a_fernandez@yahoo.com">Jose Alberto Fernandez</a>
 *
 * @since Ant 1.4
 *
 * @ant.task category="java"
 */
public class Manifest extends Task {
    /** The standard manifest version header */
    public static final String ATTRIBUTE_MANIFEST_VERSION 
        = "Manifest-Version";

    /** The standard Signature Version header */
    public static final String ATTRIBUTE_SIGNATURE_VERSION 
        = "Signature-Version";

    /** The Name Attribute is the first in a named section */
    public static final String ATTRIBUTE_NAME = "Name";

    /** The From Header is disallowed in a Manifest */
    public static final String ATTRIBUTE_FROM = "From";

    /** The Class-Path Header is special - it can be duplicated */
    public static final String ATTRIBUTE_CLASSPATH = "class-path";

    /** Default Manifest version if one is not specified */
    public static final  String DEFAULT_MANIFEST_VERSION = "1.0";

    /** The max length of a line in a Manifest */
    public static final int MAX_LINE_LENGTH = 72;
    
    /** 
     * Max length of a line section which is continued. Need to allow 
     * for the CRLF.
     */
    public static final int MAX_SECTION_LENGTH = MAX_LINE_LENGTH - 2;

    /** The End-Of-Line marker in manifests */
    public static final String EOL = "\r\n";
    
    /**
     * Helper class for Manifest's mode attribute.
     */
    public static class Mode extends EnumeratedAttribute {
        /** 
         * Get Allowed values for the mode attribute.
         *
         * @return a String array of the allowed values.
         */
        public String[] getValues() {
            return new String[] {"update", "replace"};
        }
    }

    /**
     * Class to hold manifest attributes
     */
    public static class Attribute {
        /** The attribute's name */
        private String name = null;

        /** The attribute's value */
        private Vector values = new Vector();

        /**
         * For multivalued attributes, this is the index of the attribute
         * currently being defined.
         */
        private int currentIndex = 0;
        
        /**
         * Construct an empty attribute */
        public Attribute() {
        }

        /**
         * Construct an attribute by parsing a line from the Manifest
         *
         * @param line the line containing the attribute name and value
         *
         * @throws ManifestException if the line is not valid
         */
        public Attribute(String line) throws ManifestException {
            parse(line);
        }

        /**
         * Construct a manifest by specifying its name and value
         *
         * @param name the attribute's name
         * @param value the Attribute's value
         */
        public Attribute(String name, String value) {
            this.name = name;
            setValue(value);
        }

        /**
         * @see java.lang.Object#hashCode
         */
        public int hashCode() {
            int hashCode = 0;
            
            if (name != null) {
                hashCode += name.hashCode();
            }
            
            hashCode += values.hashCode();
            return hashCode;
        }

        /**
         * @see java.lang.Object#equals
         */
        public boolean equals(Object rhs) {
            if (rhs == null || rhs.getClass() != getClass()) {
                return false;
            }
    
            if (rhs == this) {
                return true;
            }

            Attribute rhsAttribute = (Attribute) rhs;
            String lhsKey = getKey();
            String rhsKey = rhsAttribute.getKey();
            if ((lhsKey == null && rhsKey != null) 
                 || (lhsKey != null && rhsKey == null)
                 || !lhsKey.equals(rhsKey)) {
                return false;
            }
            
            return CollectionUtils.equals(values, rhsAttribute.values);
        }

        /**
         * Parse a line into name and value pairs
         *
         * @param line the line to be parsed
         *
         * @throws ManifestException if the line does not contain a colon
         * separating the name and value
         */
        public void parse(String line) throws ManifestException {
            int index = line.indexOf(": ");
            if (index == -1) {
                throw new ManifestException("Manifest line \"" + line 
                    + "\" is not valid as it does not " 
                    + "contain a name and a value separated by ': ' ");
            }
            name = line.substring(0, index);
            setValue(line.substring(index + 2));
        }

        /**
         * Set the Attribute's name
         *
         * @param name the attribute's name
         */
        public void setName(String name) {
            this.name = name;
        }

        /**
         * Get the Attribute's name
         *
         * @return the attribute's name.
         */
        public String getName() {
            return name;
        }

        /**
         * Get the attribute's Key - its name in lower case.
         *
         * @return the attribute's key.
         */
        public String getKey() {
            if (name == null) {
                return null;
            }
            return name.toLowerCase();
        }
        
        /**
         * Set the Attribute's value
         *
         * @param value the attribute's value
         */
        public void setValue(String value) {
            if (currentIndex >= values.size()) {
                values.addElement(value);
                currentIndex = values.size() - 1;
            } else {
                values.setElementAt(value, currentIndex);
            }
        }

        /**
         * Get the Attribute's value
         *
         * @return the attribute's value.
         */
        public String getValue() {
            if (values.size() == 0) {
                return null;
            }
            
            String fullValue = "";
            for (Enumeration e = getValues(); e.hasMoreElements();) {
                String value = (String) e.nextElement();
                fullValue += value + " ";
            }
            return fullValue.trim();
        }

        /**
         * Add a new value to this attribute - making it multivalued
         *
         * @param value the attribute's additional value
         */
        public void addValue(String value) {
            currentIndex++;
            setValue(value);
        }
        
        /** 
         * Get all the attribute's values
         *
         * @return an enumeration of the attributes values
         */
        public Enumeration getValues() {
            return values.elements();
        }
        
        /**
         * Add a continuation line from the Manifest file
         *
         * When lines are too long in a manifest, they are continued on the
         * next line by starting with a space. This method adds the continuation
         * data to the attribute value by skipping the first character.
         *
         * @param line the continuation line.
         */
        public void addContinuation(String line) {
            String currentValue = (String) values.elementAt(currentIndex);
            setValue(currentValue + line.substring(1));
        }

        /**
         * Write the attribute out to a print writer.
         *
         * @param writer the Writer to which the attribute is written
         *
         * @throws IOException if the attribte value cannot be written
         */
        public void write(PrintWriter writer) throws IOException {
            for (Enumeration e = getValues(); e.hasMoreElements();) {
                writeValue(writer, (String) e.nextElement());
            }
        }
        
        /**
         * Write a single attribute value out
         *
         * @param writer the Writer to which the attribute is written
         * @param value the attribute value
         *
         * @throws IOException if the attribte value cannot be written
         */
        private void writeValue(PrintWriter writer, String value) 
             throws IOException {
            String line = name + ": " + value;
            while (line.getBytes().length > MAX_LINE_LENGTH) {
                // try to find a MAX_LINE_LENGTH byte section
                int breakIndex = MAX_SECTION_LENGTH;
                String section = line.substring(0, breakIndex);
                while (section.getBytes().length > MAX_SECTION_LENGTH 
                     && breakIndex > 0) {
                    breakIndex--;
                    section = line.substring(0, breakIndex);
                }
                if (breakIndex == 0) {
                    throw new IOException("Unable to write manifest line " 
                        + name + ": " + value);
                }
                writer.print(section + EOL);
                line = " " + line.substring(breakIndex);
            }
            writer.print(line + EOL);
        }
    }
    
    /**
     * Class to represent an individual section in the
     * Manifest. A section consists of a set of attribute values,
     * separated from other sections by a blank line.
     */
    public static class Section {
        /** Warnings for this section */
        private Vector warnings = new Vector();

        /** 
         * The section's name if any. The main section in a 
         * manifest is unnamed.
         */
        private String name = null;

        /** The section's attributes.*/
        private Hashtable attributes = new Hashtable();

        /** Index used to retain the attribute ordering */
        private Vector attributeIndex = new Vector();
        
        /**
         * Set the Section's name
         *
         * @param name the section's name
         */
        public void setName(String name) {
            this.name = name;
        }

        /**
         * Get the Section's name
         *
         * @return the section's name.
         */
        public String getName() {
            return name;
        }

        /**
         * Read a section through a reader
         *
         * @param reader the reader from which the section is read
         *
         * @return the name of the next section if it has been read as 
         *         part of this section - This only happens if the 
         *         Manifest is malformed.
         *
         * @throws ManifestException if the section is not valid according 
         *         to the JAR spec
         * @throws IOException if the section cannot be read from the reader.
         */
        public String read(BufferedReader reader) 
             throws ManifestException, IOException {
            Attribute attribute = null;
            while (true) {
                String line = reader.readLine();
                if (line == null || line.length() == 0) {
                    return null;
                }
                if (line.charAt(0) == ' ') {
                    // continuation line
                    if (attribute == null) {
                        if (name != null) {
                            // a continuation on the first line is a 
                            // continuation of the name - concatenate this 
                            // line and the name
                            name += line.substring(1);
                        } else {
                            throw new ManifestException("Can't start an " 
                                + "attribute with a continuation line " + line);
                        }
                    } else {
                        attribute.addContinuation(line);
                    }
                } else {
                    attribute = new Attribute(line);
                    String nameReadAhead = addAttributeAndCheck(attribute);
                    if (nameReadAhead != null) {
                        return nameReadAhead;
                    }
                }
            }
        }

        /**
         * Merge in another section
         *
         * @param section the section to be merged with this one.
         *
         * @throws ManifestException if the sections cannot be merged.
         */
        public void merge(Section section) throws ManifestException {
            if (name == null && section.getName() != null 
                || name != null 
                && !(name.equalsIgnoreCase(section.getName()))) {
                throw new ManifestException("Unable to merge sections " 
                    + "with different names");
            }

            Enumeration e = section.getAttributeKeys();
            while (e.hasMoreElements()) {
                String attributeName = (String) e.nextElement();
                Attribute attribute = section.getAttribute(attributeName);
                if (attributeName.equals(ATTRIBUTE_CLASSPATH) &&
                        attributes.containsKey(attributeName)) {
                    Attribute ourClassPath = getAttribute(attributeName);
                    Enumeration cpe = attribute.getValues();
                    while (cpe.hasMoreElements()) {
                        String value = (String) cpe.nextElement();
                        ourClassPath.addValue(value);
                    }
                } else {
                    // the merge file always wins
                    storeAttribute(attribute);
                }
            }

            // add in the warnings
            Enumeration warnEnum = section.warnings.elements();
            while (warnEnum.hasMoreElements()) {
                warnings.addElement(warnEnum.nextElement());
            }
        }

        /**
         * Write the section out to a print writer.
         *
         * @param writer the Writer to which the section is written
         *
         * @throws IOException if the section cannot be written
         */
        public void write(PrintWriter writer) throws IOException {
            if (name != null) {
                Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name);
                nameAttr.write(writer);
            }
            Enumeration e = getAttributeKeys();
            while (e.hasMoreElements()) {
                String key = (String) e.nextElement();
                Attribute attribute = getAttribute(key);
                attribute.write(writer);
            }
            writer.print(EOL);
        }

        /**
         * Get a attribute of the section
         *
         * @param attributeName the name of the attribute
         * @return a Manifest.Attribute instance if the attribute is
         *         single-valued, otherwise a Vector of Manifest.Attribute
         *         instances.
         */
        public Attribute getAttribute(String attributeName) {
            return (Attribute) attributes.get(attributeName.toLowerCase());
        }

        /**
         * Get the attribute keys.
         *
         * @return an Enumeration of Strings, each string being the lower case
         *         key of an attribute of the section.
         */
        public Enumeration getAttributeKeys() {
            return attributeIndex.elements();
        }
        
        /**
         * Get the value of the attribute with the name given.
         *
         * @param attributeName the name of the attribute to be returned.
         *
         * @return the attribute's value or null if the attribute does not exist
         *         in the section
         */
        public String getAttributeValue(String attributeName) {
            Attribute attribute = getAttribute(attributeName.toLowerCase());
            if (attribute == null) {
                return null;
            }
            return attribute.getValue();
        }

        /**
         * Remove tge given attribute from the section
         *
         * @param attributeName the name of the attribute to be removed.
         */
        public void removeAttribute(String attributeName) {
            String key = attributeName.toLowerCase();
            attributes.remove(key);
            attributeIndex.removeElement(key);
        }

        /**
         * Add an attribute to the section.
         *
         * @param attribute the attribute to be added to the section
         *
         * @exception ManifestException if the attribute is not valid.
         */
        public void addConfiguredAttribute(Attribute attribute) 
             throws ManifestException {
            String check = addAttributeAndCheck(attribute);
            if (check != null) {
                throw new BuildException("Specify the section name using " 
                    + "the \"name\" attribute of the <section> element rather "
                    + "than using a \"Name\" manifest attribute");
            }
        }

        /**
         * Add an attribute to the section
         *
         * @param attribute the attribute to be added.
         *
         * @return the value of the attribute if it is a name 
         *         attribute - null other wise
         *
         * @exception ManifestException if the attribute already 
         *            exists in this section.
         */
        public String addAttributeAndCheck(Attribute attribute) 
             throws ManifestException {
            if (attribute.getName() == null || attribute.getValue() == null) {
                throw new BuildException("Attributes must have name and value");
            }
            if (attribute.getKey().equalsIgnoreCase(ATTRIBUTE_NAME)) {
                warnings.addElement("\"" + ATTRIBUTE_NAME + "\" attributes " 
                    + "should not occur in the main section and must be the "
                    + "first element in all other sections: \"" 
                    + attribute.getName() + ": " + attribute.getValue() + "\"");
                return attribute.getValue();
            }

            if (attribute.getKey().startsWith(ATTRIBUTE_FROM.toLowerCase())) {
                warnings.addElement("Manifest attributes should not start " 
                    + "with \"" + ATTRIBUTE_FROM + "\" in \"" 
                    + attribute.getName() + ": " + attribute.getValue() + "\"");
            } else {
                // classpath attributes go into a vector
                String attributeKey = attribute.getKey();
                if (attributeKey.equals(ATTRIBUTE_CLASSPATH)) {
                    Attribute classpathAttribute = 
                        (Attribute) attributes.get(attributeKey);
                    
                    if (classpathAttribute == null) {
                        storeAttribute(attribute);
                    } else {
                        Enumeration e = attribute.getValues();
                        while (e.hasMoreElements()) {
                            String value = (String) e.nextElement();
                            classpathAttribute.addValue(value);
                        }
                    }
                } else if (attributes.containsKey(attributeKey)) {
                    throw new ManifestException("The attribute \"" 
                        + attribute.getName() + "\" may not occur more " 
                        + "than once in the same section");
                } else {
                    storeAttribute(attribute);
                }
            }
            return null;
        }
        
        /**
         * Store an attribute and update the index.
         *
         * @param attribute the attribute to be stored
         */
        private void storeAttribute(Attribute attribute) {
            if (attribute == null) {
                return;
            }
            String attributeKey = attribute.getKey();
            attributes.put(attributeKey, attribute);
            if (!attributeIndex.contains(attributeKey)) {
                attributeIndex.addElement(attributeKey);
            }
        }

        /**
         * Get the warnings for this section.
         *
         * @return an Enumeration of warning strings.
         */
        public Enumeration getWarnings() {
            return warnings.elements();
        }

        /**
         * @see java.lang.Object#hashCode
         */
        public int hashCode() {
            int hashCode = 0;
            
            if (name != null) {
                hashCode += name.hashCode();
            }
            
            hashCode += attributes.hashCode();
            return hashCode;
        }

        /**
         * @see java.lang.Object#equals
         */
        public boolean equals(Object rhs) {
            if (rhs == null || rhs.getClass() != getClass()) {
                return false;
            }
    
            if (rhs == this) {
                return true;
            }

            Section rhsSection = (Section) rhs;
            
            return attributes.equals(rhsSection.attributes);
        }
    }


    /** The version of this manifest */
    private String manifestVersion = DEFAULT_MANIFEST_VERSION;

    /** The main section of this manifest */
    private Section mainSection = new Section();

    /** The named sections of this manifest */
    private Hashtable sections = new Hashtable();

    /** Index of sections - used to retain order of sections in manifest */
    private Vector sectionIndex = new Vector();

    /**
     * The file to which the manifest should be written when used as a task
     */
    private File manifestFile;

    /**
     * The mode with which the manifest file is written 
     */
    private Mode mode;

    /**
     * Construct a manifest from Ant's default manifest file.
     *
     * @return the default manifest.
     * @exception BuildException if there is a problem loading the 
     *            default manifest
     */
    public static Manifest getDefaultManifest() throws BuildException {
        try {
            String defManifest = "/org/apache/tools/ant/defaultManifest.mf";
            InputStream in = Manifest.class.getResourceAsStream(defManifest);
            if (in == null) {
                throw new BuildException("Could not find default manifest: " 
                    + defManifest);
            }
            try {
                return new Manifest(new InputStreamReader(in, "ASCII"));
            } catch (UnsupportedEncodingException e) {
                return new Manifest(new InputStreamReader(in));
            }
        } catch (ManifestException e) {
            throw new BuildException("Default manifest is invalid !!", e);
        } catch (IOException e) {
            throw new BuildException("Unable to read default manifest", e);
        }
    }

    /** Construct an empty manifest */
    public Manifest() {
        mode = new Mode();
        mode.setValue("replace");
        manifestVersion = null;
    }

    /**
     * Read a manifest file from the given reader
     *
     * @param r is the reader from which the Manifest is read
     *
     * @throws ManifestException if the manifest is not valid according 
     *         to the JAR spec
     * @throws IOException if the manifest cannot be read from the reader.
     */
    public Manifest(Reader r) throws ManifestException, IOException {
        BufferedReader reader = new BufferedReader(r);
        // This should be the manifest version
        String nextSectionName = mainSection.read(reader);
        String readManifestVersion 
            = mainSection.getAttributeValue(ATTRIBUTE_MANIFEST_VERSION);
        if (readManifestVersion != null) {
            manifestVersion = readManifestVersion;
            mainSection.removeAttribute(ATTRIBUTE_MANIFEST_VERSION);
        }

        String line = null;
        while ((line = reader.readLine()) != null) {
            if (line.length() == 0) {
                continue;
            }

            Section section = new Section();
            if (nextSectionName == null) {
                Attribute sectionName = new Attribute(line);
                if (!sectionName.getName().equalsIgnoreCase(ATTRIBUTE_NAME)) {
                    throw new ManifestException("Manifest sections should " 
                        + "start with a \"" + ATTRIBUTE_NAME 
                        + "\" attribute and not \"" 
                        + sectionName.getName() + "\"");
                }
                nextSectionName = sectionName.getValue();
            } else {
                // we have already started reading this section
                // this line is the first attribute. set it and then 
                // let the normal read handle the rest
                Attribute firstAttribute = new Attribute(line);
                section.addAttributeAndCheck(firstAttribute);
            }

            section.setName(nextSectionName);
            nextSectionName = section.read(reader);
            addConfiguredSection(section);
        }
    }

    /**
     * Add a section to the manifest
     *
     * @param section the manifest section to be added
     *
     * @exception ManifestException if the secti0on is not valid.
     */
    public void addConfiguredSection(Section section) 
         throws ManifestException {
        String sectionName = section.getName();
        if (sectionName == null) {
            throw new BuildException("Sections must have a name");
        }
        sections.put(sectionName, section);
        if (!sectionIndex.contains(sectionName)) {
            sectionIndex.addElement(sectionName);
        }
    }

    /**
     * Add an attribute to the manifest - it is added to the main section.
     *
     * @param attribute the attribute to be added.
     *
     * @exception ManifestException if the attribute is not valid.
     */
    public void addConfiguredAttribute(Attribute attribute) 
         throws ManifestException {
        mainSection.addConfiguredAttribute(attribute);
    }

    /**
     * Merge the contents of the given manifest into this manifest
     *
     * @param other the Manifest to be merged with this one.
     *
     * @throws ManifestException if there is a problem merging the 
     *         manfest according to the Manifest spec.
     */
    public void merge(Manifest other) throws ManifestException {
        merge(other, false);
    }

    /**
     * Merge the contents of the given manifest into this manifest
     *
     * @param other the Manifest to be merged with this one.
     * @param overwriteMain whether to overwrite the main section 
     *        of the current manifest
     *
     * @throws ManifestException if there is a problem merging the 
     *         manfest according to the Manifest spec.
     */
    public void merge(Manifest other, boolean overwriteMain) 
         throws ManifestException {
        if (other != null) {
             if (overwriteMain) {
                 mainSection = other.mainSection;
             } else {
                 mainSection.merge(other.mainSection);
             }

             if (other.manifestVersion != null) {
                 manifestVersion = other.manifestVersion;
             }

             Enumeration e = other.getSectionNames();
             while (e.hasMoreElements()) {
                 String sectionName = (String) e.nextElement();
                 Section ourSection = (Section) sections.get(sectionName);
                 Section otherSection 
                    = (Section) other.sections.get(sectionName);
                 if (ourSection == null) {
                     if (otherSection != null) {
                         addConfiguredSection(otherSection);
                     }
                 } else {
                     ourSection.merge(otherSection);
                 }
             }
         }
    }

    /**
    * Write the manifest out to a print writer.
    *
    * @param writer the Writer to which the manifest is written
    *
    * @throws IOException if the manifest cannot be written
    */
    public void write(PrintWriter writer) throws IOException {
        writer.print(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion + EOL);
        String signatureVersion 
            = mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION);
        if (signatureVersion != null) {
            writer.print(ATTRIBUTE_SIGNATURE_VERSION + ": " 
                + signatureVersion + EOL);
            mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION);
        }
        mainSection.write(writer);
        
        // add it back
        if (signatureVersion != null) {
            try {
                Attribute svAttr = new Attribute(ATTRIBUTE_SIGNATURE_VERSION, 
                    signatureVersion);
                mainSection.addConfiguredAttribute(svAttr);
            } catch (ManifestException e) {
                // shouldn't happen - ignore
            }
        }

        Enumeration e = sectionIndex.elements();
        while (e.hasMoreElements()) {
            String sectionName = (String) e.nextElement();
            Section section = getSection(sectionName);
            section.write(writer);
        }
    }

    /**
     * Convert the manifest to its string representation
     *
     * @return a multiline string with the Manifest as it 
     *         appears in a Manifest file.
     */
    public String toString() {
        StringWriter sw = new StringWriter();
        try {
            write(new PrintWriter(sw));
        } catch (IOException e) {
            return null;
        }
        return sw.toString();
    }

    /**
     * Get the warnings for this manifest.
     *
     * @return an enumeration of warning strings
     */
    public Enumeration getWarnings() {
        Vector warnings = new Vector();

        Enumeration warnEnum = mainSection.getWarnings(); 
        while (warnEnum.hasMoreElements()) {
            warnings.addElement(warnEnum.nextElement());
        }

        // create a vector and add in the warnings for all the sections
        Enumeration e = sections.elements(); 
        while (e.hasMoreElements()) {
            Section section = (Section) e.nextElement();
            Enumeration e2 = section.getWarnings(); 
            while (e2.hasMoreElements()) {
                warnings.addElement(e2.nextElement());
            }
        }

        return warnings.elements();
    }

    /**
     * @see java.lang.Object#hashCode
     */
    public int hashCode() {
        int hashCode = 0;
        
        if (manifestVersion != null) {
            hashCode += manifestVersion.hashCode();
        }
        hashCode += mainSection.hashCode();
        hashCode += sections.hashCode();
        
        return hashCode;
    }
    
    /**
     * @see java.lang.Object#equals
     */
    public boolean equals(Object rhs) {
        if (rhs == null || rhs.getClass() != getClass()) {
            return false;
        }

        if (rhs == this) {
            return true;
        }
        
        Manifest rhsManifest = (Manifest) rhs;
        if (manifestVersion == null) {
            if (rhsManifest.manifestVersion != null) {
                return false;
            }
        } else if (!manifestVersion.equals(rhsManifest.manifestVersion)) {
            return false;
        }

        if (!mainSection.equals(rhsManifest.mainSection)) {
            return false;
        }

        return sections.equals(rhsManifest.sections);
    }

    /**
     * The name of the manifest file to write (if used as a task).
     *
     * @param f the Manifest file to be written
     */
    public void setFile(File f) {
        manifestFile = f;
    }

    /**
     * Shall we update or replace an existing manifest?
     *
     * @param m the mode value - update or replace.
     */
    public void setMode(Mode m) {
        mode = m;
    }

    /**
     * Get the version of the manifest
     *
     * @return the manifest's version string
     */
    public String getManifestVersion() {
        return manifestVersion;
    }

    /**
     * Get the main section of the manifest
     *
     * @return the main section of the manifest
     */
    public Section getMainSection() {
        return mainSection;
    }

    /**
     * Get a particular section from the manifest
     *
     * @param name the name of the section desired.
     * @return the specified section or null if that section
     * does not exist in the manifest
     */
    public Section getSection(String name) {
        return (Section) sections.get(name);
    }

    /**
     * Get the section names in this manifest.
     *
     * @return an Enumeration of section names
     */
    public Enumeration getSectionNames() {
        return sectionIndex.elements();
    }

    /**
     * Create or update the Manifest when used as a task.
     *
     * @throws BuildException if the manifest cannot be written.
     */
    public void execute() throws BuildException {
        if (manifestFile == null) {
            throw new BuildException("the file attribute is required");
        }

        Manifest toWrite = getDefaultManifest();
        Manifest current = null;
        BuildException error = null;

        if (manifestFile.exists()) {
            FileReader f = null;
            try {
                f = new FileReader(manifestFile);
                current = new Manifest(f);
            } catch (ManifestException m) {
                error = new BuildException("Existing manifest " + manifestFile
                                           + " is invalid", m, location);
            } catch (IOException e) {
                error = new BuildException("Failed to read " + manifestFile,
                                           e, location);
            } finally {
                if (f != null) {
                    try {
                        f.close();
                    } catch (IOException e) {}
                }
            }
        }

        try {
            if (mode.getValue().equals("update") && manifestFile.exists()) {
                if (current != null) {
                    toWrite.merge(current);
                } else if (error != null) {
                    throw error;
                }
            }

            toWrite.merge(this);
        } catch (ManifestException m) {
            throw new BuildException("Manifest is invalid", m, location);
        }

        if (toWrite.equals(current)) {
            log("Manifest has not changed, do not recreate", 
                Project.MSG_VERBOSE);
            return;
        }

        PrintWriter w = null;
        try {
            w = new PrintWriter(new FileWriter(manifestFile));
            toWrite.write(w);
        } catch (IOException e) {
            throw new BuildException("Failed to write " + manifestFile,
                                     e, location);
        } finally {
            if (w != null) {
                w.close();
            }
        }
    }

}
