Index: api/src/main/java/org/jboss/shrinkwrap/api/descriptor/WebArchiveDescriptor.java
===================================================================
--- api/src/main/java/org/jboss/shrinkwrap/api/descriptor/WebArchiveDescriptor.java	(revision 0)
+++ api/src/main/java/org/jboss/shrinkwrap/api/descriptor/WebArchiveDescriptor.java	(revision 0)
@@ -0,0 +1,30 @@
+package org.jboss.shrinkwrap.api.descriptor;
+
+import java.util.Map;
+
+import org.jboss.shrinkwrap.api.Specializer;
+
+public interface WebArchiveDescriptor extends Specializer
+{
+
+   WebArchiveDescriptor setDisplayName(String displayName);
+
+   WebArchiveDescriptor addContextParameter(String name, String value);
+
+   WebArchiveDescriptor addListener(Class<?> clazz);
+
+   //Mapper addServlet(Class<?> clazz);
+   WebArchiveDescriptor addServlet(Class<?> clazz, String... mappings);
+
+   WebArchiveDescriptor addServlet(Class<?> clazz, Map<String, String> parameters, String... mappings);
+
+   WebArchiveDescriptor addFilter(Class<?> clazz, String... mappings);
+
+   WebArchiveDescriptor addFilter(Class<?> clazz, Map<String, String> parameters, String... mappings);
+
+   public interface Mapper {
+      
+      WebArchiveDescriptor mapTo(String... mappings);
+      
+   }
+}
\ No newline at end of file
Index: impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorImplTest.java
===================================================================
--- impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorImplTest.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorImplTest.java	(revision 0)
@@ -0,0 +1,39 @@
+package org.jboss.shrinkwrap.impl.base.descriptor;
+
+import java.io.FileOutputStream;
+import java.io.InputStream;
+
+import org.jboss.shrinkwrap.api.Archives;
+import org.jboss.shrinkwrap.api.descriptor.WebArchiveDescriptor;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.impl.base.io.IOUtil;
+import org.junit.Test;
+
+import com.acme.example.AcmeDomain;
+import com.acme.example.AcmeServlet;
+import com.acme.example.AuthFilter;
+import com.acme.example.ContextListener;
+
+public class WebArchiveDescriptorImplTest
+{
+
+   @Test
+   public void shouldBeAbleToExport() throws Exception {
+      
+      WebArchive archive = Archives.create("acme-product.war", WebArchiveDescriptor.class)
+                .setDisplayName("Acme Product Web")
+                .addContextParameter("product", "Acme Product")
+                .addServlet(AcmeServlet.class, "/*")
+                .addListener(ContextListener.class)
+                .addFilter(AuthFilter.class, "/admin/*")
+             .as(WebArchive.class)
+                .addClass(AcmeDomain.class)
+                .addLibrary("some-lib.jar");
+      
+      System.out.println(archive.toString(true));
+      
+      InputStream stream = archive.as(ZipExporter.class).exportZip();
+      IOUtil.copyWithClose(stream, new FileOutputStream("test.jar"));
+   }
+}
Index: impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorAssetTestCase.java
===================================================================
--- impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorAssetTestCase.java	(revision 0)
+++ impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorAssetTestCase.java	(revision 0)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.impl.base.descriptor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.shrinkwrap.impl.base.io.IOUtil;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * WebXMLTestCase
+ *
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ * @version $Revision: $
+ */
+public class WebArchiveDescriptorAssetTestCase
+{
+
+   @Test
+   @Ignore
+   public void shouldBeAbleToAddServletsWithMappings() throws Exception {
+      Map<String, String> initParameter = new HashMap<String, String>();
+      initParameter.put("param1", "value1");
+      
+      WebArchiveDescriptorAsset xml = new WebArchiveDescriptorAsset()
+         .setDisplayName("test-war")     
+         
+         .addContextParameter("param1", "value1")
+         .addContextParameter("param2", "value2")
+         
+         .addListener(this.getClass())
+         .addListener(IOUtil.class)
+         
+         .addServlet(this.getClass(), initParameter, "*.test", "*.test2")
+         .addServlet(IOUtil.class, "*.util", "*.io")
+         
+         .addFilter(this.getClass(), initParameter,  "*.test", "*.test2")
+         .addFilter(IOUtil.class, "*.util", "*.io");
+      
+      IOUtil.copy(xml.openStream(), System.out);
+   }
+}
Index: impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorAsset.java
===================================================================
--- impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorAsset.java	(revision 0)
+++ impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/descriptor/WebArchiveDescriptorAsset.java	(revision 0)
@@ -0,0 +1,396 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.impl.base.descriptor;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.Asset;
+import org.jboss.shrinkwrap.api.Path;
+import org.jboss.shrinkwrap.api.descriptor.WebArchiveDescriptor;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.impl.base.SpecializedBase;
+import org.jboss.shrinkwrap.impl.base.path.BasicPath;
+
+/**
+ * WebXML
+ *
+ * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
+ * @version $Revision: $
+ */
+@XmlRootElement(name = "web-app")
+public class WebArchiveDescriptorAsset extends SpecializedBase implements Asset, WebArchiveDescriptor
+{
+   /**
+    * Path to the web inside of the Archive.
+    */
+   private static final Path PATH_WEB = new BasicPath("WEB-INF");
+
+   /**
+    * Path to the classes inside of the Archive.
+    */
+   private static final Path PATH_CLASSES = new BasicPath(PATH_WEB, "classes");
+
+   
+   @XmlAttribute
+   private String version = "2.4";
+   
+   @XmlElement(name = "display-name")
+   private String displayName;
+   
+   @XmlElement(name = "context-param")
+   private List<Parameter> contextParameters = new ArrayList<Parameter>();
+   
+   @XmlElement(name = "listener")
+   private List<Listener> listeners = new ArrayList<Listener>();
+   
+   @XmlElement(name="servlet")
+   private List<Servlet> servlets = new ArrayList<Servlet>();
+   
+   @XmlElement(name="servlet-mapping")
+   private List<ServletMapping> servletMappings = new ArrayList<ServletMapping>();
+
+   @XmlElement(name = "filter")
+   private List<Filter> filters = new ArrayList<Filter>();
+   
+   @XmlElement(name = "filter-mapping")
+   private List<FilterMapping> filterMappings = new ArrayList<FilterMapping>();
+
+   private WebArchive archive;
+   
+   public WebArchiveDescriptorAsset() {
+      
+   }
+   
+   public WebArchiveDescriptorAsset(WebArchive archive)
+   {
+      this.archive = archive;
+      this.archive.add(this, new BasicPath(PATH_WEB, "web.xml"));
+   }
+
+   @Override
+   protected Archive<?> getArchive()
+   {
+      return archive;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#setDisplayName(java.lang.String)
+    */
+   public WebArchiveDescriptorAsset setDisplayName(String displayName)
+   {
+      this.displayName = displayName;
+      return this;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#addContextParameter(java.lang.String, java.lang.String)
+    */
+   public WebArchiveDescriptorAsset addContextParameter(String name, String value) 
+   {
+      contextParameters.add(new Parameter(name, value));
+      return this;
+   }
+   
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#addListener(java.lang.Class)
+    */
+   public WebArchiveDescriptorAsset addListener(Class<?> clazz) 
+   {
+      archive.addClass(clazz);
+      listeners.add(new Listener(clazz.getName()));
+      return this;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#addServlet(java.lang.Class, java.lang.String)
+    */
+   public WebArchiveDescriptorAsset addServlet(Class<?> clazz, String... mappings) 
+   {
+      addServlet(clazz, null, mappings);
+      return this;
+   }
+   
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#addServlet(java.lang.Class, java.util.Map, java.lang.String)
+    */
+   public WebArchiveDescriptorAsset addServlet(Class<?> clazz, Map<String, String> parameters, String... mappings) 
+   {
+      archive.addClass(clazz);
+      String name = clazz.getSimpleName();
+      
+      Servlet servlet = new Servlet(name, clazz.getName());
+      if(parameters != null) {
+         for(Map.Entry<String, String> entry : parameters.entrySet()) {
+            servlet.addInitParameter(entry.getKey(), entry.getValue());
+         }
+      }
+      servlets.add(servlet);
+      for(String mapping : mappings) {
+         servletMappings.add(new ServletMapping(name, mapping));
+      }
+      return this;
+   }
+
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#addFilter(java.lang.Class, java.lang.String)
+    */
+   public WebArchiveDescriptorAsset addFilter(Class<?> clazz, String... mappings) 
+   {
+      return addFilter(clazz, null, mappings);
+   }
+   
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#addFilter(java.lang.Class, java.util.Map, java.lang.String)
+    */
+   public WebArchiveDescriptorAsset addFilter(Class<?> clazz, Map<String, String> parameters, String... mappings) 
+   {
+      archive.addClass(clazz);
+      String name = clazz.getSimpleName();
+    
+      Filter filter = new Filter(name, clazz.getName());
+      if(parameters != null) {
+         for(Map.Entry<String, String> entry : parameters.entrySet()) {
+            filter.addInitParameter(entry.getKey(), entry.getValue());
+         }
+      }
+      filters.add(filter);
+      for(String mapping : mappings) {
+         filterMappings.add(new FilterMapping(name, mapping));
+      }
+      return this;
+   }
+   
+   /* (non-Javadoc)
+    * @see org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptor#getStream()
+    */
+   @Override
+   public InputStream openStream()
+   {
+      try 
+      {
+         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+         JAXBContext context = JAXBContext.newInstance(WebArchiveDescriptorAsset.class);
+         
+         Marshaller marshaller = context.createMarshaller();
+         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+         marshaller.marshal(this, outputStream);
+         return new ByteArrayInputStream(outputStream.toByteArray());
+         
+      } 
+      catch (Exception e) {
+         throw new RuntimeException("Could not convert Object to XML", e);
+      }
+   }
+
+   private class ServletMapper implements Mapper {
+      
+      private String name;
+      
+      public ServletMapper(String name)
+      {
+         this.name = name;
+      }
+      
+      @Override
+      public WebArchiveDescriptorAsset mapTo(String... mappings)
+      {
+         for(String mapping : mappings) {
+            servletMappings.add(new ServletMapping(name, mapping));
+         }
+         return WebArchiveDescriptorAsset.this;
+      }
+   }
+   
+   private static class Servlet
+   {
+      @XmlElement(name = "servlet-name")
+      private String name;
+
+      @XmlElement(name = "servlet-class")
+      private String servletClass;
+
+      @XmlElement(name = "init-param")
+      private List<Parameter> initParameter = new ArrayList<Parameter>();
+
+      protected Servlet() {}
+      
+      public Servlet(String name, String servletClass) 
+      {
+         this.name = name;
+         this.servletClass = servletClass;
+      }
+      
+      public String getName()
+      {
+         return name;
+      }
+
+      public String getServletClass()
+      {
+         return servletClass;
+      }
+
+      public void addInitParameter(String name, String value) 
+      {
+         initParameter.add(new Parameter(name, value));
+      }
+   }
+   
+   private static class ServletMapping 
+   {
+      @XmlElement(name = "servlet-name")
+      private String name;
+      
+      @XmlElement(name = "url-pattern")
+      private String mapping;
+
+      public ServletMapping() {}
+      
+      public ServletMapping(String name, String mapping)
+      {
+         this.name = name;
+         this.mapping = mapping;
+      }
+
+      public String getName()
+      {
+         return name;
+      }
+      public String getMapping()
+      {
+         return mapping;
+      }
+   }
+   
+   private static class Listener 
+   {
+      @XmlElement(name = "listener-class")
+      private String listenerClass;
+      
+      protected Listener() {}
+
+      public Listener(String listenerClass)
+      {
+         this.listenerClass = listenerClass;
+      }
+      
+      public String getListenerClass()
+      {
+         return listenerClass;
+      }
+   }
+   
+   private static class Parameter 
+   {
+      @XmlElement(name = "param-name")
+      private String name;
+      
+      @XmlElement(name = "param-value")
+      private String value;
+      
+      protected Parameter() {}
+
+      public Parameter(String name, String value)
+      {
+         this.name = name;
+         this.value = value;
+      }
+      
+      public String getName()
+      {
+         return name;
+      }
+      
+      public String getValue()
+      {
+         return value;
+      }
+   }
+
+   private static class Filter
+   {
+      @XmlElement(name = "filter-name")
+      private String name;
+
+      @XmlElement(name = "filter-class")
+      private String filterClass;
+      
+      @XmlElement(name = "init-param")
+      private List<Parameter> initParameter = new ArrayList<Parameter>();
+
+      protected Filter() {}
+      
+      public Filter(String name, String filerClass) 
+      {
+         this.name = name;
+         this.filterClass = filerClass;
+      }
+      
+      public String getName()
+      {
+         return name;
+      }
+
+      public String getFilterClass()
+      {
+         return filterClass;
+      }
+      
+      public void addInitParameter(String name, String value) 
+      {
+         initParameter.add(new Parameter(name, value));
+      }
+   }
+   
+   private static class FilterMapping 
+   {
+      @XmlElement(name = "filter-name")
+      private String name;
+      
+      @XmlElement(name = "url-pattern")
+      private String mapping;
+
+      public FilterMapping() {}
+      
+      public FilterMapping(String name, String mapping)
+      {
+         this.name = name;
+         this.mapping = mapping;
+      }
+
+      public String getName()
+      {
+         return name;
+      }
+      public String getMapping()
+      {
+         return mapping;
+      }
+   }
+}
Index: impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.api.descriptor.WebArchiveDescriptor
===================================================================
--- impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.api.descriptor.WebArchiveDescriptor	(revision 0)
+++ impl-base/src/main/resources/META-INF/services/org.jboss.shrinkwrap.api.descriptor.WebArchiveDescriptor	(revision 0)
@@ -0,0 +1 @@
+org.jboss.shrinkwrap.impl.base.descriptor.WebArchiveDescriptorAsset
\ No newline at end of file
