/*
 * Copyright 2016 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.jboss.forge.addon.maven.util;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.apache.maven.model.Activation;
import org.apache.maven.model.ActivationFile;
import org.apache.maven.model.ActivationOS;
import org.apache.maven.model.ActivationProperty;
import org.apache.maven.model.Build;
import org.apache.maven.model.BuildBase;
import org.apache.maven.model.CiManagement;
import org.apache.maven.model.ConfigurationContainer;
import org.apache.maven.model.Contributor;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.DeploymentRepository;
import org.apache.maven.model.Developer;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Exclusion;
import org.apache.maven.model.Extension;
import org.apache.maven.model.FileSet;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.model.License;
import org.apache.maven.model.MailingList;
import org.apache.maven.model.Model;
import org.apache.maven.model.ModelBase;
import org.apache.maven.model.Notifier;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Parent;
import org.apache.maven.model.PatternSet;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginConfiguration;
import org.apache.maven.model.PluginContainer;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.Prerequisites;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Relocation;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.ReportSet;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.Repository;
import org.apache.maven.model.RepositoryBase;
import org.apache.maven.model.RepositoryPolicy;
import org.apache.maven.model.Resource;
import org.apache.maven.model.Scm;
import org.apache.maven.model.Site;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.jdom.Content;
import org.jdom.DefaultJDOMFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Text;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

/**
 * Class MavenJDOMWriter.
 *
 * @version $Revision$ $Date$
 */
@SuppressWarnings("rawtypes")
public class MavenJDOMWriter
{
   // --------------------------/
   // - Class/Member Variables -/
   // --------------------------/

   /**
    * Field factory.
    */
   private DefaultJDOMFactory factory;

   /**
    * Field lineSeparator.
    */
   private String lineSeparator;

   private static final String LS = System.lineSeparator();

   // ----------------/
   // - Constructors -/
   // ----------------/

   public MavenJDOMWriter()
   {
      factory = new DefaultJDOMFactory();
      lineSeparator = "\n";
   } // -- org.apache.maven.model.io.jdom.MavenJDOMWriter()

   /**
    * Method write.
    *
    * @param project
    * @param stream
    * @param document
    * @deprecated
    */
   @Deprecated
   public void write(Model project, Document document, OutputStream stream) throws java.io.IOException
   {
      updateModel(project, "project", new Counter(0), document.getRootElement());

      XMLOutputter outputter = new XMLOutputter();
      outputter.setFormat(Format.getPrettyFormat().setIndent("  ").setLineSeparator(LS));
      outputter.output(document, stream);
   } // -- void write(Model, Document, OutputStream)

   /**
    * Method write.
    *
    * @param project
    * @param writer
    * @param document
    */
   public void write(Model project, Document document, String encoding, OutputStreamWriter writer)
            throws java.io.IOException
   {
      Format format = Format.getRawFormat().setEncoding(encoding).setLineSeparator(LS);
      write(project, document, writer, format);
   } // -- void write(Model, Document, OutputStreamWriter)

   /**
    * Method write.
    *
    * @param project
    * @param jdomFormat
    * @param writer
    * @param document
    */
   public void write(Model project, Document document, Writer writer, Format jdomFormat) throws java.io.IOException
   {
      updateModel(project, "project", new Counter(0), document.getRootElement());

      XMLOutputter outputter = new XMLOutputter();
      outputter.setFormat(jdomFormat);
      outputter.output(document, writer);
   } // -- void write(Model, Document, Writer, Format)

   // -----------/
   // - Methods -/
   // -----------/

   /**
    * Method findAndReplaceProperties.
    *
    * @param counter
    * @param props
    * @param name
    * @param parent
    */
   @SuppressWarnings("unchecked")
   protected Element findAndReplaceProperties(Counter counter, Element parent, String name, Map props)
   {
      boolean shouldExist = (props != null) && !props.isEmpty();
      Element element = updateElement(counter, parent, name, shouldExist);
      if (shouldExist)
      {
         Iterator it = props.keySet().iterator();
         Counter innerCounter = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            String key = (String) it.next();
            findAndReplaceSimpleElement(innerCounter, element, key, (String) props.get(key), null);
         }

         List<String> lst = new ArrayList<String>(props.keySet());
         it = element.getChildren().iterator();
         while (it.hasNext())
         {
            Element elem = (Element) it.next();
            String key = elem.getName();
            if (!lst.contains(key))
            {
               it.remove();
            }
         }
      }
      return element;
   } // -- Element findAndReplaceProperties(Counter, Element, String, Map)

   /**
    * Method findAndReplaceSimpleElement.
    *
    * @param counter
    * @param defaultValue
    * @param text
    * @param name
    * @param parent
    */
   protected Element findAndReplaceSimpleElement(Counter counter, Element parent, String name, String text,
            String defaultValue)
   {
      if ((defaultValue != null) && (text != null) && defaultValue.equals(text))
      {
         Element element = parent.getChild(name, parent.getNamespace());
         // if exist and is default value or if doesn't exist.. just keep the
         // way it is..
         if (((element != null) && defaultValue.equals(element.getText())) || (element == null))
         {
            return element;
         }
      }

      boolean shouldExist = (text != null) && (text.trim().length() > 0);
      Element element = updateElement(counter, parent, name, shouldExist);
      if (shouldExist)
      {
         element.setText(text);
      }
      return element;
   } // -- Element findAndReplaceSimpleElement(Counter, Element, String,
     // String, String)

   /**
    * Method findAndReplaceSimpleLists.
    *
    * @param counter
    * @param childName
    * @param parentName
    * @param list
    * @param parent
    */
   protected Element findAndReplaceSimpleLists(Counter counter, Element parent, java.util.Collection list,
            String parentName, String childName)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentName, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childName, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            String value = (String) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childName, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            el.setText(value);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
      return element;
   } // -- Element findAndReplaceSimpleLists(Counter, Element,
     // java.util.Collection, String,
     // String)

   /**
    * Method findAndReplaceXpp3DOM.
    *
    * @param counter
    * @param dom
    * @param name
    * @param parent
    */
   protected Element findAndReplaceXpp3DOM(Counter counter, Element parent, String name, Xpp3Dom dom)
   {
      boolean shouldExist = (dom != null) && ((dom.getChildCount() > 0) || (dom.getValue() != null));
      Element element = updateElement(counter, parent, name, shouldExist);
      if (shouldExist)
      {
         replaceXpp3DOM(element, dom, new Counter(counter.getDepth() + 1));
      }
      return element;
   } // -- Element findAndReplaceXpp3DOM(Counter, Element, String, Xpp3Dom)

   /**
    * Method insertAtPreferredLocation.
    *
    * @param parent
    * @param counter
    * @param child
    */
   protected void insertAtPreferredLocation(Element parent, Element child, Counter counter)
   {
      int contentIndex = 0;
      int elementCounter = 0;
      Iterator it = parent.getContent().iterator();
      Text lastText = null;
      int offset = 0;
      while (it.hasNext() && (elementCounter <= counter.getCurrentIndex()))
      {
         Object next = it.next();
         offset = offset + 1;
         if (next instanceof Element)
         {
            elementCounter = elementCounter + 1;
            contentIndex = contentIndex + offset;
            offset = 0;
         }
         if ((next instanceof Text) && it.hasNext())
         {
            lastText = (Text) next;
         }
      }
      if ((lastText != null) && (lastText.getTextTrim().length() == 0))
      {
         lastText = (Text) lastText.clone();
      }
      else
      {
         StringBuilder starter = new StringBuilder(lineSeparator);
         for (int i = 0; i < counter.getDepth(); i++)
         {
            starter.append("  "); // TODO make settable?
         }
         lastText = factory.text(starter.toString());
      }
      if (parent.getContentSize() == 0)
      {
         Text finalText = (Text) lastText.clone();
         finalText.setText(finalText.getText().substring(0, finalText.getText().length() - "  ".length()));
         parent.addContent(contentIndex, finalText);
      }
      parent.addContent(contentIndex, child);
      parent.addContent(contentIndex, lastText);
   } // -- void insertAtPreferredLocation(Element, Element, Counter)

   /**
    * Method iterateContributor.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateContributor(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Contributor value = (Contributor) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateContributor(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateContributor(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateDependency.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateDependency(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Dependency value = (Dependency) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateDependency(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateDependency(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateDeveloper.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateDeveloper(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Developer value = (Developer) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateDeveloper(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateDeveloper(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateExclusion.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateExclusion(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Exclusion value = (Exclusion) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateExclusion(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateExclusion(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateExtension.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateExtension(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Extension value = (Extension) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateExtension(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateExtension(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateLicense.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateLicense(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            License value = (License) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateLicense(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateLicense(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateMailingList.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateMailingList(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            MailingList value = (MailingList) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateMailingList(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateMailingList(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateNotifier.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateNotifier(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Notifier value = (Notifier) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateNotifier(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateNotifier(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iteratePlugin.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iteratePlugin(Counter counter, Element parent, java.util.Collection list, java.lang.String parentTag,
            java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Plugin value = (Plugin) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updatePlugin(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iteratePlugin(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iteratePluginExecution.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iteratePluginExecution(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            PluginExecution value = (PluginExecution) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updatePluginExecution(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iteratePluginExecution(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateProfile.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateProfile(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Profile value = (Profile) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateProfile(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateProfile(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateReportPlugin.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateReportPlugin(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            ReportPlugin value = (ReportPlugin) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateReportPlugin(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateReportPlugin(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateReportSet.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateReportSet(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            ReportSet value = (ReportSet) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateReportSet(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateReportSet(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateRepository.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateRepository(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Repository value = (Repository) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateRepository(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateRepository(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method iterateResource.
    *
    * @param counter
    * @param childTag
    * @param parentTag
    * @param list
    * @param parent
    */
   protected void iterateResource(Counter counter, Element parent, java.util.Collection list,
            java.lang.String parentTag, java.lang.String childTag)
   {
      boolean shouldExist = (list != null) && (list.size() > 0);
      Element element = updateElement(counter, parent, parentTag, shouldExist);
      if (shouldExist)
      {
         Iterator it = list.iterator();
         Iterator elIt = element.getChildren(childTag, element.getNamespace()).iterator();
         if (!elIt.hasNext())
         {
            elIt = null;
         }

         Counter innerCount = new Counter(counter.getDepth() + 1);
         while (it.hasNext())
         {
            Resource value = (Resource) it.next();
            Element el;
            if ((elIt != null) && elIt.hasNext())
            {
               el = (Element) elIt.next();
               if (!elIt.hasNext())
               {
                  elIt = null;
               }
            }
            else
            {
               el = factory.element(childTag, element.getNamespace());
               insertAtPreferredLocation(element, el, innerCount);
            }
            updateResource(value, childTag, innerCount, el);
            innerCount.increaseCount();
         }
         if (elIt != null)
         {
            while (elIt.hasNext())
            {
               elIt.next();
               elIt.remove();
            }
         }
      }
   } // -- void iterateResource(Counter, Element, java.util.Collection,
     // java.lang.String,
     // java.lang.String)

   /**
    * Method replaceXpp3DOM.
    *
    * @param parent
    * @param counter
    * @param parentDom
    */
   @SuppressWarnings("unchecked")
   protected void replaceXpp3DOM(final Element parent, final Xpp3Dom parentDom, final Counter counter)
   {
      if (parentDom.getChildCount() > 0)
      {
         Xpp3Dom[] childs = parentDom.getChildren();
         Collection<Xpp3Dom> domChilds = new ArrayList<>();
         for (int i = 0; i < childs.length; i++)
         {
            domChilds.add(childs[i]);
         }

         ListIterator<Element> it = parent.getChildren().listIterator();
         while (it.hasNext())
         {
            Element elem = it.next();
            Iterator<Xpp3Dom> it2 = domChilds.iterator();
            Xpp3Dom corrDom = null;
            while (it2.hasNext())
            {
               Xpp3Dom dm = it2.next();
               if (dm.getName().equals(elem.getName()))
               {
                  corrDom = dm;
                  break;
               }
            }
            if (corrDom != null)
            {
               domChilds.remove(corrDom);
               replaceXpp3DOM(elem, corrDom, new Counter(counter.getDepth() + 1));
               counter.increaseCount();
            }
            else
            {
               it.remove();
            }
         }

         Iterator<Xpp3Dom> it2 = domChilds.iterator();
         while (it2.hasNext())
         {
            Xpp3Dom dm = it2.next();
            Element elem = factory.element(dm.getName(), parent.getNamespace());
            for (String attName : dm.getAttributeNames())
            {
               elem.setAttribute(attName, dm.getAttribute(attName));
            }
            insertAtPreferredLocation(parent, elem, counter);
            counter.increaseCount();
            replaceXpp3DOM(elem, dm, new Counter(counter.getDepth() + 1));
         }
      }
      else if (parentDom.getValue() != null)
      {
         parent.setText(parentDom.getValue());
      }
   } // --
     // void
     // replaceXpp3DOM(Element,
     // Xpp3Dom,
     // Counter)

   /**
    * Method updateActivation.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateActivation(Activation value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "activeByDefault",
                  (value.isActiveByDefault() == false) ? null : String.valueOf(value.isActiveByDefault()), "false");
         findAndReplaceSimpleElement(innerCount, root, "jdk", value.getJdk(), null);
         updateActivationOS(value.getOs(), "os", innerCount, root);
         updateActivationProperty(value.getProperty(), "property", innerCount, root);
         updateActivationFile(value.getFile(), "file", innerCount, root);
      }
   } // -- void updateActivation(Activation, String, Counter, Element)

   /**
    * Method updateActivationFile.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateActivationFile(ActivationFile value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "missing", value.getMissing(), null);
         findAndReplaceSimpleElement(innerCount, root, "exists", value.getExists(), null);
      }
   } // -- void updateActivationFile(ActivationFile, String, Counter, Element)

   /**
    * Method updateActivationOS.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateActivationOS(ActivationOS value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
         findAndReplaceSimpleElement(innerCount, root, "family", value.getFamily(), null);
         findAndReplaceSimpleElement(innerCount, root, "arch", value.getArch(), null);
         findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
      }
   } // -- void updateActivationOS(ActivationOS, String, Counter, Element)

   /**
    * Method updateActivationProperty.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateActivationProperty(ActivationProperty value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
         findAndReplaceSimpleElement(innerCount, root, "value", value.getValue(), null);
      }
   } // -- void updateActivationProperty(ActivationProperty, String, Counter,
     // Element)

   /**
    * Method updateBuild.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateBuild(Build value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "sourceDirectory", value.getSourceDirectory(), null);
         findAndReplaceSimpleElement(innerCount, root, "scriptSourceDirectory", value.getScriptSourceDirectory(),
                  null);
         findAndReplaceSimpleElement(innerCount, root, "testSourceDirectory", value.getTestSourceDirectory(), null);
         findAndReplaceSimpleElement(innerCount, root, "outputDirectory", value.getOutputDirectory(), null);
         findAndReplaceSimpleElement(innerCount, root, "testOutputDirectory", value.getTestOutputDirectory(), null);
         iterateExtension(innerCount, root, value.getExtensions(), "extensions", "extension");
         findAndReplaceSimpleElement(innerCount, root, "defaultGoal", value.getDefaultGoal(), null);
         iterateResource(innerCount, root, value.getResources(), "resources", "resource");
         iterateResource(innerCount, root, value.getTestResources(), "testResources", "testResource");
         findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
         findAndReplaceSimpleElement(innerCount, root, "finalName", value.getFinalName(), null);
         findAndReplaceSimpleLists(innerCount, root, value.getFilters(), "filters", "filter");
         updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root);
         iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
      } // end if
   } // -- void updateBuild(Build, String, Counter, Element)

   /**
    * Method updateBuildBase.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateBuildBase(BuildBase value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "defaultGoal", value.getDefaultGoal(), null);
         iterateResource(innerCount, root, value.getResources(), "resources", "resource");
         iterateResource(innerCount, root, value.getTestResources(), "testResources", "testResource");
         findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
         findAndReplaceSimpleElement(innerCount, root, "finalName", value.getFinalName(), null);
         findAndReplaceSimpleLists(innerCount, root, value.getFilters(), "filters", "filter");
         updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root);
         iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
      }
   } // -- void updateBuildBase(BuildBase, String, Counter, Element)

   /**
    * Method updateCiManagement.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateCiManagement(CiManagement value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "system", value.getSystem(), null);
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
         iterateNotifier(innerCount, root, value.getNotifiers(), "notifiers", "notifier");
      }
   } // -- void updateCiManagement(CiManagement, String, Counter, Element)

   /**
    * Method updateConfigurationContainer.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateConfigurationContainer(ConfigurationContainer value, String xmlTag, Counter counter,
            Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
         findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
      }
   } // -- void updateConfigurationContainer(ConfigurationContainer, String,
     // Counter, Element)

   /**
    * Method updateContributor.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateContributor(Contributor value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
      findAndReplaceSimpleElement(innerCount, root, "email", value.getEmail(), null);
      findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      findAndReplaceSimpleElement(innerCount, root, "organization", value.getOrganization(), null);
      findAndReplaceSimpleElement(innerCount, root, "organizationUrl", value.getOrganizationUrl(), null);
      findAndReplaceSimpleLists(innerCount, root, value.getRoles(), "roles", "role");
      findAndReplaceSimpleElement(innerCount, root, "timezone", value.getTimezone(), null);
      findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
   } // -- void updateContributor(Contributor, String, Counter, Element)

   /**
    * Method updateDependency.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateDependency(Dependency value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
      findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
      findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
      findAndReplaceSimpleElement(innerCount, root, "type", value.getType(), "jar");
      findAndReplaceSimpleElement(innerCount, root, "classifier", value.getClassifier(), null);
      findAndReplaceSimpleElement(innerCount, root, "scope", value.getScope(), null);
      findAndReplaceSimpleElement(innerCount, root, "systemPath", value.getSystemPath(), null);
      iterateExclusion(innerCount, root, value.getExclusions(), "exclusions", "exclusion");
      findAndReplaceSimpleElement(innerCount, root, "optional",
               (value.isOptional() == false) ? null : String.valueOf(value.isOptional()), "false");
   } // -- void updateDependency(Dependency, String, Counter, Element)

   /**
    * Method updateDependencyManagement.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateDependencyManagement(DependencyManagement value, String xmlTag, Counter counter,
            Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
      }
   } // -- void updateDependencyManagement(DependencyManagement, String,
     // Counter, Element)

   /**
    * Method updateDeploymentRepository.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateDeploymentRepository(DeploymentRepository value, String xmlTag, Counter counter,
            Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "uniqueVersion",
                  (value.isUniqueVersion() == true) ? null : String.valueOf(value.isUniqueVersion()), "true");
         findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
         findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
         findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default");
      }
   } // -- void updateDeploymentRepository(DeploymentRepository, String,
     // Counter, Element)

   /**
    * Method updateDeveloper.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateDeveloper(Developer value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
      findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
      findAndReplaceSimpleElement(innerCount, root, "email", value.getEmail(), null);
      findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      findAndReplaceSimpleElement(innerCount, root, "organization", value.getOrganization(), null);
      findAndReplaceSimpleElement(innerCount, root, "organizationUrl", value.getOrganizationUrl(), null);
      findAndReplaceSimpleLists(innerCount, root, value.getRoles(), "roles", "role");
      findAndReplaceSimpleElement(innerCount, root, "timezone", value.getTimezone(), null);
      findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
   } // -- void updateDeveloper(Developer, String, Counter, Element)

   /**
    * Method updateDistributionManagement.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateDistributionManagement(DistributionManagement value, String xmlTag, Counter counter,
            Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         updateDeploymentRepository(value.getRepository(), "repository", innerCount, root);
         updateDeploymentRepository(value.getSnapshotRepository(), "snapshotRepository", innerCount, root);
         updateSite(value.getSite(), "site", innerCount, root);
         findAndReplaceSimpleElement(innerCount, root, "downloadUrl", value.getDownloadUrl(), null);
         updateRelocation(value.getRelocation(), "relocation", innerCount, root);
         findAndReplaceSimpleElement(innerCount, root, "status", value.getStatus(), null);
      }
   } // -- void updateDistributionManagement(DistributionManagement, String,
     // Counter, Element)

   /**
    * Method updateElement.
    *
    * @param counter
    * @param shouldExist
    * @param name
    * @param parent
    */
   protected Element updateElement(Counter counter, Element parent, String name, boolean shouldExist)
   {
      Element element = parent.getChild(name, parent.getNamespace());
      if ((element != null) && shouldExist)
      {
         counter.increaseCount();
      }
      if ((element == null) && shouldExist)
      {
         element = factory.element(name, parent.getNamespace());
         insertAtPreferredLocation(parent, element, counter);
         counter.increaseCount();
      }
      if (!shouldExist && (element != null))
      {
         int index = parent.indexOf(element);
         if (index > 0)
         {
            Content previous = parent.getContent(index - 1);
            if (previous instanceof Text)
            {
               Text txt = (Text) previous;
               if (txt.getTextTrim().length() == 0)
               {
                  parent.removeContent(txt);
               }
            }
         }
         parent.removeContent(element);
      }
      return element;
   } // -- Element updateElement(Counter, Element, String, boolean)

   /**
    * Method updateExclusion.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateExclusion(Exclusion value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
      findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
   } // -- void updateExclusion(Exclusion, String, Counter, Element)

   /**
    * Method updateExtension.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateExtension(Extension value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
      findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
      findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
   } // -- void updateExtension(Extension, String, Counter, Element)

   /**
    * Method updateFileSet.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateFileSet(FileSet value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
         findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include");
         findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude");
      }
   } // -- void updateFileSet(FileSet, String, Counter, Element)

   /**
    * Method updateIssueManagement.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateIssueManagement(IssueManagement value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "system", value.getSystem(), null);
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      }
   } // -- void updateIssueManagement(IssueManagement, String, Counter,
     // Element)

   /**
    * Method updateLicense.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateLicense(License value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
      findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      findAndReplaceSimpleElement(innerCount, root, "distribution", value.getDistribution(), null);
      findAndReplaceSimpleElement(innerCount, root, "comments", value.getComments(), null);
   } // -- void updateLicense(License, String, Counter, Element)

   /**
    * Method updateMailingList.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateMailingList(MailingList value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
      findAndReplaceSimpleElement(innerCount, root, "subscribe", value.getSubscribe(), null);
      findAndReplaceSimpleElement(innerCount, root, "unsubscribe", value.getUnsubscribe(), null);
      findAndReplaceSimpleElement(innerCount, root, "post", value.getPost(), null);
      findAndReplaceSimpleElement(innerCount, root, "archive", value.getArchive(), null);
      findAndReplaceSimpleLists(innerCount, root, value.getOtherArchives(), "otherArchives", "otherArchive");
   } // -- void updateMailingList(MailingList, String, Counter, Element)

   /**
    * Method updateModel.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateModel(Model value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      updateParent(value.getParent(), "parent", innerCount, root);
      findAndReplaceSimpleElement(innerCount, root, "modelVersion", value.getModelVersion(), null);
      findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
      findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
      findAndReplaceSimpleElement(innerCount, root, "packaging", value.getPackaging(), "jar");
      findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
      findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
      findAndReplaceSimpleElement(innerCount, root, "description", value.getDescription(), null);
      findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      updatePrerequisites(value.getPrerequisites(), "prerequisites", innerCount, root);
      updateIssueManagement(value.getIssueManagement(), "issueManagement", innerCount, root);
      updateCiManagement(value.getCiManagement(), "ciManagement", innerCount, root);
      findAndReplaceSimpleElement(innerCount, root, "inceptionYear", value.getInceptionYear(), null);
      iterateMailingList(innerCount, root, value.getMailingLists(), "mailingLists", "mailingList");
      iterateDeveloper(innerCount, root, value.getDevelopers(), "developers", "developer");
      iterateContributor(innerCount, root, value.getContributors(), "contributors", "contributor");
      iterateLicense(innerCount, root, value.getLicenses(), "licenses", "license");
      updateScm(value.getScm(), "scm", innerCount, root);
      updateOrganization(value.getOrganization(), "organization", innerCount, root);
      updateBuild(value.getBuild(), "build", innerCount, root);
      iterateProfile(innerCount, root, value.getProfiles(), "profiles", "profile");
      findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module");
      iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository");
      iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository");
      iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
      findAndReplaceXpp3DOM(innerCount, root, "reports", (Xpp3Dom) value.getReports());
      updateReporting(value.getReporting(), "reporting", innerCount, root);
      updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root);
      updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root);
      findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
   } // -- void updateModel(Model, String, Counter, Element)

   /**
    * Method updateModelBase.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateModelBase(ModelBase value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module");
         iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository");
         iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories",
                  "pluginRepository");
         iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
         findAndReplaceXpp3DOM(innerCount, root, "reports", (Xpp3Dom) value.getReports());
         updateReporting(value.getReporting(), "reporting", innerCount, root);
         updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root);
         updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root);
         findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
      }
   } // -- void updateModelBase(ModelBase, String, Counter, Element)

   /**
    * Method updateNotifier.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateNotifier(Notifier value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "type", value.getType(), "mail");
      findAndReplaceSimpleElement(innerCount, root, "sendOnError",
               (value.isSendOnError() == true) ? null : String.valueOf(value.isSendOnError()), "true");
      findAndReplaceSimpleElement(innerCount, root, "sendOnFailure",
               (value.isSendOnFailure() == true) ? null : String.valueOf(value.isSendOnFailure()), "true");
      findAndReplaceSimpleElement(innerCount, root, "sendOnSuccess",
               (value.isSendOnSuccess() == true) ? null : String.valueOf(value.isSendOnSuccess()), "true");
      findAndReplaceSimpleElement(innerCount, root, "sendOnWarning",
               (value.isSendOnWarning() == true) ? null : String.valueOf(value.isSendOnWarning()), "true");
      findAndReplaceSimpleElement(innerCount, root, "address", value.getAddress(), null);
      findAndReplaceProperties(innerCount, root, "configuration", value.getConfiguration());
   } // -- void updateNotifier(Notifier, String, Counter, Element)

   /**
    * Method updateOrganization.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateOrganization(Organization value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      }
   } // -- void updateOrganization(Organization, String, Counter, Element)

   /**
    * Method updateParent.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateParent(Parent value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
         findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
         findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
         findAndReplaceSimpleElement(innerCount, root, "relativePath", value.getRelativePath(), "../pom.xml");
      }
   } // -- void updateParent(Parent, String, Counter, Element)

   /**
    * Method updatePatternSet.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePatternSet(PatternSet value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include");
         findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude");
      }
   } // -- void updatePatternSet(PatternSet, String, Counter, Element)

   /**
    * Method updatePlugin.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePlugin(Plugin value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), "org.apache.maven.plugins");
      findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
      findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
      findAndReplaceSimpleElement(innerCount, root, "extensions",
               (value.isExtensions() == false) ? null : String.valueOf(value.isExtensions()), "false");
      iteratePluginExecution(innerCount, root, value.getExecutions(), "executions", "execution");
      iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
      findAndReplaceXpp3DOM(innerCount, root, "goals", (Xpp3Dom) value.getGoals());
      findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
      findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
   } // -- void updatePlugin(Plugin, String, Counter, Element)

   /**
    * Method updatePluginConfiguration.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePluginConfiguration(PluginConfiguration value, String xmlTag, Counter counter,
            Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         updatePluginManagement(value.getPluginManagement(), "pluginManagement", innerCount, root);
         iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
      }
   } // -- void updatePluginConfiguration(PluginConfiguration, String, Counter,
     // Element)

   /**
    * Method updatePluginContainer.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePluginContainer(PluginContainer value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
      }
   } // -- void updatePluginContainer(PluginContainer, String, Counter,
     // Element)

   /**
    * Method updatePluginExecution.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePluginExecution(PluginExecution value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default");
      findAndReplaceSimpleElement(innerCount, root, "phase", value.getPhase(), null);
      findAndReplaceSimpleLists(innerCount, root, value.getGoals(), "goals", "goal");
      findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
      findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
   } // -- void updatePluginExecution(PluginExecution, String, Counter,
     // Element)

   /**
    * Method updatePluginManagement.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePluginManagement(PluginManagement value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         iteratePlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
      }
   } // -- void updatePluginManagement(PluginManagement, String, Counter,
     // Element)

   /**
    * Method updatePrerequisites.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updatePrerequisites(Prerequisites value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "maven", value.getMaven(), "2.0");
      }
   } // -- void updatePrerequisites(Prerequisites, String, Counter, Element)

   /**
    * Method updateProfile.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateProfile(Profile value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
      updateActivation(value.getActivation(), "activation", innerCount, root);
      updateBuildBase(value.getBuild(), "build", innerCount, root);
      findAndReplaceSimpleLists(innerCount, root, value.getModules(), "modules", "module");
      iterateRepository(innerCount, root, value.getRepositories(), "repositories", "repository");
      iterateRepository(innerCount, root, value.getPluginRepositories(), "pluginRepositories", "pluginRepository");
      iterateDependency(innerCount, root, value.getDependencies(), "dependencies", "dependency");
      findAndReplaceXpp3DOM(innerCount, root, "reports", (Xpp3Dom) value.getReports());
      updateReporting(value.getReporting(), "reporting", innerCount, root);
      updateDependencyManagement(value.getDependencyManagement(), "dependencyManagement", innerCount, root);
      updateDistributionManagement(value.getDistributionManagement(), "distributionManagement", innerCount, root);
      findAndReplaceProperties(innerCount, root, "properties", value.getProperties());
   } // -- void updateProfile(Profile, String, Counter, Element)

   /**
    * Method updateRelocation.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateRelocation(Relocation value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), null);
         findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
         findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
         findAndReplaceSimpleElement(innerCount, root, "message", value.getMessage(), null);
      }
   } // -- void updateRelocation(Relocation, String, Counter, Element)

   /**
    * Method updateReporting.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateReporting(Reporting value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "excludeDefaults",
                  (value.isExcludeDefaults() == false) ? null : String.valueOf(value.isExcludeDefaults()), "false");
         findAndReplaceSimpleElement(innerCount, root, "outputDirectory", value.getOutputDirectory(), null);
         iterateReportPlugin(innerCount, root, value.getPlugins(), "plugins", "plugin");
      }
   } // -- void updateReporting(Reporting, String, Counter, Element)

   /**
    * Method updateReportPlugin.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateReportPlugin(ReportPlugin value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "groupId", value.getGroupId(), "org.apache.maven.plugins");
      findAndReplaceSimpleElement(innerCount, root, "artifactId", value.getArtifactId(), null);
      findAndReplaceSimpleElement(innerCount, root, "version", value.getVersion(), null);
      findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
      findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
      iterateReportSet(innerCount, root, value.getReportSets(), "reportSets", "reportSet");
   } // -- void updateReportPlugin(ReportPlugin, String, Counter, Element)

   /**
    * Method updateReportSet.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateReportSet(ReportSet value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), "default");
      findAndReplaceXpp3DOM(innerCount, root, "configuration", (Xpp3Dom) value.getConfiguration());
      findAndReplaceSimpleElement(innerCount, root, "inherited", value.getInherited(), null);
      findAndReplaceSimpleLists(innerCount, root, value.getReports(), "reports", "report");
   } // -- void updateReportSet(ReportSet, String, Counter, Element)

   /**
    * Method updateRepository.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateRepository(Repository value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      updateRepositoryPolicy(value.getReleases(), "releases", innerCount, root);
      updateRepositoryPolicy(value.getSnapshots(), "snapshots", innerCount, root);
      findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
      findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
      findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default");
   } // -- void updateRepository(Repository, String, Counter, Element)

   /**
    * Method updateRepositoryBase.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateRepositoryBase(RepositoryBase value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
         findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
         findAndReplaceSimpleElement(innerCount, root, "layout", value.getLayout(), "default");
      }
   } // -- void updateRepositoryBase(RepositoryBase, String, Counter, Element)

   /**
    * Method updateRepositoryPolicy.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateRepositoryPolicy(RepositoryPolicy value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "enabled",
                  (value.isEnabled() == true) ? null : String.valueOf(value.isEnabled()), "true");
         findAndReplaceSimpleElement(innerCount, root, "updatePolicy", value.getUpdatePolicy(), null);
         findAndReplaceSimpleElement(innerCount, root, "checksumPolicy", value.getChecksumPolicy(), null);
      }
   } // -- void updateRepositoryPolicy(RepositoryPolicy, String, Counter,
     // Element)

   /**
    * Method updateResource.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateResource(Resource value, String xmlTag, Counter counter, Element element)
   {
      Element root = element;
      Counter innerCount = new Counter(counter.getDepth() + 1);
      findAndReplaceSimpleElement(innerCount, root, "targetPath", value.getTargetPath(), null);
      findAndReplaceSimpleElement(innerCount, root, "filtering",
               (value.isFiltering() == false) ? null : String.valueOf(value.isFiltering()), "false");
      findAndReplaceSimpleElement(innerCount, root, "directory", value.getDirectory(), null);
      findAndReplaceSimpleLists(innerCount, root, value.getIncludes(), "includes", "include");
      findAndReplaceSimpleLists(innerCount, root, value.getExcludes(), "excludes", "exclude");
   } // -- void updateResource(Resource, String, Counter, Element)

   /**
    * Method updateScm.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateScm(Scm value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "connection", value.getConnection(), null);
         findAndReplaceSimpleElement(innerCount, root, "developerConnection", value.getDeveloperConnection(), null);
         findAndReplaceSimpleElement(innerCount, root, "tag", value.getTag(), "HEAD");
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      }
   } // -- void updateScm(Scm, String, Counter, Element)

   /**
    * Method updateSite.
    *
    * @param value
    * @param element
    * @param counter
    * @param xmlTag
    */
   protected void updateSite(Site value, String xmlTag, Counter counter, Element element)
   {
      boolean shouldExist = value != null;
      Element root = updateElement(counter, element, xmlTag, shouldExist);
      if (shouldExist)
      {
         Counter innerCount = new Counter(counter.getDepth() + 1);
         findAndReplaceSimpleElement(innerCount, root, "id", value.getId(), null);
         findAndReplaceSimpleElement(innerCount, root, "name", value.getName(), null);
         findAndReplaceSimpleElement(innerCount, root, "url", value.getUrl(), null);
      }
   } // -- void updateSite(Site, String, Counter, Element)

   // -----------------/
   // - Inner Classes -/
   // -----------------/

   /**
    * Class Counter.
    *
    * @version $Revision$ $Date$
    */
   public class Counter
   {
      // --------------------------/
      // - Class/Member Variables -/
      // --------------------------/

      /**
       * Field currentIndex.
       */
      private int currentIndex = 0;

      /**
       * Field level.
       */
      private int level;

      // ----------------/
      // - Constructors -/
      // ----------------/

      public Counter(int depthLevel)
      {
         level = depthLevel;
      } // -- org.apache.maven.model.io.jdom.Counter(int)

      // -----------/
      // - Methods -/
      // -----------/

      /**
       * Method getCurrentIndex.
       */
      public int getCurrentIndex()
      {
         return currentIndex;
      } // -- int getCurrentIndex()

      /**
       * Method getDepth.
       */
      public int getDepth()
      {
         return level;
      } // -- int getDepth()

      /**
       * Method increaseCount.
       */
      public void increaseCount()
      {
         currentIndex = currentIndex + 1;
      } // -- void increaseCount()
   }
}