### Eclipse Workspace Patch 1.0
#P rome
Index: src/java/com/sun/syndication/io/impl/RSS092Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS092Generator.java,v
retrieving revision 1.7
diff -u -r1.7 RSS092Generator.java
--- src/java/com/sun/syndication/io/impl/RSS092Generator.java	3 Aug 2005 14:13:11 -0000	1.7
+++ src/java/com/sun/syndication/io/impl/RSS092Generator.java	30 Sep 2009 06:30:45 -0000
@@ -23,138 +23,141 @@
 
 import java.util.List;
 
-
 /**
  * Feed Generator for RSS 0.92
  * <p/>
- *
+ * 
  * @author Elaine Chien
- *
+ * 
  */
 
 public class RSS092Generator extends RSS091UserlandGenerator {
 
-    public RSS092Generator() {
-        this("rss_0.92","0.92");
-    }
-
-    protected RSS092Generator(String type,String version) {
-        super(type,version);
-    }
-
-    protected void populateChannel(Channel channel,Element eChannel) {
-        super.populateChannel(channel,eChannel);
-
-        Cloud cloud = channel.getCloud();
-        if (cloud!=null) {
-            eChannel.addContent(generateCloud(cloud));
-        }
-    }
-
-    protected Element generateCloud(Cloud cloud) {
-        Element eCloud = new Element("cloud",getFeedNamespace());
-
-        if (cloud.getDomain() != null) {
-            eCloud.setAttribute(new Attribute("domain", cloud.getDomain()));
-        }
-
-        if (cloud.getPort() != 0) {
-            eCloud.setAttribute(new Attribute("port", String.valueOf(cloud.getPort())));
-        }
-
-        if (cloud.getPath() != null) {
-            eCloud.setAttribute(new Attribute("path", cloud.getPath()));
-        }
-
-        if (cloud.getRegisterProcedure() != null) {
-            eCloud.setAttribute(new Attribute("registerProcedure", cloud.getRegisterProcedure()));
-        }
-
-        if (cloud.getProtocol() != null) {
-            eCloud.setAttribute(new Attribute("protocol", cloud.getProtocol()));
-        }
-        return eCloud;
-    }
-
-    // Another one to thanks DW for
-    protected int getNumberOfEnclosures(List enclosures) {
-        return (enclosures.size()>0) ? 1 : 0;
-    }
-
-    protected void populateItem(Item item, Element eItem, int index) {
-        super.populateItem(item,eItem, index);
-
-        Source source =item.getSource();
-        if (source != null) {
-            eItem.addContent(generateSourceElement(source));
-        }
-
-        List enclosures = item.getEnclosures();
-        for(int i = 0; i < getNumberOfEnclosures(enclosures); i++) {
-            eItem.addContent(generateEnclosure((Enclosure)enclosures.get(i)));
-        }
-
-        List categories = item.getCategories();
-        for(int i = 0; i < categories.size(); i++) {
-            eItem.addContent(generateCategoryElement((Category)categories.get(i)));
-        }
-    }
-
-    protected Element generateSourceElement(Source source) {
-        Element sourceElement = new Element("source",getFeedNamespace());
-        if (source.getUrl() != null) {
-            sourceElement.setAttribute(new Attribute("url", source.getUrl()));
-        }
-        sourceElement.addContent(source.getValue());
-        return sourceElement;
-    }
-
-    protected Element generateEnclosure(Enclosure enclosure) {
-        Element enclosureElement = new Element("enclosure",getFeedNamespace());
-        if (enclosure.getUrl() != null) {
-            enclosureElement.setAttribute("url", enclosure.getUrl());
-        }
-        if (enclosure.getLength() != 0) {
-            enclosureElement.setAttribute("length", String.valueOf(enclosure.getLength()));
-        }
-        if (enclosure.getType() != null) {
-            enclosureElement.setAttribute("type", enclosure.getType());
-        }
-        return enclosureElement;
-    }
-
-    protected Element generateCategoryElement(Category category) {
-        Element categoryElement = new Element("category",getFeedNamespace());
-        if (category.getDomain() != null) {
-            categoryElement.setAttribute("domain", category.getDomain());
-        }
-        categoryElement.addContent(category.getValue());
-        return categoryElement;
-    }
-
-
-    protected void checkChannelConstraints(Element eChannel) throws FeedException {
-        checkNotNullAndLength(eChannel,"title", 0, -1);
-        checkNotNullAndLength(eChannel,"description", 0, -1);
-        checkNotNullAndLength(eChannel,"link", 0, -1);
-    }
-
-    protected void checkImageConstraints(Element eImage) throws FeedException {
-        checkNotNullAndLength(eImage,"title", 0, -1);
-        checkNotNullAndLength(eImage,"url", 0, -1);
-    }
-
-    protected void checkTextInputConstraints(Element eTextInput) throws FeedException {
-        checkNotNullAndLength(eTextInput,"title", 0, -1);
-        checkNotNullAndLength(eTextInput,"description", 0, -1);
-        checkNotNullAndLength(eTextInput,"name", 0, -1);
-        checkNotNullAndLength(eTextInput,"link", 0, -1);
-    }
+	public RSS092Generator() {
+		this("rss_0.92", "0.92");
+	}
+
+	protected RSS092Generator(String type, String version) {
+		super(type, version);
+	}
+
+	protected void populateChannel(Channel channel, Element eChannel) {
+		super.populateChannel(channel, eChannel);
+
+		Cloud cloud = channel.getCloud();
+		if (cloud != null) {
+			eChannel.addContent(generateCloud(cloud));
+		}
+	}
+
+	protected Element generateCloud(Cloud cloud) {
+		Element eCloud = new Element("cloud", getFeedNamespace());
+
+		if (cloud.getDomain() != null) {
+			eCloud.setAttribute(new Attribute("domain", cloud.getDomain()));
+		}
+
+		if (cloud.getPort() != 0) {
+			eCloud.setAttribute(new Attribute("port", String.valueOf(cloud
+					.getPort())));
+		}
+
+		if (cloud.getPath() != null) {
+			eCloud.setAttribute(new Attribute("path", cloud.getPath()));
+		}
+
+		if (cloud.getRegisterProcedure() != null) {
+			eCloud.setAttribute(new Attribute("registerProcedure", cloud
+					.getRegisterProcedure()));
+		}
+
+		if (cloud.getProtocol() != null) {
+			eCloud.setAttribute(new Attribute("protocol", cloud.getProtocol()));
+		}
+		return eCloud;
+	}
+
+	// Another one to thanks DW for
+	protected int getNumberOfEnclosures(List<Enclosure> enclosures) {
+		return (enclosures.size() > 0) ? 1 : 0;
+	}
+
+	protected void populateItem(Item item, Element eItem, int index) {
+		super.populateItem(item, eItem, index);
+
+		Source source = item.getSource();
+		if (source != null) {
+			eItem.addContent(generateSourceElement(source));
+		}
+
+		List<Enclosure> enclosures = item.getEnclosures();
+		for (int i = 0; i < getNumberOfEnclosures(enclosures); i++) {
+			eItem.addContent(generateEnclosure(enclosures.get(i)));
+		}
+
+		List<Category> categories = item.getCategories();
+		for (int i = 0; i < categories.size(); i++) {
+			eItem.addContent(generateCategoryElement(categories.get(i)));
+		}
+	}
+
+	protected Element generateSourceElement(Source source) {
+		Element sourceElement = new Element("source", getFeedNamespace());
+		if (source.getUrl() != null) {
+			sourceElement.setAttribute(new Attribute("url", source.getUrl()));
+		}
+		sourceElement.addContent(source.getValue());
+		return sourceElement;
+	}
+
+	protected Element generateEnclosure(Enclosure enclosure) {
+		Element enclosureElement = new Element("enclosure", getFeedNamespace());
+		if (enclosure.getUrl() != null) {
+			enclosureElement.setAttribute("url", enclosure.getUrl());
+		}
+		if (enclosure.getLength() != 0) {
+			enclosureElement.setAttribute("length", String.valueOf(enclosure
+					.getLength()));
+		}
+		if (enclosure.getType() != null) {
+			enclosureElement.setAttribute("type", enclosure.getType());
+		}
+		return enclosureElement;
+	}
+
+	protected Element generateCategoryElement(Category category) {
+		Element categoryElement = new Element("category", getFeedNamespace());
+		if (category.getDomain() != null) {
+			categoryElement.setAttribute("domain", category.getDomain());
+		}
+		categoryElement.addContent(category.getValue());
+		return categoryElement;
+	}
+
+	protected void checkChannelConstraints(Element eChannel)
+			throws FeedException {
+		checkNotNullAndLength(eChannel, "title", 0, -1);
+		checkNotNullAndLength(eChannel, "description", 0, -1);
+		checkNotNullAndLength(eChannel, "link", 0, -1);
+	}
+
+	protected void checkImageConstraints(Element eImage) throws FeedException {
+		checkNotNullAndLength(eImage, "title", 0, -1);
+		checkNotNullAndLength(eImage, "url", 0, -1);
+	}
+
+	protected void checkTextInputConstraints(Element eTextInput)
+			throws FeedException {
+		checkNotNullAndLength(eTextInput, "title", 0, -1);
+		checkNotNullAndLength(eTextInput, "description", 0, -1);
+		checkNotNullAndLength(eTextInput, "name", 0, -1);
+		checkNotNullAndLength(eTextInput, "link", 0, -1);
+	}
 
-    protected void checkItemsConstraints(Element parent) throws FeedException {
-    }
+	protected void checkItemsConstraints(Element parent) throws FeedException {
+	}
 
-    protected void checkItemConstraints(Element eItem) throws FeedException {
-    }
+	protected void checkItemConstraints(Element eItem) throws FeedException {
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/RSS091NetscapeGenerator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS091NetscapeGenerator.java,v
retrieving revision 1.1
diff -u -r1.1 RSS091NetscapeGenerator.java
--- src/java/com/sun/syndication/io/impl/RSS091NetscapeGenerator.java	24 Sep 2004 14:28:36 -0000	1.1
+++ src/java/com/sun/syndication/io/impl/RSS091NetscapeGenerator.java	30 Sep 2009 06:30:44 -0000
@@ -28,7 +28,6 @@
  *
  */
 public class RSS091NetscapeGenerator extends RSS091UserlandGenerator {
-    private String _version;
 
     public RSS091NetscapeGenerator() {
         this("rss_0.91N","0.91");
Index: src/java/com/sun/syndication/io/impl/RSS091UserlandParser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS091UserlandParser.java,v
retrieving revision 1.8
diff -u -r1.8 RSS091UserlandParser.java
--- src/java/com/sun/syndication/io/impl/RSS091UserlandParser.java	7 Jan 2009 22:50:11 -0000	1.8
+++ src/java/com/sun/syndication/io/impl/RSS091UserlandParser.java	30 Sep 2009 06:30:45 -0000
@@ -33,218 +33,230 @@
  */
 public class RSS091UserlandParser extends RSS090Parser {
 
-    public RSS091UserlandParser() {
-        this("rss_0.91U");
-    }
-
-    protected RSS091UserlandParser(String type) {
-        super(type, null);
-    }
-
-    public boolean isMyType(Document document) {
-        boolean ok;
-        Element rssRoot = document.getRootElement();
-        ok = rssRoot.getName().equals("rss");
-        if (ok) {
-            ok = false;
-            Attribute version = rssRoot.getAttribute("version");
-            if (version!=null) {
-                ok = version.getValue().equals(getRSSVersion());
-            }
-        }
-        return ok;
-    }
-
-    protected String getRSSVersion() {
-            return "0.91";
-    }
-
-    protected Namespace getRSSNamespace() {
-        return Namespace.getNamespace("");
-    }
-
-    /**
-     * To be overriden by RSS 0.91 Netscape and RSS 0.94
-     */
-    protected boolean isHourFormat24(Element rssRoot) {
-        return true;
-    }
-
-    /**
-     * Parses the root element of an RSS document into a Channel bean.
-     * <p/>
-     * It first invokes super.parseChannel and then parses and injects the following
-     * properties if present: language, pubDate, rating and copyright.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document to parse.
-     * @return the parsed Channel bean.
-     */
-    protected WireFeed parseChannel(Element rssRoot)  {
-        Channel channel = (Channel) super.parseChannel(rssRoot);
-
-        Element eChannel = rssRoot.getChild("channel",getRSSNamespace());
-
-        Element e = eChannel.getChild("language",getRSSNamespace());
-        if (e!=null) {
-            channel.setLanguage(e.getText());
-        }
-        e = eChannel.getChild("rating",getRSSNamespace());
-        if (e!=null) {
-            channel.setRating(e.getText());
-        }
-        e = eChannel.getChild("copyright",getRSSNamespace());
-        if (e!=null) {
-            channel.setCopyright(e.getText());
-        }
-        e = eChannel.getChild("pubDate",getRSSNamespace());
-        if (e!=null) {
-            channel.setPubDate(DateParser.parseDate(e.getText()));
-        }
-        e = eChannel.getChild("lastBuildDate",getRSSNamespace());
-        if (e!=null) {
-            channel.setLastBuildDate(DateParser.parseDate(e.getText()));
-        }
-        e = eChannel.getChild("docs",getRSSNamespace());
-        if (e!=null) {
-            channel.setDocs(e.getText());
-        }
-        e = eChannel.getChild("docs",getRSSNamespace());
-        if (e!=null) {
-            channel.setDocs(e.getText());
-        }
-        e = eChannel.getChild("managingEditor",getRSSNamespace());
-        if (e!=null) {
-            channel.setManagingEditor(e.getText());
-        }
-        e = eChannel.getChild("webMaster",getRSSNamespace());
-        if (e!=null) {
-            channel.setWebMaster(e.getText());
-        }
-        e = eChannel.getChild("skipHours");
-        if (e!=null) {
-            List skipHours = new ArrayList();
-            List eHours = e.getChildren("hour",getRSSNamespace());
-            for (int i=0;i<eHours.size();i++) {
-                Element eHour = (Element) eHours.get(i);
-                skipHours.add(new Integer(eHour.getText().trim()));
-            }
-            channel.setSkipHours(skipHours);
-        }
-
-        e = eChannel.getChild("skipDays");
-        if (e!=null) {
-            List skipDays = new ArrayList();
-            List eDays = e.getChildren("day",getRSSNamespace());
-            for (int i=0;i<eDays.size();i++) {
-                Element eDay = (Element) eDays.get(i);
-                skipDays.add(eDay.getText().trim());
-            }
-            channel.setSkipDays(skipDays);
-        }
-        return channel;
-    }
-
-    /**
-     * Parses the root element of an RSS document looking for  image information.
-     * <p/>
-     * It first invokes super.parseImage and then parses and injects the following
-     * properties if present: url, link, width, height and description.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document to parse for image information.
-     * @return the parsed RSSImage bean.
-     */
-    protected Image parseImage(Element rssRoot) {
-        Image image = super.parseImage(rssRoot);
-        if (image!=null) {
-            Element eImage = getImage(rssRoot);
-            Element e = eImage.getChild("width",getRSSNamespace());
-            if (e!=null) {
-            	Integer val = NumberParser.parseInt(e.getText());
-            	if (val != null) {
-            		image.setWidth(val.intValue());
-            	}                
-            }
-            e = eImage.getChild("height",getRSSNamespace());
-            if (e!=null) {
-            	Integer val = NumberParser.parseInt(e.getText());
-            	if (val != null) {
-            		image.setHeight(val.intValue());
-            	}
-            }
-            e = eImage.getChild("description",getRSSNamespace());
-            if (e!=null) {
-                image.setDescription(e.getText());
-            }
-        }
-        return image;
-    }
-
-
-    /**
-     * It looks for the 'item' elements under the 'channel' elemment.
-     */
-    protected List getItems(Element rssRoot) {
-        Element eChannel = rssRoot.getChild("channel",getRSSNamespace());
-        return (eChannel!=null) ? eChannel.getChildren("item",getRSSNamespace()) : Collections.EMPTY_LIST;
-    }
-
-    /**
-     * It looks for the 'image' elements under the 'channel' elemment.
-     */
-    protected Element getImage(Element rssRoot) {
-        Element eChannel = rssRoot.getChild("channel",getRSSNamespace());
-        return (eChannel!=null) ? eChannel.getChild("image",getRSSNamespace()) : null;
-    }
-
-    /**
-     * To be overriden by RSS 0.91 Netscape parser
-     */
-    protected String getTextInputLabel() {
-        return "textInput";
-    }
-
-    /**
-     * It looks for the 'textinput' elements under the 'channel' elemment.
-     */
-    protected Element getTextInput(Element rssRoot) {
-        String elementName = getTextInputLabel();
-        Element eChannel = rssRoot.getChild("channel",getRSSNamespace());
-        return (eChannel!=null) ? eChannel.getChild(elementName,getRSSNamespace()) : null;
-    }
-
-    /**
-     * Parses an item element of an RSS document looking for item information.
-     * <p/>
-     * It first invokes super.parseItem and then parses and injects the description property if present.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document in case it's needed for context.
-     * @param eItem the item element to parse.
-     * @return the parsed RSSItem bean.
-     */
-    protected Item parseItem(Element rssRoot, Element eItem) {
-        Item item = super.parseItem(rssRoot,eItem);
-        Element e = eItem.getChild("description", getRSSNamespace());
-        if (e!=null) {
-            item.setDescription(parseItemDescription(rssRoot,e));
-        }
-        Element ce = eItem.getChild("encoded", getContentNamespace());
-        if (ce != null) {
-            Content content = new Content();
-            content.setType(Content.HTML);
-            content.setValue(ce.getText());
-            item.setContent(content);
-        }
-        return item;
-    }
-
-    protected Description parseItemDescription(Element rssRoot,Element eDesc) {
-        Description desc = new Description();
-        desc.setType("text/plain");
-        desc.setValue(eDesc.getText());
-        return desc;
-    }
+	public RSS091UserlandParser() {
+		this("rss_0.91U");
+	}
+
+	protected RSS091UserlandParser(String type) {
+		super(type, null);
+	}
+
+	public boolean isMyType(Document document) {
+		boolean ok;
+		Element rssRoot = document.getRootElement();
+		ok = rssRoot.getName().equals("rss");
+		if (ok) {
+			ok = false;
+			Attribute version = rssRoot.getAttribute("version");
+			if (version != null) {
+				ok = version.getValue().equals(getRSSVersion());
+			}
+		}
+		return ok;
+	}
+
+	protected String getRSSVersion() {
+		return "0.91";
+	}
+
+	protected Namespace getRSSNamespace() {
+		return Namespace.getNamespace("");
+	}
+
+	/**
+	 * To be overriden by RSS 0.91 Netscape and RSS 0.94
+	 */
+	protected boolean isHourFormat24(Element rssRoot) {
+		return true;
+	}
+
+	/**
+	 * Parses the root element of an RSS document into a Channel bean.
+	 * <p/>
+	 * It first invokes super.parseChannel and then parses and injects the
+	 * following properties if present: language, pubDate, rating and copyright.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document to parse.
+	 * @return the parsed Channel bean.
+	 */
+	@SuppressWarnings("unchecked")
+	protected WireFeed parseChannel(Element rssRoot) {
+		Channel channel = (Channel) super.parseChannel(rssRoot);
+
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+
+		Element e = eChannel.getChild("language", getRSSNamespace());
+		if (e != null) {
+			channel.setLanguage(e.getText());
+		}
+		e = eChannel.getChild("rating", getRSSNamespace());
+		if (e != null) {
+			channel.setRating(e.getText());
+		}
+		e = eChannel.getChild("copyright", getRSSNamespace());
+		if (e != null) {
+			channel.setCopyright(e.getText());
+		}
+		e = eChannel.getChild("pubDate", getRSSNamespace());
+		if (e != null) {
+			channel.setPubDate(DateParser.parseDate(e.getText()));
+		}
+		e = eChannel.getChild("lastBuildDate", getRSSNamespace());
+		if (e != null) {
+			channel.setLastBuildDate(DateParser.parseDate(e.getText()));
+		}
+		e = eChannel.getChild("docs", getRSSNamespace());
+		if (e != null) {
+			channel.setDocs(e.getText());
+		}
+		e = eChannel.getChild("docs", getRSSNamespace());
+		if (e != null) {
+			channel.setDocs(e.getText());
+		}
+		e = eChannel.getChild("managingEditor", getRSSNamespace());
+		if (e != null) {
+			channel.setManagingEditor(e.getText());
+		}
+		e = eChannel.getChild("webMaster", getRSSNamespace());
+		if (e != null) {
+			channel.setWebMaster(e.getText());
+		}
+		e = eChannel.getChild("skipHours");
+		if (e != null) {
+			List<Integer> skipHours = new ArrayList<Integer>();
+			List<Element> eHours = e.getChildren("hour", getRSSNamespace());
+			for (int i = 0; i < eHours.size(); i++) {
+				Element eHour = eHours.get(i);
+				skipHours.add(new Integer(eHour.getText().trim()));
+			}
+			channel.setSkipHours(skipHours);
+		}
+
+		e = eChannel.getChild("skipDays");
+		if (e != null) {
+			List<String> skipDays = new ArrayList<String>();
+			List<Element> eDays = e.getChildren("day", getRSSNamespace());
+			for (int i = 0; i < eDays.size(); i++) {
+				Element eDay = eDays.get(i);
+				skipDays.add(eDay.getText().trim());
+			}
+			channel.setSkipDays(skipDays);
+		}
+		return channel;
+	}
+
+	/**
+	 * Parses the root element of an RSS document looking for image information.
+	 * <p/>
+	 * It first invokes super.parseImage and then parses and injects the
+	 * following properties if present: url, link, width, height and
+	 * description.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document to parse for image
+	 *            information.
+	 * @return the parsed RSSImage bean.
+	 */
+	protected Image parseImage(Element rssRoot) {
+		Image image = super.parseImage(rssRoot);
+		if (image != null) {
+			Element eImage = getImage(rssRoot);
+			Element e = eImage.getChild("width", getRSSNamespace());
+			if (e != null) {
+				Integer val = NumberParser.parseInt(e.getText());
+				if (val != null) {
+					image.setWidth(val.intValue());
+				}
+			}
+			e = eImage.getChild("height", getRSSNamespace());
+			if (e != null) {
+				Integer val = NumberParser.parseInt(e.getText());
+				if (val != null) {
+					image.setHeight(val.intValue());
+				}
+			}
+			e = eImage.getChild("description", getRSSNamespace());
+			if (e != null) {
+				image.setDescription(e.getText());
+			}
+		}
+		return image;
+	}
+
+	/**
+	 * It looks for the 'item' elements under the 'channel' elemment.
+	 */
+	@SuppressWarnings("unchecked")
+	protected List<Element> getItems(Element rssRoot) {
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+		return (eChannel != null) ? eChannel.getChildren("item",
+				getRSSNamespace()) : Collections.EMPTY_LIST;
+	}
+
+	/**
+	 * It looks for the 'image' elements under the 'channel' elemment.
+	 */
+	protected Element getImage(Element rssRoot) {
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+		return (eChannel != null) ? eChannel.getChild("image",
+				getRSSNamespace()) : null;
+	}
+
+	/**
+	 * To be overriden by RSS 0.91 Netscape parser
+	 */
+	protected String getTextInputLabel() {
+		return "textInput";
+	}
+
+	/**
+	 * It looks for the 'textinput' elements under the 'channel' elemment.
+	 */
+	protected Element getTextInput(Element rssRoot) {
+		String elementName = getTextInputLabel();
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+		return (eChannel != null) ? eChannel.getChild(elementName,
+				getRSSNamespace()) : null;
+	}
+
+	/**
+	 * Parses an item element of an RSS document looking for item information.
+	 * <p/>
+	 * It first invokes super.parseItem and then parses and injects the
+	 * description property if present.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document in case it's needed for
+	 *            context.
+	 * @param eItem
+	 *            the item element to parse.
+	 * @return the parsed RSSItem bean.
+	 */
+	protected Item parseItem(Element rssRoot, Element eItem) {
+		Item item = super.parseItem(rssRoot, eItem);
+		Element e = eItem.getChild("description", getRSSNamespace());
+		if (e != null) {
+			item.setDescription(parseItemDescription(rssRoot, e));
+		}
+		Element ce = eItem.getChild("encoded", getContentNamespace());
+		if (ce != null) {
+			Content content = new Content();
+			content.setType(Content.HTML);
+			content.setValue(ce.getText());
+			item.setContent(content);
+		}
+		return item;
+	}
+
+	protected Description parseItemDescription(Element rssRoot, Element eDesc) {
+		Description desc = new Description();
+		desc.setType("text/plain");
+		desc.setValue(eDesc.getText());
+		return desc;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/PluginManager.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/PluginManager.java,v
retrieving revision 1.12
diff -u -r1.12 PluginManager.java
--- src/java/com/sun/syndication/io/impl/PluginManager.java	1 Mar 2009 23:13:19 -0000	1.12
+++ src/java/com/sun/syndication/io/impl/PluginManager.java	30 Sep 2009 06:30:44 -0000
@@ -25,120 +25,140 @@
 
 /**
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
 public abstract class PluginManager {
-    private String[] _propertyValues;
-    private Map _pluginsMap;
-    private List _pluginsList;
-    private List _keys;
-    private WireFeedParser _parentParser;
-    private WireFeedGenerator _parentGenerator;
-
-    /**
-     * Creates a PluginManager
-     * <p>
-     * @param propertyKey property key defining the plugins classes
-     *
-     */
-    protected PluginManager(String propertyKey) {
-        this(propertyKey, null, null);
-    }
-
-    protected PluginManager(String propertyKey, WireFeedParser parentParser,
-                            WireFeedGenerator parentGenerator)
-    {
-        _parentParser = parentParser;
-        _parentGenerator = parentGenerator;
-        _propertyValues = PropertiesLoader.getPropertiesLoader().getTokenizedProperty(propertyKey,", ");
-        loadPlugins();
-        _pluginsMap = Collections.unmodifiableMap(_pluginsMap);
-        _pluginsList = Collections.unmodifiableList(_pluginsList);
-        _keys = Collections.unmodifiableList(new ArrayList(_pluginsMap.keySet()));
-    }
-
-    protected abstract String getKey(Object obj);
-
-    protected List getKeys() {
-        return _keys;
-    }
-
-    protected List getPlugins() {
-        return _pluginsList;
-    }
-
-    protected Map getPluginMap() {
-        return _pluginsMap;
-    }
-
-    protected Object getPlugin(String key) {
-        return _pluginsMap.get(key);
-    }
-
-    // PRIVATE - LOADER PART
-
-    private void loadPlugins() {
-        List finalPluginsList = new ArrayList();
-        _pluginsList = new ArrayList();
-        _pluginsMap = new HashMap();
-        String className = null;
-        try {
-            Class[] classes = getClasses();
-            for (int i=0;i<classes.length;i++) {
-                className = classes[i].getName();
-                Object plugin  = classes[i].newInstance();
-                if (plugin instanceof DelegatingModuleParser) {
-                    ((DelegatingModuleParser) plugin).setFeedParser(_parentParser);
-                }
-                if (plugin instanceof DelegatingModuleGenerator) {
-                    ((DelegatingModuleGenerator) plugin).setFeedGenerator(_parentGenerator);
-                }
-
-                _pluginsMap.put(getKey(plugin), plugin);
-                _pluginsList.add(plugin); // to preserve the order of definition in the rome.properties files
-            }
-            Iterator i = _pluginsMap.values().iterator();
-            while (i.hasNext()) {
-                finalPluginsList.add(i.next()); // to remove overridden plugin impls
-            }
-
-            i = _pluginsList.iterator();
-            while (i.hasNext()) {
-                Object plugin = i.next();
-                if (!finalPluginsList.contains(plugin)) {
-                    i.remove();
-                }
-            }
-        }
-        catch (Exception ex) {
-            throw new RuntimeException("could not instantiate plugin "+className,ex);
-        }catch (ExceptionInInitializerError er) {
-            throw new RuntimeException("could not instantiate plugin "+className,er);
-        }
-    }
-
-    /**
-     * Loads and returns the classes defined in the properties files. If the system property "rome.pluginmanager.useloadclass" is
-     * set to true then classLoader.loadClass will be used to load classes (instead of Class.forName). This is designed to improve
-     * OSGi compatibility. Further information can be found in https://rome.dev.java.net/issues/show_bug.cgi?id=118 
-     * <p>
-     * @return array containing the classes defined in the properties files.
-     * @throws java.lang.ClassNotFoundException thrown if one of the classes defined in the properties file cannot be loaded
-     *         and hard failure is ON.
-     *
-     */
-    private Class[] getClasses() throws ClassNotFoundException {
-        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        List classes = new ArrayList();
-        boolean useLoadClass = Boolean.valueOf(System.getProperty("rome.pluginmanager.useloadclass", "false")).booleanValue();
-        for (int i = 0; i <_propertyValues.length; i++) {
-        	Class mClass = (useLoadClass ?  classLoader.loadClass(_propertyValues[i]) : Class.forName(_propertyValues[i], true, classLoader));
-            classes.add(mClass);
-        }
-        Class[] array = new Class[classes.size()];
-        classes.toArray(array);
-        return array;
-    }
+
+	private String[] _propertyValues;
+
+	private Map<String, Object> _pluginsMap;
+
+	private List<Object> _pluginsList;
+
+	private List<String> _keys;
+
+	private WireFeedParser _parentParser;
+
+	private WireFeedGenerator _parentGenerator;
+
+	/**
+	 * Creates a PluginManager
+	 * <p>
+	 * 
+	 * @param propertyKey
+	 *            property key defining the plugins classes
+	 * 
+	 */
+	protected PluginManager(String propertyKey) {
+		this(propertyKey, null, null);
+	}
+
+	protected PluginManager(String propertyKey, WireFeedParser parentParser,
+			WireFeedGenerator parentGenerator) {
+		_parentParser = parentParser;
+		_parentGenerator = parentGenerator;
+		_propertyValues = PropertiesLoader.getPropertiesLoader()
+				.getTokenizedProperty(propertyKey, ", ");
+		loadPlugins();
+		_pluginsMap = Collections.unmodifiableMap(_pluginsMap);
+		_pluginsList = Collections.unmodifiableList(_pluginsList);
+		_keys = Collections
+				.unmodifiableList(new ArrayList<String>(_pluginsMap.keySet()));
+	}
+
+	protected abstract String getKey(Object obj);
+
+	protected List<String> getKeys() {
+		return _keys;
+	}
+
+	protected List<Object> getPlugins() {
+		return _pluginsList;
+	}
+
+	protected Map<String, Object> getPluginMap() {
+		return _pluginsMap;
+	}
+
+	protected Object getPlugin(String key) {
+		return _pluginsMap.get(key);
+	}
+
+	// PRIVATE - LOADER PART
+
+	private void loadPlugins() {
+		List<Object> finalPluginsList = new ArrayList<Object>();
+		_pluginsList = new ArrayList<Object>();
+		_pluginsMap = new HashMap<String, Object>();
+		String className = null;
+		try {
+			List<Class<?>> classes = getClasses();
+			for (Class<?> c : classes) {
+				className = c.getName();
+				Object plugin = c.newInstance();
+				if (plugin instanceof DelegatingModuleParser) {
+					((DelegatingModuleParser) plugin)
+							.setFeedParser(_parentParser);
+				}
+				if (plugin instanceof DelegatingModuleGenerator) {
+					((DelegatingModuleGenerator) plugin)
+							.setFeedGenerator(_parentGenerator);
+				}
+
+				_pluginsMap.put(getKey(plugin), plugin);
+				_pluginsList.add(plugin); // to preserve the order of definition
+				// in the rome.properties files
+			}
+			for (Object plugin : _pluginsMap.values()) {
+				finalPluginsList.add(plugin); // to remove overridden plugin
+				// impls
+			}
+			for (Iterator<Object> i = _pluginsList.iterator(); i.hasNext();) {
+				Object plugin = i.next();
+				if (finalPluginsList.contains(plugin) == false) {
+					i.remove();
+				}
+			}
+		} catch (Exception ex) {
+			throw new RuntimeException("could not instantiate plugin "
+					+ className, ex);
+		} catch (ExceptionInInitializerError er) {
+			throw new RuntimeException("could not instantiate plugin "
+					+ className, er);
+		}
+	}
+
+	/**
+	 * Loads and returns the classes defined in the properties files. If the
+	 * system property "rome.pluginmanager.useloadclass" is set to true then
+	 * classLoader.loadClass will be used to load classes (instead of
+	 * Class.forName). This is designed to improve OSGi compatibility. Further
+	 * information can be found in
+	 * https://rome.dev.java.net/issues/show_bug.cgi?id=118
+	 * <p>
+	 * 
+	 * @return array containing the classes defined in the properties files.
+	 * @throws java.lang.ClassNotFoundException
+	 *             thrown if one of the classes defined in the properties file
+	 *             cannot be loaded and hard failure is ON.
+	 * 
+	 */
+	private List<Class<?>> getClasses() throws ClassNotFoundException {
+		ClassLoader classLoader = Thread.currentThread()
+				.getContextClassLoader();
+		List<Class<?>> classes = new ArrayList<Class<?>>();
+		boolean useLoadClass = Boolean.valueOf(
+				System.getProperty("rome.pluginmanager.useloadclass", "false"))
+				.booleanValue();
+		for (int i = 0; i < _propertyValues.length; i++) {
+			Class<?> mClass = (useLoadClass ? classLoader
+					.loadClass(_propertyValues[i]) : Class.forName(
+					_propertyValues[i], true, classLoader));
+			classes.add(mClass);
+		}
+		return classes;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/RSS091UserlandGenerator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS091UserlandGenerator.java,v
retrieving revision 1.5
diff -u -r1.5 RSS091UserlandGenerator.java
--- src/java/com/sun/syndication/io/impl/RSS091UserlandGenerator.java	4 Dec 2006 19:48:20 -0000	1.5
+++ src/java/com/sun/syndication/io/impl/RSS091UserlandGenerator.java	30 Sep 2009 06:30:44 -0000
@@ -32,220 +32,236 @@
 /**
  * Feed Generator for RSS 0.91
  * <p/>
- *
+ * 
  * @author Elaine Chien
- *
+ * 
  */
 public class RSS091UserlandGenerator extends RSS090Generator {
-    private String _version;
+	private String _version;
 
-    public RSS091UserlandGenerator() {
-        this("rss_0.91U","0.91");
-    }
-
-    protected RSS091UserlandGenerator(String type,String version) {
-        super(type);
-        _version = version;
-    }
-
-    protected String getVersion() {
-        return _version;
-    }
-
-    protected Namespace getFeedNamespace() {
-        return Namespace.NO_NAMESPACE;
-    }
-
-    protected Document createDocument(Element root) {
-        return new Document(root);
-    }
-
-    protected Element createRootElement(Channel channel) {
-        Element root = new Element("rss",getFeedNamespace());
-        Attribute version = new Attribute("version", getVersion());
-        root.setAttribute(version);
-        root.addNamespaceDeclaration(getContentNamespace());
-        generateModuleNamespaceDefs(root);
-        return root;
-    }
-
-    protected void populateFeed(Channel channel,Element parent) throws FeedException  {
-        addChannel(channel,parent);
-    }
-
-    protected void addChannel(Channel channel,Element parent) throws FeedException {
-        super.addChannel(channel,parent);
-        Element eChannel = parent.getChild("channel",getFeedNamespace());
-
-        addImage(channel,eChannel);
-        addTextInput(channel,eChannel);
-        addItems(channel,eChannel);
-    }
-
-    protected void populateChannel(Channel channel,Element eChannel) {
-        super.populateChannel(channel,eChannel);
-        String language = channel.getLanguage();
-        if (language != null) {
-            eChannel.addContent(generateSimpleElement("language", language));
-        }
-
-        String rating = channel.getRating();
-        if (rating != null) {
-            eChannel.addContent(generateSimpleElement("rating", rating));
-        }
-
-        String copyright = channel.getCopyright();
-        if (copyright != null) {
-            eChannel.addContent(generateSimpleElement("copyright", copyright));
-        }
-
-        Date pubDate = channel.getPubDate();
-        if (pubDate != null) {
-            eChannel.addContent(generateSimpleElement("pubDate", DateParser.formatRFC822(pubDate)));
-        }
-
-        Date lastBuildDate = channel.getLastBuildDate();
-        if (lastBuildDate != null) {
-            eChannel.addContent(generateSimpleElement("lastBuildDate", DateParser.formatRFC822(lastBuildDate)));
-        }
-
-        String docs = channel.getDocs();
-        if (docs != null) {
-            eChannel.addContent(generateSimpleElement("docs", docs));
-        }
-
-        String managingEditor = channel.getManagingEditor();
-        if (managingEditor != null) {
-            eChannel.addContent(generateSimpleElement("managingEditor", managingEditor));
-        }
-
-        String webMaster = channel.getWebMaster();
-        if (webMaster != null) {
-            eChannel.addContent(generateSimpleElement("webMaster", webMaster));
-        }
-
-        List skipHours = channel.getSkipHours();
-        if (skipHours != null && skipHours.size()>0) {
-            eChannel.addContent(generateSkipHoursElement(skipHours));
-        }
-
-        List skipDays = channel.getSkipDays();
-        if (skipDays != null && skipDays.size()>0) {
-            eChannel.addContent(generateSkipDaysElement(skipDays));
-        }
-    }
-
-    protected Element generateSkipHoursElement(List hours) {
-        Element skipHoursElement = new Element("skipHours",getFeedNamespace());
-        for (int i = 0; i < hours.size(); i++) {
-            skipHoursElement.addContent(generateSimpleElement("hour", hours.get(i).toString()));
-        }
-        return skipHoursElement;
-    }
-
-    protected Element generateSkipDaysElement(List days) {
-        Element skipDaysElement = new Element("skipDays");
-        for (int i = 0; i < days.size(); i++) {
-            skipDaysElement.addContent(generateSimpleElement("day", days.get(i).toString()));
-        }
-        return skipDaysElement;
-    }
-
-    protected void populateImage(Image image,Element eImage) {
-        super.populateImage(image,eImage);
-
-        int width = image.getWidth();
-        if (width>-1) {
-            eImage.addContent(generateSimpleElement("width",String.valueOf(width)));
-        }
-        int height = image.getHeight();
-        if (height>-1) {
-            eImage.addContent(generateSimpleElement("height",String.valueOf(height)));
-        }
-
-        String description = image.getDescription();
-        if (description!=null) {
-            eImage.addContent(generateSimpleElement("description",description));
-        }
-    }
-
-    protected void populateItem(Item item, Element eItem, int index) {
-        super.populateItem(item,eItem, index);
-        Description description = item.getDescription();
-        if (description!=null) {
-            eItem.addContent(generateSimpleElement("description",description.getValue()));
-        }
-        if (item.getModule(getContentNamespace().getURI()) == null && item.getContent() != null) {
-            Element elem = new Element("encoded", getContentNamespace());
-            elem.addContent(item.getContent().getValue());
-            eItem.addContent(elem);
-        }
-    }
-
-    /**
-     * To be overriden by RSS 0.91 Netscape and RSS 0.94
-     */
-    protected boolean isHourFormat24() {
-        return true;
-    }
-
-    protected void checkChannelConstraints(Element eChannel) throws FeedException {
-        checkNotNullAndLength(eChannel,"title", 1, 100);
-        checkNotNullAndLength(eChannel,"description", 1, 500);
-        checkNotNullAndLength(eChannel,"link", 1, 500);
-        checkNotNullAndLength(eChannel,"language", 2, 5);
-
-        checkLength(eChannel,"rating", 20, 500);
-        checkLength(eChannel,"copyright", 1, 100);
-        checkLength(eChannel,"pubDate", 1, 100);
-        checkLength(eChannel,"lastBuildDate", 1, 100);
-        checkLength(eChannel,"docs", 1, 500);
-        checkLength(eChannel,"managingEditor", 1, 100);
-        checkLength(eChannel,"webMaster", 1, 100);
-
-        Element skipHours = eChannel.getChild("skipHours");
-        if (skipHours!=null) {
-            List hours = skipHours.getChildren();
-            for (int i=0;i<hours.size();i++) {
-                Element hour = (Element) hours.get(i);
-                int value = Integer.parseInt(hour.getText().trim());
-                if (isHourFormat24()) {
-                    if (value<1 || value>24) {
-                        throw new FeedException("Invalid hour value "+value+", it must be between 1 and 24");
-                    }
-                }
-                else {
-                    if (value<0 || value>23) {
-                        throw new FeedException("Invalid hour value "+value+", it must be between 0 and 23");
-                    }
-                }
-            }
-        }
-    }
-
-    protected void checkImageConstraints(Element eImage) throws FeedException {
-        checkNotNullAndLength(eImage,"title", 1, 100);
-        checkNotNullAndLength(eImage,"url", 1, 500);
-
-        checkLength(eImage,"link", 1, 500);
-        checkLength(eImage,"width", 1, 3);
-        checkLength(eImage,"width", 1, 3);
-        checkLength(eImage,"description", 1, 100);
-    }
-
-
-    protected void checkTextInputConstraints(Element eTextInput) throws FeedException {
-        checkNotNullAndLength(eTextInput,"title", 1, 100);
-        checkNotNullAndLength(eTextInput,"description", 1, 500);
-        checkNotNullAndLength(eTextInput,"name", 1, 20);
-        checkNotNullAndLength(eTextInput,"link", 1, 500);
-    }
-
-    protected void checkItemConstraints(Element eItem) throws FeedException {
-        checkNotNullAndLength(eItem,"title", 1, 100);
-        checkNotNullAndLength(eItem,"link", 1, 500);
+	public RSS091UserlandGenerator() {
+		this("rss_0.91U", "0.91");
+	}
+
+	protected RSS091UserlandGenerator(String type, String version) {
+		super(type);
+		_version = version;
+	}
+
+	protected String getVersion() {
+		return _version;
+	}
+
+	protected Namespace getFeedNamespace() {
+		return Namespace.NO_NAMESPACE;
+	}
+
+	protected Document createDocument(Element root) {
+		return new Document(root);
+	}
+
+	protected Element createRootElement(Channel channel) {
+		Element root = new Element("rss", getFeedNamespace());
+		Attribute version = new Attribute("version", getVersion());
+		root.setAttribute(version);
+		root.addNamespaceDeclaration(getContentNamespace());
+		generateModuleNamespaceDefs(root);
+		return root;
+	}
+
+	protected void populateFeed(Channel channel, Element parent)
+			throws FeedException {
+		addChannel(channel, parent);
+	}
+
+	protected void addChannel(Channel channel, Element parent)
+			throws FeedException {
+		super.addChannel(channel, parent);
+		Element eChannel = parent.getChild("channel", getFeedNamespace());
+
+		addImage(channel, eChannel);
+		addTextInput(channel, eChannel);
+		addItems(channel, eChannel);
+	}
+
+	protected void populateChannel(Channel channel, Element eChannel) {
+		super.populateChannel(channel, eChannel);
+		String language = channel.getLanguage();
+		if (language != null) {
+			eChannel.addContent(generateSimpleElement("language", language));
+		}
+
+		String rating = channel.getRating();
+		if (rating != null) {
+			eChannel.addContent(generateSimpleElement("rating", rating));
+		}
+
+		String copyright = channel.getCopyright();
+		if (copyright != null) {
+			eChannel.addContent(generateSimpleElement("copyright", copyright));
+		}
+
+		Date pubDate = channel.getPubDate();
+		if (pubDate != null) {
+			eChannel.addContent(generateSimpleElement("pubDate", DateParser
+					.formatRFC822(pubDate)));
+		}
+
+		Date lastBuildDate = channel.getLastBuildDate();
+		if (lastBuildDate != null) {
+			eChannel.addContent(generateSimpleElement("lastBuildDate",
+					DateParser.formatRFC822(lastBuildDate)));
+		}
+
+		String docs = channel.getDocs();
+		if (docs != null) {
+			eChannel.addContent(generateSimpleElement("docs", docs));
+		}
+
+		String managingEditor = channel.getManagingEditor();
+		if (managingEditor != null) {
+			eChannel.addContent(generateSimpleElement("managingEditor",
+					managingEditor));
+		}
+
+		String webMaster = channel.getWebMaster();
+		if (webMaster != null) {
+			eChannel.addContent(generateSimpleElement("webMaster", webMaster));
+		}
+
+		List<Integer> skipHours = channel.getSkipHours();
+		if (skipHours != null && skipHours.size() > 0) {
+			eChannel.addContent(generateSkipHoursElement(skipHours));
+		}
+
+		List<String> skipDays = channel.getSkipDays();
+		if (skipDays != null && skipDays.size() > 0) {
+			eChannel.addContent(generateSkipDaysElement(skipDays));
+		}
+	}
+
+	protected Element generateSkipHoursElement(List<Integer> hours) {
+		Element skipHoursElement = new Element("skipHours", getFeedNamespace());
+		for (int i = 0; i < hours.size(); i++) {
+			skipHoursElement.addContent(generateSimpleElement("hour", hours
+					.get(i).toString()));
+		}
+		return skipHoursElement;
+	}
+
+	protected Element generateSkipDaysElement(List<String> days) {
+		Element skipDaysElement = new Element("skipDays");
+		for (int i = 0; i < days.size(); i++) {
+			skipDaysElement.addContent(generateSimpleElement("day", days.get(i)
+					.toString()));
+		}
+		return skipDaysElement;
+	}
+
+	protected void populateImage(Image image, Element eImage) {
+		super.populateImage(image, eImage);
+
+		int width = image.getWidth();
+		if (width > -1) {
+			eImage.addContent(generateSimpleElement("width", String
+					.valueOf(width)));
+		}
+		int height = image.getHeight();
+		if (height > -1) {
+			eImage.addContent(generateSimpleElement("height", String
+					.valueOf(height)));
+		}
+
+		String description = image.getDescription();
+		if (description != null) {
+			eImage
+					.addContent(generateSimpleElement("description",
+							description));
+		}
+	}
+
+	protected void populateItem(Item item, Element eItem, int index) {
+		super.populateItem(item, eItem, index);
+		Description description = item.getDescription();
+		if (description != null) {
+			eItem.addContent(generateSimpleElement("description", description
+					.getValue()));
+		}
+		if (item.getModule(getContentNamespace().getURI()) == null
+				&& item.getContent() != null) {
+			Element elem = new Element("encoded", getContentNamespace());
+			elem.addContent(item.getContent().getValue());
+			eItem.addContent(elem);
+		}
+	}
+
+	/**
+	 * To be overriden by RSS 0.91 Netscape and RSS 0.94
+	 */
+	protected boolean isHourFormat24() {
+		return true;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void checkChannelConstraints(Element eChannel)
+			throws FeedException {
+		checkNotNullAndLength(eChannel, "title", 1, 100);
+		checkNotNullAndLength(eChannel, "description", 1, 500);
+		checkNotNullAndLength(eChannel, "link", 1, 500);
+		checkNotNullAndLength(eChannel, "language", 2, 5);
+
+		checkLength(eChannel, "rating", 20, 500);
+		checkLength(eChannel, "copyright", 1, 100);
+		checkLength(eChannel, "pubDate", 1, 100);
+		checkLength(eChannel, "lastBuildDate", 1, 100);
+		checkLength(eChannel, "docs", 1, 500);
+		checkLength(eChannel, "managingEditor", 1, 100);
+		checkLength(eChannel, "webMaster", 1, 100);
+
+		Element skipHours = eChannel.getChild("skipHours");
+		if (skipHours != null) {
+			List<Element> hours = skipHours.getChildren();
+			for (int i = 0; i < hours.size(); i++) {
+				Element hour = hours.get(i);
+				int value = Integer.parseInt(hour.getText().trim());
+				if (isHourFormat24()) {
+					if (value < 1 || value > 24) {
+						throw new FeedException("Invalid hour value " + value
+								+ ", it must be between 1 and 24");
+					}
+				} else {
+					if (value < 0 || value > 23) {
+						throw new FeedException("Invalid hour value " + value
+								+ ", it must be between 0 and 23");
+					}
+				}
+			}
+		}
+	}
+
+	protected void checkImageConstraints(Element eImage) throws FeedException {
+		checkNotNullAndLength(eImage, "title", 1, 100);
+		checkNotNullAndLength(eImage, "url", 1, 500);
+
+		checkLength(eImage, "link", 1, 500);
+		checkLength(eImage, "width", 1, 3);
+		checkLength(eImage, "width", 1, 3);
+		checkLength(eImage, "description", 1, 100);
+	}
+
+	protected void checkTextInputConstraints(Element eTextInput)
+			throws FeedException {
+		checkNotNullAndLength(eTextInput, "title", 1, 100);
+		checkNotNullAndLength(eTextInput, "description", 1, 500);
+		checkNotNullAndLength(eTextInput, "name", 1, 20);
+		checkNotNullAndLength(eTextInput, "link", 1, 500);
+	}
+
+	protected void checkItemConstraints(Element eItem) throws FeedException {
+		checkNotNullAndLength(eItem, "title", 1, 100);
+		checkNotNullAndLength(eItem, "link", 1, 500);
 
-        checkLength(eItem,"description", 1, 500);
-    }
+		checkLength(eItem, "description", 1, 500);
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/Atom10Parser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/Atom10Parser.java,v
retrieving revision 1.30
diff -u -r1.30 Atom10Parser.java
--- src/java/com/sun/syndication/io/impl/Atom10Parser.java	7 Jan 2009 22:50:11 -0000	1.30
+++ src/java/com/sun/syndication/io/impl/Atom10Parser.java	30 Sep 2009 06:30:43 -0000
@@ -16,14 +16,22 @@
  */
 package com.sun.syndication.io.impl;
 
+import java.io.IOException;
+import java.io.Reader;
+import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.regex.Pattern;
 
-import org.jdom.Document; 
+import org.jdom.Attribute;
+import org.jdom.Document;
 import org.jdom.Element;
+import org.jdom.JDOMException;
 import org.jdom.Namespace;
-import org.jdom.output.XMLOutputter; 
+import org.jdom.Parent;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
 
 import com.sun.syndication.feed.WireFeed;
 import com.sun.syndication.feed.atom.Category;
@@ -36,620 +44,651 @@
 import com.sun.syndication.io.FeedException;
 import com.sun.syndication.io.WireFeedInput;
 import com.sun.syndication.io.WireFeedOutput;
-import java.io.IOException;
-import java.io.Reader;
-import java.net.MalformedURLException;
-import java.util.regex.Pattern;
-import org.jdom.Attribute;
-import org.jdom.JDOMException;
-import org.jdom.Parent;
-import org.jdom.input.SAXBuilder;
 
 /**
  * Parser for Atom 1.0
+ * 
  * @author Dave Johnson
  */
 public class Atom10Parser extends BaseWireFeedParser {
-    private static final String ATOM_10_URI = "http://www.w3.org/2005/Atom";
-    private static final Namespace ATOM_10_NS = Namespace.getNamespace(ATOM_10_URI);
 
-    private static boolean resolveURIs = false;
+	private static final String ATOM_10_URI = "http://www.w3.org/2005/Atom";
 
-    public static void setResolveURIs(boolean resolveURIs) {
-        Atom10Parser.resolveURIs = resolveURIs;
-    }
-
-    public static boolean getResolveURIs() {
-        return resolveURIs;
-    }
-
-    public Atom10Parser() {
-        this("atom_1.0");
-    }
-    
-    protected Atom10Parser(String type) {
-        super(type, ATOM_10_NS);
-    }
-    
-    protected Namespace getAtomNamespace() {
-        return ATOM_10_NS;
-    }
-    
-    public boolean isMyType(Document document) {
-        Element rssRoot = document.getRootElement();
-        Namespace defaultNS = rssRoot.getNamespace();
-        return (defaultNS!=null) && defaultNS.equals(getAtomNamespace());
-    }
-    
-    public WireFeed parse(Document document, boolean validate)
-    throws IllegalArgumentException,FeedException {
-        if (validate) {
-            validateFeed(document);
-        }
-        Element rssRoot = document.getRootElement();
-        return parseFeed(rssRoot);
-    }
-    
-    protected void validateFeed(Document document) throws FeedException {
-        // TBD
-        // here we have to validate the Feed against a schema or whatever
-        // not sure how to do it
-        // one posibility would be to produce an ouput and attempt to parse it again
-        // with validation turned on.
-        // otherwise will have to check the document elements by hand.
-    }
-    
-    protected WireFeed parseFeed(Element eFeed) throws FeedException {
-        
-        String baseURI = null;
-        try {
-            baseURI = findBaseURI(eFeed);
-        } catch (Exception e) {
-            throw new FeedException("ERROR while finding base URI of feed", e);
-        }
-        
-        Feed feed = parseFeedMetadata(baseURI, eFeed);
-
-        String xmlBase = eFeed.getAttributeValue("base", Namespace.XML_NAMESPACE);
-        if (xmlBase != null) {
-            feed.setXmlBase(xmlBase);
-        }
-        
-        feed.setModules(parseFeedModules(eFeed));
-
-        List eList = eFeed.getChildren("entry",getAtomNamespace());
-        if (eList.size()>0) {
-            feed.setEntries(parseEntries(feed, baseURI, eList));
-        }
-
-        List foreignMarkup =
-            extractForeignMarkup(eFeed, feed, getAtomNamespace());
-        if (foreignMarkup.size() > 0) {
-            feed.setForeignMarkup(foreignMarkup);
-        }
-        return feed;
-    }
-
-    private Feed parseFeedMetadata(String baseURI, Element eFeed) {
-        com.sun.syndication.feed.atom.Feed feed =
-            new com.sun.syndication.feed.atom.Feed(getType());
-
-        Element e = eFeed.getChild("title",getAtomNamespace());
-        if (e!=null) {
-            Content c = new Content();
-            c.setValue(parseTextConstructToString(e));
-            c.setType(getAttributeValue(e, "type"));
-            feed.setTitleEx(c);
-        }
-        
-        List eList = eFeed.getChildren("link",getAtomNamespace());
-        feed.setAlternateLinks(parseAlternateLinks(feed, null, baseURI, eList));
-        feed.setOtherLinks(parseOtherLinks(feed, null, baseURI, eList));
-        
-        List cList = eFeed.getChildren("category",getAtomNamespace());
-        feed.setCategories(parseCategories(baseURI, cList));
-        
-        eList = eFeed.getChildren("author", getAtomNamespace());
-        if (eList.size()>0) {
-            feed.setAuthors(parsePersons(baseURI, eList));
-        }
-        
-        eList = eFeed.getChildren("contributor",getAtomNamespace());
-        if (eList.size()>0) {
-            feed.setContributors(parsePersons(baseURI, eList));
-        }
-        
-        e = eFeed.getChild("subtitle",getAtomNamespace());
-        if (e!=null) {
-            Content subtitle = new Content();
-            subtitle.setValue(parseTextConstructToString(e));
-            subtitle.setType(getAttributeValue(e, "type"));
-            feed.setSubtitle(subtitle);
-        }
-        
-        e = eFeed.getChild("id",getAtomNamespace());
-        if (e!=null) {
-            feed.setId(e.getText());
-        }
-        
-        e = eFeed.getChild("generator",getAtomNamespace());
-        if (e!=null) {
-            Generator gen = new Generator();
-            gen.setValue(e.getText());
-            String att = getAttributeValue(e, "uri");
-            if (att!=null) {
-                gen.setUrl(att);
-            }
-            att = getAttributeValue(e, "version");
-            if (att!=null) {
-                gen.setVersion(att);
-            }
-            feed.setGenerator(gen);
-        }
-        
-        e = eFeed.getChild("rights",getAtomNamespace());
-        if (e!=null) {
-            feed.setRights(parseTextConstructToString(e));
-        }
-        
-        e = eFeed.getChild("icon",getAtomNamespace());
-        if (e!=null) {
-            feed.setIcon(e.getText());
-        }
-        
-        e = eFeed.getChild("logo",getAtomNamespace());
-        if (e!=null) {
-            feed.setLogo(e.getText());
-        }
-        
-        e = eFeed.getChild("updated",getAtomNamespace());
-        if (e!=null) {
-            feed.setUpdated(DateParser.parseDate(e.getText()));
-        }
-        
-        return feed;
-    }
-
-    private Link parseLink(Feed feed , Entry entry, String baseURI, Element eLink) {
-        Link link = new Link();
-        String att = getAttributeValue(eLink, "rel");
-        if (att!=null) {
-            link.setRel(att);
-        }
-        att = getAttributeValue(eLink, "type");
-        if (att!=null) {
-            link.setType(att);
-        }
-        att = getAttributeValue(eLink, "href");
-        if (att!=null) {
-            link.setHref(att);
-            if (isRelativeURI(att)) {
-                link.setHrefResolved(resolveURI(baseURI, eLink, att));
-            } 
-        }
-        att = getAttributeValue(eLink, "title");
-        if (att!=null) {
-            link.setTitle(att);
-        }
-        att = getAttributeValue(eLink, "hreflang");
-        if (att!=null) {
-            link.setHreflang(att);
-        }
-        att = getAttributeValue(eLink, "length");
-        if (att!=null) {
-        	Long val = NumberParser.parseLong(att);
-        	if (val != null) {
-        		link.setLength(val.longValue());
-        	}            
-        }
-        return link;
-    }
-    
-    // List(Elements) -> List(Link)
-    private List parseAlternateLinks(Feed feed, Entry entry, String baseURI, List eLinks) {
-        List links = new ArrayList();
-        for (int i=0;i<eLinks.size();i++) {
-            Element eLink = (Element) eLinks.get(i);
-            Link link = parseLink(feed, entry, baseURI, eLink);
-            if (link.getRel() == null
-                    || "".equals(link.getRel().trim())
-                    || "alternate".equals(link.getRel())) {
-                links.add(link);
-            }
-        }
-        return (links.size()>0) ? links : null;
-    }
-    
-    private List parseOtherLinks(Feed feed, Entry entry, String baseURI, List eLinks) {
-        List links = new ArrayList();
-        for (int i=0;i<eLinks.size();i++) {
-            Element eLink = (Element) eLinks.get(i);
-            Link link = parseLink(feed, entry, baseURI, eLink);
-            if (!"alternate".equals(link.getRel())) {
-                links.add(link);
-            }
-        }
-        return (links.size()>0) ? links : null;
-    }
-    
-    private Person parsePerson(String baseURI, Element ePerson) {
-        Person person = new Person();
-        Element e = ePerson.getChild("name",getAtomNamespace());
-        if (e!=null) {
-            person.setName(e.getText());
-        }
-        e = ePerson.getChild("uri",getAtomNamespace());
-        if (e!=null) {
-            person.setUri(e.getText());
-            if (isRelativeURI(e.getText())) {
-               person.setUriResolved(resolveURI(baseURI, ePerson, e.getText())); 
-            }
-        }
-        e = ePerson.getChild("email",getAtomNamespace());
-        if (e!=null) {
-            person.setEmail(e.getText());
-        }
-        person.setModules(parsePersonModules(ePerson));        
-        return person;
-    }
-    
-    // List(Elements) -> List(Persons)
-    private List parsePersons(String baseURI, List ePersons) {
-        List persons = new ArrayList();
-        for (int i=0;i<ePersons.size();i++) {
-            persons.add(parsePerson(baseURI, (Element)ePersons.get(i)));
-        }
-        return (persons.size()>0) ? persons : null;
-    }
-    
-    private Content parseContent(Element e) {
-        String value = parseTextConstructToString(e);
-        String src = getAttributeValue(e, "src");
-        String type = getAttributeValue(e, "type");
-        Content content = new Content();
-        content.setSrc(src);
-        content.setType(type);
-        content.setValue(value);
-        return content;
-    }
-    
-    private String parseTextConstructToString(Element e) {
-        String value = null;
-        String type = getAttributeValue(e, "type");
-        type = (type!=null) ? type : Content.TEXT;
-        if (type.equals(Content.XHTML) || (type.indexOf("/xml")) != -1 || (type.indexOf("+xml")) != -1) {
-            // XHTML content needs special handling
-            XMLOutputter outputter = new XMLOutputter();
-            List eContent = e.getContent();
-            Iterator i = eContent.iterator();
-            while (i.hasNext()) {
-                org.jdom.Content c = (org.jdom.Content) i.next();
-                if (c instanceof Element) {
-                    Element eC = (Element) c;
-                    if (eC.getNamespace().equals(getAtomNamespace())) {
-                        ((Element)c).setNamespace(Namespace.NO_NAMESPACE);
-                    }
-                }
-            }
-            value = outputter.outputString(eContent);
-        } else {
-            // Everything else comes in verbatim
-            value = e.getText();
-        }
-        return value;
-    }
-    
-    // List(Elements) -> List(Entries)
-    protected List parseEntries(Feed feed, String baseURI, List eEntries) {
-        List entries = new ArrayList();
-        for (int i=0;i<eEntries.size();i++) {
-            entries.add(parseEntry(feed, (Element)eEntries.get(i), baseURI));
-        }
-        return (entries.size()>0) ? entries : null;
-    }
-    
-    protected Entry parseEntry(Feed feed, Element eEntry, String baseURI) {
-        Entry entry = new Entry();
-        
-        String xmlBase = eEntry.getAttributeValue("base", Namespace.XML_NAMESPACE);
-        if (xmlBase != null) {
-            entry.setXmlBase(xmlBase);
-        }
-        
-        Element e = eEntry.getChild("title",getAtomNamespace());
-        if (e!=null) {
-            Content c = new Content();
-            c.setValue(parseTextConstructToString(e));
-            c.setType(getAttributeValue(e, "type"));
-            entry.setTitleEx(c);
-        }
-        
-        List eList = eEntry.getChildren("link",getAtomNamespace());
-        entry.setAlternateLinks(parseAlternateLinks(feed, entry, baseURI, eList));
-        entry.setOtherLinks(parseOtherLinks(feed, entry, baseURI, eList));
-        
-        eList = eEntry.getChildren("author", getAtomNamespace());
-        if (eList.size()>0) {
-            entry.setAuthors(parsePersons(baseURI, eList));
-        }
-        
-        eList = eEntry.getChildren("contributor",getAtomNamespace());
-        if (eList.size()>0) {
-            entry.setContributors(parsePersons(baseURI, eList));
-        }
-        
-        e = eEntry.getChild("id",getAtomNamespace());
-        if (e!=null) {
-            entry.setId(e.getText());
-        }
-        
-        e = eEntry.getChild("updated",getAtomNamespace());
-        if (e!=null) {
-            entry.setUpdated(DateParser.parseDate(e.getText()));
-        }
-        
-        e = eEntry.getChild("published",getAtomNamespace());
-        if (e!=null) {
-            entry.setPublished(DateParser.parseDate(e.getText()));
-        }
-        
-        e = eEntry.getChild("summary",getAtomNamespace());
-        if (e!=null) {
-            entry.setSummary(parseContent(e));
-        }
-        
-        e = eEntry.getChild("content",getAtomNamespace());
-        if (e!=null) {
-            List contents = new ArrayList();
-            contents.add(parseContent(e));
-            entry.setContents(contents);
-        }
-        
-        e = eEntry.getChild("rights",getAtomNamespace());
-        if (e!=null) {
-            entry.setRights(e.getText());
-        }
-        
-        List cList = eEntry.getChildren("category",getAtomNamespace());
-        entry.setCategories(parseCategories(baseURI, cList));
-        
-        // TODO: SHOULD handle Atom entry source element
-        e = eEntry.getChild("source", getAtomNamespace());
-        if (e!=null) {
-            entry.setSource(parseFeedMetadata(baseURI, e));
-        }
-        
-        entry.setModules(parseItemModules(eEntry));
-        
-        List foreignMarkup =
-                extractForeignMarkup(eEntry, entry, getAtomNamespace());
-        if (foreignMarkup.size() > 0) {
-            entry.setForeignMarkup(foreignMarkup);
-        }
-        return entry;
-    }
-    
-    private List parseCategories(String baseURI, List eCategories) {
-        List cats = new ArrayList();
-        for (int i=0;i<eCategories.size();i++) {
-            Element eCategory = (Element) eCategories.get(i);
-            cats.add(parseCategory(baseURI, eCategory));
-        }
-        return (cats.size()>0) ? cats : null;
-    }
-    
-    private Category parseCategory(String baseURI, Element eCategory) {
-        Category category = new Category();
-        String att = getAttributeValue(eCategory, "term");
-        if (att!=null) {
-            category.setTerm(att);
-        }
-        att = getAttributeValue(eCategory, "scheme");
-        if (att!=null) {
-            category.setScheme(att);
-            if (isRelativeURI(att)) {
-                category.setSchemeResolved(resolveURI(baseURI, eCategory, att));
-            }
-        }
-        att = getAttributeValue(eCategory, "label");
-        if (att!=null) {
-            category.setLabel(att);
-        }
-        return category;
-        
-    }
-    
-    // Once following relative URI methods are made public in the ROME 
-    // Atom10Parser, then use them instead and delete these.
-    
-    
-    // Fix for issue #34 "valid IRI href attributes are stripped for atom:link"
-    // URI's that didn't start with http were being treated as relative URIs.
-    // So now consider an absolute URI to be any alpha-numeric string followed
-    // by a colon, followed by anything -- specified by this regex:
-    static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$");
-    
-    public static boolean isAbsoluteURI(String uri) {
-        return absoluteURIPattern.matcher(uri).find();
-    }
-    
-    /** Returns true if URI is relative. */
-    public static boolean isRelativeURI(String uri) {
-        return !isAbsoluteURI(uri);
-    }
-        
-    /**
-     * Resolve URI via base URL and parent element.
-     * Resolve URI based considering xml:base and baseURI.
-     * @param baseURI Base URI used to fetch the XML document
-     * @param parent  Parent element from which to consider xml:base
-     * @param url     URL to be resolved
-     */
-    public static String resolveURI(String baseURI, Parent parent, String url) {
-        if (!resolveURIs) {
-            return url;
-        }
-        if (isRelativeURI(url)) {
-            url = (!".".equals(url) && !"./".equals(url)) ? url : "";
-            
-            if (url.startsWith("/") && baseURI != null) {
-                String base = null;
-                int slashslash = baseURI.indexOf("//");
-                int nextslash = baseURI.indexOf("/", slashslash + 2);
-                if (nextslash != -1) base = baseURI.substring(0, nextslash);
-                return formURI(base, url);               
-            } 
-
-            // Relative URI with parent
-            if (parent != null && parent instanceof Element) {
-
-                // Do we have an xml:base?         
-                String xmlbase = ((Element)parent).getAttributeValue(
-                    "base", Namespace.XML_NAMESPACE);
-                if (xmlbase != null && xmlbase.trim().length() > 0) {
-                    if (isAbsoluteURI(xmlbase)) {
-                        // Absolute xml:base, so form URI right now 
-                        if (url.startsWith("/")) { 
-                            // Host relative URI
-                            int slashslash = xmlbase.indexOf("//");
-                            int nextslash = xmlbase.indexOf("/", slashslash + 2);
-                            if (nextslash != -1) xmlbase = xmlbase.substring(0, nextslash);
-                            return formURI(xmlbase, url); 
-                        }
-                        if (!xmlbase.endsWith("/")) {
-                            // Base URI is filename, strip it off 
-                            xmlbase = xmlbase.substring(0, xmlbase.lastIndexOf("/"));
-                        }
-                        return formURI(xmlbase, url);
-                    } else {
-                        // Relative xml:base, so walk up tree
-                        return resolveURI(baseURI, parent.getParent(), 
-                            stripTrailingSlash(xmlbase) + "/"+ stripStartingSlash(url));
-                    }
-                }
-                // No xml:base so walk up tree
-                return resolveURI(baseURI, parent.getParent(), url);
-
-            // Relative URI with no parent (i.e. top of tree), so form URI right now
-            } else if (parent == null || parent instanceof Document) {
-                return formURI(baseURI, url);        
-            } 
-        }                
-        return url;
-    }
-        
-    /**
-     * Find base URI of feed considering relative URIs.
-     * @param root Root element of feed.
-     */
-    private String findBaseURI(Element root) throws MalformedURLException {
-        String ret = null;
-        if (findAtomLink(root, "self") != null) {
-            ret = findAtomLink(root, "self");
-            if (".".equals(ret) || "./".equals(ret)) ret = "";
-            if (ret.indexOf("/") != -1) ret = ret.substring(0, ret.lastIndexOf("/"));
-            ret = resolveURI(null, root, ret);
-        }
-        return ret;
-    }
-    
-    /** 
-     * Return URL string of Atom link element under parent element.
-     * Link with no rel attribute is considered to be rel="alternate"
-     * @param parent Consider only children of this parent element
-     * @param rel    Consider only links with this relationship
-     */
-    private  String findAtomLink(Element parent, String rel) {
-        String ret = null;
-        List linksList = parent.getChildren("link", ATOM_10_NS);
-        if (linksList != null) {
-            for (Iterator links = linksList.iterator(); links.hasNext(); ) {
-                Element link = (Element)links.next();
-                Attribute relAtt = getAttribute(link, "rel");
-                Attribute hrefAtt = getAttribute(link, "href");
-                if (   (relAtt == null && "alternate".equals(rel)) 
-                    || (relAtt != null && relAtt.getValue().equals(rel))) {
-                    ret = hrefAtt.getValue();
-                    break;
-                }
-            }
-        }
-        return ret;
-    }
-        
-    /** 
-     * Form URI by combining base with append portion and giving 
-     * special consideration to append portions that begin with ".."
-     * @param base   Base of URI, may end with trailing slash
-     * @param append String to append, may begin with slash or ".."
-     */
-    private static String formURI(String base, String append) {
-        base = stripTrailingSlash(base);
-        append = stripStartingSlash(append);
-        if (append.startsWith("..")) {
-            String ret = null;
-            String[] parts = append.split("/");
-            for (int i=0; i<parts.length; i++) {
-                if ("..".equals(parts[i])) {
-                    int last = base.lastIndexOf("/");
-                    if (last != -1) {
-                        base = base.substring(0, last);
-                        append = append.substring(3, append.length());
-                    }
-                    else break;
-                }
-            }
-        }
-        return base + "/" + append;
-    }
-    
-    /** 
-     * Strip starting slash from beginning of string.
-     */
-    private static String stripStartingSlash(String s) {
-        if (s != null && s.startsWith("/")) {
-            s = s.substring(1, s.length());
-        }
-        return s;
-    }
-    
-    /** 
-     * Strip trailing slash from end of string.
-     */
-    private static String stripTrailingSlash(String s) {
-        if (s != null && s.endsWith("/")) {
-            s = s.substring(0, s.length() - 1);
-        }
-        return s;
-    }    
-
-    
-    /**
-     * Parse entry from reader.
-     */
-    public static Entry parseEntry(Reader rd, String baseURI)
-        throws JDOMException, IOException, IllegalArgumentException, FeedException {
-        // Parse entry into JDOM tree
-        SAXBuilder builder = new SAXBuilder();
-        Document entryDoc = builder.build(rd);
-        Element fetchedEntryElement = entryDoc.getRootElement();
-        fetchedEntryElement.detach();
-
-        // Put entry into a JDOM document with 'feed' root so that Rome can handle it
-        Feed feed = new Feed();
-        feed.setFeedType("atom_1.0");
-        WireFeedOutput wireFeedOutput = new WireFeedOutput();
-        Document feedDoc = wireFeedOutput.outputJDom(feed);
-        feedDoc.getRootElement().addContent(fetchedEntryElement);
-        
-        if (baseURI != null) {
-            feedDoc.getRootElement().setAttribute("base", baseURI, Namespace.XML_NAMESPACE);
-        }
-        
-        WireFeedInput input = new WireFeedInput();
-        Feed parsedFeed = (Feed)input.build(feedDoc);
-        return (Entry)parsedFeed.getEntries().get(0);
-    } 
-}
+	private static final Namespace ATOM_10_NS = Namespace
+			.getNamespace(ATOM_10_URI);
 
+	private static boolean resolveURIs = false;
 
+	public static void setResolveURIs(boolean resolveURIs) {
+		Atom10Parser.resolveURIs = resolveURIs;
+	}
+
+	public static boolean getResolveURIs() {
+		return resolveURIs;
+	}
+
+	public Atom10Parser() {
+		this("atom_1.0");
+	}
+
+	protected Atom10Parser(String type) {
+		super(type, ATOM_10_NS);
+	}
+
+	protected Namespace getAtomNamespace() {
+		return ATOM_10_NS;
+	}
+
+	public boolean isMyType(Document document) {
+		Element rssRoot = document.getRootElement();
+		Namespace defaultNS = rssRoot.getNamespace();
+		return (defaultNS != null) && defaultNS.equals(getAtomNamespace());
+	}
+
+	public WireFeed parse(Document document, boolean validate)
+			throws IllegalArgumentException, FeedException {
+		if (validate) {
+			validateFeed(document);
+		}
+		Element rssRoot = document.getRootElement();
+		return parseFeed(rssRoot);
+	}
+
+	protected void validateFeed(Document document) throws FeedException {
+		// TBD
+		// here we have to validate the Feed against a schema or whatever
+		// not sure how to do it
+		// one posibility would be to produce an ouput and attempt to parse it
+		// again
+		// with validation turned on.
+		// otherwise will have to check the document elements by hand.
+	}
+
+	@SuppressWarnings("unchecked")
+	protected WireFeed parseFeed(Element eFeed) throws FeedException {
+
+		String baseURI = null;
+		try {
+			baseURI = findBaseURI(eFeed);
+		} catch (Exception e) {
+			throw new FeedException("ERROR while finding base URI of feed", e);
+		}
+
+		Feed feed = parseFeedMetadata(baseURI, eFeed);
+
+		String xmlBase = eFeed.getAttributeValue("base",
+				Namespace.XML_NAMESPACE);
+		if (xmlBase != null) {
+			feed.setXmlBase(xmlBase);
+		}
+
+		feed.setModules(parseFeedModules(eFeed));
+
+		List<Element> eList = eFeed.getChildren("entry", getAtomNamespace());
+		if (eList.size() > 0) {
+			feed.setEntries(parseEntries(feed, baseURI, eList));
+		}
+
+		List<Object> foreignMarkup = extractForeignMarkup(eFeed, feed,
+				getAtomNamespace());
+		if (foreignMarkup.size() > 0) {
+			feed.setForeignMarkup(foreignMarkup);
+		}
+		return feed;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Feed parseFeedMetadata(String baseURI, Element eFeed) {
+		com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(
+				getType());
+
+		Element e = eFeed.getChild("title", getAtomNamespace());
+		if (e != null) {
+			Content c = new Content();
+			c.setValue(parseTextConstructToString(e));
+			c.setType(getAttributeValue(e, "type"));
+			feed.setTitleEx(c);
+		}
+
+		List<Element> eList = eFeed.getChildren("link", getAtomNamespace());
+		feed.setAlternateLinks(parseAlternateLinks(feed, null, baseURI, eList));
+		feed.setOtherLinks(parseOtherLinks(feed, null, baseURI, eList));
+
+		List<Element> cList = eFeed.getChildren("category", getAtomNamespace());
+		feed.setCategories(parseCategories(baseURI, cList));
+
+		eList = eFeed.getChildren("author", getAtomNamespace());
+		if (eList.size() > 0) {
+			feed.setAuthors(parsePersons(baseURI, eList));
+		}
+
+		eList = eFeed.getChildren("contributor", getAtomNamespace());
+		if (eList.size() > 0) {
+			feed.setContributors(parsePersons(baseURI, eList));
+		}
+
+		e = eFeed.getChild("subtitle", getAtomNamespace());
+		if (e != null) {
+			Content subtitle = new Content();
+			subtitle.setValue(parseTextConstructToString(e));
+			subtitle.setType(getAttributeValue(e, "type"));
+			feed.setSubtitle(subtitle);
+		}
+
+		e = eFeed.getChild("id", getAtomNamespace());
+		if (e != null) {
+			feed.setId(e.getText());
+		}
+
+		e = eFeed.getChild("generator", getAtomNamespace());
+		if (e != null) {
+			Generator gen = new Generator();
+			gen.setValue(e.getText());
+			String att = getAttributeValue(e, "uri");
+			if (att != null) {
+				gen.setUrl(att);
+			}
+			att = getAttributeValue(e, "version");
+			if (att != null) {
+				gen.setVersion(att);
+			}
+			feed.setGenerator(gen);
+		}
+
+		e = eFeed.getChild("rights", getAtomNamespace());
+		if (e != null) {
+			feed.setRights(parseTextConstructToString(e));
+		}
+
+		e = eFeed.getChild("icon", getAtomNamespace());
+		if (e != null) {
+			feed.setIcon(e.getText());
+		}
+
+		e = eFeed.getChild("logo", getAtomNamespace());
+		if (e != null) {
+			feed.setLogo(e.getText());
+		}
+
+		e = eFeed.getChild("updated", getAtomNamespace());
+		if (e != null) {
+			feed.setUpdated(DateParser.parseDate(e.getText()));
+		}
+
+		return feed;
+	}
+
+	private Link parseLink(Feed feed, Entry entry, String baseURI, Element eLink) {
+		Link link = new Link();
+		String att = getAttributeValue(eLink, "rel");
+		if (att != null) {
+			link.setRel(att);
+		}
+		att = getAttributeValue(eLink, "type");
+		if (att != null) {
+			link.setType(att);
+		}
+		att = getAttributeValue(eLink, "href");
+		if (att != null) {
+			link.setHref(att);
+			if (isRelativeURI(att)) {
+				link.setHrefResolved(resolveURI(baseURI, eLink, att));
+			}
+		}
+		att = getAttributeValue(eLink, "title");
+		if (att != null) {
+			link.setTitle(att);
+		}
+		att = getAttributeValue(eLink, "hreflang");
+		if (att != null) {
+			link.setHreflang(att);
+		}
+		att = getAttributeValue(eLink, "length");
+		if (att != null) {
+			Long val = NumberParser.parseLong(att);
+			if (val != null) {
+				link.setLength(val.longValue());
+			}
+		}
+		return link;
+	}
+
+	// List(Elements) -> List(Link)
+	private List<Link> parseAlternateLinks(Feed feed, Entry entry,
+			String baseURI, List<Element> eLinks) {
+		List<Link> links = new ArrayList<Link>();
+		for (int i = 0; i < eLinks.size(); i++) {
+			Element eLink = eLinks.get(i);
+			Link link = parseLink(feed, entry, baseURI, eLink);
+			if (link.getRel() == null || "".equals(link.getRel().trim())
+					|| "alternate".equals(link.getRel())) {
+				links.add(link);
+			}
+		}
+		return (links.size() > 0) ? links : null;
+	}
+
+	private List<Link> parseOtherLinks(Feed feed, Entry entry, String baseURI,
+			List<Element> eLinks) {
+		List<Link> links = new ArrayList<Link>();
+		for (int i = 0; i < eLinks.size(); i++) {
+			Element eLink = eLinks.get(i);
+			Link link = parseLink(feed, entry, baseURI, eLink);
+			if ("alternate".equals(link.getRel()) == false) {
+				links.add(link);
+			}
+		}
+		return (links.size() > 0) ? links : null;
+	}
+
+	private Person parsePerson(String baseURI, Element ePerson) {
+		Person person = new Person();
+		Element e = ePerson.getChild("name", getAtomNamespace());
+		if (e != null) {
+			person.setName(e.getText());
+		}
+		e = ePerson.getChild("uri", getAtomNamespace());
+		if (e != null) {
+			person.setUri(e.getText());
+			if (isRelativeURI(e.getText())) {
+				person
+						.setUriResolved(resolveURI(baseURI, ePerson, e
+								.getText()));
+			}
+		}
+		e = ePerson.getChild("email", getAtomNamespace());
+		if (e != null) {
+			person.setEmail(e.getText());
+		}
+		person.setModules(parsePersonModules(ePerson));
+		return person;
+	}
+
+	// List(Elements) -> List(Persons)
+	private List<Person> parsePersons(String baseURI, List<Element> ePersons) {
+		List<Person> persons = new ArrayList<Person>();
+		for (int i = 0; i < ePersons.size(); i++) {
+			persons.add(parsePerson(baseURI, ePersons.get(i)));
+		}
+		return (persons.size() > 0) ? persons : null;
+	}
+
+	private Content parseContent(Element e) {
+		String value = parseTextConstructToString(e);
+		String src = getAttributeValue(e, "src");
+		String type = getAttributeValue(e, "type");
+		Content content = new Content();
+		content.setSrc(src);
+		content.setType(type);
+		content.setValue(value);
+		return content;
+	}
+
+	@SuppressWarnings("unchecked")
+	private String parseTextConstructToString(Element e) {
+		String value = null;
+		String type = getAttributeValue(e, "type");
+		type = (type != null) ? type : Content.TEXT;
+		if (type.equals(Content.XHTML) || (type.indexOf("/xml")) != -1
+				|| (type.indexOf("+xml")) != -1) {
+			// XHTML content needs special handling
+			XMLOutputter outputter = new XMLOutputter();
+			List<org.jdom.Content> eContent = e.getContent();
+			Iterator<org.jdom.Content> i = eContent.iterator();
+			while (i.hasNext()) {
+				org.jdom.Content c = i.next();
+				if (c instanceof Element) {
+					Element eC = (Element) c;
+					if (eC.getNamespace().equals(getAtomNamespace())) {
+						((Element) c).setNamespace(Namespace.NO_NAMESPACE);
+					}
+				}
+			}
+			value = outputter.outputString(eContent);
+		} else {
+			// Everything else comes in verbatim
+			value = e.getText();
+		}
+		return value;
+	}
+
+	// List(Elements) -> List(Entries)
+	protected List<Entry> parseEntries(Feed feed, String baseURI,
+			List<Element> eEntries) {
+		List<Entry> entries = new ArrayList<Entry>();
+		for (int i = 0; i < eEntries.size(); i++) {
+			entries.add(parseEntry(feed, eEntries.get(i), baseURI));
+		}
+		return (entries.size() > 0) ? entries : null;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected Entry parseEntry(Feed feed, Element eEntry, String baseURI) {
+		Entry entry = new Entry();
+
+		String xmlBase = eEntry.getAttributeValue("base",
+				Namespace.XML_NAMESPACE);
+		if (xmlBase != null) {
+			entry.setXmlBase(xmlBase);
+		}
+
+		Element e = eEntry.getChild("title", getAtomNamespace());
+		if (e != null) {
+			Content c = new Content();
+			c.setValue(parseTextConstructToString(e));
+			c.setType(getAttributeValue(e, "type"));
+			entry.setTitleEx(c);
+		}
+
+		List<Element> eList = eEntry.getChildren("link", getAtomNamespace());
+		entry
+				.setAlternateLinks(parseAlternateLinks(feed, entry, baseURI,
+						eList));
+		entry.setOtherLinks(parseOtherLinks(feed, entry, baseURI, eList));
+
+		eList = eEntry.getChildren("author", getAtomNamespace());
+		if (eList.size() > 0) {
+			entry.setAuthors(parsePersons(baseURI, eList));
+		}
+
+		eList = eEntry.getChildren("contributor", getAtomNamespace());
+		if (eList.size() > 0) {
+			entry.setContributors(parsePersons(baseURI, eList));
+		}
+
+		e = eEntry.getChild("id", getAtomNamespace());
+		if (e != null) {
+			entry.setId(e.getText());
+		}
+
+		e = eEntry.getChild("updated", getAtomNamespace());
+		if (e != null) {
+			entry.setUpdated(DateParser.parseDate(e.getText()));
+		}
+
+		e = eEntry.getChild("published", getAtomNamespace());
+		if (e != null) {
+			entry.setPublished(DateParser.parseDate(e.getText()));
+		}
+
+		e = eEntry.getChild("summary", getAtomNamespace());
+		if (e != null) {
+			entry.setSummary(parseContent(e));
+		}
+
+		e = eEntry.getChild("content", getAtomNamespace());
+		if (e != null) {
+			List contents = new ArrayList();
+			contents.add(parseContent(e));
+			entry.setContents(contents);
+		}
+
+		e = eEntry.getChild("rights", getAtomNamespace());
+		if (e != null) {
+			entry.setRights(e.getText());
+		}
+
+		List cList = eEntry.getChildren("category", getAtomNamespace());
+		entry.setCategories(parseCategories(baseURI, cList));
+
+		// TODO: SHOULD handle Atom entry source element
+		e = eEntry.getChild("source", getAtomNamespace());
+		if (e != null) {
+			entry.setSource(parseFeedMetadata(baseURI, e));
+		}
+
+		entry.setModules(parseItemModules(eEntry));
+
+		List foreignMarkup = extractForeignMarkup(eEntry, entry,
+				getAtomNamespace());
+		if (foreignMarkup.size() > 0) {
+			entry.setForeignMarkup(foreignMarkup);
+		}
+		return entry;
+	}
+
+	private List<Category> parseCategories(String baseURI,
+			List<Element> eCategories) {
+		List<Category> cats = new ArrayList<Category>();
+		for (int i = 0; i < eCategories.size(); i++) {
+			Element eCategory = (Element) eCategories.get(i);
+			cats.add(parseCategory(baseURI, eCategory));
+		}
+		return (cats.size() > 0) ? cats : null;
+	}
+
+	private Category parseCategory(String baseURI, Element eCategory) {
+		Category category = new Category();
+		String att = getAttributeValue(eCategory, "term");
+		if (att != null) {
+			category.setTerm(att);
+		}
+		att = getAttributeValue(eCategory, "scheme");
+		if (att != null) {
+			category.setScheme(att);
+			if (isRelativeURI(att)) {
+				category.setSchemeResolved(resolveURI(baseURI, eCategory, att));
+			}
+		}
+		att = getAttributeValue(eCategory, "label");
+		if (att != null) {
+			category.setLabel(att);
+		}
+		return category;
+
+	}
+
+	// Once following relative URI methods are made public in the ROME
+	// Atom10Parser, then use them instead and delete these.
+
+	// Fix for issue #34 "valid IRI href attributes are stripped for atom:link"
+	// URI's that didn't start with http were being treated as relative URIs.
+	// So now consider an absolute URI to be any alpha-numeric string followed
+	// by a colon, followed by anything -- specified by this regex:
+	static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$");
+
+	public static boolean isAbsoluteURI(String uri) {
+		return absoluteURIPattern.matcher(uri).find();
+	}
+
+	/** Returns true if URI is relative. */
+	public static boolean isRelativeURI(String uri) {
+		return !isAbsoluteURI(uri);
+	}
+
+	/**
+	 * Resolve URI via base URL and parent element. Resolve URI based
+	 * considering xml:base and baseURI.
+	 * 
+	 * @param baseURI
+	 *            Base URI used to fetch the XML document
+	 * @param parent
+	 *            Parent element from which to consider xml:base
+	 * @param url
+	 *            URL to be resolved
+	 */
+	public static String resolveURI(String baseURI, Parent parent, String url) {
+		if (!resolveURIs) {
+			return url;
+		}
+		if (isRelativeURI(url)) {
+			url = (!".".equals(url) && !"./".equals(url)) ? url : "";
+
+			if (url.startsWith("/") && baseURI != null) {
+				String base = null;
+				int slashslash = baseURI.indexOf("//");
+				int nextslash = baseURI.indexOf("/", slashslash + 2);
+				if (nextslash != -1)
+					base = baseURI.substring(0, nextslash);
+				return formURI(base, url);
+			}
+
+			// Relative URI with parent
+			if (parent != null && parent instanceof Element) {
+
+				// Do we have an xml:base?
+				String xmlbase = ((Element) parent).getAttributeValue("base",
+						Namespace.XML_NAMESPACE);
+				if (xmlbase != null && xmlbase.trim().length() > 0) {
+					if (isAbsoluteURI(xmlbase)) {
+						// Absolute xml:base, so form URI right now
+						if (url.startsWith("/")) {
+							// Host relative URI
+							int slashslash = xmlbase.indexOf("//");
+							int nextslash = xmlbase
+									.indexOf("/", slashslash + 2);
+							if (nextslash != -1)
+								xmlbase = xmlbase.substring(0, nextslash);
+							return formURI(xmlbase, url);
+						}
+						if (!xmlbase.endsWith("/")) {
+							// Base URI is filename, strip it off
+							xmlbase = xmlbase.substring(0, xmlbase
+									.lastIndexOf("/"));
+						}
+						return formURI(xmlbase, url);
+					} else {
+						// Relative xml:base, so walk up tree
+						return resolveURI(baseURI, parent.getParent(),
+								stripTrailingSlash(xmlbase) + "/"
+										+ stripStartingSlash(url));
+					}
+				}
+				// No xml:base so walk up tree
+				return resolveURI(baseURI, parent.getParent(), url);
+
+				// Relative URI with no parent (i.e. top of tree), so form URI
+				// right now
+			} else if (parent == null || parent instanceof Document) {
+				return formURI(baseURI, url);
+			}
+		}
+		return url;
+	}
+
+	/**
+	 * Find base URI of feed considering relative URIs.
+	 * 
+	 * @param root
+	 *            Root element of feed.
+	 */
+	private String findBaseURI(Element root) throws MalformedURLException {
+		String ret = null;
+		if (findAtomLink(root, "self") != null) {
+			ret = findAtomLink(root, "self");
+			if (".".equals(ret) || "./".equals(ret))
+				ret = "";
+			if (ret.indexOf("/") != -1)
+				ret = ret.substring(0, ret.lastIndexOf("/"));
+			ret = resolveURI(null, root, ret);
+		}
+		return ret;
+	}
+
+	/**
+	 * Return URL string of Atom link element under parent element. Link with no
+	 * rel attribute is considered to be rel="alternate"
+	 * 
+	 * @param parent
+	 *            Consider only children of this parent element
+	 * @param rel
+	 *            Consider only links with this relationship
+	 */
+	@SuppressWarnings("unchecked")
+	private String findAtomLink(Element parent, String rel) {
+		String ret = null;
+		List<Element> linksList = parent.getChildren("link", ATOM_10_NS);
+		if (linksList != null) {
+			for (Iterator<Element> links = linksList.iterator(); links
+					.hasNext();) {
+				Element link = links.next();
+				Attribute relAtt = getAttribute(link, "rel");
+				Attribute hrefAtt = getAttribute(link, "href");
+				if ((relAtt == null && "alternate".equals(rel))
+						|| (relAtt != null && relAtt.getValue().equals(rel))) {
+					ret = hrefAtt.getValue();
+					break;
+				}
+			}
+		}
+		return ret;
+	}
+
+	/**
+	 * Form URI by combining base with append portion and giving special
+	 * consideration to append portions that begin with ".."
+	 * 
+	 * @param base
+	 *            Base of URI, may end with trailing slash
+	 * @param append
+	 *            String to append, may begin with slash or ".."
+	 */
+	private static String formURI(String base, String append) {
+		base = stripTrailingSlash(base);
+		append = stripStartingSlash(append);
+		if (append.startsWith("..")) {
+			String[] parts = append.split("/");
+			for (int i = 0; i < parts.length; i++) {
+				if ("..".equals(parts[i])) {
+					int last = base.lastIndexOf("/");
+					if (last != -1) {
+						base = base.substring(0, last);
+						append = append.substring(3, append.length());
+					} else
+						break;
+				}
+			}
+		}
+		return base + "/" + append;
+	}
+
+	/**
+	 * Strip starting slash from beginning of string.
+	 */
+	private static String stripStartingSlash(String s) {
+		if (s != null && s.startsWith("/")) {
+			s = s.substring(1, s.length());
+		}
+		return s;
+	}
+
+	/**
+	 * Strip trailing slash from end of string.
+	 */
+	private static String stripTrailingSlash(String s) {
+		if (s != null && s.endsWith("/")) {
+			s = s.substring(0, s.length() - 1);
+		}
+		return s;
+	}
+
+	/**
+	 * Parse entry from reader.
+	 */
+	public static Entry parseEntry(Reader rd, String baseURI)
+			throws JDOMException, IOException, IllegalArgumentException,
+			FeedException {
+		// Parse entry into JDOM tree
+		SAXBuilder builder = new SAXBuilder();
+		Document entryDoc = builder.build(rd);
+		Element fetchedEntryElement = entryDoc.getRootElement();
+		fetchedEntryElement.detach();
+
+		// Put entry into a JDOM document with 'feed' root so that Rome can
+		// handle it
+		Feed feed = new Feed();
+		feed.setFeedType("atom_1.0");
+		WireFeedOutput wireFeedOutput = new WireFeedOutput();
+		Document feedDoc = wireFeedOutput.outputJDom(feed);
+		feedDoc.getRootElement().addContent(fetchedEntryElement);
+
+		if (baseURI != null) {
+			feedDoc.getRootElement().setAttribute("base", baseURI,
+					Namespace.XML_NAMESPACE);
+		}
+
+		WireFeedInput input = new WireFeedInput();
+		Feed parsedFeed = (Feed) input.build(feedDoc);
+		return parsedFeed.getEntries().get(0);
+	}
+}
Index: src/java/com/sun/syndication/io/impl/RSS20Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS20Generator.java,v
retrieving revision 1.6
diff -u -r1.6 RSS20Generator.java
--- src/java/com/sun/syndication/io/impl/RSS20Generator.java	15 Sep 2006 00:51:47 -0000	1.6
+++ src/java/com/sun/syndication/io/impl/RSS20Generator.java	30 Sep 2009 06:30:45 -0000
@@ -56,9 +56,9 @@
             eChannel.addContent(generateSimpleElement("ttl", String.valueOf(ttl)));
         }
 
-        List categories = channel.getCategories();
+        List<Category> categories = channel.getCategories();
         for(int i = 0; i < categories.size(); i++) {
-            eChannel.addContent(generateCategoryElement((Category)categories.get(i)));
+            eChannel.addContent(generateCategoryElement(categories.get(i)));
         }
 
     }
Index: src/java/com/sun/syndication/io/impl/RSS10Parser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS10Parser.java,v
retrieving revision 1.8
diff -u -r1.8 RSS10Parser.java
--- src/java/com/sun/syndication/io/impl/RSS10Parser.java	14 Aug 2007 11:21:56 -0000	1.8
+++ src/java/com/sun/syndication/io/impl/RSS10Parser.java	30 Sep 2009 06:30:45 -0000
@@ -51,12 +51,13 @@
      * @param document document to check if it can be parsed with this parser implementation.
      * @return <b>true</b> if the document is RSS1., <b>false</b> otherwise.
      */
-    public boolean isMyType(Document document) {
+    @SuppressWarnings("unchecked")
+	public boolean isMyType(Document document) {
         boolean ok = false;
 
         Element rssRoot = document.getRootElement();
         Namespace defaultNS = rssRoot.getNamespace();
-        List additionalNSs = rssRoot.getAdditionalNamespaces();
+        List<Namespace> additionalNSs = rssRoot.getAdditionalNamespaces();
 
         ok = defaultNS!=null && defaultNS.equals(getRDFNamespace());
         if (ok) {
Index: src/java/com/sun/syndication/io/impl/ModuleParsers.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/ModuleParsers.java,v
retrieving revision 1.5
diff -u -r1.5 ModuleParsers.java
--- src/java/com/sun/syndication/io/impl/ModuleParsers.java	4 Oct 2006 15:13:20 -0000	1.5
+++ src/java/com/sun/syndication/io/impl/ModuleParsers.java	30 Sep 2009 06:30:44 -0000
@@ -16,61 +16,64 @@
  */
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.feed.module.Module;
-import com.sun.syndication.io.ModuleParser;
-import com.sun.syndication.io.WireFeedParser;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.jdom.Element;
 import org.jdom.Namespace;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleParser;
+import com.sun.syndication.io.WireFeedParser;
 
 /**
  */
 public class ModuleParsers extends PluginManager {
-    public ModuleParsers(String propertyKey, WireFeedParser parentParser) {
-        super(propertyKey, parentParser, null);
-    }
-
-    public String getKey(Object obj) {
-        return ((ModuleParser)obj).getNamespaceUri();
-    }
-
-    public List getModuleNamespaces() {
-        return getKeys();
-    }
-
-    public List parseModules(Element root) {
-        List parsers = getPlugins();
-        List modules = null;
-        for (int i=0;i<parsers.size();i++) {
-            ModuleParser parser = (ModuleParser) parsers.get(i);
-            String namespaceUri = parser.getNamespaceUri();
-            Namespace namespace = Namespace.getNamespace(namespaceUri);
-            if (hasElementsFrom(root, namespace)) {
-                Module module = parser.parse(root);
-                if (module != null) {
-                    if (modules == null) {
-                        modules = new ArrayList();
-                    }
-                    modules.add(module);
-                }
-            }
-        }
-        return modules;
-    }
-
-    private boolean hasElementsFrom(Element root, Namespace namespace) {
-        boolean hasElements = false;
-//        boolean hasElements = namespace.equals(root.getNamespace());
-
-        if (!hasElements) {
-            List children = root.getChildren();
-            for (int i=0;!hasElements && i < children.size();i++) {
-                Element child = (Element) children.get(i);
-                hasElements = namespace.equals(child.getNamespace());
-            }
-        }
-        return hasElements;
-    }
+
+	public ModuleParsers(String propertyKey, WireFeedParser parentParser) {
+		super(propertyKey, parentParser, null);
+	}
+
+	public String getKey(Object obj) {
+		return ((ModuleParser) obj).getNamespaceUri();
+	}
+
+	public List<String> getModuleNamespaces() {
+		return getKeys();
+	}
+
+	public List<Module> parseModules(Element root) {
+		List<Object> parsers = getPlugins();
+		List<Module> modules = null;
+		for (int i = 0; i < parsers.size(); i++) {
+			ModuleParser parser = (ModuleParser) parsers.get(i);
+			String namespaceUri = parser.getNamespaceUri();
+			Namespace namespace = Namespace.getNamespace(namespaceUri);
+			if (hasElementsFrom(root, namespace)) {
+				Module module = parser.parse(root);
+				if (module != null) {
+					if (modules == null) {
+						modules = new ArrayList<Module>();
+					}
+					modules.add(module);
+				}
+			}
+		}
+		return modules;
+	}
+
+	@SuppressWarnings("unchecked")
+	private boolean hasElementsFrom(Element root, Namespace namespace) {
+		boolean hasElements = false;
+		// boolean hasElements = namespace.equals(root.getNamespace());
+
+		if (!hasElements) {
+			List<Element> children = root.getChildren();
+			for (int i = 0; !hasElements && i < children.size(); i++) {
+				Element child = children.get(i);
+				hasElements = namespace.equals(child.getNamespace());
+			}
+		}
+		return hasElements;
+	}
 }
Index: src/java/com/sun/syndication/io/impl/RSS10Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS10Generator.java,v
retrieving revision 1.13
diff -u -r1.13 RSS10Generator.java
--- src/java/com/sun/syndication/io/impl/RSS10Generator.java	1 Apr 2008 18:01:21 -0000	1.13
+++ src/java/com/sun/syndication/io/impl/RSS10Generator.java	30 Sep 2009 06:30:45 -0000
@@ -55,12 +55,12 @@
         if (channel.getUri() != null) {
             eChannel.setAttribute("about", channel.getUri(), getRDFNamespace());
         }
-        List items = channel.getItems();
+        List<Item> items = channel.getItems();
         if (items.size()>0) {
             Element eItems = new Element("items",getFeedNamespace());
             Element eSeq = new Element("Seq",getRDFNamespace());
             for (int i=0;i<items.size();i++) {
-                Item item = (Item) items.get(i);
+                Item item = items.get(i);
                 Element eLi = new Element("li",getRDFNamespace());
                 String uri = item.getUri();
                 if (uri!=null) {
Index: src/java/com/sun/syndication/io/impl/Atom03Parser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/Atom03Parser.java,v
retrieving revision 1.19
diff -u -r1.19 Atom03Parser.java
--- src/java/com/sun/syndication/io/impl/Atom03Parser.java	1 Apr 2008 17:37:41 -0000	1.19
+++ src/java/com/sun/syndication/io/impl/Atom03Parser.java	30 Sep 2009 06:30:43 -0000
@@ -29,313 +29,316 @@
 /**
  */
 public class Atom03Parser extends BaseWireFeedParser {
-    private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
-    private static final Namespace ATOM_03_NS = Namespace.getNamespace(ATOM_03_URI);
 
-    public Atom03Parser() {
-        this("atom_0.3", ATOM_03_NS);
-    }
-
-    protected Atom03Parser(String type, Namespace ns) {
-        super(type, ns);
-    }
-
-    protected Namespace getAtomNamespace() {
-        return ATOM_03_NS;
-    }
-
-    public boolean isMyType(Document document) {
-        Element rssRoot = document.getRootElement();
-        Namespace defaultNS = rssRoot.getNamespace();
-        return (defaultNS!=null) && defaultNS.equals(getAtomNamespace());
-    }
-
-    public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException {
-        if (validate) {
-            validateFeed(document);
-        }
-        Element rssRoot = document.getRootElement();
-        return parseFeed(rssRoot);
-    }
-
-    protected void validateFeed(Document document) throws FeedException {
-        // TBD
-        // here we have to validate the Feed against a schema or whatever
-        // not sure how to do it
-        // one posibility would be to produce an ouput and attempt to parse it again
-        // with validation turned on.
-        // otherwise will have to check the document elements by hand.
-    }
-
-    protected WireFeed parseFeed(Element eFeed) {
-
-        com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
-
-        Element e = eFeed.getChild("title",getAtomNamespace());
-        if (e!=null) {
-            feed.setTitleEx(parseContent(e));
-        }
-
-        List eList = eFeed.getChildren("link",getAtomNamespace());
-        feed.setAlternateLinks(parseAlternateLinks(eList));
-        feed.setOtherLinks(parseOtherLinks(eList));
-
-        e = eFeed.getChild("author",getAtomNamespace());
-        if (e!=null) {
-            List authors = new ArrayList();
-            authors.add(parsePerson(e));
-            feed.setAuthors(authors);
-        }
-
-        eList = eFeed.getChildren("contributor",getAtomNamespace());
-        if (eList.size()>0) {
-            feed.setContributors(parsePersons(eList));
-        }
-
-        e = eFeed.getChild("tagline",getAtomNamespace());
-        if (e!=null) {
-            feed.setTagline(parseContent(e));
-        }
-
-        e = eFeed.getChild("id",getAtomNamespace());
-        if (e!=null) {
-            feed.setId(e.getText());
-        }
-
-        e = eFeed.getChild("generator",getAtomNamespace());
-        if (e!=null) {
-            Generator gen = new Generator();
-            gen.setValue(e.getText());
-            String att = getAttributeValue(e, "url");
-            if (att!=null) {
-                gen.setUrl(att);
-            }
-            att = getAttributeValue(e, "version");
-            if (att!=null) {
-                gen.setVersion(att);
-            }
-            feed.setGenerator(gen);
-        }
-
-        e = eFeed.getChild("copyright",getAtomNamespace());
-        if (e!=null) {
-            feed.setCopyright(e.getText());
-        }
-
-        e = eFeed.getChild("info",getAtomNamespace());
-        if (e!=null) {
-            feed.setInfo(parseContent(e));
-        }
-
-        e = eFeed.getChild("modified",getAtomNamespace());
-        if (e!=null) {
-            feed.setModified(DateParser.parseDate(e.getText()));
-        }
-
-        feed.setModules(parseFeedModules(eFeed));
-        
-        eList = eFeed.getChildren("entry",getAtomNamespace());
-        if (eList.size()>0) {
-            feed.setEntries(parseEntries(eList));
-        }
-
-        List foreignMarkup = 
-            extractForeignMarkup(eFeed, feed, getAtomNamespace());
-        if (foreignMarkup.size() > 0) {
-            feed.setForeignMarkup(foreignMarkup);
-        } 
-        return feed;
-    }
-
-    private Link parseLink(Element eLink) {
-        Link link = new Link();
-        String att = getAttributeValue(eLink, "rel");
-        if (att!=null) {
-            link.setRel(att);
-        }
-        att = getAttributeValue(eLink, "type");
-        if (att!=null) {
-            link.setType(att);
-        }
-        att = getAttributeValue(eLink, "href");
-        if (att!=null) {
-            link.setHref(att);
-        }
-        return link;
-    }
-
-    // List(Elements) -> List(Link)
-    private List parseLinks(List eLinks,boolean alternate) {
-        List links = new ArrayList();
-        for (int i=0;i<eLinks.size();i++) {
-            Element eLink = (Element) eLinks.get(i);
-            String rel = getAttributeValue(eLink, "rel");
-            if (alternate) {
-                if ("alternate".equals(rel)) {
-                    links.add(parseLink(eLink));
-                }
-            }
-            else {
-                if (!("alternate".equals(rel))) {
-                    links.add(parseLink(eLink));
-                }
-            }
-        }
-        return (links.size()>0) ? links : null;
-    }
-
-    // List(Elements) -> List(Link)
-    private List parseAlternateLinks(List eLinks) {
-        return parseLinks(eLinks,true);
-    }
-
-    // List(Elements) -> List(Link)
-    private List parseOtherLinks(List eLinks) {
-        return parseLinks(eLinks,false);
-    }
-
-    private Person parsePerson(Element ePerson) {
-        Person person = new Person();
-        Element e = ePerson.getChild("name",getAtomNamespace());
-        if (e!=null) {
-            person.setName(e.getText());
-        }
-        e = ePerson.getChild("url",getAtomNamespace());
-        if (e!=null) {
-            person.setUrl(e.getText());
-        }
-        e = ePerson.getChild("email",getAtomNamespace());
-        if (e!=null) {
-            person.setEmail(e.getText());
-        }
-        return person;
-    }
-
-    // List(Elements) -> List(Persons)
-    private List parsePersons(List ePersons) {
-        List persons = new ArrayList();
-        for (int i=0;i<ePersons.size();i++) {
-            persons.add(parsePerson((Element)ePersons.get(i)));
-        }
-        return (persons.size()>0) ? persons : null;
-    }
-
-    private Content parseContent(Element e) {
-        String value = null;
-        String type = getAttributeValue(e, "type");
-        type = (type!=null) ? type : "text/plain";
-        String mode = getAttributeValue(e, "mode");
-        if (mode == null) {
-            mode = Content.XML; // default to xml content
-        }
-        if (mode.equals(Content.ESCAPED)) {
-            // do nothing XML Parser took care of this
-            value = e.getText();
-        }
-        else
-        if (mode.equals(Content.BASE64)) {
-                value = Base64.decode(e.getText());
-        }
-        else
-        if (mode.equals(Content.XML)) {
-            XMLOutputter outputter = new XMLOutputter();
-            List eContent = e.getContent();
-            Iterator i = eContent.iterator();
-            while (i.hasNext()) {
-                org.jdom.Content c = (org.jdom.Content) i.next();
-                if (c instanceof Element) {
-                    Element eC = (Element) c;
-                    if (eC.getNamespace().equals(getAtomNamespace())) {
-                        ((Element)c).setNamespace(Namespace.NO_NAMESPACE);
-                    }
-                }
-            }
-            value = outputter.outputString(eContent);
-        }
-
-        Content content = new Content();
-        content.setType(type);
-        content.setMode(mode);
-        content.setValue(value);
-        return content;
-    }
-
-    // List(Elements) -> List(Entries)
-    private List parseEntries(List eEntries) {
-        List entries = new ArrayList();
-        for (int i=0;i<eEntries.size();i++) {
-            entries.add(parseEntry((Element)eEntries.get(i)));
-        }
-        return (entries.size()>0) ? entries : null;
-    }
-
-    private Entry parseEntry(Element eEntry) {
-        Entry entry = new Entry();
-
-        Element e = eEntry.getChild("title",getAtomNamespace());
-        if (e!=null) {
-            entry.setTitleEx(parseContent(e));
-        }
-
-        List eList = eEntry.getChildren("link",getAtomNamespace());
-        entry.setAlternateLinks(parseAlternateLinks(eList));
-        entry.setOtherLinks(parseOtherLinks(eList));
-
-        e = eEntry.getChild("author",getAtomNamespace());
-        if (e!=null) {
-            List authors = new ArrayList();
-            authors.add(parsePerson(e));
-            entry.setAuthors(authors);
-        }
-
-        eList = eEntry.getChildren("contributor",getAtomNamespace());
-        if (eList.size()>0) {
-            entry.setContributors(parsePersons(eList));
-        }
-
-        e = eEntry.getChild("id",getAtomNamespace());
-        if (e!=null) {
-            entry.setId(e.getText());
-        }
-
-        e = eEntry.getChild("modified",getAtomNamespace());
-        if (e!=null) {
-            entry.setModified(DateParser.parseDate(e.getText()));
-        }
-
-        e = eEntry.getChild("issued",getAtomNamespace());
-        if (e!=null) {
-            entry.setIssued(DateParser.parseDate(e.getText()));
-        }
-
-        e = eEntry.getChild("created",getAtomNamespace());
-        if (e!=null) {
-            entry.setCreated(DateParser.parseDate(e.getText()));
-        }
-
-        e = eEntry.getChild("summary",getAtomNamespace());
-        if (e!=null) {
-            entry.setSummary(parseContent(e));
-        }
-
-        eList = eEntry.getChildren("content",getAtomNamespace());
-        if (eList.size()>0) {
-            List content = new ArrayList();
-            for (int i=0;i<eList.size();i++) {
-                content.add(parseContent((Element)eList.get(i)));
-            }
-            entry.setContents(content);
-        }
-
-        entry.setModules(parseItemModules(eEntry));
-
-        List foreignMarkup = 
-            extractForeignMarkup(eEntry, entry, getAtomNamespace());
-        if (foreignMarkup.size() > 0) {
-            entry.setForeignMarkup(foreignMarkup);
-        } 
-        return entry;
-    }
+	private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
 
+	private static final Namespace ATOM_03_NS = Namespace
+			.getNamespace(ATOM_03_URI);
+
+	public Atom03Parser() {
+		this("atom_0.3", ATOM_03_NS);
+	}
+
+	protected Atom03Parser(String type, Namespace ns) {
+		super(type, ns);
+	}
+
+	protected Namespace getAtomNamespace() {
+		return ATOM_03_NS;
+	}
+
+	public boolean isMyType(Document document) {
+		Element rssRoot = document.getRootElement();
+		Namespace defaultNS = rssRoot.getNamespace();
+		return (defaultNS != null) && defaultNS.equals(getAtomNamespace());
+	}
+
+	public WireFeed parse(Document document, boolean validate)
+			throws IllegalArgumentException, FeedException {
+		if (validate) {
+			validateFeed(document);
+		}
+		Element rssRoot = document.getRootElement();
+		return parseFeed(rssRoot);
+	}
+
+	protected void validateFeed(Document document) throws FeedException {
+		// TBD
+		// here we have to validate the Feed against a schema or whatever
+		// not sure how to do it
+		// one posibility would be to produce an ouput and attempt to parse it
+		// again
+		// with validation turned on.
+		// otherwise will have to check the document elements by hand.
+	}
+
+	@SuppressWarnings("unchecked")
+	protected WireFeed parseFeed(Element eFeed) {
+
+		com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(
+				getType());
+
+		Element e = eFeed.getChild("title", getAtomNamespace());
+		if (e != null) {
+			feed.setTitleEx(parseContent(e));
+		}
+
+		List<Element> eList = eFeed.getChildren("link", getAtomNamespace());
+		feed.setAlternateLinks(parseAlternateLinks(eList));
+		feed.setOtherLinks(parseOtherLinks(eList));
+
+		e = eFeed.getChild("author", getAtomNamespace());
+		if (e != null) {
+			List<Person> authors = new ArrayList<Person>();
+			authors.add(parsePerson(e));
+			feed.setAuthors(authors);
+		}
+
+		eList = eFeed.getChildren("contributor", getAtomNamespace());
+		if (eList.size() > 0) {
+			feed.setContributors(parsePersons(eList));
+		}
+
+		e = eFeed.getChild("tagline", getAtomNamespace());
+		if (e != null) {
+			feed.setTagline(parseContent(e));
+		}
+
+		e = eFeed.getChild("id", getAtomNamespace());
+		if (e != null) {
+			feed.setId(e.getText());
+		}
+
+		e = eFeed.getChild("generator", getAtomNamespace());
+		if (e != null) {
+			Generator gen = new Generator();
+			gen.setValue(e.getText());
+			String att = getAttributeValue(e, "url");
+			if (att != null) {
+				gen.setUrl(att);
+			}
+			att = getAttributeValue(e, "version");
+			if (att != null) {
+				gen.setVersion(att);
+			}
+			feed.setGenerator(gen);
+		}
+
+		e = eFeed.getChild("copyright", getAtomNamespace());
+		if (e != null) {
+			feed.setCopyright(e.getText());
+		}
+
+		e = eFeed.getChild("info", getAtomNamespace());
+		if (e != null) {
+			feed.setInfo(parseContent(e));
+		}
+
+		e = eFeed.getChild("modified", getAtomNamespace());
+		if (e != null) {
+			feed.setModified(DateParser.parseDate(e.getText()));
+		}
+
+		feed.setModules(parseFeedModules(eFeed));
+
+		eList = eFeed.getChildren("entry", getAtomNamespace());
+		if (eList.size() > 0) {
+			feed.setEntries(parseEntries(eList));
+		}
+
+		List<Object> foreignMarkup = extractForeignMarkup(eFeed, feed,
+				getAtomNamespace());
+		if (foreignMarkup.size() > 0) {
+			feed.setForeignMarkup(foreignMarkup);
+		}
+		return feed;
+	}
+
+	private Link parseLink(Element eLink) {
+		Link link = new Link();
+		String att = getAttributeValue(eLink, "rel");
+		if (att != null) {
+			link.setRel(att);
+		}
+		att = getAttributeValue(eLink, "type");
+		if (att != null) {
+			link.setType(att);
+		}
+		att = getAttributeValue(eLink, "href");
+		if (att != null) {
+			link.setHref(att);
+		}
+		return link;
+	}
+
+	// List(Elements) -> List(Link)
+	private List<Link> parseLinks(List<Element> eLinks, boolean alternate) {
+		List<Link> links = new ArrayList<Link>();
+		for (int i = 0; i < eLinks.size(); i++) {
+			Element eLink = (Element) eLinks.get(i);
+			String rel = getAttributeValue(eLink, "rel");
+			if (alternate) {
+				if ("alternate".equals(rel)) {
+					links.add(parseLink(eLink));
+				}
+			} else {
+				if (!("alternate".equals(rel))) {
+					links.add(parseLink(eLink));
+				}
+			}
+		}
+		return (links.size() > 0) ? links : null;
+	}
+
+	// List(Elements) -> List(Link)
+	private List<Link> parseAlternateLinks(List<Element> eLinks) {
+		return parseLinks(eLinks, true);
+	}
+
+	// List(Elements) -> List(Link)
+	private List<Link> parseOtherLinks(List<Element> eLinks) {
+		return parseLinks(eLinks, false);
+	}
+
+	private Person parsePerson(Element ePerson) {
+		Person person = new Person();
+		Element e = ePerson.getChild("name", getAtomNamespace());
+		if (e != null) {
+			person.setName(e.getText());
+		}
+		e = ePerson.getChild("url", getAtomNamespace());
+		if (e != null) {
+			person.setUrl(e.getText());
+		}
+		e = ePerson.getChild("email", getAtomNamespace());
+		if (e != null) {
+			person.setEmail(e.getText());
+		}
+		return person;
+	}
+
+	// List(Elements) -> List(Persons)
+	private List<Person> parsePersons(List<Element> ePersons) {
+		List<Person> persons = new ArrayList<Person>();
+		for (int i = 0; i < ePersons.size(); i++) {
+			persons.add(parsePerson(ePersons.get(i)));
+		}
+		return (persons.size() > 0) ? persons : null;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Content parseContent(Element e) {
+		String value = null;
+		String type = getAttributeValue(e, "type");
+		type = (type != null) ? type : "text/plain";
+		String mode = getAttributeValue(e, "mode");
+		if (mode == null) {
+			mode = Content.XML; // default to xml content
+		}
+		if (mode.equals(Content.ESCAPED)) {
+			// do nothing XML Parser took care of this
+			value = e.getText();
+		} else if (mode.equals(Content.BASE64)) {
+			value = Base64.decode(e.getText());
+		} else if (mode.equals(Content.XML)) {
+			XMLOutputter outputter = new XMLOutputter();
+			List eContent = e.getContent();
+			Iterator i = eContent.iterator();
+			while (i.hasNext()) {
+				org.jdom.Content c = (org.jdom.Content) i.next();
+				if (c instanceof Element) {
+					Element eC = (Element) c;
+					if (eC.getNamespace().equals(getAtomNamespace())) {
+						((Element) c).setNamespace(Namespace.NO_NAMESPACE);
+					}
+				}
+			}
+			value = outputter.outputString(eContent);
+		}
+
+		Content content = new Content();
+		content.setType(type);
+		content.setMode(mode);
+		content.setValue(value);
+		return content;
+	}
+
+	// List(Elements) -> List(Entries)
+	private List<Entry> parseEntries(List<Element> eEntries) {
+		List<Entry> entries = new ArrayList<Entry>();
+		for (int i = 0; i < eEntries.size(); i++) {
+			entries.add(parseEntry(eEntries.get(i)));
+		}
+		return (entries.size() > 0) ? entries : null;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Entry parseEntry(Element eEntry) {
+		Entry entry = new Entry();
+
+		Element e = eEntry.getChild("title", getAtomNamespace());
+		if (e != null) {
+			entry.setTitleEx(parseContent(e));
+		}
+
+		List<Element> eList = eEntry.getChildren("link", getAtomNamespace());
+		entry.setAlternateLinks(parseAlternateLinks(eList));
+		entry.setOtherLinks(parseOtherLinks(eList));
+
+		e = eEntry.getChild("author", getAtomNamespace());
+		if (e != null) {
+			List<Person> authors = new ArrayList<Person>();
+			authors.add(parsePerson(e));
+			entry.setAuthors(authors);
+		}
+
+		eList = eEntry.getChildren("contributor", getAtomNamespace());
+		if (eList.size() > 0) {
+			entry.setContributors(parsePersons(eList));
+		}
+
+		e = eEntry.getChild("id", getAtomNamespace());
+		if (e != null) {
+			entry.setId(e.getText());
+		}
+
+		e = eEntry.getChild("modified", getAtomNamespace());
+		if (e != null) {
+			entry.setModified(DateParser.parseDate(e.getText()));
+		}
+
+		e = eEntry.getChild("issued", getAtomNamespace());
+		if (e != null) {
+			entry.setIssued(DateParser.parseDate(e.getText()));
+		}
+
+		e = eEntry.getChild("created", getAtomNamespace());
+		if (e != null) {
+			entry.setCreated(DateParser.parseDate(e.getText()));
+		}
+
+		e = eEntry.getChild("summary", getAtomNamespace());
+		if (e != null) {
+			entry.setSummary(parseContent(e));
+		}
+
+		eList = eEntry.getChildren("content", getAtomNamespace());
+		if (eList.size() > 0) {
+			List<Content> content = new ArrayList<Content>();
+			for (int i = 0; i < eList.size(); i++) {
+				content.add(parseContent(eList.get(i)));
+			}
+			entry.setContents(content);
+		}
+
+		entry.setModules(parseItemModules(eEntry));
+
+		List<Object> foreignMarkup = extractForeignMarkup(eEntry, entry,
+				getAtomNamespace());
+		if (foreignMarkup.size() > 0) {
+			entry.setForeignMarkup(foreignMarkup);
+		}
+		return entry;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/RSS090Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS090Generator.java,v
retrieving revision 1.11
diff -u -r1.11 RSS090Generator.java
--- src/java/com/sun/syndication/io/impl/RSS090Generator.java	16 Jul 2008 14:34:56 -0000	1.11
+++ src/java/com/sun/syndication/io/impl/RSS090Generator.java	30 Sep 2009 06:30:44 -0000
@@ -25,247 +25,273 @@
 
 import java.util.List;
 
-
 /**
  * Feed Generator for RSS 0.90
  * <p/>
- *
+ * 
  * @author Elaine Chien
  */
 public class RSS090Generator extends BaseWireFeedGenerator {
 
-    private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
-    private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/";
-    private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
-
-    private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI);
-    private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
-    private static final Namespace CONTENT_NS = Namespace.getNamespace("content", CONTENT_URI);
-
-    public RSS090Generator() {
-        this("rss_0.9");
-    }
-
-    protected RSS090Generator(String type) {
-        super(type);
-    }
-
-    public Document generate(WireFeed feed) throws FeedException {
-        Channel channel = (Channel)feed;
-        Element root = createRootElement(channel);
-        populateFeed(channel,root);
-        purgeUnusedNamespaceDeclarations(root);
-        return createDocument(root);
-    }
-
-    protected Namespace getFeedNamespace() {
-        return RSS_NS;
-    }
-
-    protected Namespace getRDFNamespace() {
-        return RDF_NS;
-    }
-
-    protected Namespace getContentNamespace() {
-        return CONTENT_NS;
-    }
-
-    protected Document createDocument(Element root) {
-        return new Document(root);
-    }
-
-    protected Element createRootElement(Channel channel) {
-        Element root = new Element("RDF",getRDFNamespace());
-        root.addNamespaceDeclaration(getFeedNamespace());
-        root.addNamespaceDeclaration(getRDFNamespace());
-        root.addNamespaceDeclaration(getContentNamespace());
-        generateModuleNamespaceDefs(root);
-        return root;
-    }
-
-    protected void populateFeed(Channel channel, Element parent) throws FeedException  {
-        addChannel(channel,parent);
-        addImage(channel,parent);
-        addTextInput(channel,parent);
-        addItems(channel,parent);
-        generateForeignMarkup(parent, (List)channel.getForeignMarkup());
-    }
-
-    protected void addChannel(Channel channel,Element parent) throws FeedException {
-        Element eChannel = new Element("channel", getFeedNamespace());
-        populateChannel(channel,eChannel);
-        checkChannelConstraints(eChannel);
-        parent.addContent(eChannel);
-        generateFeedModules(channel.getModules(),eChannel);
-    }
-
-    /**
-     * Populates the given channel with parsed data from the ROME element that holds the
-     * channel data.
-     *
-     * @param channel the channel into which parsed data will be added.
-     * @param eChannel the XML element that holds the data for the channel.
-     */
-    protected void populateChannel(Channel channel,Element eChannel) {
-        String title = channel.getTitle();
-        if (title!=null) {
-            eChannel.addContent(generateSimpleElement("title",title));
-        }
-        String link = channel.getLink();
-        if (link!=null) {
-            eChannel.addContent(generateSimpleElement("link",link));
-        }
-        String description = channel.getDescription();
-        if (description!=null) {
-            eChannel.addContent(generateSimpleElement("description",description));
-        }
-    }
-
-    // maxLen == -1 means unlimited.
-    protected void checkNotNullAndLength(Element parent, String childName, int minLen, int maxLen) throws FeedException {
-        Element  child = parent.getChild(childName,getFeedNamespace());
-        if (child == null) {
-            throw new FeedException("Invalid "+getType()+" feed, missing "+parent.getName()+" "+childName);
-        }
-        checkLength(parent,childName,minLen,maxLen);
-    }
-
-    // maxLen == -1 means unlimited.
-    protected void checkLength(Element parent, String childName, int minLen, int maxLen) throws FeedException {
-        Element  child = parent.getChild(childName,getFeedNamespace());
-        if (child != null) {
-            if (minLen>0 && child.getText().length()<minLen) {
-                throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "short of "+minLen+" length");
-            }
-            if (maxLen>-1 && child.getText().length()>maxLen) {
-                throw new FeedException("Invalid "+getType()+" feed, "+parent.getName()+" "+childName + "exceeds "+maxLen+" length");
-            }
-        }
-    }
-
-
-    protected void addImage(Channel channel,Element parent) throws FeedException {
-        Image image = channel.getImage();
-        if (image!=null) {
-            Element eImage = new Element("image", getFeedNamespace());
-            populateImage(image,eImage);
-            checkImageConstraints(eImage);
-            parent.addContent(eImage);
-        }
-    }
-
-    protected void populateImage(Image image,Element eImage) {
-        String title = image.getTitle();
-        if (title!=null) {
-            eImage.addContent(generateSimpleElement("title",title));
-        }
-        String url = image.getUrl();
-        if (url!=null) {
-            eImage.addContent(generateSimpleElement("url",url));
-        }
-        String link = image.getLink();
-        if (link!=null) {
-            eImage.addContent(generateSimpleElement("link",link));
-        }
-    }
-
-    // Thxs DW for this one
-    protected String getTextInputLabel() {
-        return "textInput";
-    }
-
-    protected void addTextInput(Channel channel,Element parent) throws FeedException {
-        TextInput textInput = channel.getTextInput();
-        if (textInput!=null) {
-            Element eTextInput = new Element(getTextInputLabel(), getFeedNamespace());
-            populateTextInput(textInput,eTextInput);
-            checkTextInputConstraints(eTextInput);
-            parent.addContent(eTextInput);
-        }
-    }
-
-    protected void populateTextInput(TextInput textInput,Element eTextInput) {
-        String title = textInput.getTitle();
-        if (title!=null) {
-            eTextInput.addContent(generateSimpleElement("title",title));
-        }
-        String description = textInput.getDescription();
-        if (description!=null) {
-            eTextInput.addContent(generateSimpleElement("description",description));
-        }
-        String name = textInput.getName();
-        if (name!=null) {
-            eTextInput.addContent(generateSimpleElement("name",name));
-        }
-        String link = textInput.getLink();
-        if (link!=null) {
-            eTextInput.addContent(generateSimpleElement("link",link));
-        }
-    }
-
-    protected void addItems(Channel channel,Element parent) throws FeedException {
-        List items = channel.getItems();
-        for (int i=0;i<items.size();i++) {
-            addItem((Item)items.get(i),parent, i);
-        }
-        checkItemsConstraints(parent);
-    }
-
-    protected void addItem(Item item, Element parent, int index) throws FeedException {
-        Element eItem = new Element("item", getFeedNamespace());
-        populateItem(item,eItem, index);
-        checkItemConstraints(eItem);
-        generateItemModules(item.getModules(),eItem);
-        parent.addContent(eItem);
-    }
-
-    protected void populateItem(Item item, Element eItem, int index) {
-        String title = item.getTitle();
-        if (title!=null) {
-            eItem.addContent(generateSimpleElement("title",title));
-        }
-        String link = item.getLink();
-        if (link!=null) {
-            eItem.addContent(generateSimpleElement("link",link));
-        }
-        generateForeignMarkup(eItem, (List)item.getForeignMarkup());
-    }
-
-    protected Element generateSimpleElement(String name, String value) {
-        Element element = new Element(name, getFeedNamespace());
-        element.addContent(value);
-        return element;
-    }
-
-    protected void checkChannelConstraints(Element eChannel) throws FeedException {
-        checkNotNullAndLength(eChannel,"title", 0, 40);
-        checkNotNullAndLength(eChannel,"description", 0, 500);
-        checkNotNullAndLength(eChannel,"link", 0, 500);
-    }
-
-    protected void checkImageConstraints(Element eImage) throws FeedException {
-        checkNotNullAndLength(eImage,"title", 0, 40);
-        checkNotNullAndLength(eImage,"url", 0, 500);
-        checkNotNullAndLength(eImage,"link", 0, 500);
-    }
-
-    protected void checkTextInputConstraints(Element eTextInput) throws FeedException {
-        checkNotNullAndLength(eTextInput,"title", 0, 40);
-        checkNotNullAndLength(eTextInput,"description", 0, 100);
-        checkNotNullAndLength(eTextInput,"name", 0, 500);
-        checkNotNullAndLength(eTextInput,"link", 0, 500);
-    }
-
-    protected void checkItemsConstraints(Element parent) throws FeedException {
-        int count = parent.getChildren("item",getFeedNamespace()).size();
-        if (count<1 || count>15) {
-            throw new FeedException("Invalid "+getType()+" feed, item count is "+count+" it must be between 1 an 15");
-        }
-    }
-
-    protected void checkItemConstraints(Element eItem) throws FeedException {
-        checkNotNullAndLength(eItem,"title", 0, 100);
-        checkNotNullAndLength(eItem,"link", 0, 500);
-    }
+	private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+	private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/";
+
+	private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
+
+	private static final Namespace RDF_NS = Namespace.getNamespace("rdf",
+			RDF_URI);
+
+	private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
+
+	private static final Namespace CONTENT_NS = Namespace.getNamespace(
+			"content", CONTENT_URI);
+
+	public RSS090Generator() {
+		this("rss_0.9");
+	}
+
+	protected RSS090Generator(String type) {
+		super(type);
+	}
+
+	public Document generate(WireFeed feed) throws FeedException {
+		Channel channel = (Channel) feed;
+		Element root = createRootElement(channel);
+		populateFeed(channel, root);
+		purgeUnusedNamespaceDeclarations(root);
+		return createDocument(root);
+	}
+
+	protected Namespace getFeedNamespace() {
+		return RSS_NS;
+	}
+
+	protected Namespace getRDFNamespace() {
+		return RDF_NS;
+	}
+
+	protected Namespace getContentNamespace() {
+		return CONTENT_NS;
+	}
+
+	protected Document createDocument(Element root) {
+		return new Document(root);
+	}
+
+	protected Element createRootElement(Channel channel) {
+		Element root = new Element("RDF", getRDFNamespace());
+		root.addNamespaceDeclaration(getFeedNamespace());
+		root.addNamespaceDeclaration(getRDFNamespace());
+		root.addNamespaceDeclaration(getContentNamespace());
+		generateModuleNamespaceDefs(root);
+		return root;
+	}
+
+	protected void populateFeed(Channel channel, Element parent)
+			throws FeedException {
+		addChannel(channel, parent);
+		addImage(channel, parent);
+		addTextInput(channel, parent);
+		addItems(channel, parent);
+		generateForeignMarkup(parent, channel.getForeignMarkup());
+	}
+
+	protected void addChannel(Channel channel, Element parent)
+			throws FeedException {
+		Element eChannel = new Element("channel", getFeedNamespace());
+		populateChannel(channel, eChannel);
+		checkChannelConstraints(eChannel);
+		parent.addContent(eChannel);
+		generateFeedModules(channel.getModules(), eChannel);
+	}
+
+	/**
+	 * Populates the given channel with parsed data from the ROME element that
+	 * holds the channel data.
+	 * 
+	 * @param channel
+	 *            the channel into which parsed data will be added.
+	 * @param eChannel
+	 *            the XML element that holds the data for the channel.
+	 */
+	protected void populateChannel(Channel channel, Element eChannel) {
+		String title = channel.getTitle();
+		if (title != null) {
+			eChannel.addContent(generateSimpleElement("title", title));
+		}
+		String link = channel.getLink();
+		if (link != null) {
+			eChannel.addContent(generateSimpleElement("link", link));
+		}
+		String description = channel.getDescription();
+		if (description != null) {
+			eChannel.addContent(generateSimpleElement("description",
+					description));
+		}
+	}
+
+	// maxLen == -1 means unlimited.
+	protected void checkNotNullAndLength(Element parent, String childName,
+			int minLen, int maxLen) throws FeedException {
+		Element child = parent.getChild(childName, getFeedNamespace());
+		if (child == null) {
+			throw new FeedException("Invalid " + getType() + " feed, missing "
+					+ parent.getName() + " " + childName);
+		}
+		checkLength(parent, childName, minLen, maxLen);
+	}
+
+	// maxLen == -1 means unlimited.
+	protected void checkLength(Element parent, String childName, int minLen,
+			int maxLen) throws FeedException {
+		Element child = parent.getChild(childName, getFeedNamespace());
+		if (child != null) {
+			if (minLen > 0 && child.getText().length() < minLen) {
+				throw new FeedException("Invalid " + getType() + " feed, "
+						+ parent.getName() + " " + childName + "short of "
+						+ minLen + " length");
+			}
+			if (maxLen > -1 && child.getText().length() > maxLen) {
+				throw new FeedException("Invalid " + getType() + " feed, "
+						+ parent.getName() + " " + childName + "exceeds "
+						+ maxLen + " length");
+			}
+		}
+	}
+
+	protected void addImage(Channel channel, Element parent)
+			throws FeedException {
+		Image image = channel.getImage();
+		if (image != null) {
+			Element eImage = new Element("image", getFeedNamespace());
+			populateImage(image, eImage);
+			checkImageConstraints(eImage);
+			parent.addContent(eImage);
+		}
+	}
+
+	protected void populateImage(Image image, Element eImage) {
+		String title = image.getTitle();
+		if (title != null) {
+			eImage.addContent(generateSimpleElement("title", title));
+		}
+		String url = image.getUrl();
+		if (url != null) {
+			eImage.addContent(generateSimpleElement("url", url));
+		}
+		String link = image.getLink();
+		if (link != null) {
+			eImage.addContent(generateSimpleElement("link", link));
+		}
+	}
+
+	// Thxs DW for this one
+	protected String getTextInputLabel() {
+		return "textInput";
+	}
+
+	protected void addTextInput(Channel channel, Element parent)
+			throws FeedException {
+		TextInput textInput = channel.getTextInput();
+		if (textInput != null) {
+			Element eTextInput = new Element(getTextInputLabel(),
+					getFeedNamespace());
+			populateTextInput(textInput, eTextInput);
+			checkTextInputConstraints(eTextInput);
+			parent.addContent(eTextInput);
+		}
+	}
+
+	protected void populateTextInput(TextInput textInput, Element eTextInput) {
+		String title = textInput.getTitle();
+		if (title != null) {
+			eTextInput.addContent(generateSimpleElement("title", title));
+		}
+		String description = textInput.getDescription();
+		if (description != null) {
+			eTextInput.addContent(generateSimpleElement("description",
+					description));
+		}
+		String name = textInput.getName();
+		if (name != null) {
+			eTextInput.addContent(generateSimpleElement("name", name));
+		}
+		String link = textInput.getLink();
+		if (link != null) {
+			eTextInput.addContent(generateSimpleElement("link", link));
+		}
+	}
+
+	protected void addItems(Channel channel, Element parent)
+			throws FeedException {
+		List<Item> items = channel.getItems();
+		for (int i = 0; i < items.size(); i++) {
+			addItem(items.get(i), parent, i);
+		}
+		checkItemsConstraints(parent);
+	}
+
+	protected void addItem(Item item, Element parent, int index)
+			throws FeedException {
+		Element eItem = new Element("item", getFeedNamespace());
+		populateItem(item, eItem, index);
+		checkItemConstraints(eItem);
+		generateItemModules(item.getModules(), eItem);
+		parent.addContent(eItem);
+	}
+
+	protected void populateItem(Item item, Element eItem, int index) {
+		String title = item.getTitle();
+		if (title != null) {
+			eItem.addContent(generateSimpleElement("title", title));
+		}
+		String link = item.getLink();
+		if (link != null) {
+			eItem.addContent(generateSimpleElement("link", link));
+		}
+		generateForeignMarkup(eItem, item.getForeignMarkup());
+	}
+
+	protected Element generateSimpleElement(String name, String value) {
+		Element element = new Element(name, getFeedNamespace());
+		element.addContent(value);
+		return element;
+	}
+
+	protected void checkChannelConstraints(Element eChannel)
+			throws FeedException {
+		checkNotNullAndLength(eChannel, "title", 0, 40);
+		checkNotNullAndLength(eChannel, "description", 0, 500);
+		checkNotNullAndLength(eChannel, "link", 0, 500);
+	}
+
+	protected void checkImageConstraints(Element eImage) throws FeedException {
+		checkNotNullAndLength(eImage, "title", 0, 40);
+		checkNotNullAndLength(eImage, "url", 0, 500);
+		checkNotNullAndLength(eImage, "link", 0, 500);
+	}
+
+	protected void checkTextInputConstraints(Element eTextInput)
+			throws FeedException {
+		checkNotNullAndLength(eTextInput, "title", 0, 40);
+		checkNotNullAndLength(eTextInput, "description", 0, 100);
+		checkNotNullAndLength(eTextInput, "name", 0, 500);
+		checkNotNullAndLength(eTextInput, "link", 0, 500);
+	}
+
+	protected void checkItemsConstraints(Element parent) throws FeedException {
+		int count = parent.getChildren("item", getFeedNamespace()).size();
+		if (count < 1 || count > 15) {
+			throw new FeedException("Invalid " + getType()
+					+ " feed, item count is " + count
+					+ " it must be between 1 an 15");
+		}
+	}
+
+	protected void checkItemConstraints(Element eItem) throws FeedException {
+		checkNotNullAndLength(eItem, "title", 0, 100);
+		checkNotNullAndLength(eItem, "link", 0, 500);
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/FeedParsers.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/FeedParsers.java,v
retrieving revision 1.3
diff -u -r1.3 FeedParsers.java
--- src/java/com/sun/syndication/io/impl/FeedParsers.java	18 Jun 2004 07:59:56 -0000	1.3
+++ src/java/com/sun/syndication/io/impl/FeedParsers.java	30 Sep 2009 06:30:44 -0000
@@ -16,10 +16,12 @@
  */
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.io.WireFeedParser;
-import org.jdom.Document;
 import java.util.List;
 
+import org.jdom.Document;
+
+import com.sun.syndication.io.WireFeedParser;
+
 /**
  * Parses an XML document (JDOM Document) into a Feed.
  * <p>
@@ -30,54 +32,59 @@
  * <p>
  * WireFeedParser instances are thread safe.
  * <p>
- * Parsers for a specific type must extend this class and register in the parser list.
- * (Right now registration is hardcoded in the WireFeedParser constructor).
+ * Parsers for a specific type must extend this class and register in the parser
+ * list. (Right now registration is hardcoded in the WireFeedParser
+ * constructor).
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
 public class FeedParsers extends PluginManager {
 
-    /**
-     * WireFeedParser.classes=  [className] ...
-     *
-     */
-    public static final String FEED_PARSERS_KEY = "WireFeedParser.classes";
-
-    /**
-     * Creates a parser instance.
-     * <p>
-     *
-     */
-    public FeedParsers() {
-        super(FEED_PARSERS_KEY);
-    }
-
-    public List getSupportedFeedTypes() {
-        return getKeys();
-    }
-
-    /**
-     * Finds the real parser type for the given document feed.
-     * <p>
-     * @param document document feed to find the parser for.
-     * @return the parser for the given document or <b>null</b> if there is no parser for that document.
-     *
-     */
-    public WireFeedParser getParserFor(Document document) {
-        List parsers = getPlugins();
-        WireFeedParser parser = null;
-        for (int i=0;parser==null && i<parsers.size();i++) {
-            parser = (WireFeedParser) parsers.get(i);
-            if (!parser.isMyType(document)) {
-                parser = null;
-            }
-        }
-        return parser;
-    }
-
-    protected String getKey(Object obj) {
-        return ((WireFeedParser)obj).getType();
-    }
+	/**
+	 * WireFeedParser.classes= [className] ...
+	 * 
+	 */
+	public static final String FEED_PARSERS_KEY = "WireFeedParser.classes";
+
+	/**
+	 * Creates a parser instance.
+	 * <p>
+	 * 
+	 */
+	public FeedParsers() {
+		super(FEED_PARSERS_KEY);
+	}
+
+	public List<String> getSupportedFeedTypes() {
+		return getKeys();
+	}
+
+	/**
+	 * Finds the real parser type for the given document feed.
+	 * <p>
+	 * 
+	 * @param document
+	 *            document feed to find the parser for.
+	 * @return the parser for the given document or <b>null</b> if there is no
+	 *         parser for that document.
+	 * 
+	 */
+	public WireFeedParser getParserFor(Document document) {
+		List<Object> parsers = getPlugins();
+		WireFeedParser parser = null;
+		for (int i = 0; parser == null && i < parsers.size(); i++) {
+			parser = (WireFeedParser) parsers.get(i);
+			if (parser.isMyType(document) == false) {
+				parser = null;
+			}
+		}
+		return parser;
+	}
+
+	protected String getKey(Object obj) {
+		return ((WireFeedParser) obj).getType();
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/FeedGenerators.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/FeedGenerators.java,v
retrieving revision 1.3
diff -u -r1.3 FeedGenerators.java
--- src/java/com/sun/syndication/io/impl/FeedGenerators.java	18 Jun 2004 07:59:55 -0000	1.3
+++ src/java/com/sun/syndication/io/impl/FeedGenerators.java	30 Sep 2009 06:30:44 -0000
@@ -16,47 +16,48 @@
  */
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.io.WireFeedGenerator;
-
 import java.util.List;
 
+import com.sun.syndication.io.WireFeedGenerator;
+
 /**
  * Generates an XML document (JDOM Document) out of a Feed.
  * <p>
- * It can generate all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and 2.0) and
- * Atom 0.3 feed.
+ * It can generate all flavors of RSS (0.90, 0.91, 0.92, 0.93, 0.94, 1.0 and
+ * 2.0) and Atom 0.3 feed.
  * <p>
  * WireFeedGenerator instances are thread safe.
  * <p>
- * Generators for a specific type must extend this class and register in the generator list.
- * (Right now registration is hardcoded in the WireFeedGenerator constructor).
+ * Generators for a specific type must extend this class and register in the
+ * generator list. (Right now registration is hardcoded in the WireFeedGenerator
+ * constructor).
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
 public class FeedGenerators extends PluginManager {
 
-    /**
-     * WireFeedGenerator.classes=  [className] ...
-     *
-     */
-    public static final String FEED_GENERATORS_KEY = "WireFeedGenerator.classes";
-
-
-    public FeedGenerators() {
-        super(FEED_GENERATORS_KEY);
-    }
-
-    public WireFeedGenerator getGenerator(String feedType) {
-        return (WireFeedGenerator) getPlugin(feedType);
-    }
-
-    protected String getKey(Object obj) {
-        return ((WireFeedGenerator)obj).getType();
-    }
-
-    public List getSupportedFeedTypes() {
-        return getKeys();
-    }
+	/**
+	 * WireFeedGenerator.classes= [className] ...
+	 * 
+	 */
+	public static final String FEED_GENERATORS_KEY = "WireFeedGenerator.classes";
+
+	public FeedGenerators() {
+		super(FEED_GENERATORS_KEY);
+	}
+
+	public WireFeedGenerator getGenerator(String feedType) {
+		return (WireFeedGenerator) getPlugin(feedType);
+	}
+
+	protected String getKey(Object obj) {
+		return ((WireFeedGenerator) obj).getType();
+	}
+
+	public List<String> getSupportedFeedTypes() {
+		return getKeys();
+	}
 
 }
\ No newline at end of file
Index: src/java/com/sun/syndication/io/impl/SyModuleGenerator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/SyModuleGenerator.java,v
retrieving revision 1.6
diff -u -r1.6 SyModuleGenerator.java
--- src/java/com/sun/syndication/io/impl/SyModuleGenerator.java	3 Sep 2008 10:53:34 -0000	1.6
+++ src/java/com/sun/syndication/io/impl/SyModuleGenerator.java	30 Sep 2009 06:30:45 -0000
@@ -29,59 +29,65 @@
 /**
  * Feed Generator for SY ModuleImpl
  * <p/>
- *
+ * 
  * @author Elaine Chien
- *
+ * 
  */
 
 public class SyModuleGenerator implements ModuleGenerator {
 
-    private static final String SY_URI  = "http://purl.org/rss/1.0/modules/syndication/";
-    private static final Namespace SY_NS  = Namespace.getNamespace("sy", SY_URI);
+	private static final String SY_URI = "http://purl.org/rss/1.0/modules/syndication/";
 
-    private static final Set NAMESPACES;
+	private static final Namespace SY_NS = Namespace.getNamespace("sy", SY_URI);
 
-    static {
-        Set nss = new HashSet();
-        nss.add(SY_NS);
-        NAMESPACES = Collections.unmodifiableSet(nss);
-    }
-
-    public String getNamespaceUri() {
-        return SY_URI;
-    }
-
-    /**
-     * Returns a set with all the URIs (JDOM Namespace elements) this module generator uses.
-     * <p/>
-     * It is used by the the feed generators to add their namespace definition in
-     * the root element of the generated document (forward-missing of Java 5.0 Generics).
-     * <p/>
-     *
-     * @return a set with all the URIs (JDOM Namespace elements) this module generator uses.
-     */
-    public Set getNamespaces() {
-        return NAMESPACES;
-    }
-
-    public void generate(Module module, Element element) {
-
-        SyModule syModule = (SyModule)module;
-
-        if (syModule.getUpdatePeriod() != null) {
-            Element updatePeriodElement = new Element("updatePeriod", SY_NS);
-            updatePeriodElement.addContent(syModule.getUpdatePeriod());
-            element.addContent(updatePeriodElement);
-        }
-
-        Element updateFrequencyElement = new Element("updateFrequency", SY_NS);
-        updateFrequencyElement.addContent(String.valueOf(syModule.getUpdateFrequency()));
-        element.addContent(updateFrequencyElement);
-
-        if (syModule.getUpdateBase() != null) {
-            Element updateBaseElement = new Element("updateBase", SY_NS);
-            updateBaseElement.addContent(DateParser.formatW3CDateTime(syModule.getUpdateBase()));
-            element.addContent(updateBaseElement);
-        }
-    }
+	private static final Set<Namespace> NAMESPACES;
+
+	static {
+		Set<Namespace> nss = new HashSet<Namespace>();
+		nss.add(SY_NS);
+		NAMESPACES = Collections.unmodifiableSet(nss);
+	}
+
+	public String getNamespaceUri() {
+		return SY_URI;
+	}
+
+	/**
+	 * Returns a set with all the URIs (JDOM Namespace elements) this module
+	 * generator uses.
+	 * <p/>
+	 * It is used by the the feed generators to add their namespace definition
+	 * in the root element of the generated document (forward-missing of Java
+	 * 5.0 Generics).
+	 * <p/>
+	 * 
+	 * @return a set with all the URIs (JDOM Namespace elements) this module
+	 *         generator uses.
+	 */
+	public Set<Namespace> getNamespaces() {
+		return NAMESPACES;
+	}
+
+	public void generate(Module module, Element element) {
+
+		SyModule syModule = (SyModule) module;
+
+		if (syModule.getUpdatePeriod() != null) {
+			Element updatePeriodElement = new Element("updatePeriod", SY_NS);
+			updatePeriodElement.addContent(syModule.getUpdatePeriod());
+			element.addContent(updatePeriodElement);
+		}
+
+		Element updateFrequencyElement = new Element("updateFrequency", SY_NS);
+		updateFrequencyElement.addContent(String.valueOf(syModule
+				.getUpdateFrequency()));
+		element.addContent(updateFrequencyElement);
+
+		if (syModule.getUpdateBase() != null) {
+			Element updateBaseElement = new Element("updateBase", SY_NS);
+			updateBaseElement.addContent(DateParser.formatW3CDateTime(syModule
+					.getUpdateBase()));
+			element.addContent(updateBaseElement);
+		}
+	}
 }
Index: src/java/com/sun/syndication/io/impl/RSS094Parser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS094Parser.java,v
retrieving revision 1.6
diff -u -r1.6 RSS094Parser.java
--- src/java/com/sun/syndication/io/impl/RSS094Parser.java	19 Jul 2006 20:43:05 -0000	1.6
+++ src/java/com/sun/syndication/io/impl/RSS094Parser.java	30 Sep 2009 06:30:45 -0000
@@ -41,12 +41,14 @@
             return "0.94";
     }
 
-    protected WireFeed parseChannel(Element rssRoot)  {
-        Channel channel = (Channel) super.parseChannel(rssRoot);
-        Element eChannel = rssRoot.getChild("channel",getRSSNamespace());
-
-        List eCats = eChannel.getChildren("category",getRSSNamespace());
-        channel.setCategories(parseCategories(eCats));
+    @SuppressWarnings("unchecked")
+	protected WireFeed parseChannel(Element rssRoot)  {
+		Channel channel = (Channel) super.parseChannel(rssRoot);
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+
+		List<Element> eCats = eChannel.getChildren("category",
+				getRSSNamespace());
+		channel.setCategories(parseCategories(eCats));
 
         Element eTtl = eChannel.getChild("ttl",getRSSNamespace());
         if (eTtl!=null && eTtl.getText() != null ) {
Index: src/java/com/sun/syndication/io/impl/DateParser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/DateParser.java,v
retrieving revision 1.15
diff -u -r1.15 DateParser.java
--- src/java/com/sun/syndication/io/impl/DateParser.java	30 Jul 2008 08:33:53 -0000	1.15
+++ src/java/com/sun/syndication/io/impl/DateParser.java	30 Sep 2009 06:30:44 -0000
@@ -87,7 +87,8 @@
    * These are a lot more forgiving than what the Atom spec allows.  
    * The forms that are invalid according to the spec are indicated.
    */
-  private static final String[] masks = {
+  @SuppressWarnings("unused")
+private static final String[] masks = {
     "yyyy-MM-dd'T'HH:mm:ss.SSSz",
     "yyyy-MM-dd't'HH:mm:ss.SSSz",                         // invalid
     "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
Index: src/java/com/sun/syndication/io/impl/RSS093Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS093Generator.java,v
retrieving revision 1.5
diff -u -r1.5 RSS093Generator.java
--- src/java/com/sun/syndication/io/impl/RSS093Generator.java	9 Mar 2005 07:51:07 -0000	1.5
+++ src/java/com/sun/syndication/io/impl/RSS093Generator.java	30 Sep 2009 06:30:45 -0000
@@ -16,47 +16,49 @@
  */
 package com.sun.syndication.io.impl;
 
+import com.sun.syndication.feed.rss.Enclosure;
 import com.sun.syndication.feed.rss.Item;
 import org.jdom.Element;
 
 import java.util.Date;
 import java.util.List;
 
-
 /**
  * Feed Generator for RSS 0.93
  * <p/>
- *
+ * 
  * @author Elaine Chien
- *
+ * 
  */
 public class RSS093Generator extends RSS092Generator {
 
-    public RSS093Generator() {
-        this("rss_0.93","0.93");
-    }
-
-    protected RSS093Generator(String feedType,String version) {
-        super(feedType,version);
-    }
-
-    protected void populateItem(Item item, Element eItem, int index) {
-        super.populateItem(item,eItem, index);
-
-        Date pubDate = item.getPubDate();
-        if (pubDate != null) {
-            eItem.addContent(generateSimpleElement("pubDate", DateParser.formatRFC822(pubDate)));
-        }
-
-        Date expirationDate = item.getExpirationDate();
-        if (expirationDate != null) {
-            eItem.addContent(generateSimpleElement("expirationDate", DateParser.formatRFC822(expirationDate)));
-        }
-    }
-
-    // Another one to thanks DW for
-    protected int getNumberOfEnclosures(List enclosures) {
-        return enclosures.size();
-    }
+	public RSS093Generator() {
+		this("rss_0.93", "0.93");
+	}
+
+	protected RSS093Generator(String feedType, String version) {
+		super(feedType, version);
+	}
+
+	protected void populateItem(Item item, Element eItem, int index) {
+		super.populateItem(item, eItem, index);
+
+		Date pubDate = item.getPubDate();
+		if (pubDate != null) {
+			eItem.addContent(generateSimpleElement("pubDate", DateParser
+					.formatRFC822(pubDate)));
+		}
+
+		Date expirationDate = item.getExpirationDate();
+		if (expirationDate != null) {
+			eItem.addContent(generateSimpleElement("expirationDate", DateParser
+					.formatRFC822(expirationDate)));
+		}
+	}
+
+	// Another one to thanks DW for
+	protected int getNumberOfEnclosures(List<Enclosure> enclosures) {
+		return enclosures.size();
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/Atom10Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/Atom10Generator.java,v
retrieving revision 1.18
diff -u -r1.18 Atom10Generator.java
--- src/java/com/sun/syndication/io/impl/Atom10Generator.java	4 Jan 2009 22:40:45 -0000	1.18
+++ src/java/com/sun/syndication/io/impl/Atom10Generator.java	30 Sep 2009 06:30:43 -0000
@@ -44,430 +44,465 @@
 /**
  * Feed Generator for Atom
  * <p/>
- *
+ * 
  * @author Elaine Chien
  * @author Dave Johnson (updated for Atom 1.0)
- *
+ * 
  */
 
 public class Atom10Generator extends BaseWireFeedGenerator {
-    private static final String ATOM_10_URI = "http://www.w3.org/2005/Atom";
-    private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_10_URI);
-
-    private String _version;
-
-    public Atom10Generator() {
-        this("atom_1.0","1.0");
-    }
-
-    protected Atom10Generator(String type,String version) {
-        super(type);
-        _version = version;
-    }
-
-    protected String getVersion() {
-        return _version;
-    }
-
-    protected Namespace getFeedNamespace() {
-        return ATOM_NS;
-    }
-
-    public Document generate(WireFeed wFeed) throws FeedException {
-        Feed feed = (Feed) wFeed;
-        Element root = createRootElement(feed);
-        populateFeed(feed,root);
-        purgeUnusedNamespaceDeclarations(root);
-        return createDocument(root);
-    }
-
-    protected Document createDocument(Element root) {
-        return new Document(root);
-    }
-
-    protected Element createRootElement(Feed feed) {
-        Element root = new Element("feed",getFeedNamespace());
-        root.addNamespaceDeclaration(getFeedNamespace());
-        //Attribute version = new Attribute("version", getVersion());
-        //root.setAttribute(version);
-        if (feed.getXmlBase() != null) {
-            root.setAttribute("base", feed.getXmlBase(), Namespace.XML_NAMESPACE);
-        }
-        generateModuleNamespaceDefs(root);
-        return root;
-    }
-
-    protected void populateFeed(Feed feed,Element parent) throws FeedException  {
-        addFeed(feed,parent);
-        addEntries(feed,parent);
-    }
-
-    protected void addFeed(Feed feed,Element parent) throws FeedException {
-        Element eFeed = parent;
-        populateFeedHeader(feed,eFeed);
-        generateForeignMarkup(eFeed, (List)feed.getForeignMarkup());
-        checkFeedHeaderConstraints(eFeed);
-        generateFeedModules(feed.getModules(),eFeed);
-    }
-
-    protected void addEntries(Feed feed,Element parent) throws FeedException {
-        List items = feed.getEntries();
-        for (int i=0;i<items.size();i++) {
-            addEntry((Entry)items.get(i),parent);
-        }
-        checkEntriesConstraints(parent);
-    }
-
-    protected void addEntry(Entry entry,Element parent) throws FeedException {
-        Element eEntry = new Element("entry", getFeedNamespace());
-        if (entry.getXmlBase() != null) {
-            eEntry.setAttribute("base", entry.getXmlBase(), Namespace.XML_NAMESPACE);
-        }
-        populateEntry(entry,eEntry);
-        generateForeignMarkup(eEntry, (List)entry.getForeignMarkup());
-        checkEntryConstraints(eEntry);
-        generateItemModules(entry.getModules(),eEntry);
-        parent.addContent(eEntry);
-    }
-
-    protected void populateFeedHeader(Feed feed,Element eFeed) throws FeedException {
-        if (feed.getTitleEx() != null) {
-            Element titleElement = new Element("title", getFeedNamespace());
-            fillContentElement(titleElement, feed.getTitleEx());
-            eFeed.addContent(titleElement);
-        }
-
-        List links = feed.getAlternateLinks();
-        if (links != null) for (int i = 0; i < links.size(); i++) {
-            eFeed.addContent(generateLinkElement((Link)links.get(i)));
-        }
-        links = feed.getOtherLinks();
-        if (links != null) for (int j = 0; j < links.size(); j++) {
-            eFeed.addContent(generateLinkElement((Link)links.get(j)));
-        }
-
-        List cats = feed.getCategories();
-        if (cats != null) for (Iterator iter=cats.iterator(); iter.hasNext();) {
-            eFeed.addContent(generateCategoryElement((Category)iter.next()));
-        }
-            
-        List authors = feed.getAuthors();
-        if (authors != null && authors.size() > 0) {
-            for (int i = 0; i < authors.size(); i++) {
-                Element authorElement = new Element("author", getFeedNamespace());
-                fillPersonElement(authorElement, (Person)feed.getAuthors().get(i));
-                eFeed.addContent(authorElement);
-            }
-        }
-
-        List contributors = feed.getContributors();
-        if (contributors != null && contributors.size() > 0) {
-            for (int i = 0; i < contributors.size(); i++) {
-                Element contributorElement = new Element("contributor", getFeedNamespace());
-                fillPersonElement(contributorElement, (Person)contributors.get(i));
-                eFeed.addContent(contributorElement);
-            }
-        }
-
-        if (feed.getSubtitle() != null) {
-          Element subtitleElement = new Element("subtitle", getFeedNamespace());
-          fillContentElement(subtitleElement, feed.getSubtitle());
-                eFeed.addContent(subtitleElement);
-        }
-
-        if (feed.getId() != null) {
-            eFeed.addContent(generateSimpleElement("id", feed.getId()));
-        }
-
-        if (feed.getGenerator() != null) {
-            eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
-        }
-
-        if (feed.getRights() != null) {
-            eFeed.addContent(generateSimpleElement("rights", feed.getRights()));
-        }
-
-        if (feed.getIcon() != null) {
-          eFeed.addContent(generateSimpleElement("icon", feed.getIcon()));
-        }
-
-        if (feed.getLogo() != null) {
-          eFeed.addContent(generateSimpleElement("logo", feed.getLogo()));
-        }
-
-        if (feed.getUpdated() != null) {
-            Element updatedElement = new Element("updated", getFeedNamespace());
-            updatedElement.addContent(DateParser.formatW3CDateTime(feed.getUpdated()));
-            eFeed.addContent(updatedElement);
-        }
-    }
-
-    protected void populateEntry(Entry entry, Element eEntry) throws FeedException {
-        if (entry.getTitleEx() != null) {
-            Element titleElement = new Element("title", getFeedNamespace());
-            fillContentElement(titleElement, entry.getTitleEx());
-            eEntry.addContent(titleElement);
-        }
-        List links = entry.getAlternateLinks();
-        if (links != null) {
-            for (int i = 0; i < links.size(); i++) {
-                eEntry.addContent(generateLinkElement((Link)links.get(i)));
-            }
-        }
-        links = entry.getOtherLinks();
-        if (links != null) {
-            for (int i = 0; i < links.size(); i++) {
-                eEntry.addContent(generateLinkElement((Link)links.get(i)));
-            }
-        }
-
-        List cats = entry.getCategories();
-        if (cats != null) {
-            for (int i = 0; i < cats.size(); i++) {
-                eEntry.addContent(generateCategoryElement((Category)cats.get(i)));
-            }
-        }
-        
-        List authors = entry.getAuthors();
-        if (authors != null && authors.size() > 0) {
-            for (int i = 0; i < authors.size(); i++)  {
-                Element authorElement = new Element("author", getFeedNamespace());
-                fillPersonElement(authorElement, (Person)entry.getAuthors().get(i));
-                eEntry.addContent(authorElement);            
-            }
-        }
-
-        List contributors = entry.getContributors();
-        if (contributors != null && contributors.size() > 0) {
-            for (int i = 0; i < contributors.size(); i++) {
-                Element contributorElement = new Element("contributor", getFeedNamespace());
-                fillPersonElement(contributorElement, (Person)contributors.get(i));
-                eEntry.addContent(contributorElement);
-            }
-        }
-        if (entry.getId() != null) {
-            eEntry.addContent(generateSimpleElement("id", entry.getId()));
-        }
-
-        if (entry.getUpdated() != null) {
-            Element updatedElement = new Element("updated", getFeedNamespace());
-            updatedElement.addContent(DateParser.formatW3CDateTime(entry.getUpdated()));
-            eEntry.addContent(updatedElement);
-        }
-
-        if (entry.getPublished() != null) {
-            Element publishedElement = new Element("published", getFeedNamespace());
-            publishedElement.addContent(DateParser.formatW3CDateTime(entry.getPublished()));
-            eEntry.addContent(publishedElement);
-        }
-
-        if (entry.getContents() != null && entry.getContents().size() > 0) {
-            Element contentElement = new Element("content", getFeedNamespace());
-            Content content = (Content)entry.getContents().get(0);
-            fillContentElement(contentElement, content);
-            eEntry.addContent(contentElement);
-        }
-
-        if (entry.getSummary() != null) {
-            Element summaryElement = new Element("summary", getFeedNamespace());
-            fillContentElement(summaryElement, entry.getSummary());
-            eEntry.addContent(summaryElement);
-        }
-
-        if (entry.getSource() != null) {
-        	Element sourceElement = new Element("source", getFeedNamespace());
-            populateFeedHeader(entry.getSource(), sourceElement);
-            eEntry.addContent(sourceElement);
-        }
-    }
-
-    protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException {
-    }
-
-    protected void checkEntriesConstraints(Element parent) throws FeedException {
-    }
-
-    protected void checkEntryConstraints(Element eEntry) throws FeedException {
-    }
-
-
-    protected Element generateCategoryElement(Category cat) {
-        Element catElement = new Element("category", getFeedNamespace());
-
-        if (cat.getTerm() != null) {
-            Attribute termAttribute = new Attribute("term", cat.getTerm());
-            catElement.setAttribute(termAttribute);
-        }
-
-        if (cat.getLabel() != null) {
-            Attribute labelAttribute = new Attribute("label", cat.getLabel());
-            catElement.setAttribute(labelAttribute);
-        }
-
-        if (cat.getScheme() != null) {
-            Attribute schemeAttribute = new Attribute("scheme", cat.getScheme());
-            catElement.setAttribute(schemeAttribute);
-        }
-        return catElement;
-    }
-
-    protected Element generateLinkElement(Link link) {
-        Element linkElement = new Element("link", getFeedNamespace());
-
-        if (link.getRel() != null) {
-            Attribute relAttribute = new Attribute("rel", link.getRel());
-            linkElement.setAttribute(relAttribute);
-        }
-
-        if (link.getType() != null) {
-            Attribute typeAttribute = new Attribute("type", link.getType());
-            linkElement.setAttribute(typeAttribute);
-        }
-
-        if (link.getHref() != null) {
-            Attribute hrefAttribute = new Attribute("href", link.getHref());
-            linkElement.setAttribute(hrefAttribute);
-        }
-        
-        if (link.getHreflang() != null) {
-            Attribute hreflangAttribute = new Attribute("hreflang", link.getHreflang());
-            linkElement.setAttribute(hreflangAttribute);
-        }
-        if (link.getTitle() != null) {
-            Attribute title = new Attribute("title", link.getTitle());
-            linkElement.setAttribute(title);
-        }
-        if (link.getLength() != 0) {
-            Attribute lenght = new Attribute("length", Long.toString(link.getLength()));
-            linkElement.setAttribute(lenght);
-        }
-        return linkElement;
-    }
-
-
-    protected void fillPersonElement(Element element, Person person) {
-        if (person.getName() != null) {
-            element.addContent(generateSimpleElement("name", person.getName()));
-        }
-        if (person.getUri() != null) {
-            element.addContent(generateSimpleElement("uri", person.getUri()));
-        }
-
-        if (person.getEmail() != null) {
-            element.addContent(generateSimpleElement("email", person.getEmail()));
-        }
-        generatePersonModules(person.getModules(), element);
-    }
-
-    protected Element generateTagLineElement(Content tagline) {
-        Element taglineElement = new Element("subtitle", getFeedNamespace());
-
-        if (tagline.getType() != null) {
-            Attribute typeAttribute = new Attribute("type", tagline.getType());
-            taglineElement.setAttribute(typeAttribute);
-        }
-
-        if (tagline.getValue() != null) {
-            taglineElement.addContent(tagline.getValue());
-        }
-        return taglineElement;
-    }
-
-    protected void fillContentElement(Element contentElement, Content content)
-        throws FeedException {
-
-        String type = content.getType();
-            String atomType = type;
-        if (type != null) {
-            // Fix for issue #39 "Atom 1.0 Text Types Not Set Correctly"
-            // we're not sure who set this value, so ensure Atom types are used
-            if ("text/plain".equals(type)) atomType = Content.TEXT;
-            else if ("text/html".equals(type)) atomType = Content.HTML;
-            else if ("application/xhtml+xml".equals(type)) atomType = Content.XHTML;
-            
-            Attribute typeAttribute = new Attribute("type", atomType);
-            contentElement.setAttribute(typeAttribute);
-        }
-        String href = content.getSrc();
-        if (href != null) {
-            Attribute srcAttribute = new Attribute("src", href);
-            contentElement.setAttribute(srcAttribute);
-        }
-        if (content.getValue() != null) {
-            if (atomType != null && (atomType.equals(Content.XHTML) || (atomType.indexOf("/xml")) != -1 ||
-                (atomType.indexOf("+xml")) != -1)) {
-
-                StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
-                tmpDocString.append(content.getValue());
-                tmpDocString.append("</tmpdoc>");
-                StringReader tmpDocReader = new StringReader(tmpDocString.toString());
-                Document tmpDoc;
-                try {
-                    SAXBuilder saxBuilder = new SAXBuilder();
-                    tmpDoc = saxBuilder.build(tmpDocReader);
-                }
-                catch (Exception ex) {
-                    throw new FeedException("Invalid XML",ex);
-                }
-                List children = tmpDoc.getRootElement().removeContent();
-                contentElement.addContent(children);
-            } else { 
-                // must be type html, text or some other non-XML format
-                // JDOM will escape property for XML
-                contentElement.addContent(content.getValue());
-            }
-        }
-    }
-
-    protected Element generateGeneratorElement(Generator generator) {
-        Element generatorElement = new Element("generator", getFeedNamespace());
-
-        if (generator.getUrl() != null) {
-            Attribute urlAttribute = new Attribute("uri", generator.getUrl());
-            generatorElement.setAttribute(urlAttribute);
-        }
-
-        if (generator.getVersion() != null) {
-            Attribute versionAttribute = new Attribute("version", generator.getVersion());
-            generatorElement.setAttribute(versionAttribute);
-        }
-
-        if (generator.getValue() != null) {
-            generatorElement.addContent(generator.getValue());
-        }
-
-        return generatorElement;
-
-    }
-
-    protected Element generateSimpleElement(String name, String value) {
-        Element element = new Element(name, getFeedNamespace());
-        element.addContent(value);
-        return element;
-    }
-    
-    /**
-     * Utility method to serialize an entry to writer.
-     */
-    public static void serializeEntry(Entry entry, Writer writer)
-        throws IllegalArgumentException, FeedException, IOException {
-        
-        // Build a feed containing only the entry
-        List entries = new ArrayList();
-        entries.add(entry);
-        Feed feed1 = new Feed();
-        feed1.setFeedType("atom_1.0");
-        feed1.setEntries(entries);
-
-        // Get Rome to output feed as a JDOM document
-        WireFeedOutput wireFeedOutput = new WireFeedOutput();
-        Document feedDoc = wireFeedOutput.outputJDom(feed1);
-
-        // Grab entry element from feed and get JDOM to serialize it
-        Element entryElement= (Element)feedDoc.getRootElement().getChildren().get(0);
-
-        XMLOutputter outputter = new XMLOutputter();
-        outputter.output(entryElement, writer);
-    }
+	private static final String ATOM_10_URI = "http://www.w3.org/2005/Atom";
+	private static final Namespace ATOM_NS = Namespace
+			.getNamespace(ATOM_10_URI);
+
+	private String _version;
+
+	public Atom10Generator() {
+		this("atom_1.0", "1.0");
+	}
+
+	protected Atom10Generator(String type, String version) {
+		super(type);
+		_version = version;
+	}
+
+	protected String getVersion() {
+		return _version;
+	}
+
+	protected Namespace getFeedNamespace() {
+		return ATOM_NS;
+	}
+
+	public Document generate(WireFeed wFeed) throws FeedException {
+		Feed feed = (Feed) wFeed;
+		Element root = createRootElement(feed);
+		populateFeed(feed, root);
+		purgeUnusedNamespaceDeclarations(root);
+		return createDocument(root);
+	}
+
+	protected Document createDocument(Element root) {
+		return new Document(root);
+	}
+
+	protected Element createRootElement(Feed feed) {
+		Element root = new Element("feed", getFeedNamespace());
+		root.addNamespaceDeclaration(getFeedNamespace());
+		// Attribute version = new Attribute("version", getVersion());
+		// root.setAttribute(version);
+		if (feed.getXmlBase() != null) {
+			root.setAttribute("base", feed.getXmlBase(),
+					Namespace.XML_NAMESPACE);
+		}
+		generateModuleNamespaceDefs(root);
+		return root;
+	}
+
+	protected void populateFeed(Feed feed, Element parent) throws FeedException {
+		addFeed(feed, parent);
+		addEntries(feed, parent);
+	}
+
+	protected void addFeed(Feed feed, Element parent) throws FeedException {
+		Element eFeed = parent;
+		populateFeedHeader(feed, eFeed);
+		generateForeignMarkup(eFeed, feed.getForeignMarkup());
+		checkFeedHeaderConstraints(eFeed);
+		generateFeedModules(feed.getModules(), eFeed);
+	}
+
+	protected void addEntries(Feed feed, Element parent) throws FeedException {
+		List<Entry> items = feed.getEntries();
+		for (int i = 0; i < items.size(); i++) {
+			addEntry(items.get(i), parent);
+		}
+		checkEntriesConstraints(parent);
+	}
+
+	protected void addEntry(Entry entry, Element parent) throws FeedException {
+		Element eEntry = new Element("entry", getFeedNamespace());
+		if (entry.getXmlBase() != null) {
+			eEntry.setAttribute("base", entry.getXmlBase(),
+					Namespace.XML_NAMESPACE);
+		}
+		populateEntry(entry, eEntry);
+		generateForeignMarkup(eEntry, entry.getForeignMarkup());
+		checkEntryConstraints(eEntry);
+		generateItemModules(entry.getModules(), eEntry);
+		parent.addContent(eEntry);
+	}
+
+	protected void populateFeedHeader(Feed feed, Element eFeed)
+			throws FeedException {
+		if (feed.getTitleEx() != null) {
+			Element titleElement = new Element("title", getFeedNamespace());
+			fillContentElement(titleElement, feed.getTitleEx());
+			eFeed.addContent(titleElement);
+		}
+
+		List<Link> links = feed.getAlternateLinks();
+		if (links != null)
+			for (int i = 0; i < links.size(); i++) {
+				eFeed.addContent(generateLinkElement((Link) links.get(i)));
+			}
+		links = feed.getOtherLinks();
+		if (links != null)
+			for (int j = 0; j < links.size(); j++) {
+				eFeed.addContent(generateLinkElement((Link) links.get(j)));
+			}
+
+		List<Category> cats = feed.getCategories();
+		if (cats != null)
+			for (Iterator<Category> iter = cats.iterator(); iter.hasNext();) {
+				eFeed
+						.addContent(generateCategoryElement((Category) iter
+								.next()));
+			}
+
+		List<Person> authors = feed.getAuthors();
+		if (authors != null && authors.size() > 0) {
+			for (int i = 0; i < authors.size(); i++) {
+				Element authorElement = new Element("author",
+						getFeedNamespace());
+				fillPersonElement(authorElement, (Person) feed.getAuthors()
+						.get(i));
+				eFeed.addContent(authorElement);
+			}
+		}
+
+		List<Person> contributors = feed.getContributors();
+		if (contributors != null && contributors.size() > 0) {
+			for (int i = 0; i < contributors.size(); i++) {
+				Element contributorElement = new Element("contributor",
+						getFeedNamespace());
+				fillPersonElement(contributorElement, (Person) contributors
+						.get(i));
+				eFeed.addContent(contributorElement);
+			}
+		}
+
+		if (feed.getSubtitle() != null) {
+			Element subtitleElement = new Element("subtitle",
+					getFeedNamespace());
+			fillContentElement(subtitleElement, feed.getSubtitle());
+			eFeed.addContent(subtitleElement);
+		}
+
+		if (feed.getId() != null) {
+			eFeed.addContent(generateSimpleElement("id", feed.getId()));
+		}
+
+		if (feed.getGenerator() != null) {
+			eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
+		}
+
+		if (feed.getRights() != null) {
+			eFeed.addContent(generateSimpleElement("rights", feed.getRights()));
+		}
+
+		if (feed.getIcon() != null) {
+			eFeed.addContent(generateSimpleElement("icon", feed.getIcon()));
+		}
+
+		if (feed.getLogo() != null) {
+			eFeed.addContent(generateSimpleElement("logo", feed.getLogo()));
+		}
+
+		if (feed.getUpdated() != null) {
+			Element updatedElement = new Element("updated", getFeedNamespace());
+			updatedElement.addContent(DateParser.formatW3CDateTime(feed
+					.getUpdated()));
+			eFeed.addContent(updatedElement);
+		}
+	}
+
+	protected void populateEntry(Entry entry, Element eEntry)
+			throws FeedException {
+		if (entry.getTitleEx() != null) {
+			Element titleElement = new Element("title", getFeedNamespace());
+			fillContentElement(titleElement, entry.getTitleEx());
+			eEntry.addContent(titleElement);
+		}
+		List<Link> links = entry.getAlternateLinks();
+		if (links != null) {
+			for (int i = 0; i < links.size(); i++) {
+				eEntry.addContent(generateLinkElement((Link) links.get(i)));
+			}
+		}
+		links = entry.getOtherLinks();
+		if (links != null) {
+			for (int i = 0; i < links.size(); i++) {
+				eEntry.addContent(generateLinkElement((Link) links.get(i)));
+			}
+		}
+
+		List<Category> cats = entry.getCategories();
+		if (cats != null) {
+			for (int i = 0; i < cats.size(); i++) {
+				eEntry.addContent(generateCategoryElement((Category) cats
+						.get(i)));
+			}
+		}
+
+		List<Person> authors = entry.getAuthors();
+		if (authors != null && authors.size() > 0) {
+			for (int i = 0; i < authors.size(); i++) {
+				Element authorElement = new Element("author",
+						getFeedNamespace());
+				fillPersonElement(authorElement, (Person) entry.getAuthors()
+						.get(i));
+				eEntry.addContent(authorElement);
+			}
+		}
+
+		List<Person> contributors = entry.getContributors();
+		if (contributors != null && contributors.size() > 0) {
+			for (int i = 0; i < contributors.size(); i++) {
+				Element contributorElement = new Element("contributor",
+						getFeedNamespace());
+				fillPersonElement(contributorElement, (Person) contributors
+						.get(i));
+				eEntry.addContent(contributorElement);
+			}
+		}
+		if (entry.getId() != null) {
+			eEntry.addContent(generateSimpleElement("id", entry.getId()));
+		}
+
+		if (entry.getUpdated() != null) {
+			Element updatedElement = new Element("updated", getFeedNamespace());
+			updatedElement.addContent(DateParser.formatW3CDateTime(entry
+					.getUpdated()));
+			eEntry.addContent(updatedElement);
+		}
+
+		if (entry.getPublished() != null) {
+			Element publishedElement = new Element("published",
+					getFeedNamespace());
+			publishedElement.addContent(DateParser.formatW3CDateTime(entry
+					.getPublished()));
+			eEntry.addContent(publishedElement);
+		}
+
+		if (entry.getContents() != null && entry.getContents().size() > 0) {
+			Element contentElement = new Element("content", getFeedNamespace());
+			Content content = (Content) entry.getContents().get(0);
+			fillContentElement(contentElement, content);
+			eEntry.addContent(contentElement);
+		}
+
+		if (entry.getSummary() != null) {
+			Element summaryElement = new Element("summary", getFeedNamespace());
+			fillContentElement(summaryElement, entry.getSummary());
+			eEntry.addContent(summaryElement);
+		}
+
+		if (entry.getSource() != null) {
+			Element sourceElement = new Element("source", getFeedNamespace());
+			populateFeedHeader(entry.getSource(), sourceElement);
+			eEntry.addContent(sourceElement);
+		}
+	}
+
+	protected void checkFeedHeaderConstraints(Element eFeed)
+			throws FeedException {
+	}
+
+	protected void checkEntriesConstraints(Element parent) throws FeedException {
+	}
+
+	protected void checkEntryConstraints(Element eEntry) throws FeedException {
+	}
+
+	protected Element generateCategoryElement(Category cat) {
+		Element catElement = new Element("category", getFeedNamespace());
+
+		if (cat.getTerm() != null) {
+			Attribute termAttribute = new Attribute("term", cat.getTerm());
+			catElement.setAttribute(termAttribute);
+		}
+
+		if (cat.getLabel() != null) {
+			Attribute labelAttribute = new Attribute("label", cat.getLabel());
+			catElement.setAttribute(labelAttribute);
+		}
+
+		if (cat.getScheme() != null) {
+			Attribute schemeAttribute = new Attribute("scheme", cat.getScheme());
+			catElement.setAttribute(schemeAttribute);
+		}
+		return catElement;
+	}
+
+	protected Element generateLinkElement(Link link) {
+		Element linkElement = new Element("link", getFeedNamespace());
+
+		if (link.getRel() != null) {
+			Attribute relAttribute = new Attribute("rel", link.getRel());
+			linkElement.setAttribute(relAttribute);
+		}
+
+		if (link.getType() != null) {
+			Attribute typeAttribute = new Attribute("type", link.getType());
+			linkElement.setAttribute(typeAttribute);
+		}
+
+		if (link.getHref() != null) {
+			Attribute hrefAttribute = new Attribute("href", link.getHref());
+			linkElement.setAttribute(hrefAttribute);
+		}
+
+		if (link.getHreflang() != null) {
+			Attribute hreflangAttribute = new Attribute("hreflang", link
+					.getHreflang());
+			linkElement.setAttribute(hreflangAttribute);
+		}
+		if (link.getTitle() != null) {
+			Attribute title = new Attribute("title", link.getTitle());
+			linkElement.setAttribute(title);
+		}
+		if (link.getLength() != 0) {
+			Attribute lenght = new Attribute("length", Long.toString(link
+					.getLength()));
+			linkElement.setAttribute(lenght);
+		}
+		return linkElement;
+	}
+
+	protected void fillPersonElement(Element element, Person person) {
+		if (person.getName() != null) {
+			element.addContent(generateSimpleElement("name", person.getName()));
+		}
+		if (person.getUri() != null) {
+			element.addContent(generateSimpleElement("uri", person.getUri()));
+		}
+
+		if (person.getEmail() != null) {
+			element
+					.addContent(generateSimpleElement("email", person
+							.getEmail()));
+		}
+		generatePersonModules(person.getModules(), element);
+	}
+
+	protected Element generateTagLineElement(Content tagline) {
+		Element taglineElement = new Element("subtitle", getFeedNamespace());
+
+		if (tagline.getType() != null) {
+			Attribute typeAttribute = new Attribute("type", tagline.getType());
+			taglineElement.setAttribute(typeAttribute);
+		}
+
+		if (tagline.getValue() != null) {
+			taglineElement.addContent(tagline.getValue());
+		}
+		return taglineElement;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void fillContentElement(Element contentElement, Content content)
+			throws FeedException {
+
+		String type = content.getType();
+		String atomType = type;
+		if (type != null) {
+			// Fix for issue #39 "Atom 1.0 Text Types Not Set Correctly"
+			// we're not sure who set this value, so ensure Atom types are used
+			if ("text/plain".equals(type))
+				atomType = Content.TEXT;
+			else if ("text/html".equals(type))
+				atomType = Content.HTML;
+			else if ("application/xhtml+xml".equals(type))
+				atomType = Content.XHTML;
+
+			Attribute typeAttribute = new Attribute("type", atomType);
+			contentElement.setAttribute(typeAttribute);
+		}
+		String href = content.getSrc();
+		if (href != null) {
+			Attribute srcAttribute = new Attribute("src", href);
+			contentElement.setAttribute(srcAttribute);
+		}
+		if (content.getValue() != null) {
+			if (atomType != null
+					&& (atomType.equals(Content.XHTML)
+							|| (atomType.indexOf("/xml")) != -1 || (atomType
+							.indexOf("+xml")) != -1)) {
+
+				StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
+				tmpDocString.append(content.getValue());
+				tmpDocString.append("</tmpdoc>");
+				StringReader tmpDocReader = new StringReader(tmpDocString
+						.toString());
+				Document tmpDoc;
+				try {
+					SAXBuilder saxBuilder = new SAXBuilder();
+					tmpDoc = saxBuilder.build(tmpDocReader);
+				} catch (Exception ex) {
+					throw new FeedException("Invalid XML", ex);
+				}
+				List children = tmpDoc.getRootElement().removeContent();
+				contentElement.addContent(children);
+			} else {
+				// must be type html, text or some other non-XML format
+				// JDOM will escape property for XML
+				contentElement.addContent(content.getValue());
+			}
+		}
+	}
+
+	protected Element generateGeneratorElement(Generator generator) {
+		Element generatorElement = new Element("generator", getFeedNamespace());
+
+		if (generator.getUrl() != null) {
+			Attribute urlAttribute = new Attribute("uri", generator.getUrl());
+			generatorElement.setAttribute(urlAttribute);
+		}
+
+		if (generator.getVersion() != null) {
+			Attribute versionAttribute = new Attribute("version", generator
+					.getVersion());
+			generatorElement.setAttribute(versionAttribute);
+		}
+
+		if (generator.getValue() != null) {
+			generatorElement.addContent(generator.getValue());
+		}
+
+		return generatorElement;
+
+	}
+
+	protected Element generateSimpleElement(String name, String value) {
+		Element element = new Element(name, getFeedNamespace());
+		element.addContent(value);
+		return element;
+	}
+
+	/**
+	 * Utility method to serialize an entry to writer.
+	 */
+	public static void serializeEntry(Entry entry, Writer writer)
+			throws IllegalArgumentException, FeedException, IOException {
+
+		// Build a feed containing only the entry
+		List<Entry> entries = new ArrayList<Entry>();
+		entries.add(entry);
+		Feed feed1 = new Feed();
+		feed1.setFeedType("atom_1.0");
+		feed1.setEntries(entries);
+
+		// Get Rome to output feed as a JDOM document
+		WireFeedOutput wireFeedOutput = new WireFeedOutput();
+		Document feedDoc = wireFeedOutput.outputJDom(feed1);
+
+		// Grab entry element from feed and get JDOM to serialize it
+		Element entryElement = (Element) feedDoc.getRootElement().getChildren()
+				.get(0);
+
+		XMLOutputter outputter = new XMLOutputter();
+		outputter.output(entryElement, writer);
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/RSS092Parser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS092Parser.java,v
retrieving revision 1.11
diff -u -r1.11 RSS092Parser.java
--- src/java/com/sun/syndication/io/impl/RSS092Parser.java	7 Jan 2009 22:50:11 -0000	1.11
+++ src/java/com/sun/syndication/io/impl/RSS092Parser.java	30 Sep 2009 06:30:45 -0000
@@ -33,115 +33,116 @@
  */
 public class RSS092Parser extends RSS091UserlandParser {
 
-    public RSS092Parser() {
-        this("rss_0.92");
-    }
-
-    protected RSS092Parser(String type) {
-        super(type);
-    }
-
-    protected String getRSSVersion() {
-            return "0.92";
-    }
-
-    protected WireFeed parseChannel(Element rssRoot)  {
-        Channel channel = (Channel) super.parseChannel(rssRoot);
-
-        Element eChannel = rssRoot.getChild("channel",getRSSNamespace());
-        Element eCloud = eChannel.getChild("cloud",getRSSNamespace());
-        if (eCloud!=null) {
-            Cloud cloud = new Cloud();
-            String att = eCloud.getAttributeValue("domain");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-            if (att!=null) {
-                cloud.setDomain(att);
-            }
-            att = eCloud.getAttributeValue("port");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-            if (att!=null) {
-                cloud.setPort(Integer.parseInt(att.trim()));
-            }
-            att = eCloud.getAttributeValue("path");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-            if (att!=null) {
-                cloud.setPath(att);
-            }
-            att = eCloud.getAttributeValue("registerProcedure");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-            if (att!=null) {
-                cloud.setRegisterProcedure(att);
-            }
-            att = eCloud.getAttributeValue("protocol");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-            if (att!=null) {
-                cloud.setProtocol(att);
-            }
-            channel.setCloud(cloud);
-        }
-        return channel;
-    }
-
-    protected Item parseItem(Element rssRoot,Element eItem) {
-        Item item = super.parseItem(rssRoot,eItem);
-
-        Element e = eItem.getChild("source",getRSSNamespace());
-        if (e!=null) {
-            Source source = new Source();
-            String url = e.getAttributeValue("url");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-            source.setUrl(url);
-            source.setValue(e.getText());
-            item.setSource(source);
-        }
-
-        // 0.92 allows one enclosure occurrence, 0.93 multiple
-        // just saving to write some code.
-        List eEnclosures = eItem.getChildren("enclosure");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-        if (eEnclosures.size()>0) {
-            List enclosures = new ArrayList();
-            for (int i=0;i<eEnclosures.size();i++) {
-                e = (Element) eEnclosures.get(i);
-
-                Enclosure enclosure = new Enclosure();
-                String att = e.getAttributeValue("url");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-                if (att!=null) {
-                    enclosure.setUrl(att);
-                }
-                att = e.getAttributeValue("length");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-                enclosure.setLength(NumberParser.parseLong(att,0L));
-
-                att = e.getAttributeValue("type");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-                if (att!=null) {
-                    enclosure.setType(att);
-                }
-                enclosures.add(enclosure);
-            }
-            item.setEnclosures(enclosures);
-        }
-
-        List eCats = eItem.getChildren("category");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-        item.setCategories(parseCategories(eCats));
-
-        return item;
-    }
-
-    protected List parseCategories(List eCats) {
-        List cats = null;
-        if (eCats.size()>0) {
-            cats = new ArrayList();
-            for (int i=0;i<eCats.size();i++) {
-                Category cat = new Category();
-                Element e = (Element) eCats.get(i);
-                String att = e.getAttributeValue("domain");//getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
-                if (att!=null) {
-                    cat.setDomain(att);
-                }
-                cat.setValue(e.getText());
-                cats.add(cat);
-            }
-        }
-        return cats;
-    }
-
-    protected Description parseItemDescription(Element rssRoot,Element eDesc) {
-        Description desc = super.parseItemDescription(rssRoot,eDesc);
-        desc.setType("text/html");
-        return desc;
-    }
+	public RSS092Parser() {
+		this("rss_0.92");
+	}
+
+	protected RSS092Parser(String type) {
+		super(type);
+	}
+
+	protected String getRSSVersion() {
+		return "0.92";
+	}
+
+	protected WireFeed parseChannel(Element rssRoot) {
+		Channel channel = (Channel) super.parseChannel(rssRoot);
+
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+		Element eCloud = eChannel.getChild("cloud", getRSSNamespace());
+		if (eCloud != null) {
+			Cloud cloud = new Cloud();
+			String att = eCloud.getAttributeValue("domain");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+			if (att != null) {
+				cloud.setDomain(att);
+			}
+			att = eCloud.getAttributeValue("port");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+			if (att != null) {
+				cloud.setPort(Integer.parseInt(att.trim()));
+			}
+			att = eCloud.getAttributeValue("path");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+			if (att != null) {
+				cloud.setPath(att);
+			}
+			att = eCloud.getAttributeValue("registerProcedure");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+			if (att != null) {
+				cloud.setRegisterProcedure(att);
+			}
+			att = eCloud.getAttributeValue("protocol");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+			if (att != null) {
+				cloud.setProtocol(att);
+			}
+			channel.setCloud(cloud);
+		}
+		return channel;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected Item parseItem(Element rssRoot, Element eItem) {
+		Item item = super.parseItem(rssRoot, eItem);
+
+		Element e = eItem.getChild("source", getRSSNamespace());
+		if (e != null) {
+			Source source = new Source();
+			String url = e.getAttributeValue("url");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+			source.setUrl(url);
+			source.setValue(e.getText());
+			item.setSource(source);
+		}
+
+		// 0.92 allows one enclosure occurrence, 0.93 multiple
+		// just saving to write some code.
+		List<Element> eEnclosures = eItem.getChildren("enclosure");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+		if (eEnclosures.size() > 0) {
+			List<Enclosure> enclosures = new ArrayList<Enclosure>();
+			for (int i = 0; i < eEnclosures.size(); i++) {
+				e = (Element) eEnclosures.get(i);
+
+				Enclosure enclosure = new Enclosure();
+				String att = e.getAttributeValue("url");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+				if (att != null) {
+					enclosure.setUrl(att);
+				}
+				att = e.getAttributeValue("length");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+				enclosure.setLength(NumberParser.parseLong(att, 0L));
+
+				att = e.getAttributeValue("type");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+				if (att != null) {
+					enclosure.setType(att);
+				}
+				enclosures.add(enclosure);
+			}
+			item.setEnclosures(enclosures);
+		}
+
+		List<Element> eCats = eItem.getChildren("category");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+		item.setCategories(parseCategories(eCats));
+
+		return item;
+	}
+
+	protected List<Category> parseCategories(List<Element> eCats) {
+		List<Category> cats = null;
+		if (eCats.size() > 0) {
+			cats = new ArrayList<Category>();
+			for (int i = 0; i < eCats.size(); i++) {
+				Category cat = new Category();
+				Element e = eCats.get(i);
+				String att = e.getAttributeValue("domain");// getRSSNamespace()); DONT KNOW WHY DOESN'T WORK
+				if (att != null) {
+					cat.setDomain(att);
+				}
+				cat.setValue(e.getText());
+				cats.add(cat);
+			}
+		}
+		return cats;
+	}
+
+	protected Description parseItemDescription(Element rssRoot, Element eDesc) {
+		Description desc = super.parseItemDescription(rssRoot, eDesc);
+		desc.setType("text/html");
+		return desc;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/XmlFixerReader.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/XmlFixerReader.java,v
retrieving revision 1.4
diff -u -r1.4 XmlFixerReader.java
--- src/java/com/sun/syndication/io/impl/XmlFixerReader.java	17 Jun 2008 13:32:45 -0000	1.4
+++ src/java/com/sun/syndication/io/impl/XmlFixerReader.java	30 Sep 2009 06:30:45 -0000
@@ -28,625 +28,592 @@
  */
 public class XmlFixerReader extends Reader {
 
-    protected Reader in;
+	protected Reader in;
 
-    public XmlFixerReader(Reader in) {
-        super(in);
-        this.in = in;
-        _buffer = new StringBuffer();
-        _state = 0;
-    }
-
-    private boolean trimmed;
-    private StringBuffer _buffer;
-    private int _bufferPos;
-    private int _state = 0;
-
-    private boolean trimStream() throws IOException {
-        boolean hasContent = true;
-        int state = 0;
-        boolean loop;
-        int c;
-        do {
-            switch (state) {
-                case 0:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = false;
-                    }
-                    else
-                    if (c==' ' || c=='\n') {
-                        loop = true;
-                    }
-                    else
-                    if (c=='<') {
-                        state = 1;
-                        _buffer.setLength(0);
-                        _bufferPos = 0;
-                        _buffer.append((char)c);
-                        loop = true;
-                    }
-                    else {
-                        _buffer.setLength(0);
-                        _bufferPos = 0;
-                        _buffer.append((char)c);
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    break;
-                case 1:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else
-                    if (c!='!') {
-                        _buffer.append((char)c);
-                        _state = 3;
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else {
-                        _buffer.append((char)c);
-                        state = 2;
-                        loop = true;
-                    }
-                    break;
-                case 2:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else
-                    if (c=='-') {
-                        _buffer.append((char)c);
-                        state = 3;
-                        loop = true;
-                    }
-                    else {
-                        _buffer.append((char)c);
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    break;
-                case 3:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else
-                    if (c=='-') {
-                        _buffer.append((char)c);
-                        state = 4;
-                        loop = true;
-                    }
-                    else {
-                        _buffer.append((char)c);
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    break;
-                case 4:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else
-                    if (c!='-') {
-                        _buffer.append((char)c);
-                        loop = true;
-                    }
-                    else {
-                        _buffer.append((char)c);
-                        state = 5;
-                        loop = true;
-                    }
-                    break;
-                case 5:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else
-                    if (c!='-') {
-                        _buffer.append((char)c);
-                        loop = true;
-                        state = 4;
-                    }
-                    else {
-                        _buffer.append((char)c);
-                        state = 6;
-                        loop = true;
-                    }
-                    break;
-                case 6:
-                    c = in.read();
-                    if (c==-1) {
-                        loop = false;
-                        hasContent = true;
-                        _state = 3;
-                    }
-                    else
-                    if (c!='>') {
-                        _buffer.append((char)c);
-                        loop = true;
-                        state = 4;
-                    }
-                    else {
-                        _buffer.setLength(0);
-                        state = 0;
-                        loop = true;
-                    }
-                    break;
-                default:
-                    throw new IOException("It shouldn't happen");
-            }
-        } while (loop);
-        return hasContent;
-    }
-
-    public int read() throws IOException {
-        boolean loop;
-        if (!trimmed) { // trims XML stream
-            trimmed = true;
-            if (!trimStream()) {
-                return -1;
-            }
-        }
-        int c;
-        do { // converts literal entities to coded entities
-            switch (_state) {
-                case 0: // reading chars from stream
-                    c = in.read();
-                    if (c>-1) {
-                        if (c=='&') {
-                            _state = 1;
-                            _buffer.setLength(0);
-                            _bufferPos = 0;
-                            _buffer.append((char)c);
-                            _state = 1;
-                            loop = true;
-                        }
-                        else {
-                            loop = false;
-                        }
-                    }
-                    else {
-                        loop = false;
-                    }
-                    break;
-                case 1: // reading entity from stream
-                    c = in.read();
-                    if (c>-1) {
-                        if (c==';') {
-                            _buffer.append((char)c);
-                            _state = 2;
-                            loop = true;
-                        }
-                        else
-                        if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c=='#') || (c>='0' && c<='9')) {
-                            _buffer.append((char)c);
-                            loop = true;
-                        }
-                        else {
-                            // no ';' to match the '&' lets just make the '&'
-                            // a legal xml character entity '&amp;'
-                            _buffer.insert(1, "amp;");
-                            _buffer.append((char)c);
-                            _state = 3;
-                            loop = true;
-                        }
-                    }
-                    else {
-                        // no ';' to match the '&' lets just make the '&'
-                        // a legal xml character entity '&amp;'
-                        _buffer.insert(1, "amp;");
-                        _state = 3;
-                        loop = true;
-                    }
-                    break;
-                case 2: // replacing entity
-                    c = 0;
-                    String literalEntity = _buffer.toString();
-                    String codedEntity = (String) CODED_ENTITIES.get(literalEntity);
-                    if (codedEntity!=null) {
-                        _buffer.setLength(0);
-                        _buffer.append(codedEntity);
-                    } // else we leave what was in the stream
-                    _state = 3;
-                    loop = true;
-                    break;
-                case 3: // consuming buffer
-                    if (_bufferPos<_buffer.length()) {
-                        c = _buffer.charAt(_bufferPos++);
-                        loop = false;
-                    }
-                    else {
-                        c = 0;
-                        _state = 0;
-                        loop = true;
-                    }
-                    break;
-                 default:
-                    throw new IOException("It shouldn't happen");
-            }
-        } while (loop);
-        return c;
-    }
-
-    public int read(char[] buffer,int offset,int len) throws IOException {
-        int charsRead = 0;
-        int c = read();
-        if (c==-1) {
-            return -1;
-        }
-        buffer[offset+(charsRead++)] = (char) c;
-        while (charsRead<len && (c=read())>-1) {
-            buffer[offset+(charsRead++)] = (char) c;
-        }
-        return charsRead;
-    }
-
-    public long skip(long n) throws IOException {
-        if (n==0) {
-            return 0;
-        }
-        else
-        if (n<0) {
-            throw new IllegalArgumentException("'n' cannot be negative");
-        }
-        int c = read();
-        long counter = 1;
-        while (c>-1 && counter<n) {
-            c = read();
-            counter++;
-        }
-        return counter;
-    }
-
-    public boolean ready() throws IOException {
-        return (_state!=0) || in.ready();
-    }
-
-    public boolean markSupported() {
-        return false;
-    }
-
-    public void mark(int readAheadLimit) throws IOException {
-        throw new IOException("Stream does not support mark");
-    }
-
-    public void reset() throws IOException {
-        throw new IOException("Stream does not support mark");
-    }
-
-    public void close() throws IOException {
-        in.close();
-    }
-
-    private static Map CODED_ENTITIES = new HashMap();
-
-    static {
-        // note: refer to Character entity references in HTML 4
-        // at http://www.w3.org/TR/REC-html40/sgml/entities.html
-
-    	// Character entity set.
-    	// HTMLlat1 "-//W3C//ENTITIES Latin 1//EN//HTML"
-
-    	CODED_ENTITIES.put("&nbsp;",  "&#160;");
-        CODED_ENTITIES.put("&iexcl;", "&#161;");
-        CODED_ENTITIES.put("&cent;",  "&#162;");
-        CODED_ENTITIES.put("&pound;", "&#163;");
-        CODED_ENTITIES.put("&curren;","&#164;");
-        CODED_ENTITIES.put("&yen;",   "&#165;");
-        CODED_ENTITIES.put("&brvbar;","&#166;");
-        CODED_ENTITIES.put("&sect;",  "&#167;");
-        CODED_ENTITIES.put("&uml;",   "&#168;");
-        CODED_ENTITIES.put("&copy;",  "&#169;");
-        CODED_ENTITIES.put("&ordf;",  "&#170;");
-        CODED_ENTITIES.put("&laquo;", "&#171;");
-        CODED_ENTITIES.put("&not;",   "&#172;");
-        CODED_ENTITIES.put("&shy;",   "&#173;");
-        CODED_ENTITIES.put("&reg;",   "&#174;");
-        CODED_ENTITIES.put("&macr;",  "&#175;");
-        CODED_ENTITIES.put("&deg;",   "&#176;");
-        CODED_ENTITIES.put("&plusmn;","&#177;");
-        CODED_ENTITIES.put("&sup2;",  "&#178;");
-        CODED_ENTITIES.put("&sup3;",  "&#179;");
-        CODED_ENTITIES.put("&acute;", "&#180;");
-        CODED_ENTITIES.put("&micro;", "&#181;");
-        CODED_ENTITIES.put("&para;",  "&#182;");
-        CODED_ENTITIES.put("&middot;","&#183;");
-        CODED_ENTITIES.put("&cedil;", "&#184;");
-        CODED_ENTITIES.put("&sup1;",  "&#185;");
-        CODED_ENTITIES.put("&ordm;",  "&#186;");
-        CODED_ENTITIES.put("&raquo;", "&#187;");
-        CODED_ENTITIES.put("&frac14;","&#188;");
-        CODED_ENTITIES.put("&frac12;","&#189;");
-        CODED_ENTITIES.put("&frac34;","&#190;");
-        CODED_ENTITIES.put("&iquest;","&#191;");
-        CODED_ENTITIES.put("&Agrave;","&#192;");
-        CODED_ENTITIES.put("&Aacute;","&#193;");
-        CODED_ENTITIES.put("&Acirc;", "&#194;");
-        CODED_ENTITIES.put("&Atilde;","&#195;");
-        CODED_ENTITIES.put("&Auml;",  "&#196;");
-        CODED_ENTITIES.put("&Aring;", "&#197;");
-        CODED_ENTITIES.put("&AElig;", "&#198;");
-        CODED_ENTITIES.put("&Ccedil;","&#199;");
-        CODED_ENTITIES.put("&Egrave;","&#200;");
-        CODED_ENTITIES.put("&Eacute;","&#201;");
-        CODED_ENTITIES.put("&Ecirc;", "&#202;");
-        CODED_ENTITIES.put("&Euml;",  "&#203;");
-        CODED_ENTITIES.put("&Igrave;","&#204;");
-        CODED_ENTITIES.put("&Iacute;","&#205;");
-        CODED_ENTITIES.put("&Icirc;", "&#206;");
-        CODED_ENTITIES.put("&Iuml;",  "&#207;");
-        CODED_ENTITIES.put("&ETH;",   "&#208;");
-        CODED_ENTITIES.put("&Ntilde;","&#209;");
-        CODED_ENTITIES.put("&Ograve;","&#210;");
-        CODED_ENTITIES.put("&Oacute;","&#211;");
-        CODED_ENTITIES.put("&Ocirc;", "&#212;");
-        CODED_ENTITIES.put("&Otilde;","&#213;");
-        CODED_ENTITIES.put("&Ouml;",  "&#214;");
-        CODED_ENTITIES.put("&times;", "&#215;");
-        CODED_ENTITIES.put("&Oslash;","&#216;");
-        CODED_ENTITIES.put("&Ugrave;","&#217;");
-        CODED_ENTITIES.put("&Uacute;","&#218;");
-        CODED_ENTITIES.put("&Ucirc;", "&#219;");
-        CODED_ENTITIES.put("&Uuml;",  "&#220;");
-        CODED_ENTITIES.put("&Yacute;","&#221;");
-        CODED_ENTITIES.put("&THORN;", "&#222;");
-        CODED_ENTITIES.put("&szlig;", "&#223;");
-        CODED_ENTITIES.put("&agrave;","&#224;");
-        CODED_ENTITIES.put("&aacute;","&#225;");
-        CODED_ENTITIES.put("&acirc;", "&#226;");
-        CODED_ENTITIES.put("&atilde;","&#227;");
-        CODED_ENTITIES.put("&auml;",  "&#228;");
-        CODED_ENTITIES.put("&aring;", "&#229;");
-        CODED_ENTITIES.put("&aelig;", "&#230;");
-        CODED_ENTITIES.put("&ccedil;","&#231;");
-        CODED_ENTITIES.put("&egrave;","&#232;");
-        CODED_ENTITIES.put("&eacute;","&#233;");
-        CODED_ENTITIES.put("&ecirc;", "&#234;");
-        CODED_ENTITIES.put("&euml;",  "&#235;");
-        CODED_ENTITIES.put("&igrave;","&#236;");
-        CODED_ENTITIES.put("&iacute;","&#237;");
-        CODED_ENTITIES.put("&icirc;", "&#238;");
-        CODED_ENTITIES.put("&iuml;",  "&#239;");
-        CODED_ENTITIES.put("&eth;",   "&#240;");
-        CODED_ENTITIES.put("&ntilde;","&#241;");
-        CODED_ENTITIES.put("&ograve;","&#242;");
-        CODED_ENTITIES.put("&oacute;","&#243;");
-        CODED_ENTITIES.put("&ocirc;", "&#244;");
-        CODED_ENTITIES.put("&otilde;","&#245;");
-        CODED_ENTITIES.put("&ouml;",  "&#246;");
-        CODED_ENTITIES.put("&divide;","&#247;");
-        CODED_ENTITIES.put("&oslash;","&#248;");
-        CODED_ENTITIES.put("&ugrave;","&#249;");
-        CODED_ENTITIES.put("&uacute;","&#250;");
-        CODED_ENTITIES.put("&ucirc;", "&#251;");
-        CODED_ENTITIES.put("&uuml;",  "&#252;");
-        CODED_ENTITIES.put("&yacute;","&#253;");
-        CODED_ENTITIES.put("&thorn;", "&#254;");
-        CODED_ENTITIES.put("&yuml;",  "&#255;");
-
-        // Mathematical, Greek and Symbolic characters for HTML.
-        // HTMLsymbol "-//W3C//ENTITIES Symbols//EN//HTML"
-
-        CODED_ENTITIES.put("&fnof;",     "&#402;");
-        CODED_ENTITIES.put("&Alpha;",    "&#913;");
-        CODED_ENTITIES.put("&Beta;",     "&#914;");
-        CODED_ENTITIES.put("&Gamma;",    "&#915;");
-        CODED_ENTITIES.put("&Delta;",    "&#916;");
-        CODED_ENTITIES.put("&Epsilon;",  "&#917;");
-        CODED_ENTITIES.put("&Zeta;",     "&#918;");
-        CODED_ENTITIES.put("&Eta;",      "&#919;");
-        CODED_ENTITIES.put("&Theta;",    "&#920;");
-        CODED_ENTITIES.put("&Iota;",     "&#921;");
-        CODED_ENTITIES.put("&Kappa;",    "&#922;");
-        CODED_ENTITIES.put("&Lambda;",   "&#923;");
-        CODED_ENTITIES.put("&Mu;",       "&#924;");
-        CODED_ENTITIES.put("&Nu;",       "&#925;");
-        CODED_ENTITIES.put("&Xi;",       "&#926;");
-        CODED_ENTITIES.put("&Omicron;",  "&#927;");
-        CODED_ENTITIES.put("&Pi;",       "&#928;");
-        CODED_ENTITIES.put("&Rho;",      "&#929;");
-        CODED_ENTITIES.put("&Sigma;",    "&#931;");
-        CODED_ENTITIES.put("&Tau;",      "&#932;");
-        CODED_ENTITIES.put("&Upsilon;",  "&#933;");
-        CODED_ENTITIES.put("&Phi;",      "&#934;");
-        CODED_ENTITIES.put("&Chi;",      "&#935;");
-        CODED_ENTITIES.put("&Psi;",      "&#936;");
-        CODED_ENTITIES.put("&Omega;",    "&#937;");
-        CODED_ENTITIES.put("&alpha;",    "&#945;");
-        CODED_ENTITIES.put("&beta;",     "&#946;");
-        CODED_ENTITIES.put("&gamma;",    "&#947;");
-        CODED_ENTITIES.put("&delta;",    "&#948;");
-        CODED_ENTITIES.put("&epsilon;",  "&#949;");
-        CODED_ENTITIES.put("&zeta;",     "&#950;");
-        CODED_ENTITIES.put("&eta;",      "&#951;");
-        CODED_ENTITIES.put("&theta;",    "&#952;");
-        CODED_ENTITIES.put("&iota;",     "&#953;");
-        CODED_ENTITIES.put("&kappa;",    "&#954;");
-        CODED_ENTITIES.put("&lambda;",   "&#955;");
-        CODED_ENTITIES.put("&mu;",       "&#956;");
-        CODED_ENTITIES.put("&nu;",       "&#957;");
-        CODED_ENTITIES.put("&xi;",       "&#958;");
-        CODED_ENTITIES.put("&omicron;",  "&#959;");
-        CODED_ENTITIES.put("&pi;",       "&#960;");
-        CODED_ENTITIES.put("&rho;",      "&#961;");
-        CODED_ENTITIES.put("&sigmaf;",   "&#962;");
-        CODED_ENTITIES.put("&sigma;",    "&#963;");
-        CODED_ENTITIES.put("&tau;",      "&#964;");
-        CODED_ENTITIES.put("&upsilon;",  "&#965;");
-        CODED_ENTITIES.put("&phi;",      "&#966;");
-        CODED_ENTITIES.put("&chi;",      "&#967;");
-        CODED_ENTITIES.put("&psi;",      "&#968;");
-        CODED_ENTITIES.put("&omega;",    "&#969;");
-        CODED_ENTITIES.put("&thetasym;", "&#977;");
-        CODED_ENTITIES.put("&upsih;",    "&#978;");
-        CODED_ENTITIES.put("&piv;",      "&#982;");
-        CODED_ENTITIES.put("&bull;",     "&#8226;");
-        CODED_ENTITIES.put("&hellip;",   "&#8230;");
-        CODED_ENTITIES.put("&prime;",    "&#8242;");
-        CODED_ENTITIES.put("&Prime;",    "&#8243;");
-        CODED_ENTITIES.put("&oline;",    "&#8254;");
-        CODED_ENTITIES.put("&frasl;",    "&#8260;");
-        CODED_ENTITIES.put("&weierp;",   "&#8472;");
-        CODED_ENTITIES.put("&image;",    "&#8465;");
-        CODED_ENTITIES.put("&real;",     "&#8476;");
-        CODED_ENTITIES.put("&trade;",    "&#8482;");
-        CODED_ENTITIES.put("&alefsym;",  "&#8501;");
-        CODED_ENTITIES.put("&larr;",     "&#8592;");
-        CODED_ENTITIES.put("&uarr;",     "&#8593;");
-        CODED_ENTITIES.put("&rarr;",     "&#8594;");
-        CODED_ENTITIES.put("&darr;",     "&#8595;");
-        CODED_ENTITIES.put("&harr;",     "&#8596;");
-        CODED_ENTITIES.put("&crarr;",    "&#8629;");
-        CODED_ENTITIES.put("&lArr;",     "&#8656;");
-        CODED_ENTITIES.put("&uArr;",     "&#8657;");
-        CODED_ENTITIES.put("&rArr;",     "&#8658;");
-        CODED_ENTITIES.put("&dArr;",     "&#8659;");
-        CODED_ENTITIES.put("&hArr;",     "&#8660;");
-        CODED_ENTITIES.put("&forall;",   "&#8704;");
-        CODED_ENTITIES.put("&part;",     "&#8706;");
-        CODED_ENTITIES.put("&exist;",    "&#8707;");
-        CODED_ENTITIES.put("&empty;",    "&#8709;");
-        CODED_ENTITIES.put("&nabla;",    "&#8711;");
-        CODED_ENTITIES.put("&isin;",     "&#8712;");
-        CODED_ENTITIES.put("&notin;",    "&#8713;");
-        CODED_ENTITIES.put("&ni;",       "&#8715;");
-        CODED_ENTITIES.put("&prod;",     "&#8719;");
-        CODED_ENTITIES.put("&sum;",      "&#8721;");
-        CODED_ENTITIES.put("&minus;",    "&#8722;");
-        CODED_ENTITIES.put("&lowast;",   "&#8727;");
-        CODED_ENTITIES.put("&radic;",    "&#8730;");
-        CODED_ENTITIES.put("&prop;",     "&#8733;");
-        CODED_ENTITIES.put("&infin;",    "&#8734;");
-        CODED_ENTITIES.put("&ang;",      "&#8736;");
-        CODED_ENTITIES.put("&and;",      "&#8743;");
-        CODED_ENTITIES.put("&or;",       "&#8744;");
-        CODED_ENTITIES.put("&cap;",      "&#8745;");
-        CODED_ENTITIES.put("&cup;",      "&#8746;");
-        CODED_ENTITIES.put("&int;",      "&#8747;");
-        CODED_ENTITIES.put("&there4;",   "&#8756;");
-        CODED_ENTITIES.put("&sim;",      "&#8764;");
-        CODED_ENTITIES.put("&cong;",     "&#8773;");
-        CODED_ENTITIES.put("&asymp;",    "&#8776;");
-        CODED_ENTITIES.put("&ne;",       "&#8800;");
-        CODED_ENTITIES.put("&equiv;",    "&#8801;");
-        CODED_ENTITIES.put("&le;",       "&#8804;");
-        CODED_ENTITIES.put("&ge;",       "&#8805;");
-        CODED_ENTITIES.put("&sub;",      "&#8834;");
-        CODED_ENTITIES.put("&sup;",      "&#8835;");
-        CODED_ENTITIES.put("&nsub;",     "&#8836;");
-        CODED_ENTITIES.put("&sube;",     "&#8838;");
-        CODED_ENTITIES.put("&supe;",     "&#8839;");
-        CODED_ENTITIES.put("&oplus;",    "&#8853;");
-        CODED_ENTITIES.put("&otimes;",   "&#8855;");
-        CODED_ENTITIES.put("&perp;",     "&#8869;");
-        CODED_ENTITIES.put("&sdot;",     "&#8901;");
-        CODED_ENTITIES.put("&lceil;",    "&#8968;");
-        CODED_ENTITIES.put("&rceil;",    "&#8969;");
-        CODED_ENTITIES.put("&lfloor;",   "&#8970;");
-        CODED_ENTITIES.put("&rfloor;",   "&#8971;");
-        CODED_ENTITIES.put("&lang;",     "&#9001;");
-        CODED_ENTITIES.put("&rang;",     "&#9002;");
-        CODED_ENTITIES.put("&loz;",      "&#9674;");
-        CODED_ENTITIES.put("&spades;",   "&#9824;");
-        CODED_ENTITIES.put("&clubs;",    "&#9827;");
-        CODED_ENTITIES.put("&hearts;",   "&#9829;");
-        CODED_ENTITIES.put("&diams;",    "&#9830;");
-
-       // Special characters for HTML.
-       // HTMLspecial "-//W3C//ENTITIES Special//EN//HTML"
-
-        CODED_ENTITIES.put("&quot;",      "&#34;");
-        CODED_ENTITIES.put("&amp;",       "&#38;");
-        CODED_ENTITIES.put("&lt;",        "&#60;");
-        CODED_ENTITIES.put("&gt;",        "&#62;");
-        CODED_ENTITIES.put("&OElig;",     "&#338;");
-        CODED_ENTITIES.put("&oelig;",     "&#339;");
-        CODED_ENTITIES.put("&Scaron;",    "&#352;");
-        CODED_ENTITIES.put("&scaron;",    "&#353;");
-        CODED_ENTITIES.put("&Yuml;",      "&#376;");
-        CODED_ENTITIES.put("&circ;",      "&#710;");
-        CODED_ENTITIES.put("&tilde;",     "&#732;");
-        CODED_ENTITIES.put("&ensp;",      "&#8194;");
-        CODED_ENTITIES.put("&emsp;",      "&#8195;");
-        CODED_ENTITIES.put("&thinsp;",    "&#8201;");
-        CODED_ENTITIES.put("&zwnj;",      "&#8204;");
-        CODED_ENTITIES.put("&zwj;",       "&#8205;");
-        CODED_ENTITIES.put("&lrm;",       "&#8206;");
-        CODED_ENTITIES.put("&rlm;",       "&#8207;");
-        CODED_ENTITIES.put("&ndash;",     "&#8211;");
-        CODED_ENTITIES.put("&mdash;",     "&#8212;");
-        CODED_ENTITIES.put("&lsquo;",     "&#8216;");
-        CODED_ENTITIES.put("&rsquo;",     "&#8217;");
-        CODED_ENTITIES.put("&sbquo;",     "&#8218;");
-        CODED_ENTITIES.put("&ldquo;",     "&#8220;");
-        CODED_ENTITIES.put("&rdquo;",     "&#8221;");
-        CODED_ENTITIES.put("&bdquo;",     "&#8222;");
-        CODED_ENTITIES.put("&dagger;",    "&#8224;");
-        CODED_ENTITIES.put("&Dagger;",    "&#8225;");
-        CODED_ENTITIES.put("&permil;",    "&#8240;");
-        CODED_ENTITIES.put("&lsaquo;",    "&#8249;");
-        CODED_ENTITIES.put("&rsaquo;",    "&#8250;");
-        CODED_ENTITIES.put("&euro;",      "&#8364;");
-    }
-
-    //
-    // It shouldn't be here but well, just reusing the CODED_ENTITIES Map :)
-    //
-
-    private static Pattern ENTITIES_PATTERN = Pattern.compile( "&[A-Za-z^#]+;" );
-
-
-    public String processHtmlEntities(String s) {
-        if (s.indexOf('&')==-1) {
-            return s;
-        }
-        StringBuffer sb = new StringBuffer(s.length());
-        int pos = 0;
-        while (pos<s.length()) {
-            String chunck = s.substring(pos);
-            Matcher m = ENTITIES_PATTERN.matcher(chunck);
-            if (m.find()) {
-                int b = pos + m.start();
-                int e = pos + m.end();
-                if (b>pos) {
-                    sb.append(s.substring(pos,b));
-                    pos = b;
-                }
-                chunck = s.substring(pos,e);
-                String codedEntity = (String) CODED_ENTITIES.get(chunck);
-                if (codedEntity==null) {
-                    codedEntity = chunck;
-                }
-                sb.append(codedEntity);
-                pos = e;
-            }
-            else {
-                sb.append(chunck);
-                pos += chunck.length();
-            }
-        }
-        return sb.toString();
-    }
+	public XmlFixerReader(Reader in) {
+		super(in);
+		this.in = in;
+		_buffer = new StringBuffer();
+		_state = 0;
+	}
+
+	private boolean trimmed;
+	private StringBuffer _buffer;
+	private int _bufferPos;
+	private int _state = 0;
+
+	private boolean trimStream() throws IOException {
+		boolean hasContent = true;
+		int state = 0;
+		boolean loop;
+		int c;
+		do {
+			switch (state) {
+			case 0:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = false;
+				} else if (c == ' ' || c == '\n') {
+					loop = true;
+				} else if (c == '<') {
+					state = 1;
+					_buffer.setLength(0);
+					_bufferPos = 0;
+					_buffer.append((char) c);
+					loop = true;
+				} else {
+					_buffer.setLength(0);
+					_bufferPos = 0;
+					_buffer.append((char) c);
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				}
+				break;
+			case 1:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else if (c != '!') {
+					_buffer.append((char) c);
+					_state = 3;
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else {
+					_buffer.append((char) c);
+					state = 2;
+					loop = true;
+				}
+				break;
+			case 2:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else if (c == '-') {
+					_buffer.append((char) c);
+					state = 3;
+					loop = true;
+				} else {
+					_buffer.append((char) c);
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				}
+				break;
+			case 3:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else if (c == '-') {
+					_buffer.append((char) c);
+					state = 4;
+					loop = true;
+				} else {
+					_buffer.append((char) c);
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				}
+				break;
+			case 4:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else if (c != '-') {
+					_buffer.append((char) c);
+					loop = true;
+				} else {
+					_buffer.append((char) c);
+					state = 5;
+					loop = true;
+				}
+				break;
+			case 5:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else if (c != '-') {
+					_buffer.append((char) c);
+					loop = true;
+					state = 4;
+				} else {
+					_buffer.append((char) c);
+					state = 6;
+					loop = true;
+				}
+				break;
+			case 6:
+				c = in.read();
+				if (c == -1) {
+					loop = false;
+					hasContent = true;
+					_state = 3;
+				} else if (c != '>') {
+					_buffer.append((char) c);
+					loop = true;
+					state = 4;
+				} else {
+					_buffer.setLength(0);
+					state = 0;
+					loop = true;
+				}
+				break;
+			default:
+				throw new IOException("It shouldn't happen");
+			}
+		} while (loop);
+		return hasContent;
+	}
+
+	public int read() throws IOException {
+		boolean loop;
+		if (!trimmed) { // trims XML stream
+			trimmed = true;
+			if (!trimStream()) {
+				return -1;
+			}
+		}
+		int c;
+		do { // converts literal entities to coded entities
+			switch (_state) {
+			case 0: // reading chars from stream
+				c = in.read();
+				if (c > -1) {
+					if (c == '&') {
+						_state = 1;
+						_buffer.setLength(0);
+						_bufferPos = 0;
+						_buffer.append((char) c);
+						_state = 1;
+						loop = true;
+					} else {
+						loop = false;
+					}
+				} else {
+					loop = false;
+				}
+				break;
+			case 1: // reading entity from stream
+				c = in.read();
+				if (c > -1) {
+					if (c == ';') {
+						_buffer.append((char) c);
+						_state = 2;
+						loop = true;
+					} else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+							|| (c == '#') || (c >= '0' && c <= '9')) {
+						_buffer.append((char) c);
+						loop = true;
+					} else {
+						// no ';' to match the '&' lets just make the '&'
+						// a legal xml character entity '&amp;'
+						_buffer.insert(1, "amp;");
+						_buffer.append((char) c);
+						_state = 3;
+						loop = true;
+					}
+				} else {
+					// no ';' to match the '&' lets just make the '&'
+					// a legal xml character entity '&amp;'
+					_buffer.insert(1, "amp;");
+					_state = 3;
+					loop = true;
+				}
+				break;
+			case 2: // replacing entity
+				c = 0;
+				String literalEntity = _buffer.toString();
+				String codedEntity = (String) CODED_ENTITIES.get(literalEntity);
+				if (codedEntity != null) {
+					_buffer.setLength(0);
+					_buffer.append(codedEntity);
+				} // else we leave what was in the stream
+				_state = 3;
+				loop = true;
+				break;
+			case 3: // consuming buffer
+				if (_bufferPos < _buffer.length()) {
+					c = _buffer.charAt(_bufferPos++);
+					loop = false;
+				} else {
+					c = 0;
+					_state = 0;
+					loop = true;
+				}
+				break;
+			default:
+				throw new IOException("It shouldn't happen");
+			}
+		} while (loop);
+		return c;
+	}
+
+	public int read(char[] buffer, int offset, int len) throws IOException {
+		int charsRead = 0;
+		int c = read();
+		if (c == -1) {
+			return -1;
+		}
+		buffer[offset + (charsRead++)] = (char) c;
+		while (charsRead < len && (c = read()) > -1) {
+			buffer[offset + (charsRead++)] = (char) c;
+		}
+		return charsRead;
+	}
+
+	public long skip(long n) throws IOException {
+		if (n == 0) {
+			return 0;
+		} else if (n < 0) {
+			throw new IllegalArgumentException("'n' cannot be negative");
+		}
+		int c = read();
+		long counter = 1;
+		while (c > -1 && counter < n) {
+			c = read();
+			counter++;
+		}
+		return counter;
+	}
+
+	public boolean ready() throws IOException {
+		return (_state != 0) || in.ready();
+	}
+
+	public boolean markSupported() {
+		return false;
+	}
+
+	public void mark(int readAheadLimit) throws IOException {
+		throw new IOException("Stream does not support mark");
+	}
+
+	public void reset() throws IOException {
+		throw new IOException("Stream does not support mark");
+	}
+
+	public void close() throws IOException {
+		in.close();
+	}
+
+	private static Map<String, String> CODED_ENTITIES = new HashMap<String, String>();
+
+	static {
+		// note: refer to Character entity references in HTML 4
+		// at http://www.w3.org/TR/REC-html40/sgml/entities.html
+
+		// Character entity set.
+		// HTMLlat1 "-//W3C//ENTITIES Latin 1//EN//HTML"
+
+		CODED_ENTITIES.put("&nbsp;", "&#160;");
+		CODED_ENTITIES.put("&iexcl;", "&#161;");
+		CODED_ENTITIES.put("&cent;", "&#162;");
+		CODED_ENTITIES.put("&pound;", "&#163;");
+		CODED_ENTITIES.put("&curren;", "&#164;");
+		CODED_ENTITIES.put("&yen;", "&#165;");
+		CODED_ENTITIES.put("&brvbar;", "&#166;");
+		CODED_ENTITIES.put("&sect;", "&#167;");
+		CODED_ENTITIES.put("&uml;", "&#168;");
+		CODED_ENTITIES.put("&copy;", "&#169;");
+		CODED_ENTITIES.put("&ordf;", "&#170;");
+		CODED_ENTITIES.put("&laquo;", "&#171;");
+		CODED_ENTITIES.put("&not;", "&#172;");
+		CODED_ENTITIES.put("&shy;", "&#173;");
+		CODED_ENTITIES.put("&reg;", "&#174;");
+		CODED_ENTITIES.put("&macr;", "&#175;");
+		CODED_ENTITIES.put("&deg;", "&#176;");
+		CODED_ENTITIES.put("&plusmn;", "&#177;");
+		CODED_ENTITIES.put("&sup2;", "&#178;");
+		CODED_ENTITIES.put("&sup3;", "&#179;");
+		CODED_ENTITIES.put("&acute;", "&#180;");
+		CODED_ENTITIES.put("&micro;", "&#181;");
+		CODED_ENTITIES.put("&para;", "&#182;");
+		CODED_ENTITIES.put("&middot;", "&#183;");
+		CODED_ENTITIES.put("&cedil;", "&#184;");
+		CODED_ENTITIES.put("&sup1;", "&#185;");
+		CODED_ENTITIES.put("&ordm;", "&#186;");
+		CODED_ENTITIES.put("&raquo;", "&#187;");
+		CODED_ENTITIES.put("&frac14;", "&#188;");
+		CODED_ENTITIES.put("&frac12;", "&#189;");
+		CODED_ENTITIES.put("&frac34;", "&#190;");
+		CODED_ENTITIES.put("&iquest;", "&#191;");
+		CODED_ENTITIES.put("&Agrave;", "&#192;");
+		CODED_ENTITIES.put("&Aacute;", "&#193;");
+		CODED_ENTITIES.put("&Acirc;", "&#194;");
+		CODED_ENTITIES.put("&Atilde;", "&#195;");
+		CODED_ENTITIES.put("&Auml;", "&#196;");
+		CODED_ENTITIES.put("&Aring;", "&#197;");
+		CODED_ENTITIES.put("&AElig;", "&#198;");
+		CODED_ENTITIES.put("&Ccedil;", "&#199;");
+		CODED_ENTITIES.put("&Egrave;", "&#200;");
+		CODED_ENTITIES.put("&Eacute;", "&#201;");
+		CODED_ENTITIES.put("&Ecirc;", "&#202;");
+		CODED_ENTITIES.put("&Euml;", "&#203;");
+		CODED_ENTITIES.put("&Igrave;", "&#204;");
+		CODED_ENTITIES.put("&Iacute;", "&#205;");
+		CODED_ENTITIES.put("&Icirc;", "&#206;");
+		CODED_ENTITIES.put("&Iuml;", "&#207;");
+		CODED_ENTITIES.put("&ETH;", "&#208;");
+		CODED_ENTITIES.put("&Ntilde;", "&#209;");
+		CODED_ENTITIES.put("&Ograve;", "&#210;");
+		CODED_ENTITIES.put("&Oacute;", "&#211;");
+		CODED_ENTITIES.put("&Ocirc;", "&#212;");
+		CODED_ENTITIES.put("&Otilde;", "&#213;");
+		CODED_ENTITIES.put("&Ouml;", "&#214;");
+		CODED_ENTITIES.put("&times;", "&#215;");
+		CODED_ENTITIES.put("&Oslash;", "&#216;");
+		CODED_ENTITIES.put("&Ugrave;", "&#217;");
+		CODED_ENTITIES.put("&Uacute;", "&#218;");
+		CODED_ENTITIES.put("&Ucirc;", "&#219;");
+		CODED_ENTITIES.put("&Uuml;", "&#220;");
+		CODED_ENTITIES.put("&Yacute;", "&#221;");
+		CODED_ENTITIES.put("&THORN;", "&#222;");
+		CODED_ENTITIES.put("&szlig;", "&#223;");
+		CODED_ENTITIES.put("&agrave;", "&#224;");
+		CODED_ENTITIES.put("&aacute;", "&#225;");
+		CODED_ENTITIES.put("&acirc;", "&#226;");
+		CODED_ENTITIES.put("&atilde;", "&#227;");
+		CODED_ENTITIES.put("&auml;", "&#228;");
+		CODED_ENTITIES.put("&aring;", "&#229;");
+		CODED_ENTITIES.put("&aelig;", "&#230;");
+		CODED_ENTITIES.put("&ccedil;", "&#231;");
+		CODED_ENTITIES.put("&egrave;", "&#232;");
+		CODED_ENTITIES.put("&eacute;", "&#233;");
+		CODED_ENTITIES.put("&ecirc;", "&#234;");
+		CODED_ENTITIES.put("&euml;", "&#235;");
+		CODED_ENTITIES.put("&igrave;", "&#236;");
+		CODED_ENTITIES.put("&iacute;", "&#237;");
+		CODED_ENTITIES.put("&icirc;", "&#238;");
+		CODED_ENTITIES.put("&iuml;", "&#239;");
+		CODED_ENTITIES.put("&eth;", "&#240;");
+		CODED_ENTITIES.put("&ntilde;", "&#241;");
+		CODED_ENTITIES.put("&ograve;", "&#242;");
+		CODED_ENTITIES.put("&oacute;", "&#243;");
+		CODED_ENTITIES.put("&ocirc;", "&#244;");
+		CODED_ENTITIES.put("&otilde;", "&#245;");
+		CODED_ENTITIES.put("&ouml;", "&#246;");
+		CODED_ENTITIES.put("&divide;", "&#247;");
+		CODED_ENTITIES.put("&oslash;", "&#248;");
+		CODED_ENTITIES.put("&ugrave;", "&#249;");
+		CODED_ENTITIES.put("&uacute;", "&#250;");
+		CODED_ENTITIES.put("&ucirc;", "&#251;");
+		CODED_ENTITIES.put("&uuml;", "&#252;");
+		CODED_ENTITIES.put("&yacute;", "&#253;");
+		CODED_ENTITIES.put("&thorn;", "&#254;");
+		CODED_ENTITIES.put("&yuml;", "&#255;");
+
+		// Mathematical, Greek and Symbolic characters for HTML.
+		// HTMLsymbol "-//W3C//ENTITIES Symbols//EN//HTML"
+
+		CODED_ENTITIES.put("&fnof;", "&#402;");
+		CODED_ENTITIES.put("&Alpha;", "&#913;");
+		CODED_ENTITIES.put("&Beta;", "&#914;");
+		CODED_ENTITIES.put("&Gamma;", "&#915;");
+		CODED_ENTITIES.put("&Delta;", "&#916;");
+		CODED_ENTITIES.put("&Epsilon;", "&#917;");
+		CODED_ENTITIES.put("&Zeta;", "&#918;");
+		CODED_ENTITIES.put("&Eta;", "&#919;");
+		CODED_ENTITIES.put("&Theta;", "&#920;");
+		CODED_ENTITIES.put("&Iota;", "&#921;");
+		CODED_ENTITIES.put("&Kappa;", "&#922;");
+		CODED_ENTITIES.put("&Lambda;", "&#923;");
+		CODED_ENTITIES.put("&Mu;", "&#924;");
+		CODED_ENTITIES.put("&Nu;", "&#925;");
+		CODED_ENTITIES.put("&Xi;", "&#926;");
+		CODED_ENTITIES.put("&Omicron;", "&#927;");
+		CODED_ENTITIES.put("&Pi;", "&#928;");
+		CODED_ENTITIES.put("&Rho;", "&#929;");
+		CODED_ENTITIES.put("&Sigma;", "&#931;");
+		CODED_ENTITIES.put("&Tau;", "&#932;");
+		CODED_ENTITIES.put("&Upsilon;", "&#933;");
+		CODED_ENTITIES.put("&Phi;", "&#934;");
+		CODED_ENTITIES.put("&Chi;", "&#935;");
+		CODED_ENTITIES.put("&Psi;", "&#936;");
+		CODED_ENTITIES.put("&Omega;", "&#937;");
+		CODED_ENTITIES.put("&alpha;", "&#945;");
+		CODED_ENTITIES.put("&beta;", "&#946;");
+		CODED_ENTITIES.put("&gamma;", "&#947;");
+		CODED_ENTITIES.put("&delta;", "&#948;");
+		CODED_ENTITIES.put("&epsilon;", "&#949;");
+		CODED_ENTITIES.put("&zeta;", "&#950;");
+		CODED_ENTITIES.put("&eta;", "&#951;");
+		CODED_ENTITIES.put("&theta;", "&#952;");
+		CODED_ENTITIES.put("&iota;", "&#953;");
+		CODED_ENTITIES.put("&kappa;", "&#954;");
+		CODED_ENTITIES.put("&lambda;", "&#955;");
+		CODED_ENTITIES.put("&mu;", "&#956;");
+		CODED_ENTITIES.put("&nu;", "&#957;");
+		CODED_ENTITIES.put("&xi;", "&#958;");
+		CODED_ENTITIES.put("&omicron;", "&#959;");
+		CODED_ENTITIES.put("&pi;", "&#960;");
+		CODED_ENTITIES.put("&rho;", "&#961;");
+		CODED_ENTITIES.put("&sigmaf;", "&#962;");
+		CODED_ENTITIES.put("&sigma;", "&#963;");
+		CODED_ENTITIES.put("&tau;", "&#964;");
+		CODED_ENTITIES.put("&upsilon;", "&#965;");
+		CODED_ENTITIES.put("&phi;", "&#966;");
+		CODED_ENTITIES.put("&chi;", "&#967;");
+		CODED_ENTITIES.put("&psi;", "&#968;");
+		CODED_ENTITIES.put("&omega;", "&#969;");
+		CODED_ENTITIES.put("&thetasym;", "&#977;");
+		CODED_ENTITIES.put("&upsih;", "&#978;");
+		CODED_ENTITIES.put("&piv;", "&#982;");
+		CODED_ENTITIES.put("&bull;", "&#8226;");
+		CODED_ENTITIES.put("&hellip;", "&#8230;");
+		CODED_ENTITIES.put("&prime;", "&#8242;");
+		CODED_ENTITIES.put("&Prime;", "&#8243;");
+		CODED_ENTITIES.put("&oline;", "&#8254;");
+		CODED_ENTITIES.put("&frasl;", "&#8260;");
+		CODED_ENTITIES.put("&weierp;", "&#8472;");
+		CODED_ENTITIES.put("&image;", "&#8465;");
+		CODED_ENTITIES.put("&real;", "&#8476;");
+		CODED_ENTITIES.put("&trade;", "&#8482;");
+		CODED_ENTITIES.put("&alefsym;", "&#8501;");
+		CODED_ENTITIES.put("&larr;", "&#8592;");
+		CODED_ENTITIES.put("&uarr;", "&#8593;");
+		CODED_ENTITIES.put("&rarr;", "&#8594;");
+		CODED_ENTITIES.put("&darr;", "&#8595;");
+		CODED_ENTITIES.put("&harr;", "&#8596;");
+		CODED_ENTITIES.put("&crarr;", "&#8629;");
+		CODED_ENTITIES.put("&lArr;", "&#8656;");
+		CODED_ENTITIES.put("&uArr;", "&#8657;");
+		CODED_ENTITIES.put("&rArr;", "&#8658;");
+		CODED_ENTITIES.put("&dArr;", "&#8659;");
+		CODED_ENTITIES.put("&hArr;", "&#8660;");
+		CODED_ENTITIES.put("&forall;", "&#8704;");
+		CODED_ENTITIES.put("&part;", "&#8706;");
+		CODED_ENTITIES.put("&exist;", "&#8707;");
+		CODED_ENTITIES.put("&empty;", "&#8709;");
+		CODED_ENTITIES.put("&nabla;", "&#8711;");
+		CODED_ENTITIES.put("&isin;", "&#8712;");
+		CODED_ENTITIES.put("&notin;", "&#8713;");
+		CODED_ENTITIES.put("&ni;", "&#8715;");
+		CODED_ENTITIES.put("&prod;", "&#8719;");
+		CODED_ENTITIES.put("&sum;", "&#8721;");
+		CODED_ENTITIES.put("&minus;", "&#8722;");
+		CODED_ENTITIES.put("&lowast;", "&#8727;");
+		CODED_ENTITIES.put("&radic;", "&#8730;");
+		CODED_ENTITIES.put("&prop;", "&#8733;");
+		CODED_ENTITIES.put("&infin;", "&#8734;");
+		CODED_ENTITIES.put("&ang;", "&#8736;");
+		CODED_ENTITIES.put("&and;", "&#8743;");
+		CODED_ENTITIES.put("&or;", "&#8744;");
+		CODED_ENTITIES.put("&cap;", "&#8745;");
+		CODED_ENTITIES.put("&cup;", "&#8746;");
+		CODED_ENTITIES.put("&int;", "&#8747;");
+		CODED_ENTITIES.put("&there4;", "&#8756;");
+		CODED_ENTITIES.put("&sim;", "&#8764;");
+		CODED_ENTITIES.put("&cong;", "&#8773;");
+		CODED_ENTITIES.put("&asymp;", "&#8776;");
+		CODED_ENTITIES.put("&ne;", "&#8800;");
+		CODED_ENTITIES.put("&equiv;", "&#8801;");
+		CODED_ENTITIES.put("&le;", "&#8804;");
+		CODED_ENTITIES.put("&ge;", "&#8805;");
+		CODED_ENTITIES.put("&sub;", "&#8834;");
+		CODED_ENTITIES.put("&sup;", "&#8835;");
+		CODED_ENTITIES.put("&nsub;", "&#8836;");
+		CODED_ENTITIES.put("&sube;", "&#8838;");
+		CODED_ENTITIES.put("&supe;", "&#8839;");
+		CODED_ENTITIES.put("&oplus;", "&#8853;");
+		CODED_ENTITIES.put("&otimes;", "&#8855;");
+		CODED_ENTITIES.put("&perp;", "&#8869;");
+		CODED_ENTITIES.put("&sdot;", "&#8901;");
+		CODED_ENTITIES.put("&lceil;", "&#8968;");
+		CODED_ENTITIES.put("&rceil;", "&#8969;");
+		CODED_ENTITIES.put("&lfloor;", "&#8970;");
+		CODED_ENTITIES.put("&rfloor;", "&#8971;");
+		CODED_ENTITIES.put("&lang;", "&#9001;");
+		CODED_ENTITIES.put("&rang;", "&#9002;");
+		CODED_ENTITIES.put("&loz;", "&#9674;");
+		CODED_ENTITIES.put("&spades;", "&#9824;");
+		CODED_ENTITIES.put("&clubs;", "&#9827;");
+		CODED_ENTITIES.put("&hearts;", "&#9829;");
+		CODED_ENTITIES.put("&diams;", "&#9830;");
+
+		// Special characters for HTML.
+		// HTMLspecial "-//W3C//ENTITIES Special//EN//HTML"
+
+		CODED_ENTITIES.put("&quot;", "&#34;");
+		CODED_ENTITIES.put("&amp;", "&#38;");
+		CODED_ENTITIES.put("&lt;", "&#60;");
+		CODED_ENTITIES.put("&gt;", "&#62;");
+		CODED_ENTITIES.put("&OElig;", "&#338;");
+		CODED_ENTITIES.put("&oelig;", "&#339;");
+		CODED_ENTITIES.put("&Scaron;", "&#352;");
+		CODED_ENTITIES.put("&scaron;", "&#353;");
+		CODED_ENTITIES.put("&Yuml;", "&#376;");
+		CODED_ENTITIES.put("&circ;", "&#710;");
+		CODED_ENTITIES.put("&tilde;", "&#732;");
+		CODED_ENTITIES.put("&ensp;", "&#8194;");
+		CODED_ENTITIES.put("&emsp;", "&#8195;");
+		CODED_ENTITIES.put("&thinsp;", "&#8201;");
+		CODED_ENTITIES.put("&zwnj;", "&#8204;");
+		CODED_ENTITIES.put("&zwj;", "&#8205;");
+		CODED_ENTITIES.put("&lrm;", "&#8206;");
+		CODED_ENTITIES.put("&rlm;", "&#8207;");
+		CODED_ENTITIES.put("&ndash;", "&#8211;");
+		CODED_ENTITIES.put("&mdash;", "&#8212;");
+		CODED_ENTITIES.put("&lsquo;", "&#8216;");
+		CODED_ENTITIES.put("&rsquo;", "&#8217;");
+		CODED_ENTITIES.put("&sbquo;", "&#8218;");
+		CODED_ENTITIES.put("&ldquo;", "&#8220;");
+		CODED_ENTITIES.put("&rdquo;", "&#8221;");
+		CODED_ENTITIES.put("&bdquo;", "&#8222;");
+		CODED_ENTITIES.put("&dagger;", "&#8224;");
+		CODED_ENTITIES.put("&Dagger;", "&#8225;");
+		CODED_ENTITIES.put("&permil;", "&#8240;");
+		CODED_ENTITIES.put("&lsaquo;", "&#8249;");
+		CODED_ENTITIES.put("&rsaquo;", "&#8250;");
+		CODED_ENTITIES.put("&euro;", "&#8364;");
+	}
+
+	//
+	// It shouldn't be here but well, just reusing the CODED_ENTITIES Map :)
+	//
+
+	private static Pattern ENTITIES_PATTERN = Pattern.compile("&[A-Za-z^#]+;");
+
+	public String processHtmlEntities(String s) {
+		if (s.indexOf('&') == -1) {
+			return s;
+		}
+		StringBuffer sb = new StringBuffer(s.length());
+		int pos = 0;
+		while (pos < s.length()) {
+			String chunck = s.substring(pos);
+			Matcher m = ENTITIES_PATTERN.matcher(chunck);
+			if (m.find()) {
+				int b = pos + m.start();
+				int e = pos + m.end();
+				if (b > pos) {
+					sb.append(s.substring(pos, b));
+					pos = b;
+				}
+				chunck = s.substring(pos, e);
+				String codedEntity = (String) CODED_ENTITIES.get(chunck);
+				if (codedEntity == null) {
+					codedEntity = chunck;
+				}
+				sb.append(codedEntity);
+				pos = e;
+			} else {
+				sb.append(chunck);
+				pos += chunck.length();
+			}
+		}
+		return sb.toString();
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/PropertiesLoader.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/PropertiesLoader.java,v
retrieving revision 1.2
diff -u -r1.2 PropertiesLoader.java
--- src/java/com/sun/syndication/io/impl/PropertiesLoader.java	31 Jul 2007 16:58:07 -0000	1.2
+++ src/java/com/sun/syndication/io/impl/PropertiesLoader.java	30 Sep 2009 06:30:44 -0000
@@ -6,150 +6,166 @@
 import java.util.*;
 
 /**
- * Properties loader that aggregates a master properties file and several extra properties files,
- * all from the current classpath.
+ * Properties loader that aggregates a master properties file and several extra
+ * properties files, all from the current classpath.
  * <P>
- * The master properties file has to be in a distinct location than the extra properties files.
- * First the master properties file is loaded, then all the extra properties files in their order
- * of appearance in the classpath.
+ * The master properties file has to be in a distinct location than the extra
+ * properties files. First the master properties file is loaded, then all the
+ * extra properties files in their order of appearance in the classpath.
  * <P>
- * Current use cases (plugin manager for parsers/converters/generators for feeds and modules
- * and date formats) assume properties are list of tokens, that why the only method to get
- * property values is the getTokenizedProperty().
+ * Current use cases (plugin manager for parsers/converters/generators for feeds
+ * and modules and date formats) assume properties are list of tokens, that why
+ * the only method to get property values is the getTokenizedProperty().
  * <p>
- *
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
 public class PropertiesLoader {
 
-    private static final String MASTER_PLUGIN_FILE = "com/sun/syndication/rome.properties";
-    private static final String EXTRA_PLUGIN_FILE = "rome.properties";
+	private static final String MASTER_PLUGIN_FILE = "com/sun/syndication/rome.properties";
 
+	private static final String EXTRA_PLUGIN_FILE = "rome.properties";
 
-    private static Map clMap =
-        new WeakHashMap();
+	private static Map<ClassLoader, PropertiesLoader> clMap = new WeakHashMap<ClassLoader, PropertiesLoader>();
 
+	private Properties[] _properties;
 
-    /**
-     * Returns the PropertiesLoader singleton used by ROME to load plugin components.
-     *
-     * @return PropertiesLoader singleton.
-     *
-     */
-    public static PropertiesLoader getPropertiesLoader() {
-        synchronized(PropertiesLoader.class) {
-            PropertiesLoader loader = (PropertiesLoader)
-                clMap.get(Thread.currentThread().getContextClassLoader());
-            if (loader == null) {
-                try {
-                    loader = new PropertiesLoader(MASTER_PLUGIN_FILE, EXTRA_PLUGIN_FILE);
-                    clMap.put(Thread.currentThread().getContextClassLoader(), loader);
-                }
-                catch (IOException ex) {
-                    throw new RuntimeException(ex);
-                }
-            }
-            return loader;
-        }
-    }
-
-    private Properties[] _properties;
-
-    /**
-     * Creates a PropertiesLoader.
-     * <p>
-     * @param masterFileLocation master file location, there must be only one.
-     * @param extraFileLocation extra file location, there may be many.
-     * @throws IOException thrown if one of the properties file could not be read.
-     *
-     */
-    private PropertiesLoader(String masterFileLocation,String extraFileLocation) throws IOException {
-        List propertiesList = new ArrayList();
-        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
-        try {
-            InputStream is = classLoader.getResourceAsStream(masterFileLocation);
-            Properties p = new Properties();
-            p.load(is);
-            is.close();
-            propertiesList.add(p);
-        }
-        catch (IOException ioex) {
-            IOException ex = new IOException("could not load ROME master plugins file ["+masterFileLocation+"], "+
-                                             ioex.getMessage());
-            ex.setStackTrace(ioex.getStackTrace());
-            throw ex;
-        }
-
-        Enumeration urls = classLoader.getResources(extraFileLocation);
-        while (urls.hasMoreElements()) {
-            URL url = (URL) urls.nextElement();
-            Properties p = new Properties();
-            try {
-                InputStream is = url.openStream();
-                p.load(is);
-                is.close();
-            }
-            catch (IOException ioex) {
-                IOException ex = new IOException("could not load ROME extensions plugins file ["+url.toString()+"], "+
-                                                 ioex.getMessage());
-                ex.setStackTrace(ioex.getStackTrace());
-                throw ex;
-            }
-            propertiesList.add(p);
-        }
-
-        _properties = new Properties[propertiesList.size()];
-        propertiesList.toArray(_properties);
-    }
-
-    /**
-     * Returns an array of tokenized values stored under a property key in all properties files.
-     * If the master file has this property its tokens will be the first ones in the array.
-     * <p>
-     * @param key property key to retrieve values
-     * @param separator String with all separator characters to tokenize from the values in all
-     * properties files.
-     * @return all the tokens for the given property key from all the properties files.
-     *
-     */
-    public String[] getTokenizedProperty(String key,String separator) {
-        List entriesList = new ArrayList();
-        for (int i=0;i<_properties.length;i++) {
-            String values = _properties[i].getProperty(key);
-            if (values!=null) {
-                StringTokenizer st = new StringTokenizer(values,separator);
-                while (st.hasMoreTokens()) {
-                    String token = st.nextToken();
-                    entriesList.add(token);
-                }
-            }
-        }
-        String[] entries = new String[entriesList.size()];
-        entriesList.toArray(entries);
-        return entries;
-    }
-
-    /**
-     * Returns an array of values stored under a property key in all properties files.
-     * If the master file has this property it will be the first ones in the array.
-     * <p>
-     * @param key property key to retrieve values
-     * @return all the values for the given property key from all the properties files.
-     *
-     */
-    public String[] getProperty(String key) {
-        List entriesList = new ArrayList();
-        for (int i=0;i<_properties.length;i++) {
-            String values = _properties[i].getProperty(key);
-            if (values!=null) {
-                entriesList.add(values);
-            }
-        }
-        String[] entries = new String[entriesList.size()];
-        entriesList.toArray(entries);
-        return entries;
-    }
+	/**
+	 * Returns the PropertiesLoader singleton used by ROME to load plugin
+	 * components.
+	 * 
+	 * @return PropertiesLoader singleton.
+	 * 
+	 */
+	public static PropertiesLoader getPropertiesLoader() {
+		synchronized (PropertiesLoader.class) {
+			final ClassLoader classLoader = Thread.currentThread()
+					.getContextClassLoader();
+			PropertiesLoader loader = (PropertiesLoader) clMap.get(classLoader);
+			if (loader == null) {
+				try {
+					loader = new PropertiesLoader(MASTER_PLUGIN_FILE,
+							EXTRA_PLUGIN_FILE);
+					clMap.put(classLoader, loader);
+				} catch (IOException ex) {
+					throw new RuntimeException(ex);
+				}
+			}
+			return loader;
+		}
+	}
+
+	/**
+	 * Creates a PropertiesLoader.
+	 * <p>
+	 * 
+	 * @param masterFileLocation
+	 *            master file location, there must be only one.
+	 * @param extraFileLocation
+	 *            extra file location, there may be many.
+	 * @throws IOException
+	 *             thrown if one of the properties file could not be read.
+	 * 
+	 */
+	private PropertiesLoader(String masterFileLocation, String extraFileLocation)
+			throws IOException {
+		List<Properties> propertiesList = new ArrayList<Properties>();
+		ClassLoader classLoader = Thread.currentThread()
+				.getContextClassLoader();
+
+		try {
+			InputStream is = classLoader
+					.getResourceAsStream(masterFileLocation);
+			Properties p = new Properties();
+			p.load(is);
+			is.close();
+			propertiesList.add(p);
+		} catch (IOException ioex) {
+			IOException ex = new IOException(
+					"could not load ROME master plugins file ["
+							+ masterFileLocation + "], " + ioex.getMessage());
+			ex.setStackTrace(ioex.getStackTrace());
+			throw ex;
+		}
+
+		Enumeration<URL> urls = classLoader.getResources(extraFileLocation);
+		while (urls.hasMoreElements()) {
+			URL url = urls.nextElement();
+			Properties p = new Properties();
+			try {
+				InputStream is = url.openStream();
+				p.load(is);
+				is.close();
+			} catch (IOException ioex) {
+				IOException ex = new IOException(
+						"could not load ROME extensions plugins file ["
+								+ url.toString() + "], " + ioex.getMessage());
+				ex.setStackTrace(ioex.getStackTrace());
+				throw ex;
+			}
+			propertiesList.add(p);
+		}
+
+		_properties = new Properties[propertiesList.size()];
+		propertiesList.toArray(_properties);
+	}
+
+	/**
+	 * Returns an array of tokenized values stored under a property key in all
+	 * properties files. If the master file has this property its tokens will be
+	 * the first ones in the array.
+	 * <p>
+	 * 
+	 * @param key
+	 *            property key to retrieve values
+	 * @param separator
+	 *            String with all separator characters to tokenize from the
+	 *            values in all properties files.
+	 * @return all the tokens for the given property key from all the properties
+	 *         files.
+	 * 
+	 */
+	public String[] getTokenizedProperty(String key, String separator) {
+		List<String> entriesList = new ArrayList<String>();
+		for (int i = 0; i < _properties.length; i++) {
+			String values = _properties[i].getProperty(key);
+			if (values != null) {
+				StringTokenizer st = new StringTokenizer(values, separator);
+				while (st.hasMoreTokens()) {
+					String token = st.nextToken();
+					entriesList.add(token);
+				}
+			}
+		}
+		String[] entries = new String[entriesList.size()];
+		entriesList.toArray(entries);
+		return entries;
+	}
+
+	/**
+	 * Returns an array of values stored under a property key in all properties
+	 * files. If the master file has this property it will be the first ones in
+	 * the array.
+	 * <p>
+	 * 
+	 * @param key
+	 *            property key to retrieve values
+	 * @return all the values for the given property key from all the properties
+	 *         files.
+	 * 
+	 */
+	public String[] getProperty(String key) {
+		List<String> entriesList = new ArrayList<String>();
+		for (int i = 0; i < _properties.length; i++) {
+			String values = _properties[i].getProperty(key);
+			if (values != null) {
+				entriesList.add(values);
+			}
+		}
+		String[] entries = new String[entriesList.size()];
+		entriesList.toArray(entries);
+		return entries;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/ModuleGenerators.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/ModuleGenerators.java,v
retrieving revision 1.5
diff -u -r1.5 ModuleGenerators.java
--- src/java/com/sun/syndication/io/impl/ModuleGenerators.java	15 Sep 2006 00:51:47 -0000	1.5
+++ src/java/com/sun/syndication/io/impl/ModuleGenerators.java	30 Sep 2009 06:30:44 -0000
@@ -19,6 +19,7 @@
 import com.sun.syndication.feed.module.Module;
 import com.sun.syndication.io.ModuleGenerator;
 import org.jdom.Element;
+import org.jdom.Namespace;
 
 import java.util.HashSet;
 import java.util.List;
@@ -28,45 +29,48 @@
 /**
  */
 public class ModuleGenerators extends PluginManager {
-    private Set _allNamespaces;
 
-    public ModuleGenerators(String propertyKey, BaseWireFeedGenerator parentGenerator) {
-        super(propertyKey, null, parentGenerator);
-    }
-
-    public ModuleGenerator getGenerator(String uri) {
-        return (ModuleGenerator) getPlugin(uri);
-    }
-
-    protected String getKey(Object obj) {
-        return ((ModuleGenerator)obj).getNamespaceUri();
-    }
-
-    public List getModuleNamespaces() {
-        return getKeys();
-    }
-
-    public void generateModules(List modules, Element element) {
-        Map generators = getPluginMap();
-        for (int i = 0; i < modules.size(); i++) {
-            Module module = (Module) modules.get(i);
-            String namespaceUri = module.getUri();
-            ModuleGenerator generator = (ModuleGenerator)generators.get(namespaceUri);
-            if (generator != null) {
-                generator.generate(module, element);
-            }
-        }
-    }
-
-    public Set getAllNamespaces() {
-        if (_allNamespaces==null) {
-            _allNamespaces = new HashSet();
-            List mUris = getModuleNamespaces();
-            for (int i=0;i<mUris.size();i++) {
-                ModuleGenerator mGen = getGenerator((String)mUris.get(i));
-                _allNamespaces.addAll(mGen.getNamespaces());
-            }
-        }
-        return _allNamespaces;
-    }
+	private Set<Namespace> _allNamespaces;
+
+	public ModuleGenerators(String propertyKey,
+			BaseWireFeedGenerator parentGenerator) {
+		super(propertyKey, null, parentGenerator);
+	}
+
+	public ModuleGenerator getGenerator(String uri) {
+		return (ModuleGenerator) getPlugin(uri);
+	}
+
+	protected String getKey(Object obj) {
+		return ((ModuleGenerator) obj).getNamespaceUri();
+	}
+
+	public List<String> getModuleNamespaces() {
+		return getKeys();
+	}
+
+	public void generateModules(List<Module> modules, Element element) {
+		Map<String, Object> generators = getPluginMap();
+		for (int i = 0; i < modules.size(); i++) {
+			Module module = modules.get(i);
+			String namespaceUri = module.getUri();
+			ModuleGenerator generator = (ModuleGenerator) generators
+					.get(namespaceUri);
+			if (generator != null) {
+				generator.generate(module, element);
+			}
+		}
+	}
+
+	public Set<Namespace> getAllNamespaces() {
+		if (_allNamespaces == null) {
+			_allNamespaces = new HashSet<Namespace>();
+			List<String> mUris = getModuleNamespaces();
+			for (int i = 0; i < mUris.size(); i++) {
+				ModuleGenerator mGen = getGenerator(mUris.get(i));
+				_allNamespaces.addAll(mGen.getNamespaces());
+			}
+		}
+		return _allNamespaces;
+	}
 }
Index: src/java/com/sun/syndication/io/impl/DCModuleParser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/DCModuleParser.java,v
retrieving revision 1.6
diff -u -r1.6 DCModuleParser.java
--- src/java/com/sun/syndication/io/impl/DCModuleParser.java	20 Jul 2006 17:00:05 -0000	1.6
+++ src/java/com/sun/syndication/io/impl/DCModuleParser.java	30 Sep 2009 06:30:44 -0000
@@ -16,216 +16,232 @@
  */
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.feed.module.DCModuleImpl;
-import com.sun.syndication.feed.module.DCSubjectImpl;
-import com.sun.syndication.feed.module.Module;
-import com.sun.syndication.feed.module.DCModule;
-import com.sun.syndication.feed.module.DCSubject;
-import com.sun.syndication.io.ModuleParser;
-import com.sun.syndication.io.WireFeedParser;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
 import org.jdom.Attribute;
 import org.jdom.Element;
 import org.jdom.Namespace;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import com.sun.syndication.feed.module.DCModule;
+import com.sun.syndication.feed.module.DCModuleImpl;
+import com.sun.syndication.feed.module.DCSubject;
+import com.sun.syndication.feed.module.DCSubjectImpl;
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleParser;
 
 /**
  * Parser for the Dublin Core module.
  */
 public class DCModuleParser implements ModuleParser {
 
-    private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
-    private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/";
+	private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+	private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/";
+
+	private static final Namespace DC_NS = Namespace.getNamespace(DCModule.URI);
 
-    private static final Namespace DC_NS = Namespace.getNamespace(DCModule.URI);
-    private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
-    private static final Namespace TAXO_NS = Namespace.getNamespace(TAXO_URI);
-
-    public final String getNamespaceUri() {
-        return DCModule.URI;
-    }
-
-    private final Namespace getDCNamespace() {
-        return DC_NS;
-    }
-
-    private final Namespace getRDFNamespace() {
-        return RDF_NS;
-    }
-
-    private final Namespace getTaxonomyNamespace() {
-        return TAXO_NS;
-    }
-
-    /**
-     * Parse an element tree and return the module found in it.
-     * <p>
-     * @param dcRoot the root element containing the module elements.
-     * @return the module parsed from the element tree, <i>null</i> if none.
-     */
-    public Module parse(Element dcRoot) {
-        boolean foundSomething = false;
-        DCModule dcm = new DCModuleImpl();
-
-        List eList = dcRoot.getChildren("title", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setTitles(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("creator", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setCreators(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("subject", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setSubjects(parseSubjects(eList));
-        }
-        eList = dcRoot.getChildren("description", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setDescriptions(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("publisher", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setPublishers(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("contributor", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setContributors(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("date", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setDates(parseElementListDate(eList));
-        }
-        eList = dcRoot.getChildren("type", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setTypes(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("format", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setFormats(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("identifier", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setIdentifiers(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("source", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setSources(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("language", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setLanguages(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("relation", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setRelations(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("coverage", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setCoverages(parseElementList(eList));
-        }
-        eList = dcRoot.getChildren("rights", getDCNamespace());
-        if (eList.size() > 0) {
-            foundSomething = true;
-            dcm.setRightsList(parseElementList(eList));
-        }
-
-        return (foundSomething) ? dcm : null;
-    }
-
-    /**
-     * Utility method to parse a taxonomy from an element.
-     * <p>
-     * @param desc the taxonomy description element.
-     * @return the string contained in the resource of the element.
-     */
-    protected final String getTaxonomy(Element desc) {
-        String d = null;
-        Element taxo = desc.getChild("topic", getTaxonomyNamespace());
-        if (taxo!=null) {
-            Attribute a = taxo.getAttribute("resource", getRDFNamespace());
-            if (a!=null) {
-                d = a.getValue();
-            }
-        }
-        return d;
-    }
-
-    /**
-     * Utility method to parse a list of subjects out of a list of elements.
-     * <p>
-     * @param eList the element list to parse.
-     * @return a list of subjects parsed from the elements.
-     */
-    protected final List parseSubjects(List eList) {
-        List subjects = new ArrayList();
-        for (Iterator i = eList.iterator(); i.hasNext();) {
-            Element eSubject = (Element) i.next();
-            Element eDesc = eSubject.getChild("Description", getRDFNamespace());
-            if (eDesc != null) {
-                String taxonomy = getTaxonomy(eDesc);
-                List eValues = eDesc.getChildren("value", getRDFNamespace());
-                for (Iterator v = eValues.iterator(); v.hasNext();) {
-                    Element eValue = (Element) v.next();
-                    DCSubject subject = new DCSubjectImpl();
-                    subject.setTaxonomyUri(taxonomy);
-                    subject.setValue(eValue.getText());
-                    subjects.add(subject);
-                }
-            } else {
-                DCSubject subject = new DCSubjectImpl();
-                subject.setValue(eSubject.getText());
-                subjects.add(subject);
-            }
-        }
-
-        return subjects;
-    }
-
-    /**
-     * Utility method to parse a list of strings out of a list of elements.
-     * <p>
-     * @param eList the list of elements to parse.
-     * @return the list of strings
-     */
-    protected final List parseElementList(List eList) {
-        List values= new ArrayList();
-        for (Iterator i = eList.iterator(); i.hasNext();) {
-            Element e = (Element) i.next();
-            values.add(e.getText());
-        }
-
-        return values;
-    }
-
-    /**
-     * Utility method to parse a list of dates out of a list of elements.
-     * <p>
-     * @param eList the list of elements to parse.
-     * @return the list of dates.
-     */
-    protected final List parseElementListDate(List eList) {
-        List values = new ArrayList();
-        for (Iterator i = eList.iterator(); i.hasNext();) {
-            Element e = (Element) i.next();
-            values.add(DateParser.parseDate(e.getText()));
-        }
+	private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
 
-        return values;
-    }
+	private static final Namespace TAXO_NS = Namespace.getNamespace(TAXO_URI);
+
+	public final String getNamespaceUri() {
+		return DCModule.URI;
+	}
+
+	private final Namespace getDCNamespace() {
+		return DC_NS;
+	}
+
+	private final Namespace getRDFNamespace() {
+		return RDF_NS;
+	}
+
+	private final Namespace getTaxonomyNamespace() {
+		return TAXO_NS;
+	}
+
+	/**
+	 * Parse an element tree and return the module found in it.
+	 * <p>
+	 * 
+	 * @param dcRoot
+	 *            the root element containing the module elements.
+	 * @return the module parsed from the element tree, <i>null</i> if none.
+	 */
+	@SuppressWarnings("unchecked")
+	public Module parse(Element dcRoot) {
+		boolean foundSomething = false;
+		DCModule dcm = new DCModuleImpl();
+
+		List<Element> eList = dcRoot.getChildren("title", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setTitles(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("creator", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setCreators(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("subject", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setSubjects(parseSubjects(eList));
+		}
+		eList = dcRoot.getChildren("description", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setDescriptions(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("publisher", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setPublishers(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("contributor", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setContributors(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("date", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setDates(parseElementListDate(eList));
+		}
+		eList = dcRoot.getChildren("type", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setTypes(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("format", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setFormats(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("identifier", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setIdentifiers(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("source", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setSources(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("language", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setLanguages(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("relation", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setRelations(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("coverage", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setCoverages(parseElementList(eList));
+		}
+		eList = dcRoot.getChildren("rights", getDCNamespace());
+		if (eList.size() > 0) {
+			foundSomething = true;
+			dcm.setRightsList(parseElementList(eList));
+		}
+
+		return (foundSomething) ? dcm : null;
+	}
+
+	/**
+	 * Utility method to parse a taxonomy from an element.
+	 * <p>
+	 * 
+	 * @param desc
+	 *            the taxonomy description element.
+	 * @return the string contained in the resource of the element.
+	 */
+	protected final String getTaxonomy(Element desc) {
+		String d = null;
+		Element taxo = desc.getChild("topic", getTaxonomyNamespace());
+		if (taxo != null) {
+			Attribute a = taxo.getAttribute("resource", getRDFNamespace());
+			if (a != null) {
+				d = a.getValue();
+			}
+		}
+		return d;
+	}
+
+	/**
+	 * Utility method to parse a list of subjects out of a list of elements.
+	 * <p>
+	 * 
+	 * @param eList
+	 *            the element list to parse.
+	 * @return a list of subjects parsed from the elements.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final List<DCSubject> parseSubjects(List<Element> eList) {
+		List<DCSubject> subjects = new ArrayList<DCSubject>();
+		for (Iterator<Element> i = eList.iterator(); i.hasNext();) {
+			Element eSubject = i.next();
+			Element eDesc = eSubject.getChild("Description", getRDFNamespace());
+			if (eDesc != null) {
+				String taxonomy = getTaxonomy(eDesc);
+				List<Element> eValues = eDesc.getChildren("value",
+						getRDFNamespace());
+				for (Iterator<Element> v = eValues.iterator(); v.hasNext();) {
+					Element eValue = v.next();
+					DCSubject subject = new DCSubjectImpl();
+					subject.setTaxonomyUri(taxonomy);
+					subject.setValue(eValue.getText());
+					subjects.add(subject);
+				}
+			} else {
+				DCSubject subject = new DCSubjectImpl();
+				subject.setValue(eSubject.getText());
+				subjects.add(subject);
+			}
+		}
+
+		return subjects;
+	}
+
+	/**
+	 * Utility method to parse a list of strings out of a list of elements.
+	 * <p>
+	 * 
+	 * @param eList
+	 *            the list of elements to parse.
+	 * @return the list of strings
+	 */
+	protected final List<String> parseElementList(List<Element> eList) {
+		List<String> values = new ArrayList<String>();
+		for (Iterator<Element> i = eList.iterator(); i.hasNext();) {
+			Element e = i.next();
+			values.add(e.getText());
+		}
+
+		return values;
+	}
+
+	/**
+	 * Utility method to parse a list of dates out of a list of elements.
+	 * <p>
+	 * 
+	 * @param eList
+	 *            the list of elements to parse.
+	 * @return the list of dates.
+	 */
+	protected final List<Date> parseElementListDate(List<Element> eList) {
+		List<Date> values = new ArrayList<Date>();
+		for (Iterator<Element> i = eList.iterator(); i.hasNext();) {
+			Element e = i.next();
+			values.add(DateParser.parseDate(e.getText()));
+		}
+		return values;
+	}
 }
Index: src/java/com/sun/syndication/io/impl/DCModuleGenerator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/DCModuleGenerator.java,v
retrieving revision 1.6
diff -u -r1.6 DCModuleGenerator.java
--- src/java/com/sun/syndication/io/impl/DCModuleGenerator.java	25 Mar 2005 20:24:16 -0000	1.6
+++ src/java/com/sun/syndication/io/impl/DCModuleGenerator.java	30 Sep 2009 06:30:44 -0000
@@ -16,197 +16,229 @@
  */
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.feed.module.Module;
-import com.sun.syndication.feed.module.DCModule;
-import com.sun.syndication.feed.module.DCSubject;
-import com.sun.syndication.io.ModuleGenerator;
-import org.jdom.Attribute;
-import org.jdom.Element;
-import org.jdom.Namespace;
-
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
 
+import org.jdom.Attribute;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import com.sun.syndication.feed.module.DCModule;
+import com.sun.syndication.feed.module.DCSubject;
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleGenerator;
 
 /**
  * Feed Generator for DublinCore Module.
  * <p/>
- *
+ * 
  * @author Elaine Chien
- *
+ * 
  */
 public class DCModuleGenerator implements ModuleGenerator {
 
-    private static final String DC_URI  = "http://purl.org/dc/elements/1.1/";
-    private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/";
-    private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
-
-    private static final Namespace DC_NS  = Namespace.getNamespace("dc", DC_URI);
-    private static final Namespace TAXO_NS = Namespace.getNamespace("taxo", TAXO_URI);
-    private static final Namespace RDF_NS = Namespace.getNamespace("rdf", RDF_URI);
-
-    private static final Set NAMESPACES;
-
-    static {
-        Set nss = new HashSet();
-        nss.add(DC_NS);
-        nss.add(TAXO_NS);
-        nss.add(RDF_NS);
-        NAMESPACES = Collections.unmodifiableSet(nss);
-    }
-
-    public final String getNamespaceUri() {
-        return DC_URI;
-    }
-    
-    private final Namespace getDCNamespace() {
-        return DC_NS;
-    }
-
-    private final Namespace getRDFNamespace() {
-        return RDF_NS;
-    }
-
-    private final Namespace getTaxonomyNamespace() {
-        return TAXO_NS;
-    }
-
-    /**
-     * Returns a set with all the URIs (JDOM Namespace elements) this module
-     * generator uses.
-     * <p/>
-     * It is used by the the feed generators to add their namespace definition
-     * in the root element of the generated document (forward-missing of
-     * Java 5.0 Generics).
-     * <p/>
-     *
-     * @return a set with all the URIs this module generator uses.
-     */
-    public final Set getNamespaces() {
-        return NAMESPACES;
-    }
-
-    /**
-     * Populate an element tree with elements for a module.
-     * <p>
-     * @param module the module to populate from.
-     * @param element the root element to attach child elements to.
-     */
-    public final void generate(Module module, Element element) {
-        DCModule dcModule = (DCModule) module;
-
-        if (dcModule.getTitle() != null) {
-            element.addContent(generateSimpleElementList("title", dcModule.getTitles()));
-        }
-        if (dcModule.getCreator() != null) {
-            element.addContent(generateSimpleElementList("creator", dcModule.getCreators()));
-        }
-        List subjects = dcModule.getSubjects();
-        for (int i = 0; i < subjects.size(); i++) {
-            element.addContent(generateSubjectElement((DCSubject) subjects.get(i)));
-        }
-        if (dcModule.getDescription() != null) {
-            element.addContent(generateSimpleElementList("description", dcModule.getDescriptions()));
-        }
-        if (dcModule.getPublisher() != null) {
-            element.addContent(generateSimpleElementList("publisher", dcModule.getPublishers()));
-        }
-        if (dcModule.getContributors() != null) {
-            element.addContent(generateSimpleElementList("contributor", dcModule.getContributors()));
-        }
-        if (dcModule.getDate() != null) {
-            for (Iterator i = dcModule.getDates().iterator(); i.hasNext();) {
-                element.addContent(generateSimpleElement("date",
-                        DateParser.formatW3CDateTime((Date) i.next())));
-            }
-        }
-        if (dcModule.getType() != null) {
-            element.addContent(generateSimpleElementList("type", dcModule.getTypes()));
-        }
-        if (dcModule.getFormat() != null) {
-            element.addContent(generateSimpleElementList("format", dcModule.getFormats()));
-        }
-        if (dcModule.getIdentifier() != null) {
-            element.addContent(generateSimpleElementList("identifier", dcModule.getIdentifiers()));
-        }
-        if (dcModule.getSource() != null) {
-            element.addContent(generateSimpleElementList("source", dcModule.getSources()));
-        }
-        if (dcModule.getLanguage() != null) {
-            element.addContent(generateSimpleElementList("language", dcModule.getLanguages()));
-        }
-        if (dcModule.getRelation() != null) {
-            element.addContent(generateSimpleElementList("relation", dcModule.getRelations()));
-        }
-        if (dcModule.getCoverage() != null) {
-            element.addContent(generateSimpleElementList("coverage", dcModule.getCoverages()));
-        }
-        if (dcModule.getRights() != null) {
-            element.addContent(generateSimpleElementList("rights", dcModule.getRightsList()));
-        }
-    }
-
-    /**
-     * Utility method to generate an element for a subject.
-     * <p>
-     * @param subject the subject to generate an element for.
-     * @return the element for the subject.
-     */
-    protected final Element generateSubjectElement(DCSubject subject) {
-        Element subjectElement = new Element("subject", getDCNamespace());
-
-        if (subject.getTaxonomyUri() != null) {
-            Element descriptionElement = new Element("Description", getRDFNamespace());
-            Element topicElement = new Element("topic", getTaxonomyNamespace());
-            Attribute resourceAttribute = new Attribute("resource", subject.getTaxonomyUri(), getRDFNamespace());
-            topicElement.setAttribute(resourceAttribute);
-            descriptionElement.addContent(topicElement);
-
-            if (subject.getValue() != null) {
-                Element valueElement = new Element("value", getRDFNamespace());
-                valueElement.addContent(subject.getValue());
-                descriptionElement.addContent(valueElement);
-            }
-            subjectElement.addContent(descriptionElement);
-        } else {
-            subjectElement.addContent(subject.getValue());
-        }
-        return subjectElement;
-    }
-
-
-    /**
-     * Utility method to generate a single element containing a string.
-     * <p>
-     * @param name the name of the elment to generate.
-     * @param value the value of the text in the element.
-     * @return the element generated.
-     */
-    protected final Element generateSimpleElement(String name, String value)  {
-        Element element = new Element(name, getDCNamespace());
-        element.addContent(value);
-
-        return element;
-    }
-
-    /**
-     * Utility method to generate a list of simple elements.
-     * <p>
-     * @param name the name of the element list to generate.
-     * @param value the list of values for the elements.
-     * @return a list of Elements created.
-     */
-    protected final List generateSimpleElementList(String name, List value) {
-        List elements = new ArrayList();
-        for (Iterator i = value.iterator(); i.hasNext();) {
-            elements.add(generateSimpleElement(name, (String) i.next()));
-        }
+	private static final String DC_URI = "http://purl.org/dc/elements/1.1/";
+
+	private static final String TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/";
+
+	private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+	private static final Namespace DC_NS = Namespace.getNamespace("dc", DC_URI);
+
+	private static final Namespace TAXO_NS = Namespace.getNamespace("taxo",
+			TAXO_URI);
+
+	private static final Namespace RDF_NS = Namespace.getNamespace("rdf",
+			RDF_URI);
+
+	private static final Set<Namespace> NAMESPACES;
+
+	static {
+		Set<Namespace> nss = new HashSet<Namespace>();
+		nss.add(DC_NS);
+		nss.add(TAXO_NS);
+		nss.add(RDF_NS);
+		NAMESPACES = Collections.unmodifiableSet(nss);
+	}
+
+	public final String getNamespaceUri() {
+		return DC_URI;
+	}
+
+	private final Namespace getDCNamespace() {
+		return DC_NS;
+	}
+
+	private final Namespace getRDFNamespace() {
+		return RDF_NS;
+	}
+
+	private final Namespace getTaxonomyNamespace() {
+		return TAXO_NS;
+	}
+
+	/**
+	 * Returns a set with all the URIs (JDOM Namespace elements) this module
+	 * generator uses.
+	 * <p/>
+	 * It is used by the the feed generators to add their namespace definition
+	 * in the root element of the generated document (forward-missing of Java
+	 * 5.0 Generics).
+	 * <p/>
+	 * 
+	 * @return a set with all the URIs this module generator uses.
+	 */
+	public final Set<Namespace> getNamespaces() {
+		return NAMESPACES;
+	}
+
+	/**
+	 * Populate an element tree with elements for a module.
+	 * <p>
+	 * 
+	 * @param module
+	 *            the module to populate from.
+	 * @param element
+	 *            the root element to attach child elements to.
+	 */
+	public final void generate(Module module, Element element) {
+		DCModule dcModule = (DCModule) module;
+
+		if (dcModule.getTitle() != null) {
+			element.addContent(generateSimpleElementList("title", dcModule
+					.getTitles()));
+		}
+		if (dcModule.getCreator() != null) {
+			element.addContent(generateSimpleElementList("creator", dcModule
+					.getCreators()));
+		}
+		List<DCSubject> subjects = dcModule.getSubjects();
+		for (int i = 0; i < subjects.size(); i++) {
+			element.addContent(generateSubjectElement(subjects.get(i)));
+		}
+		if (dcModule.getDescription() != null) {
+			element.addContent(generateSimpleElementList("description",
+					dcModule.getDescriptions()));
+		}
+		if (dcModule.getPublisher() != null) {
+			element.addContent(generateSimpleElementList("publisher", dcModule
+					.getPublishers()));
+		}
+		if (dcModule.getContributors() != null) {
+			element.addContent(generateSimpleElementList("contributor",
+					dcModule.getContributors()));
+		}
+		if (dcModule.getDate() != null) {
+			for (Iterator<Date> i = dcModule.getDates().iterator(); i.hasNext();) {
+				element.addContent(generateSimpleElement("date", DateParser
+						.formatW3CDateTime(i.next())));
+			}
+		}
+		if (dcModule.getType() != null) {
+			element.addContent(generateSimpleElementList("type", dcModule
+					.getTypes()));
+		}
+		if (dcModule.getFormat() != null) {
+			element.addContent(generateSimpleElementList("format", dcModule
+					.getFormats()));
+		}
+		if (dcModule.getIdentifier() != null) {
+			element.addContent(generateSimpleElementList("identifier", dcModule
+					.getIdentifiers()));
+		}
+		if (dcModule.getSource() != null) {
+			element.addContent(generateSimpleElementList("source", dcModule
+					.getSources()));
+		}
+		if (dcModule.getLanguage() != null) {
+			element.addContent(generateSimpleElementList("language", dcModule
+					.getLanguages()));
+		}
+		if (dcModule.getRelation() != null) {
+			element.addContent(generateSimpleElementList("relation", dcModule
+					.getRelations()));
+		}
+		if (dcModule.getCoverage() != null) {
+			element.addContent(generateSimpleElementList("coverage", dcModule
+					.getCoverages()));
+		}
+		if (dcModule.getRights() != null) {
+			element.addContent(generateSimpleElementList("rights", dcModule
+					.getRightsList()));
+		}
+	}
+
+	/**
+	 * Utility method to generate an element for a subject.
+	 * <p>
+	 * 
+	 * @param subject
+	 *            the subject to generate an element for.
+	 * @return the element for the subject.
+	 */
+	protected final Element generateSubjectElement(DCSubject subject) {
+		Element subjectElement = new Element("subject", getDCNamespace());
+
+		if (subject.getTaxonomyUri() != null) {
+			Element descriptionElement = new Element("Description",
+					getRDFNamespace());
+			Element topicElement = new Element("topic", getTaxonomyNamespace());
+			Attribute resourceAttribute = new Attribute("resource", subject
+					.getTaxonomyUri(), getRDFNamespace());
+			topicElement.setAttribute(resourceAttribute);
+			descriptionElement.addContent(topicElement);
+
+			if (subject.getValue() != null) {
+				Element valueElement = new Element("value", getRDFNamespace());
+				valueElement.addContent(subject.getValue());
+				descriptionElement.addContent(valueElement);
+			}
+			subjectElement.addContent(descriptionElement);
+		} else {
+			subjectElement.addContent(subject.getValue());
+		}
+		return subjectElement;
+	}
+
+	/**
+	 * Utility method to generate a single element containing a string.
+	 * <p>
+	 * 
+	 * @param name
+	 *            the name of the elment to generate.
+	 * @param value
+	 *            the value of the text in the element.
+	 * @return the element generated.
+	 */
+	protected final Element generateSimpleElement(String name, String value) {
+		Element element = new Element(name, getDCNamespace());
+		element.addContent(value);
+
+		return element;
+	}
+
+	/**
+	 * Utility method to generate a list of simple elements.
+	 * <p>
+	 * 
+	 * @param name
+	 *            the name of the element list to generate.
+	 * @param value
+	 *            the list of values for the elements.
+	 * @return a list of Elements created.
+	 */
+	protected final List<Element> generateSimpleElementList(String name,
+			List<String> value) {
+		List<Element> elements = new ArrayList<Element>();
+		for (Iterator<String> i = value.iterator(); i.hasNext();) {
+			elements.add(generateSimpleElement(name, i.next()));
+		}
 
-        return elements;
-    }
+		return elements;
+	}
 }
Index: src/java/com/sun/syndication/io/impl/RSS091NetscapeParser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS091NetscapeParser.java,v
retrieving revision 1.1
diff -u -r1.1 RSS091NetscapeParser.java
--- src/java/com/sun/syndication/io/impl/RSS091NetscapeParser.java	24 Sep 2004 14:28:36 -0000	1.1
+++ src/java/com/sun/syndication/io/impl/RSS091NetscapeParser.java	30 Sep 2009 06:30:44 -0000
@@ -22,6 +22,12 @@
  */
 public class RSS091NetscapeParser extends RSS091UserlandParser {
 
+    static final String ELEMENT_NAME = "rss";
+    
+    static final String PUBLIC_ID = "-//Netscape Communications//DTD RSS 0.91//EN";
+    
+    static final String SYSTEM_ID = "http://my.netscape.com/publish/formats/rss-0.91.dtd";
+
     public RSS091NetscapeParser() {
         this("rss_0.91N");
     }
@@ -30,10 +36,6 @@
         super(type);
     }
 
-    static final String ELEMENT_NAME = "rss";
-    static final String PUBLIC_ID = "-//Netscape Communications//DTD RSS 0.91//EN";
-    static final String SYSTEM_ID = "http://my.netscape.com/publish/formats/rss-0.91.dtd";
-
     public boolean isMyType(Document document) {
         boolean ok = false;
         Element rssRoot = document.getRootElement();
Index: src/java/com/sun/syndication/io/impl/BaseWireFeedParser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/BaseWireFeedParser.java,v
retrieving revision 1.7
diff -u -r1.7 BaseWireFeedParser.java
--- src/java/com/sun/syndication/io/impl/BaseWireFeedParser.java	4 Jan 2009 22:40:45 -0000	1.7
+++ src/java/com/sun/syndication/io/impl/BaseWireFeedParser.java	30 Sep 2009 06:30:44 -0000
@@ -1,114 +1,120 @@
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.feed.WireFeed;
-import com.sun.syndication.feed.module.Extendable;
-import com.sun.syndication.io.WireFeedParser;
 import java.util.ArrayList;
 import java.util.Iterator;
-import org.jdom.Element;
-
 import java.util.List;
-import org.jdom.Namespace;
+
 import org.jdom.Attribute;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import com.sun.syndication.feed.WireFeed;
+import com.sun.syndication.feed.module.Extendable;
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.WireFeedParser;
 
 /**
  * @author Alejandro Abdelnur
  */
 public abstract class BaseWireFeedParser implements WireFeedParser {
-    /**
-     * [TYPE].feed.ModuleParser.classes=  [className] ...
-     *
-     */
-    private static final String FEED_MODULE_PARSERS_POSFIX_KEY = ".feed.ModuleParser.classes";
-
-    /**
-     * [TYPE].item.ModuleParser.classes= [className] ...
-     *
-     */
-    private static final String ITEM_MODULE_PARSERS_POSFIX_KEY = ".item.ModuleParser.classes";
-
-    /**
-     * [TYPE].person.ModuleParser.classes= [className] ...
-     *
-     */
-    private static final String PERSON_MODULE_PARSERS_POSFIX_KEY = ".person.ModuleParser.classes";
-
-
-    private String _type;
-    private ModuleParsers _feedModuleParsers;
-    private ModuleParsers _itemModuleParsers;
-    private ModuleParsers _personModuleParsers;
-    private Namespace _namespace;
-
-    protected BaseWireFeedParser(String type, Namespace namespace) {
-        _type = type;
-        _namespace = namespace;
-        _feedModuleParsers = new ModuleParsers(type+FEED_MODULE_PARSERS_POSFIX_KEY, this);
-        _itemModuleParsers = new ModuleParsers(type+ITEM_MODULE_PARSERS_POSFIX_KEY, this);
-        _personModuleParsers = new ModuleParsers(type+PERSON_MODULE_PARSERS_POSFIX_KEY, this);
-    }
-
-    /**
-     * Returns the type of feed the parser handles.
-     * <p>
-     * @see WireFeed for details on the format of this string.
-     * <p>
-     * @return the type of feed the parser handles.
-     *
-     */
-    public String getType() {
-        return _type;
-    }
-
-    protected List parseFeedModules(Element feedElement) {
-        return _feedModuleParsers.parseModules(feedElement);
-    }
-
-    protected List parseItemModules(Element itemElement) {
-        return _itemModuleParsers.parseModules(itemElement);
-    }
-
-    protected List parsePersonModules(Element itemElement) {
-        return _personModuleParsers.parseModules(itemElement);
-    }
-
-    protected List extractForeignMarkup(Element e, Extendable ext, Namespace basens) {
-        ArrayList foreignMarkup = new ArrayList();
-        Iterator children = e.getChildren().iterator();
-        while (children.hasNext()) {
-            Element elem = (Element)children.next();
-            if  ( 
-               // if elemet not in the RSS namespace
-               !basens.equals(elem.getNamespace())
-               // and elem was not handled by a module
-               && null == ext.getModule(elem.getNamespaceURI())) {
-
-               // save it as foreign markup, 
-               // but we can't detach it while we're iterating
-               foreignMarkup.add(elem.clone()); 
-            }
-        }
-        // Now we can detach the foreign markup elements
-        Iterator fm = foreignMarkup.iterator();
-        while (fm.hasNext()) {
-            Element elem = (Element)fm.next();
-            elem.detach();
-        }
-        return foreignMarkup;
-    }
-
-    protected Attribute getAttribute(Element e, String attributeName) {
-        Attribute attribute = e.getAttribute(attributeName);
-        if (attribute == null) {
-            attribute = e.getAttribute(attributeName, _namespace);
-        }
-        return attribute;
-    }
-
-    protected String getAttributeValue(Element e, String attributeName) {
-        Attribute attr = getAttribute(e, attributeName);
-        return (attr != null) ? attr.getValue() : null;
-    }
+	/**
+	 * [TYPE].feed.ModuleParser.classes= [className] ...
+	 * 
+	 */
+	private static final String FEED_MODULE_PARSERS_POSFIX_KEY = ".feed.ModuleParser.classes";
+
+	/**
+	 * [TYPE].item.ModuleParser.classes= [className] ...
+	 * 
+	 */
+	private static final String ITEM_MODULE_PARSERS_POSFIX_KEY = ".item.ModuleParser.classes";
+
+	/**
+	 * [TYPE].person.ModuleParser.classes= [className] ...
+	 * 
+	 */
+	private static final String PERSON_MODULE_PARSERS_POSFIX_KEY = ".person.ModuleParser.classes";
+
+	private String _type;
+	private ModuleParsers _feedModuleParsers;
+	private ModuleParsers _itemModuleParsers;
+	private ModuleParsers _personModuleParsers;
+	private Namespace _namespace;
+
+	protected BaseWireFeedParser(String type, Namespace namespace) {
+		_type = type;
+		_namespace = namespace;
+		_feedModuleParsers = new ModuleParsers(type
+				+ FEED_MODULE_PARSERS_POSFIX_KEY, this);
+		_itemModuleParsers = new ModuleParsers(type
+				+ ITEM_MODULE_PARSERS_POSFIX_KEY, this);
+		_personModuleParsers = new ModuleParsers(type
+				+ PERSON_MODULE_PARSERS_POSFIX_KEY, this);
+	}
+
+	/**
+	 * Returns the type of feed the parser handles.
+	 * <p>
+	 * 
+	 * @see WireFeed for details on the format of this string.
+	 *      <p>
+	 * @return the type of feed the parser handles.
+	 * 
+	 */
+	public String getType() {
+		return _type;
+	}
+
+	protected List<Module> parseFeedModules(Element feedElement) {
+		return _feedModuleParsers.parseModules(feedElement);
+	}
+
+	protected List<Module> parseItemModules(Element itemElement) {
+		return _itemModuleParsers.parseModules(itemElement);
+	}
+
+	protected List<Module> parsePersonModules(Element itemElement) {
+		return _personModuleParsers.parseModules(itemElement);
+	}
+
+	@SuppressWarnings("unchecked")
+	protected List<Object> extractForeignMarkup(Element e, Extendable ext,
+			Namespace basens) {
+		ArrayList<Object> foreignMarkup = new ArrayList<Object>();
+		Iterator<Element> children = e.getChildren().iterator();
+		while (children.hasNext()) {
+			Element elem = children.next();
+			if (
+			// if elemet not in the RSS namespace
+			!basens.equals(elem.getNamespace())
+			// and elem was not handled by a module
+					&& null == ext.getModule(elem.getNamespaceURI())) {
+
+				// save it as foreign markup,
+				// but we can't detach it while we're iterating
+				foreignMarkup.add(elem.clone());
+			}
+		}
+		// Now we can detach the foreign markup elements
+		Iterator<Object> fm = foreignMarkup.iterator();
+		while (fm.hasNext()) {
+			Element elem = (Element) fm.next();
+			elem.detach();
+		}
+		return foreignMarkup;
+	}
+
+	protected Attribute getAttribute(Element e, String attributeName) {
+		Attribute attribute = e.getAttribute(attributeName);
+		if (attribute == null) {
+			attribute = e.getAttribute(attributeName, _namespace);
+		}
+		return attribute;
+	}
+
+	protected String getAttributeValue(Element e, String attributeName) {
+		Attribute attr = getAttribute(e, attributeName);
+		return (attr != null) ? attr.getValue() : null;
+	}
 
 }
-
Index: src/java/com/sun/syndication/io/impl/RSS090Parser.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/RSS090Parser.java,v
retrieving revision 1.13
diff -u -r1.13 RSS090Parser.java
--- src/java/com/sun/syndication/io/impl/RSS090Parser.java	22 Jun 2008 00:31:06 -0000	1.13
+++ src/java/com/sun/syndication/io/impl/RSS090Parser.java	30 Sep 2009 06:30:44 -0000
@@ -17,6 +17,7 @@
 package com.sun.syndication.io.impl;
 
 import com.sun.syndication.feed.WireFeed;
+import com.sun.syndication.feed.module.Module;
 import com.sun.syndication.feed.rss.Channel;
 import com.sun.syndication.feed.rss.Image;
 import com.sun.syndication.feed.rss.Item;
@@ -35,312 +36,336 @@
  */
 public class RSS090Parser extends BaseWireFeedParser {
 
-    private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
-    private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/";
-    private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
-    
-    private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
-    private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
-    private static final Namespace CONTENT_NS = Namespace.getNamespace(CONTENT_URI);
-
-
-    public RSS090Parser() {
-        this("rss_0.9", RSS_NS);
-    }
-
-    protected RSS090Parser(String type, Namespace ns) {
-        super(type, ns);
-    }
-
-    public boolean isMyType(Document document) {
-        boolean ok = false;
-
-        Element rssRoot = document.getRootElement();
-        Namespace defaultNS = rssRoot.getNamespace();
-        List additionalNSs = rssRoot.getAdditionalNamespaces();
-
-        ok = defaultNS!=null && defaultNS.equals(getRDFNamespace());
-        if (ok) {
-            if (additionalNSs==null) {
-                ok = false;
-            }
-            else {
-                ok = false;
-                for (int i=0;!ok && i<additionalNSs.size();i++) {
-                    ok = getRSSNamespace().equals(additionalNSs.get(i));
-                }
-            }
-        }
-        return ok;
-    }
-
-    public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException {
-        if (validate) {
-            validateFeed(document);
-        }
-        Element rssRoot = document.getRootElement();
-        return parseChannel(rssRoot);
-    }
-
-    protected void validateFeed(Document document) throws FeedException {
-        // TBD
-        // here we have to validate the Feed against a schema or whatever
-        // not sure how to do it
-        // one posibility would be to inject our own schema for the feed (they don't exist out there)
-        // to the document, produce an ouput and attempt to parse it again with validation turned on.
-        // otherwise will have to check the document elements by hand.
-    }
-
-    /**
-     * Returns the namespace used by RSS elements in document of the RSS version the parser supports.
-     * <P>
-     * This implementation returns the EMTPY namespace.
-     * <p>
-     *
-     * @return returns the EMPTY namespace.
-     */
-    protected Namespace getRSSNamespace() {
-        return RSS_NS;
-    }
-
-    /**
-     * Returns the namespace used by RDF elements in document of the RSS version the parser supports.
-     * <P>
-     * This implementation returns the EMTPY namespace.
-     * <p>
-     *
-     * @return returns the EMPTY namespace.
-     */
-    protected Namespace getRDFNamespace() {
-        return RDF_NS;
-    }
-
-    /**
-     * Returns the namespace used by Content Module elements in document.
-     * <P>
-     * This implementation returns the EMTPY namespace.
-     * <p>
-     *
-     * @return returns the EMPTY namespace.
-     */
-    protected Namespace getContentNamespace() {
-        return CONTENT_NS;
-    }
-
-    /**
-     * Parses the root element of an RSS document into a Channel bean.
-     * <p/>
-     * It reads title, link and description and delegates to parseImage, parseItems
-     * and parseTextInput. This delegation always passes the root element of the RSS
-     * document as different RSS version may have this information in different parts
-     * of the XML tree (no assumptions made thanks to the specs variaty)
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document to parse.
-     * @return the parsed Channel bean.
-     */
-    protected WireFeed parseChannel(Element rssRoot) {
-        Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
-
-        Channel channel = new Channel(getType());
-
-        Element e = eChannel.getChild("title",getRSSNamespace());
-        if (e!=null) {
-            channel.setTitle(e.getText());
-        }
-        e = eChannel.getChild("link",getRSSNamespace());
-        if (e!=null) {
-            channel.setLink(e.getText());
-        }
-        e = eChannel.getChild("description",getRSSNamespace());
-        if (e!=null) {
-            channel.setDescription(e.getText());
-        }
-
-        channel.setImage(parseImage(rssRoot));
-
-        channel.setTextInput(parseTextInput(rssRoot));
-
-        // Unfortunately Microsoft's SSE extension has a special case of 
-        // effectively putting the sharing channel module inside the RSS tag 
-        // and not inside the channel itself. So we also need to look for 
-        // channel modules from the root RSS element.
-        List allFeedModules = new ArrayList();
-        List rootModules = parseFeedModules(rssRoot);
-        List channelModules = parseFeedModules(eChannel); 
-        if (rootModules != null) {
-            allFeedModules.addAll(rootModules);
-        }
-        if (channelModules != null) {
-            allFeedModules.addAll(channelModules);
-        }
-        channel.setModules(allFeedModules);
-        channel.setItems(parseItems(rssRoot));
-
-        List foreignMarkup = 
-            extractForeignMarkup(eChannel, channel, getRSSNamespace());
-        if (foreignMarkup.size() > 0) {
-            channel.setForeignMarkup(foreignMarkup);
-        }          
-        return channel;
-    }
-
-
-    /**
-     * This method exists because RSS0.90 and RSS1.0 have the 'item' elements under the root elemment.
-     * And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and RSS2.0 have the item elements under the 'channel' element.
-     * <p/>
-     */
-    protected List getItems(Element rssRoot) {
-        return rssRoot.getChildren("item",getRSSNamespace());
-    }
-
-    /**
-     * This method exists because RSS0.90 and RSS1.0 have the 'image' element under the root elemment.
-     * And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and RSS2.0 have it under the 'channel' element.
-     * <p/>
-     */
-    protected Element getImage(Element rssRoot) {
-        return rssRoot.getChild("image",getRSSNamespace());
-    }
-
-    /**
-     * This method exists because RSS0.90 and RSS1.0 have the 'textinput' element under the root elemment.
-     * And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and RSS2.0 have it under the 'channel' element.
-     * <p/>
-     */
-    protected Element getTextInput(Element rssRoot) {
-        return rssRoot.getChild("textinput",getRSSNamespace());
-    }
-
-    /**
-     * Parses the root element of an RSS document looking for  image information.
-     * <p/>
-     * It reads title and url out of the 'image' element.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document to parse for image information.
-     * @return the parsed image bean.
-     */
-    protected Image parseImage(Element rssRoot) {
-        Image image = null;
-        Element eImage = getImage(rssRoot);
-        if (eImage!=null) {
-            image = new Image();
-
-            Element e = eImage.getChild("title",getRSSNamespace());
-            if (e!=null) {
-                image.setTitle(e.getText());
-            }
-            e = eImage.getChild("url",getRSSNamespace());
-            if (e!=null) {
-                image.setUrl(e.getText());
-            }
-            e = eImage.getChild("link",getRSSNamespace());
-            if (e!=null) {
-                image.setLink(e.getText());
-            }
-        }
-        return image;
-    }
-
-    /**
-     * Parses the root element of an RSS document looking for all items information.
-     * <p/>
-     * It iterates through the item elements list, obtained from the getItems() method, and invoke parseItem()
-     * for each item element. The resulting RSSItem of each item element is stored in a list.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document to parse for all items information.
-     * @return a list with all the parsed RSSItem beans.
-     */
-    protected List parseItems(Element rssRoot)  {
-        Collection eItems = getItems(rssRoot);
-
-        List items = new ArrayList();
-        for (Iterator i=eItems.iterator();i.hasNext();) {
-            Element eItem = (Element) i.next();
-            items.add(parseItem(rssRoot,eItem));
-        }
-        return items;
-    }
-
-    /**
-     * Parses an item element of an RSS document looking for item information.
-     * <p/>
-     * It reads title and link out of the 'item' element.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document in case it's needed for context.
-     * @param eItem the item element to parse.
-     * @return the parsed RSSItem bean.
-     */
-    protected Item parseItem(Element rssRoot,Element eItem) {
-        Item item = new Item();
-        Element e = eItem.getChild("title",getRSSNamespace());
-        if (e!=null) {
-            item.setTitle(e.getText());
-        }
-        e = eItem.getChild("link",getRSSNamespace());
-        if (e!=null) {
-            item.setLink(e.getText());
-            item.setUri(e.getText());
-        }
-        
-        item.setModules(parseItemModules(eItem));
-                
-        List foreignMarkup = 
-            extractForeignMarkup(eItem, item, getRSSNamespace());
-        //content:encoded elements are treated special, without a module, they have to be removed from the foreign
-        //markup to avoid duplication in case of read/write. Note that this fix will break if a content module is
-        //used
-        Iterator iterator = foreignMarkup.iterator();
-        while (iterator.hasNext()) {
-            Element ie = (Element)iterator.next();
-            if (getContentNamespace().equals(ie.getNamespace()) && ie.getName().equals("encoded")) {
-                iterator.remove();
-            }
-        }
-        if (foreignMarkup.size() > 0) {
-            item.setForeignMarkup(foreignMarkup);
-        }
-        return item;
-    }
-
-
-    /**
-     * Parses the root element of an RSS document looking for  text-input information.
-     * <p/>
-     * It reads title, description, name and link out of the 'textinput' or 'textInput' element.
-     * <p/>
-     *
-     * @param rssRoot the root element of the RSS document to parse for text-input information.
-     * @return the parsed RSSTextInput bean.
-     */
-    protected TextInput parseTextInput(Element rssRoot) {
-        TextInput textInput = null;
-        Element eTextInput = getTextInput(rssRoot);
-        if (eTextInput!=null) {
-            textInput = new TextInput();
-            Element e = eTextInput.getChild("title",getRSSNamespace());
-            if (e!=null) {
-                textInput.setTitle(e.getText());
-            }
-            e = eTextInput.getChild("description",getRSSNamespace());
-            if (e!=null) {
-                textInput.setDescription(e.getText());
-            }
-            e = eTextInput.getChild("name",getRSSNamespace());
-            if (e!=null) {
-                textInput.setName(e.getText());
-            }
-            e = eTextInput.getChild("link",getRSSNamespace());
-            if (e!=null) {
-                textInput.setLink(e.getText());
-            }
-        }
-        return textInput;
-    }
-
+	private static final String RDF_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+	private static final String RSS_URI = "http://my.netscape.com/rdf/simple/0.9/";
+	private static final String CONTENT_URI = "http://purl.org/rss/1.0/modules/content/";
+
+	private static final Namespace RDF_NS = Namespace.getNamespace(RDF_URI);
+	private static final Namespace RSS_NS = Namespace.getNamespace(RSS_URI);
+	private static final Namespace CONTENT_NS = Namespace
+			.getNamespace(CONTENT_URI);
+
+	public RSS090Parser() {
+		this("rss_0.9", RSS_NS);
+	}
+
+	protected RSS090Parser(String type, Namespace ns) {
+		super(type, ns);
+	}
+
+	@SuppressWarnings("unchecked")
+	public boolean isMyType(Document document) {
+		boolean ok = false;
+
+		Element rssRoot = document.getRootElement();
+		Namespace defaultNS = rssRoot.getNamespace();
+		List<Namespace> additionalNSs = rssRoot.getAdditionalNamespaces();
+
+		ok = defaultNS != null && defaultNS.equals(getRDFNamespace());
+		if (ok) {
+			if (additionalNSs == null) {
+				ok = false;
+			} else {
+				ok = false;
+				for (int i = 0; !ok && i < additionalNSs.size(); i++) {
+					ok = getRSSNamespace().equals(additionalNSs.get(i));
+				}
+			}
+		}
+		return ok;
+	}
+
+	public WireFeed parse(Document document, boolean validate)
+			throws IllegalArgumentException, FeedException {
+		if (validate) {
+			validateFeed(document);
+		}
+		Element rssRoot = document.getRootElement();
+		return parseChannel(rssRoot);
+	}
+
+	protected void validateFeed(Document document) throws FeedException {
+		// TBD
+		// here we have to validate the Feed against a schema or whatever
+		// not sure how to do it
+		// one posibility would be to inject our own schema for the feed (they
+		// don't exist out there)
+		// to the document, produce an ouput and attempt to parse it again with
+		// validation turned on.
+		// otherwise will have to check the document elements by hand.
+	}
+
+	/**
+	 * Returns the namespace used by RSS elements in document of the RSS version
+	 * the parser supports.
+	 * <P>
+	 * This implementation returns the EMTPY namespace.
+	 * <p>
+	 * 
+	 * @return returns the EMPTY namespace.
+	 */
+	protected Namespace getRSSNamespace() {
+		return RSS_NS;
+	}
+
+	/**
+	 * Returns the namespace used by RDF elements in document of the RSS version
+	 * the parser supports.
+	 * <P>
+	 * This implementation returns the EMTPY namespace.
+	 * <p>
+	 * 
+	 * @return returns the EMPTY namespace.
+	 */
+	protected Namespace getRDFNamespace() {
+		return RDF_NS;
+	}
+
+	/**
+	 * Returns the namespace used by Content Module elements in document.
+	 * <P>
+	 * This implementation returns the EMTPY namespace.
+	 * <p>
+	 * 
+	 * @return returns the EMPTY namespace.
+	 */
+	protected Namespace getContentNamespace() {
+		return CONTENT_NS;
+	}
+
+	/**
+	 * Parses the root element of an RSS document into a Channel bean.
+	 * <p/>
+	 * It reads title, link and description and delegates to parseImage,
+	 * parseItems and parseTextInput. This delegation always passes the root
+	 * element of the RSS document as different RSS version may have this
+	 * information in different parts of the XML tree (no assumptions made
+	 * thanks to the specs variaty)
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document to parse.
+	 * @return the parsed Channel bean.
+	 */
+	protected WireFeed parseChannel(Element rssRoot) {
+		Element eChannel = rssRoot.getChild("channel", getRSSNamespace());
+
+		Channel channel = new Channel(getType());
+
+		Element e = eChannel.getChild("title", getRSSNamespace());
+		if (e != null) {
+			channel.setTitle(e.getText());
+		}
+		e = eChannel.getChild("link", getRSSNamespace());
+		if (e != null) {
+			channel.setLink(e.getText());
+		}
+		e = eChannel.getChild("description", getRSSNamespace());
+		if (e != null) {
+			channel.setDescription(e.getText());
+		}
+
+		channel.setImage(parseImage(rssRoot));
+
+		channel.setTextInput(parseTextInput(rssRoot));
+
+		// Unfortunately Microsoft's SSE extension has a special case of
+		// effectively putting the sharing channel module inside the RSS tag
+		// and not inside the channel itself. So we also need to look for
+		// channel modules from the root RSS element.
+		List<Module> allFeedModules = new ArrayList<Module>();
+		List<Module> rootModules = parseFeedModules(rssRoot);
+		List<Module> channelModules = parseFeedModules(eChannel);
+		if (rootModules != null) {
+			allFeedModules.addAll(rootModules);
+		}
+		if (channelModules != null) {
+			allFeedModules.addAll(channelModules);
+		}
+		channel.setModules(allFeedModules);
+		channel.setItems(parseItems(rssRoot));
+
+		List<Object> foreignMarkup = extractForeignMarkup(eChannel, channel,
+				getRSSNamespace());
+		if (foreignMarkup.size() > 0) {
+			channel.setForeignMarkup(foreignMarkup);
+		}
+		return channel;
+	}
+
+	/**
+	 * This method exists because RSS0.90 and RSS1.0 have the 'item' elements
+	 * under the root elemment. And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and
+	 * RSS2.0 have the item elements under the 'channel' element.
+	 * <p/>
+	 */
+	@SuppressWarnings("unchecked")
+	protected List<Element> getItems(Element rssRoot) {
+		return rssRoot.getChildren("item", getRSSNamespace());
+	}
+
+	/**
+	 * This method exists because RSS0.90 and RSS1.0 have the 'image' element
+	 * under the root elemment. And RSS0.91, RSS0.02, RSS0.93, RSS0.94 and
+	 * RSS2.0 have it under the 'channel' element.
+	 * <p/>
+	 */
+	protected Element getImage(Element rssRoot) {
+		return rssRoot.getChild("image", getRSSNamespace());
+	}
+
+	/**
+	 * This method exists because RSS0.90 and RSS1.0 have the 'textinput'
+	 * element under the root elemment. And RSS0.91, RSS0.02, RSS0.93, RSS0.94
+	 * and RSS2.0 have it under the 'channel' element.
+	 * <p/>
+	 */
+	protected Element getTextInput(Element rssRoot) {
+		return rssRoot.getChild("textinput", getRSSNamespace());
+	}
+
+	/**
+	 * Parses the root element of an RSS document looking for image information.
+	 * <p/>
+	 * It reads title and url out of the 'image' element.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document to parse for image
+	 *            information.
+	 * @return the parsed image bean.
+	 */
+	protected Image parseImage(Element rssRoot) {
+		Image image = null;
+		Element eImage = getImage(rssRoot);
+		if (eImage != null) {
+			image = new Image();
+
+			Element e = eImage.getChild("title", getRSSNamespace());
+			if (e != null) {
+				image.setTitle(e.getText());
+			}
+			e = eImage.getChild("url", getRSSNamespace());
+			if (e != null) {
+				image.setUrl(e.getText());
+			}
+			e = eImage.getChild("link", getRSSNamespace());
+			if (e != null) {
+				image.setLink(e.getText());
+			}
+		}
+		return image;
+	}
+
+	/**
+	 * Parses the root element of an RSS document looking for all items
+	 * information.
+	 * <p/>
+	 * It iterates through the item elements list, obtained from the getItems()
+	 * method, and invoke parseItem() for each item element. The resulting
+	 * RSSItem of each item element is stored in a list.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document to parse for all items
+	 *            information.
+	 * @return a list with all the parsed RSSItem beans.
+	 */
+	protected List<Item> parseItems(Element rssRoot) {
+		Collection<Element> eItems = getItems(rssRoot);
+
+		List<Item> items = new ArrayList<Item>();
+		for (Iterator<Element> i = eItems.iterator(); i.hasNext();) {
+			Element eItem = i.next();
+			items.add(parseItem(rssRoot, eItem));
+		}
+		return items;
+	}
+
+	/**
+	 * Parses an item element of an RSS document looking for item information.
+	 * <p/>
+	 * It reads title and link out of the 'item' element.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document in case it's needed for
+	 *            context.
+	 * @param eItem
+	 *            the item element to parse.
+	 * @return the parsed RSSItem bean.
+	 */
+	protected Item parseItem(Element rssRoot, Element eItem) {
+		Item item = new Item();
+		Element e = eItem.getChild("title", getRSSNamespace());
+		if (e != null) {
+			item.setTitle(e.getText());
+		}
+		e = eItem.getChild("link", getRSSNamespace());
+		if (e != null) {
+			item.setLink(e.getText());
+			item.setUri(e.getText());
+		}
+
+		item.setModules(parseItemModules(eItem));
+
+		List<Object> foreignMarkup = extractForeignMarkup(eItem, item,
+				getRSSNamespace());
+		// content:encoded elements are treated special, without a module, they
+		// have to be removed from the foreign
+		// markup to avoid duplication in case of read/write. Note that this fix
+		// will break if a content module is
+		// used
+		Iterator<Object> iterator = foreignMarkup.iterator();
+		while (iterator.hasNext()) {
+			Element ie = (Element) iterator.next();
+			if (getContentNamespace().equals(ie.getNamespace())
+					&& ie.getName().equals("encoded")) {
+				iterator.remove();
+			}
+		}
+		if (foreignMarkup.size() > 0) {
+			item.setForeignMarkup(foreignMarkup);
+		}
+		return item;
+	}
+
+	/**
+	 * Parses the root element of an RSS document looking for text-input
+	 * information.
+	 * <p/>
+	 * It reads title, description, name and link out of the 'textinput' or
+	 * 'textInput' element.
+	 * <p/>
+	 * 
+	 * @param rssRoot
+	 *            the root element of the RSS document to parse for text-input
+	 *            information.
+	 * @return the parsed RSSTextInput bean.
+	 */
+	protected TextInput parseTextInput(Element rssRoot) {
+		TextInput textInput = null;
+		Element eTextInput = getTextInput(rssRoot);
+		if (eTextInput != null) {
+			textInput = new TextInput();
+			Element e = eTextInput.getChild("title", getRSSNamespace());
+			if (e != null) {
+				textInput.setTitle(e.getText());
+			}
+			e = eTextInput.getChild("description", getRSSNamespace());
+			if (e != null) {
+				textInput.setDescription(e.getText());
+			}
+			e = eTextInput.getChild("name", getRSSNamespace());
+			if (e != null) {
+				textInput.setName(e.getText());
+			}
+			e = eTextInput.getChild("link", getRSSNamespace());
+			if (e != null) {
+				textInput.setLink(e.getText());
+			}
+		}
+		return textInput;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/Atom03Generator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/Atom03Generator.java,v
retrieving revision 1.14
diff -u -r1.14 Atom03Generator.java
--- src/java/com/sun/syndication/io/impl/Atom03Generator.java	16 Jul 2008 14:34:56 -0000	1.14
+++ src/java/com/sun/syndication/io/impl/Atom03Generator.java	30 Sep 2009 06:30:43 -0000
@@ -31,335 +31,352 @@
 /**
  * Feed Generator for Atom
  * <p/>
- *
+ * 
  * @author Elaine Chien
- *
+ * 
  */
 
 public class Atom03Generator extends BaseWireFeedGenerator {
-    private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
-    private static final Namespace ATOM_NS = Namespace.getNamespace(ATOM_03_URI);
-
-    private String _version;
-
-    public Atom03Generator() {
-        this("atom_0.3","0.3");
-    }
-
-    protected Atom03Generator(String type,String version) {
-        super(type);
-        _version = version;
-    }
-
-    protected String getVersion() {
-        return _version;
-    }
-
-    protected Namespace getFeedNamespace() {
-        return ATOM_NS;
-    }
-
-    public Document generate(WireFeed wFeed) throws FeedException {
-        Feed feed = (Feed) wFeed;
-        Element root = createRootElement(feed);
-        populateFeed(feed,root);
-        purgeUnusedNamespaceDeclarations(root); 
-        return createDocument(root);
-    }
-
-    protected Document createDocument(Element root) {
-        return new Document(root);
-    }
-
-    protected Element createRootElement(Feed feed) {
-        Element root = new Element("feed",getFeedNamespace());
-        root.addNamespaceDeclaration(getFeedNamespace());
-        Attribute version = new Attribute("version", getVersion());
-        root.setAttribute(version);
-        generateModuleNamespaceDefs(root);
-        return root;
-    }
-
-    protected void populateFeed(Feed feed,Element parent) throws FeedException  {
-        addFeed(feed,parent);
-        addEntries(feed,parent);
-    }
-
-    protected void addFeed(Feed feed, Element parent) throws FeedException {
-        Element eFeed = parent;
-        populateFeedHeader(feed,eFeed);
-        checkFeedHeaderConstraints(eFeed);
-        generateFeedModules(feed.getModules(),eFeed);
-        generateForeignMarkup(eFeed, (List)feed.getForeignMarkup()); 
-    }
-
-    protected void addEntries(Feed feed,Element parent) throws FeedException {
-        List items = feed.getEntries();
-        for (int i=0;i<items.size();i++) {
-            addEntry((Entry)items.get(i),parent);
-        }
-        checkEntriesConstraints(parent);
-    }
-
-    protected void addEntry(Entry entry,Element parent) throws FeedException {
-        Element eEntry = new Element("entry", getFeedNamespace());
-        populateEntry(entry,eEntry);
-        checkEntryConstraints(eEntry);
-        generateItemModules(entry.getModules(),eEntry);
-        parent.addContent(eEntry);
-    }
-
-    protected void populateFeedHeader(Feed feed, Element eFeed) throws FeedException {
-        if (feed.getTitleEx() != null) {
-            Element titleElement = new Element("title", getFeedNamespace());
-            fillContentElement(titleElement, feed.getTitleEx());
-            eFeed.addContent(titleElement);
-        }
-
-        List links = feed.getAlternateLinks();
-        for (int i = 0; i < links.size(); i++) {
-            eFeed.addContent(generateLinkElement((Link)links.get(i)));
-        }
-
-        links = feed.getOtherLinks();
-        for (int i = 0; i < links.size(); i++) {
-            eFeed.addContent(generateLinkElement((Link)links.get(i)));
-        }
-        if (feed.getAuthors()!=null && feed.getAuthors().size() > 0) {
-            Element authorElement = new Element("author", getFeedNamespace());
-            fillPersonElement(authorElement, (Person)feed.getAuthors().get(0));
-            eFeed.addContent(authorElement);
-        }
-
-        List contributors = feed.getContributors();
-        for (int i = 0; i < contributors.size(); i++) {
-            Element contributorElement = new Element("contributor", getFeedNamespace());
-            fillPersonElement(contributorElement, (Person)contributors.get(i));
-            eFeed.addContent(contributorElement);
-        }
-
-        if (feed.getTagline() != null) {
-            Element taglineElement = new Element("tagline", getFeedNamespace());
-            fillContentElement(taglineElement, feed.getTagline());
-            eFeed.addContent(taglineElement);
-        }
-
-        if (feed.getId() != null) {
-            eFeed.addContent(generateSimpleElement("id", feed.getId()));
-        }
-
-        if (feed.getGenerator() != null) {
-            eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
-        }
-
-        if (feed.getCopyright() != null) {
-            eFeed.addContent(generateSimpleElement("copyright", feed.getCopyright()));
-        }
-
-        if (feed.getInfo() != null) {
-            Element infoElement = new Element("info", getFeedNamespace());
-            fillContentElement(infoElement, feed.getInfo());
-            eFeed.addContent(infoElement);
-        }
-
-        if (feed.getModified() != null) {
-            Element modifiedElement = new Element("modified", getFeedNamespace());
-            modifiedElement.addContent(DateParser.formatW3CDateTime(feed.getModified()));
-            eFeed.addContent(modifiedElement);
-        }
-    }
-
-    protected void populateEntry(Entry entry, Element eEntry) throws FeedException {
-        if (entry.getTitleEx() != null) {
-            Element titleElement = new Element("title", getFeedNamespace());
-            fillContentElement(titleElement, entry.getTitleEx());
-            eEntry.addContent(titleElement);
-        }
-        List links = entry.getAlternateLinks();
-        for (int i = 0; i < links.size(); i++) {
-            eEntry.addContent(generateLinkElement((Link)links.get(i)));
-        }
-
-        links = entry.getOtherLinks();
-        for (int i = 0; i < links.size(); i++) {
-            eEntry.addContent(generateLinkElement((Link)links.get(i)));
-        }
-
-        if (entry.getAuthors()!=null && entry.getAuthors().size() > 0) {
-            Element authorElement = new Element("author", getFeedNamespace());
-            fillPersonElement(authorElement, (Person)entry.getAuthors().get(0));
-            eEntry.addContent(authorElement);
-        }
-
-        List contributors = entry.getContributors();
-        for (int i = 0; i < contributors.size(); i++) {
-            Element contributorElement = new Element("contributor", getFeedNamespace());
-            fillPersonElement(contributorElement, (Person)contributors.get(i));
-            eEntry.addContent(contributorElement);
-        }
-        if (entry.getId() != null) {
-            eEntry.addContent(generateSimpleElement("id", entry.getId()));
-        }
-
-        if (entry.getModified() != null) {
-            Element modifiedElement = new Element("modified", getFeedNamespace());
-            modifiedElement.addContent(DateParser.formatW3CDateTime(entry.getModified()));
-            eEntry.addContent(modifiedElement);
-        }
-
-        if (entry.getIssued() != null) {
-            Element issuedElement = new Element("issued", getFeedNamespace());
-            issuedElement.addContent(DateParser.formatW3CDateTime(entry.getIssued()));
-            eEntry.addContent(issuedElement);
-        }
-
-        if (entry.getCreated() != null) {
-            Element createdElement = new Element("created", getFeedNamespace());
-            createdElement.addContent(DateParser.formatW3CDateTime(entry.getCreated()));
-            eEntry.addContent(createdElement);
-        }
-
-        if (entry.getSummary() != null) {
-            Element summaryElement = new Element("summary", getFeedNamespace());
-            fillContentElement(summaryElement, entry.getSummary());
-            eEntry.addContent(summaryElement);
-        }
-
-        List contents = entry.getContents();
-        for (int i = 0; i < contents.size(); i++) {
-            Element contentElement = new Element("content", getFeedNamespace());
-            fillContentElement(contentElement, (Content)contents.get(i));
-            eEntry.addContent(contentElement);
-        }
-        
-        generateForeignMarkup(eEntry, (List)entry.getForeignMarkup());
-    }
-
-    protected void checkFeedHeaderConstraints(Element eFeed) throws FeedException {
-    }
-
-    protected void checkEntriesConstraints(Element parent) throws FeedException {
-    }
-
-    protected void checkEntryConstraints(Element eEntry) throws FeedException {
-    }
-
-
-    protected Element generateLinkElement(Link link) {
-        Element linkElement = new Element("link", getFeedNamespace());
-
-        if (link.getRel() != null) {
-            Attribute relAttribute = new Attribute("rel", link.getRel().toString());
-            linkElement.setAttribute(relAttribute);
-        }
-
-        if (link.getType() != null) {
-            Attribute typeAttribute = new Attribute("type", link.getType());
-            linkElement.setAttribute(typeAttribute);
-        }
-
-        if (link.getHref() != null) {
-            Attribute hrefAttribute = new Attribute("href", link.getHref());
-            linkElement.setAttribute(hrefAttribute);
-        }
-        return linkElement;
-    }
-
-
-    protected void fillPersonElement(Element element, Person person) {
-        if (person.getName() != null) {
-            element.addContent(generateSimpleElement("name", person.getName()));
-        }
-        if (person.getUrl() != null) {
-            element.addContent(generateSimpleElement("url", person.getUrl()));
-        }
-
-        if (person.getEmail() != null) {
-            element.addContent(generateSimpleElement("email", person.getEmail()));
-        }
-    }
-
-    protected Element generateTagLineElement(Content tagline) {
-        Element taglineElement = new Element("tagline", getFeedNamespace());
-
-        if (tagline.getType() != null) {
-            Attribute typeAttribute = new Attribute("type", tagline.getType());
-            taglineElement.setAttribute(typeAttribute);
-        }
-
-        if (tagline.getValue() != null) {
-            taglineElement.addContent(tagline.getValue());
-        }
-        return taglineElement;
-    }
-
-    protected void fillContentElement(Element contentElement, Content content)
-        throws FeedException {
-
-        if (content.getType() != null) {
-            Attribute typeAttribute = new Attribute("type", content.getType());
-            contentElement.setAttribute(typeAttribute);
-        }
-
-        String mode = content.getMode();
-        if (mode != null) {
-            Attribute modeAttribute = new Attribute("mode", content.getMode().toString());
-            contentElement.setAttribute(modeAttribute);
-        }
-
-        if (content.getValue() != null) {
-
-            if (mode == null || mode.equals(Content.ESCAPED)) {
-                contentElement.addContent(content.getValue());
-            } else if (mode.equals(Content.BASE64)) {
-                contentElement.addContent(Base64.encode(content.getValue()));
-            } else if (mode.equals(Content.XML)) {
-
-                StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
-                tmpDocString.append(content.getValue());
-                tmpDocString.append("</tmpdoc>");
-                StringReader tmpDocReader = new StringReader(tmpDocString.toString());
-                Document tmpDoc;
-
-                try {
-                    SAXBuilder saxBuilder = new SAXBuilder();
-                    tmpDoc = saxBuilder.build(tmpDocReader);
-                }
-                catch (Exception ex) {
-                    throw new FeedException("Invalid XML",ex);
-                }
-
-                List children = tmpDoc.getRootElement().removeContent();
-                contentElement.addContent(children);
-            }
-        }
-    }
-
-    protected Element generateGeneratorElement(Generator generator) {
-        Element generatorElement = new Element("generator", getFeedNamespace());
-
-        if (generator.getUrl() != null) {
-            Attribute urlAttribute = new Attribute("url", generator.getUrl());
-            generatorElement.setAttribute(urlAttribute);
-        }
-
-        if (generator.getVersion() != null) {
-            Attribute versionAttribute = new Attribute("version", generator.getVersion());
-            generatorElement.setAttribute(versionAttribute);
-        }
-
-        if (generator.getValue() != null) {
-            generatorElement.addContent(generator.getValue());
-        }
-
-        return generatorElement;
-
-    }
-
-    protected Element generateSimpleElement(String name, String value) {
-        Element element = new Element(name, getFeedNamespace());
-        element.addContent(value);
-        return element;
-    }
+	private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
+	private static final Namespace ATOM_NS = Namespace
+			.getNamespace(ATOM_03_URI);
+
+	private String _version;
+
+	public Atom03Generator() {
+		this("atom_0.3", "0.3");
+	}
+
+	protected Atom03Generator(String type, String version) {
+		super(type);
+		_version = version;
+	}
+
+	protected String getVersion() {
+		return _version;
+	}
+
+	protected Namespace getFeedNamespace() {
+		return ATOM_NS;
+	}
+
+	public Document generate(WireFeed wFeed) throws FeedException {
+		Feed feed = (Feed) wFeed;
+		Element root = createRootElement(feed);
+		populateFeed(feed, root);
+		purgeUnusedNamespaceDeclarations(root);
+		return createDocument(root);
+	}
+
+	protected Document createDocument(Element root) {
+		return new Document(root);
+	}
+
+	protected Element createRootElement(Feed feed) {
+		Element root = new Element("feed", getFeedNamespace());
+		root.addNamespaceDeclaration(getFeedNamespace());
+		Attribute version = new Attribute("version", getVersion());
+		root.setAttribute(version);
+		generateModuleNamespaceDefs(root);
+		return root;
+	}
+
+	protected void populateFeed(Feed feed, Element parent) throws FeedException {
+		addFeed(feed, parent);
+		addEntries(feed, parent);
+	}
+
+	protected void addFeed(Feed feed, Element parent) throws FeedException {
+		Element eFeed = parent;
+		populateFeedHeader(feed, eFeed);
+		checkFeedHeaderConstraints(eFeed);
+		generateFeedModules(feed.getModules(), eFeed);
+		generateForeignMarkup(eFeed, feed.getForeignMarkup());
+	}
+
+	protected void addEntries(Feed feed, Element parent) throws FeedException {
+		List<Entry> items = feed.getEntries();
+		for (int i = 0; i < items.size(); i++) {
+			addEntry(items.get(i), parent);
+		}
+		checkEntriesConstraints(parent);
+	}
+
+	protected void addEntry(Entry entry, Element parent) throws FeedException {
+		Element eEntry = new Element("entry", getFeedNamespace());
+		populateEntry(entry, eEntry);
+		checkEntryConstraints(eEntry);
+		generateItemModules(entry.getModules(), eEntry);
+		parent.addContent(eEntry);
+	}
+
+	protected void populateFeedHeader(Feed feed, Element eFeed)
+			throws FeedException {
+		if (feed.getTitleEx() != null) {
+			Element titleElement = new Element("title", getFeedNamespace());
+			fillContentElement(titleElement, feed.getTitleEx());
+			eFeed.addContent(titleElement);
+		}
+
+		List<Link> links = feed.getAlternateLinks();
+		for (int i = 0; i < links.size(); i++) {
+			eFeed.addContent(generateLinkElement(links.get(i)));
+		}
+
+		links = feed.getOtherLinks();
+		for (int i = 0; i < links.size(); i++) {
+			eFeed.addContent(generateLinkElement((Link) links.get(i)));
+		}
+		if (feed.getAuthors() != null && feed.getAuthors().size() > 0) {
+			Element authorElement = new Element("author", getFeedNamespace());
+			fillPersonElement(authorElement, feed.getAuthors().get(0));
+			eFeed.addContent(authorElement);
+		}
+
+		List<Person> contributors = feed.getContributors();
+		for (int i = 0; i < contributors.size(); i++) {
+			Element contributorElement = new Element("contributor",
+					getFeedNamespace());
+			fillPersonElement(contributorElement, contributors.get(i));
+			eFeed.addContent(contributorElement);
+		}
+
+		if (feed.getTagline() != null) {
+			Element taglineElement = new Element("tagline", getFeedNamespace());
+			fillContentElement(taglineElement, feed.getTagline());
+			eFeed.addContent(taglineElement);
+		}
+
+		if (feed.getId() != null) {
+			eFeed.addContent(generateSimpleElement("id", feed.getId()));
+		}
+
+		if (feed.getGenerator() != null) {
+			eFeed.addContent(generateGeneratorElement(feed.getGenerator()));
+		}
+
+		if (feed.getCopyright() != null) {
+			eFeed.addContent(generateSimpleElement("copyright", feed
+					.getCopyright()));
+		}
+
+		if (feed.getInfo() != null) {
+			Element infoElement = new Element("info", getFeedNamespace());
+			fillContentElement(infoElement, feed.getInfo());
+			eFeed.addContent(infoElement);
+		}
+
+		if (feed.getModified() != null) {
+			Element modifiedElement = new Element("modified",
+					getFeedNamespace());
+			modifiedElement.addContent(DateParser.formatW3CDateTime(feed
+					.getModified()));
+			eFeed.addContent(modifiedElement);
+		}
+	}
+
+	protected void populateEntry(Entry entry, Element eEntry)
+			throws FeedException {
+		if (entry.getTitleEx() != null) {
+			Element titleElement = new Element("title", getFeedNamespace());
+			fillContentElement(titleElement, entry.getTitleEx());
+			eEntry.addContent(titleElement);
+		}
+		List<Link> links = entry.getAlternateLinks();
+		for (int i = 0; i < links.size(); i++) {
+			eEntry.addContent(generateLinkElement(links.get(i)));
+		}
+
+		links = entry.getOtherLinks();
+		for (int i = 0; i < links.size(); i++) {
+			eEntry.addContent(generateLinkElement(links.get(i)));
+		}
+
+		if (entry.getAuthors() != null && entry.getAuthors().size() > 0) {
+			Element authorElement = new Element("author", getFeedNamespace());
+			fillPersonElement(authorElement, entry.getAuthors().get(0));
+			eEntry.addContent(authorElement);
+		}
+
+		List<Person> contributors = entry.getContributors();
+		for (int i = 0; i < contributors.size(); i++) {
+			Element contributorElement = new Element("contributor",
+					getFeedNamespace());
+			fillPersonElement(contributorElement, contributors.get(i));
+			eEntry.addContent(contributorElement);
+		}
+		if (entry.getId() != null) {
+			eEntry.addContent(generateSimpleElement("id", entry.getId()));
+		}
+
+		if (entry.getModified() != null) {
+			Element modifiedElement = new Element("modified",
+					getFeedNamespace());
+			modifiedElement.addContent(DateParser.formatW3CDateTime(entry
+					.getModified()));
+			eEntry.addContent(modifiedElement);
+		}
+
+		if (entry.getIssued() != null) {
+			Element issuedElement = new Element("issued", getFeedNamespace());
+			issuedElement.addContent(DateParser.formatW3CDateTime(entry
+					.getIssued()));
+			eEntry.addContent(issuedElement);
+		}
+
+		if (entry.getCreated() != null) {
+			Element createdElement = new Element("created", getFeedNamespace());
+			createdElement.addContent(DateParser.formatW3CDateTime(entry
+					.getCreated()));
+			eEntry.addContent(createdElement);
+		}
+
+		if (entry.getSummary() != null) {
+			Element summaryElement = new Element("summary", getFeedNamespace());
+			fillContentElement(summaryElement, entry.getSummary());
+			eEntry.addContent(summaryElement);
+		}
+
+		List<Content> contents = entry.getContents();
+		for (int i = 0; i < contents.size(); i++) {
+			Element contentElement = new Element("content", getFeedNamespace());
+			fillContentElement(contentElement, contents.get(i));
+			eEntry.addContent(contentElement);
+		}
+
+		generateForeignMarkup(eEntry, entry.getForeignMarkup());
+	}
+
+	protected void checkFeedHeaderConstraints(Element eFeed)
+			throws FeedException {
+	}
+
+	protected void checkEntriesConstraints(Element parent) throws FeedException {
+	}
+
+	protected void checkEntryConstraints(Element eEntry) throws FeedException {
+	}
+
+	protected Element generateLinkElement(Link link) {
+		Element linkElement = new Element("link", getFeedNamespace());
+
+		if (link.getRel() != null) {
+			Attribute relAttribute = new Attribute("rel", link.getRel()
+					.toString());
+			linkElement.setAttribute(relAttribute);
+		}
+
+		if (link.getType() != null) {
+			Attribute typeAttribute = new Attribute("type", link.getType());
+			linkElement.setAttribute(typeAttribute);
+		}
+
+		if (link.getHref() != null) {
+			Attribute hrefAttribute = new Attribute("href", link.getHref());
+			linkElement.setAttribute(hrefAttribute);
+		}
+		return linkElement;
+	}
+
+	protected void fillPersonElement(Element element, Person person) {
+		if (person.getName() != null) {
+			element.addContent(generateSimpleElement("name", person.getName()));
+		}
+		if (person.getUrl() != null) {
+			element.addContent(generateSimpleElement("url", person.getUrl()));
+		}
+
+		if (person.getEmail() != null) {
+			element
+					.addContent(generateSimpleElement("email", person
+							.getEmail()));
+		}
+	}
+
+	protected Element generateTagLineElement(Content tagline) {
+		Element taglineElement = new Element("tagline", getFeedNamespace());
+
+		if (tagline.getType() != null) {
+			Attribute typeAttribute = new Attribute("type", tagline.getType());
+			taglineElement.setAttribute(typeAttribute);
+		}
+
+		if (tagline.getValue() != null) {
+			taglineElement.addContent(tagline.getValue());
+		}
+		return taglineElement;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void fillContentElement(Element contentElement, Content content)
+			throws FeedException {
+
+		if (content.getType() != null) {
+			Attribute typeAttribute = new Attribute("type", content.getType());
+			contentElement.setAttribute(typeAttribute);
+		}
+
+		String mode = content.getMode();
+		if (mode != null) {
+			Attribute modeAttribute = new Attribute("mode", content.getMode()
+					.toString());
+			contentElement.setAttribute(modeAttribute);
+		}
+
+		if (content.getValue() != null) {
+
+			if (mode == null || mode.equals(Content.ESCAPED)) {
+				contentElement.addContent(content.getValue());
+			} else if (mode.equals(Content.BASE64)) {
+				contentElement.addContent(Base64.encode(content.getValue()));
+			} else if (mode.equals(Content.XML)) {
+
+				StringBuffer tmpDocString = new StringBuffer("<tmpdoc>");
+				tmpDocString.append(content.getValue());
+				tmpDocString.append("</tmpdoc>");
+				StringReader tmpDocReader = new StringReader(tmpDocString
+						.toString());
+				Document tmpDoc;
+
+				try {
+					SAXBuilder saxBuilder = new SAXBuilder();
+					tmpDoc = saxBuilder.build(tmpDocReader);
+				} catch (Exception ex) {
+					throw new FeedException("Invalid XML", ex);
+				}
+
+				List children = tmpDoc.getRootElement().removeContent();
+				contentElement.addContent(children);
+			}
+		}
+	}
+
+	protected Element generateGeneratorElement(Generator generator) {
+		Element generatorElement = new Element("generator", getFeedNamespace());
+
+		if (generator.getUrl() != null) {
+			Attribute urlAttribute = new Attribute("url", generator.getUrl());
+			generatorElement.setAttribute(urlAttribute);
+		}
+
+		if (generator.getVersion() != null) {
+			Attribute versionAttribute = new Attribute("version", generator
+					.getVersion());
+			generatorElement.setAttribute(versionAttribute);
+		}
+
+		if (generator.getValue() != null) {
+			generatorElement.addContent(generator.getValue());
+		}
+
+		return generatorElement;
+
+	}
+
+	protected Element generateSimpleElement(String name, String value) {
+		Element element = new Element(name, getFeedNamespace());
+		element.addContent(value);
+		return element;
+	}
 
 }
Index: src/java/com/sun/syndication/io/impl/BaseWireFeedGenerator.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/io/impl/BaseWireFeedGenerator.java,v
retrieving revision 1.7
diff -u -r1.7 BaseWireFeedGenerator.java
--- src/java/com/sun/syndication/io/impl/BaseWireFeedGenerator.java	4 Jan 2009 22:40:45 -0000	1.7
+++ src/java/com/sun/syndication/io/impl/BaseWireFeedGenerator.java	30 Sep 2009 06:30:44 -0000
@@ -1,136 +1,152 @@
 package com.sun.syndication.io.impl;
 
-import com.sun.syndication.io.WireFeedGenerator;
-import org.jdom.Element;
-import org.jdom.Namespace;
-import org.jdom.Parent;
-
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.Parent;
+
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.WireFeedGenerator;
+
 /**
  * @author Alejandro Abdelnur
  */
 public abstract class BaseWireFeedGenerator implements WireFeedGenerator {
 
-    /**
-     * [TYPE].feed.ModuleParser.classes=  [className] ...
-     */
-    private static final String FEED_MODULE_GENERATORS_POSFIX_KEY = ".feed.ModuleGenerator.classes";
-
-    /**
-     * [TYPE].item.ModuleParser.classes= [className] ...
-     */
-    private static final String ITEM_MODULE_GENERATORS_POSFIX_KEY = ".item.ModuleGenerator.classes";
-
-    /**
-     * [TYPE].person.ModuleParser.classes= [className] ...
-     */
-    private static final String PERSON_MODULE_GENERATORS_POSFIX_KEY = ".person.ModuleGenerator.classes";
-
-
-    private String _type;
-    private ModuleGenerators _feedModuleGenerators;
-    private ModuleGenerators _itemModuleGenerators;
-    private ModuleGenerators _personModuleGenerators;
-    private Namespace[] _allModuleNamespaces;
-
-    protected BaseWireFeedGenerator(String type) {
-        _type = type;
-        _feedModuleGenerators = new ModuleGenerators(type + FEED_MODULE_GENERATORS_POSFIX_KEY, this);
-        _itemModuleGenerators = new ModuleGenerators(type + ITEM_MODULE_GENERATORS_POSFIX_KEY, this);
-        _personModuleGenerators = new ModuleGenerators(type + PERSON_MODULE_GENERATORS_POSFIX_KEY, this);
-        Set allModuleNamespaces = new HashSet();
-        Iterator i = _feedModuleGenerators.getAllNamespaces().iterator();
-        while (i.hasNext()) {
-            allModuleNamespaces.add(i.next());
-        }
-        i = _itemModuleGenerators.getAllNamespaces().iterator();
-        while (i.hasNext()) {
-            allModuleNamespaces.add(i.next());
-        }
-        i = _personModuleGenerators.getAllNamespaces().iterator();
-        while (i.hasNext()) {
-            allModuleNamespaces.add(i.next());
-        }
-        _allModuleNamespaces = new Namespace[allModuleNamespaces.size()];
-        allModuleNamespaces.toArray(_allModuleNamespaces);
-    }
-
-    public String getType() {
-        return _type;
-    }
-
-    protected void generateModuleNamespaceDefs(Element root) {
-        for (int i = 0; i < _allModuleNamespaces.length; i++) {
-            root.addNamespaceDeclaration(_allModuleNamespaces[i]);
-        }
-    }
-
-    protected void generateFeedModules(List modules, Element feed) {
-        _feedModuleGenerators.generateModules(modules, feed);
-    }
-
-    public void generateItemModules(List modules, Element item) {
-        _itemModuleGenerators.generateModules(modules, item);
-    }
-
-    public void generatePersonModules(List modules, Element person) {
-        _personModuleGenerators.generateModules(modules, person);
-    }
-
-    protected void generateForeignMarkup(Element e, List foreignMarkup) {
-        if (foreignMarkup != null) {
-            Iterator elems = (Iterator) foreignMarkup.iterator();
-            while (elems.hasNext()) {
-                Element elem = (Element) elems.next();
-                Parent parent = elem.getParent();
-                if (parent != null) {
-                    parent.removeContent(elem);
-                }
-                e.addContent(elem);
-            }
-        }
-    }
-
-    /**
-     * Purging unused declarations is less optimal, performance-wise, than never adding them in the first place.  So, we
-     * should still ask the ROME guys to fix their code (not adding dozens of unnecessary module declarations). Having
-     * said that: purging them here, before XML generation, is more efficient than parsing and re-molding the XML after
-     * ROME generates it.
-     * <p/>
-     * Note that the calling app could still add declarations/modules to the Feed tree after this.  Which is fine.  But
-     * those modules are then responsible for crawling to the root of the tree, at generate() time, to make sure their
-     * namespace declarations are present.
-     */
-    protected static void purgeUnusedNamespaceDeclarations(Element root) {
-        java.util.Set usedPrefixes = new java.util.HashSet();
-        collectUsedPrefixes(root, usedPrefixes);
-
-        List list = root.getAdditionalNamespaces();
-        List additionalNamespaces = new java.util.ArrayList();
-        additionalNamespaces.addAll(list); // the duplication will prevent a ConcurrentModificationException below
-
-        for (int i = 0; i < additionalNamespaces.size(); i++) {
-            Namespace ns = (Namespace) additionalNamespaces.get(i);
-            String prefix = ns.getPrefix();
-            if (prefix != null && prefix.length() > 0 && !usedPrefixes.contains(prefix)) {
-                root.removeNamespaceDeclaration(ns);
-            }
-        }
-    }
-
-    private static void collectUsedPrefixes(Element el, java.util.Set collector) {
-        String prefix = el.getNamespacePrefix();
-        if (prefix != null && prefix.length() > 0 && !collector.contains(prefix)) {
-            collector.add(prefix);
-        }
-        List kids = el.getChildren();
-        for (int i = 0; i < kids.size(); i++) {
-            collectUsedPrefixes((Element) kids.get(i), collector); // recursion - worth it
-        }
-    }
+	/**
+	 * [TYPE].feed.ModuleParser.classes= [className] ...
+	 */
+	private static final String FEED_MODULE_GENERATORS_POSFIX_KEY = ".feed.ModuleGenerator.classes";
+
+	/**
+	 * [TYPE].item.ModuleParser.classes= [className] ...
+	 */
+	private static final String ITEM_MODULE_GENERATORS_POSFIX_KEY = ".item.ModuleGenerator.classes";
+
+	/**
+	 * [TYPE].person.ModuleParser.classes= [className] ...
+	 */
+	private static final String PERSON_MODULE_GENERATORS_POSFIX_KEY = ".person.ModuleGenerator.classes";
+
+	private String _type;
+	private ModuleGenerators _feedModuleGenerators;
+	private ModuleGenerators _itemModuleGenerators;
+	private ModuleGenerators _personModuleGenerators;
+	private Namespace[] _allModuleNamespaces;
+
+	protected BaseWireFeedGenerator(String type) {
+		_type = type;
+		_feedModuleGenerators = new ModuleGenerators(type
+				+ FEED_MODULE_GENERATORS_POSFIX_KEY, this);
+		_itemModuleGenerators = new ModuleGenerators(type
+				+ ITEM_MODULE_GENERATORS_POSFIX_KEY, this);
+		_personModuleGenerators = new ModuleGenerators(type
+				+ PERSON_MODULE_GENERATORS_POSFIX_KEY, this);
+		Set<Namespace> allModuleNamespaces = new HashSet<Namespace>();
+		Iterator<Namespace> i = _feedModuleGenerators.getAllNamespaces()
+				.iterator();
+		while (i.hasNext()) {
+			allModuleNamespaces.add(i.next());
+		}
+		i = _itemModuleGenerators.getAllNamespaces().iterator();
+		while (i.hasNext()) {
+			allModuleNamespaces.add(i.next());
+		}
+		i = _personModuleGenerators.getAllNamespaces().iterator();
+		while (i.hasNext()) {
+			allModuleNamespaces.add(i.next());
+		}
+		_allModuleNamespaces = new Namespace[allModuleNamespaces.size()];
+		allModuleNamespaces.toArray(_allModuleNamespaces);
+	}
+
+	public String getType() {
+		return _type;
+	}
+
+	protected void generateModuleNamespaceDefs(Element root) {
+		for (int i = 0; i < _allModuleNamespaces.length; i++) {
+			root.addNamespaceDeclaration(_allModuleNamespaces[i]);
+		}
+	}
+
+	protected void generateFeedModules(List<Module> modules, Element feed) {
+		_feedModuleGenerators.generateModules(modules, feed);
+	}
+
+	public void generateItemModules(List<Module> modules, Element item) {
+		_itemModuleGenerators.generateModules(modules, item);
+	}
+
+	public void generatePersonModules(List<Module> modules, Element person) {
+		_personModuleGenerators.generateModules(modules, person);
+	}
+
+	protected void generateForeignMarkup(Element e, List<Object> foreignMarkup) {
+		if (foreignMarkup != null) {
+			Iterator<Object> elems = foreignMarkup.iterator();
+			while (elems.hasNext()) {
+				Element elem = (Element) elems.next();
+				Parent parent = elem.getParent();
+				if (parent != null) {
+					parent.removeContent(elem);
+				}
+				e.addContent(elem);
+			}
+		}
+	}
+
+	/**
+	 * Purging unused declarations is less optimal, performance-wise, than never
+	 * adding them in the first place. So, we should still ask the ROME guys to
+	 * fix their code (not adding dozens of unnecessary module declarations).
+	 * Having said that: purging them here, before XML generation, is more
+	 * efficient than parsing and re-molding the XML after ROME generates it.
+	 * <p/>
+	 * Note that the calling app could still add declarations/modules to the
+	 * Feed tree after this. Which is fine. But those modules are then
+	 * responsible for crawling to the root of the tree, at generate() time, to
+	 * make sure their namespace declarations are present.
+	 */
+	@SuppressWarnings("unchecked")
+	protected static void purgeUnusedNamespaceDeclarations(Element root) {
+		Set<String> usedPrefixes = new HashSet<String>();
+		collectUsedPrefixes(root, usedPrefixes);
+
+		List<Namespace> list = root.getAdditionalNamespaces();
+		List<Namespace> additionalNamespaces = new ArrayList<Namespace>();
+		additionalNamespaces.addAll(list); // the duplication will prevent a
+		// ConcurrentModificationException
+		// below
+
+		for (int i = 0; i < additionalNamespaces.size(); i++) {
+			Namespace ns = additionalNamespaces.get(i);
+			String prefix = ns.getPrefix();
+			if (prefix != null && prefix.length() > 0
+					&& !usedPrefixes.contains(prefix)) {
+				root.removeNamespaceDeclaration(ns);
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private static void collectUsedPrefixes(Element el, Set<String> collector) {
+		String prefix = el.getNamespacePrefix();
+		if (prefix != null && prefix.length() > 0
+				&& collector.contains(prefix) == false) {
+			collector.add(prefix);
+		}
+		List<Element> kids = el.getChildren();
+		for (int i = 0; i < kids.size(); i++) {
+			collectUsedPrefixes(kids.get(i), collector); // recursion
+			// - worth
+			// it
+		}
+	}
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndEntryImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndEntryImpl.java,v
retrieving revision 1.25
diff -u -r1.25 SyndEntryImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndEntryImpl.java	2 Mar 2009 22:39:05 -0000	1.25
+++ src/java/com/sun/syndication/feed/synd/SyndEntryImpl.java	30 Sep 2009 06:30:40 -0000
@@ -16,555 +16,666 @@
  */
 package com.sun.syndication.feed.synd;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.syndication.feed.CopyFrom;
+import com.sun.syndication.feed.impl.CopyFromHelper;
 import com.sun.syndication.feed.impl.ObjectBean;
-import com.sun.syndication.feed.module.*;
+import com.sun.syndication.feed.module.DCModule;
+import com.sun.syndication.feed.module.DCModuleImpl;
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.feed.module.SyModule;
+import com.sun.syndication.feed.module.SyModuleImpl;
 import com.sun.syndication.feed.module.impl.ModuleUtils;
 import com.sun.syndication.feed.synd.impl.URINormalizer;
-import com.sun.syndication.feed.impl.CopyFromHelper;
-
-import java.util.*;
-import java.io.Serializable; 
 
 /**
  * Bean for entries of SyndFeedImpl feeds.
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
-public class SyndEntryImpl implements Serializable,SyndEntry {
-    private ObjectBean _objBean;
-    private String _uri;
-    private String _link;
-    private Date _updatedDate;
-    private SyndContent _title;       
-    private SyndContent _description;
-    private List _links;
-    private List _contents; // deprecated by Atom 1.0
-    private List _modules;
-    private List _enclosures;
-    private List _authors;
-    private List _contributors;
-    private SyndFeed _source;
-    private List _foreignMarkup;
-    private Object wireEntry; // com.sun.syndication.feed.atom.Entry or com.sun.syndication.feed.rss.Item
-    
-    // ISSUE: some converters assume this is never null
-    private List _categories = new ArrayList(); 
-
-    private static final Set IGNORE_PROPERTIES = new HashSet();
-
-    /**
-     * Unmodifiable Set containing the convenience properties of this class.
-     * <p>
-     * Convenience properties are mapped to Modules, for cloning the convenience properties
-     * can be ignored as the will be copied as part of the module cloning.
-     */
-    public static final Set CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
-
-    static {
-        IGNORE_PROPERTIES.add("publishedDate");
-        IGNORE_PROPERTIES.add("author");
-    }
-
-    /**
-     * For implementations extending SyndEntryImpl to be able to use the ObjectBean functionality
-     * with extended interfaces.
-     * <p>
-     * @param beanClass
-     * @param convenienceProperties set containing the convenience properties of the SyndEntryImpl
-     * (the are ignored during cloning, check CloneableBean for details).
-     *
-     */
-    protected SyndEntryImpl(Class beanClass,Set convenienceProperties) {
-        _objBean = new ObjectBean(beanClass,this,convenienceProperties);
-    }
-
-    /**
-     * Default constructor. All properties are set to <b>null</b>.
-     * <p>
-     *
-     */
-    public SyndEntryImpl() {
-        this(SyndEntry.class,IGNORE_PROPERTIES);
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        if (other == null) {
-            return false;
-        }
-        // while ObjectBean does this check this method does a cast to obtain the foreign markup
-        // so we need to check before doing so.
-        if (!(other instanceof SyndEntryImpl)) {
-            return false;
-        }
-        // can't use foreign markup in equals, due to JDOM equals impl
-        Object fm = getForeignMarkup();
-        setForeignMarkup(((SyndEntryImpl)other).getForeignMarkup());              
-        boolean ret = _objBean.equals(other);
-        // restore foreign markup
-        setForeignMarkup(fm);
-        return ret;
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-
-    /**
-     * Returns the entry URI.
-     * <p>
-     * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
-     * the concrete feed type. This is explained in detail in Rome documentation,
-     * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
-     * <p>
-     * The returned URI is a normalized URI as specified in RFC 2396bis.
-     * <p>
-     * @return the entry URI, <b>null</b> if none.
-     *
-     */
-    public String getUri() {
-        return _uri;
-    }
-
-    /**
-     * Sets the entry URI.
-     * <p>
-     * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
-     * the concrete feed type. This is explained in detail in Rome documentation,
-     * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
-     * <p>
-     * @param uri the entry URI to set, <b>null</b> if none.
-     *
-     */
-    public void setUri(String uri) {
-        _uri = URINormalizer.normalize(uri);
-    }
-
-    /**
-     * Returns the entry title.
-     * <p>
-     * @return the entry title, <b>null</b> if none.
-     *
-     */
-    public String getTitle() {
-        if (_title != null) return _title.getValue();
-        return null;
-    }
-
-    /**
-     * Sets the entry title.
-     * <p>
-     * @param title the entry title to set, <b>null</b> if none.
-     *
-     */
-    public void setTitle(String title) {
-        if (_title == null) _title = new SyndContentImpl();
-        _title.setValue(title);
-    }
-
-    /**
-     * Returns the entry title as a text construct.
-     * <p>
-     * @return the entry title, <b>null</b> if none.
-     *
-     */
-    public SyndContent getTitleEx() {
-        return _title;
-    }
-
-    /**
-     * Sets the entry title as a text construct.
-     * <p>
-     * @param title the entry title to set, <b>null</b> if none.
-     *
-     */
-    public void setTitleEx(SyndContent title) {
-        _title = title;
-    }
-
-    /**
-     * Returns the entry link.
-     * <p>
-     * @return the entry link, <b>null</b> if none.
-     *
-     */
-    public String getLink() {
-        return _link;
-    }
-
-    /**
-     * Sets the entry link.
-     * <p>
-     * @param link the entry link to set, <b>null</b> if none.
-     *
-     */
-    public void setLink(String link) {
-        _link = link;
-    }
-
-    /**
-     * Returns the entry description.
-     * <p>
-     * @return the entry description, <b>null</b> if none.
-     *
-     */
-    public SyndContent getDescription() {
-        return _description;
-    }
-
-    /**
-     * Sets the entry description.
-     * <p>
-     * @param description the entry description to set, <b>null</b> if none.
-     *
-     */
-    public void setDescription(SyndContent description) {
-        _description = description;
-    }
-
-    /**
-     * Returns the entry contents.
-     * <p>
-     * @return a list of SyndContentImpl elements with the entry contents,
-     *         an empty list if none.
-     *
-     */
-    public List getContents() {
-        return (_contents==null) ? (_contents=new ArrayList()) : _contents;
-    }
-
-    /**
-     * Sets the entry contents.
-     * <p>
-     * @param contents the list of SyndContentImpl elements with the entry contents to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setContents(List contents) {
-        _contents = contents;
-    }
-
-    /**
-     * Returns the entry enclosures.
-     * <p>
-     * @return a list of SyndEnclosure elements with the entry enclosures,
-     *         an empty list if none.
-     *
-     */
-    public List getEnclosures() {
-        return (_enclosures==null) ? (_enclosures=new ArrayList()) : _enclosures;
-    }
-
-    /**
-     * Sets the entry enclosures.
-     * <p>
-     * @param enclosures the list of SyndEnclosure elements with the entry enclosures to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setEnclosures(List enclosures) {
-        _enclosures = enclosures;
-    }
-
-
-    /**
-     * Returns the entry published date.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module date.
-     * <p>
-     * @return the entry published date, <b>null</b> if none.
-     *
-     */
-    public Date getPublishedDate() {
-        return getDCModule().getDate();
-    }
-
-    /**
-     * Sets the entry published date.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module date.
-     * <p>
-     * @param publishedDate the entry published date to set, <b>null</b> if none.
-     *
-     */
-    public void setPublishedDate(Date publishedDate) {
-        getDCModule().setDate(publishedDate);
-    }
-
-    /**
-     * Returns the entry categories.
-     * <p>
-     * @return a list of SyndCategoryImpl elements with the entry categories,
-     *         an empty list if none.
-     *
-     */
-    public List getCategories() {
-       return _categories;
-    }
-
-    /**
-     * Sets the entry categories.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module subjects.
-     * <p>
-     * @param categories the list of SyndCategoryImpl elements with the entry categories to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setCategories(List categories) {
-        _categories = categories;
-    }
-
-    /**
-     * Returns the entry modules.
-     * <p>
-     * @return a list of ModuleImpl elements with the entry modules,
-     *         an empty list if none.
-     *
-     */
-    public List getModules() {
-        if  (_modules==null) {
-            _modules=new ArrayList();
-        }
-        if (ModuleUtils.getModule(_modules,DCModule.URI)==null) {
-            _modules.add(new DCModuleImpl());
-        }
-        return _modules;
-    }
-
-    /**
-     * Sets the entry modules.
-     * <p>
-     * @param modules the list of ModuleImpl elements with the entry modules to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setModules(List modules) {
-        _modules = modules;
-    }
-
-    /**
-     * Returns the module identified by a given URI.
-     * <p>
-     * @param uri the URI of the ModuleImpl.
-     * @return The module with the given URI, <b>null</b> if none.
-     */
-    public Module getModule(String uri) {
-        return ModuleUtils.getModule(getModules(),uri);
-    }
-
-    /**
-     * Returns the Dublin Core module of the feed.
-     * @return the DC module, it's never <b>null</b>
-     *
-     */
-    private DCModule getDCModule() {
-        return (DCModule) getModule(DCModule.URI);
-    }
-
-    public Class getInterface() {
-        return SyndEntry.class;
-    }
-
-    public void copyFrom(Object obj) {
-        COPY_FROM_HELPER.copy(this,obj);
-    }
-
-    private static final CopyFromHelper COPY_FROM_HELPER;
-
-    static {
-        Map basePropInterfaceMap = new HashMap();
-        basePropInterfaceMap.put("uri",String.class);
-        basePropInterfaceMap.put("title",String.class);
-        basePropInterfaceMap.put("link",String.class);
-        basePropInterfaceMap.put("uri",String.class);
-        basePropInterfaceMap.put("description",SyndContent.class);
-        basePropInterfaceMap.put("contents",SyndContent.class);
-        basePropInterfaceMap.put("enclosures",SyndEnclosure.class);
-        basePropInterfaceMap.put("modules",Module.class);
-
-        Map basePropClassImplMap = new HashMap();
-        basePropClassImplMap.put(SyndContent.class,SyndContentImpl.class);
-        basePropClassImplMap.put(SyndEnclosure.class,SyndEnclosureImpl.class);
-        basePropClassImplMap.put(DCModule.class,DCModuleImpl.class);
-        basePropClassImplMap.put(SyModule.class,SyModuleImpl.class);
-
-        COPY_FROM_HELPER = new CopyFromHelper(SyndEntry.class,basePropInterfaceMap,basePropClassImplMap);
-    }
-
-    /**
-     * Returns the links
-     * <p>
-     * @return Returns the links.
-     */
-    public List getLinks() {
-        return (_links==null) ? (_links=new ArrayList()) : _links;
-    }
-    
-    /**
-     * Set the links
-     * <p>
-     * @param links The links to set.
-     */
-    public void setLinks(List links) {
-        _links = links;
-    }    
-    
-    /**
-     * Returns the updatedDate
-     * <p>
-     * @return Returns the updatedDate.
-     */
-    public Date getUpdatedDate() {
-        return _updatedDate;
-    }
-    
-    /**
-     * Set the updatedDate
-     * <p>
-     * @param updatedDate The updatedDate to set.
-     */
-    public void setUpdatedDate(Date updatedDate) {
-        _updatedDate = updatedDate;
-    }
-
-    public List getAuthors() {
-        return (_authors==null) ? (_authors=new ArrayList()) : _authors;
-    }
-
-    /* (non-Javadoc)
-     * @see com.sun.syndication.feed.synd.SyndEntry#setAuthors(java.util.List)
-     */
-    public void setAuthors(List authors) {
-        _authors = authors;
-    }
-
-    /**
-     * Returns the entry author.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module creator.
-     * <p>
-     * @return the entry author, <b>null</b> if none.
-     *
-     */
-    public String getAuthor() {
-        String author;
-        
-        // Start out looking for one or more authors in _authors. For non-Atom
-        // feeds, _authors may actually be null.
-        if ((_authors != null) && (_authors.size() > 0)) {
-            author = ((SyndPerson)_authors.get(0)).getName();
-        } else {
-            author = getDCModule().getCreator();
-        }
-        if (author == null) {
-            author = "";
-        }
-        
-        return author;
-    }
-
-    /**
-     * Sets the entry author.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module creator.
-     * <p>
-     * @param author the entry author to set, <b>null</b> if none.
-     *
-     */
-    public void setAuthor(String author) {
+public class SyndEntryImpl implements Serializable, SyndEntry {
+
+	private static final long serialVersionUID = 3790691473647330956L;
+
+	private ObjectBean _objBean;
+
+	private String _uri;
+
+	private String _link;
+
+	private Date _updatedDate;
+
+	private SyndContent _title;
+
+	private SyndContent _description;
+
+	private List<SyndLink> _links;
+
+	private List<SyndContent> _contents; // deprecated by Atom 1.0
+
+	private List<Module> _modules;
+
+	private List<SyndEnclosure> _enclosures;
+
+	private List<SyndPerson> _authors;
+
+	private List<SyndPerson> _contributors;
+
+	private SyndFeed _source;
+
+	private List<Object> _foreignMarkup;
+
+	private Object wireEntry; // com.sun.syndication.feed.atom.Entry or com.sun.syndication.feed.rss.Item
+
+	// ISSUE: some converters assume this is never null
+	private List<SyndCategory> _categories = new ArrayList<SyndCategory>();
+
+	private static final Set<String> IGNORE_PROPERTIES = new HashSet<String>();
+
+	/**
+	 * Unmodifiable Set containing the convenience properties of this class.
+	 * <p>
+	 * Convenience properties are mapped to Modules, for cloning the convenience
+	 * properties can be ignored as the will be copied as part of the module
+	 * cloning.
+	 */
+	public static final Set<String> CONVENIENCE_PROPERTIES = Collections
+			.unmodifiableSet(IGNORE_PROPERTIES);
+
+	static {
+		IGNORE_PROPERTIES.add("publishedDate");
+		IGNORE_PROPERTIES.add("author");
+	}
+
+	private static final CopyFromHelper COPY_FROM_HELPER;
+
+	static {
+		Map<String, Class<?>> basePropInterfaceMap = new HashMap<String, Class<?>>();
+		basePropInterfaceMap.put("uri", String.class);
+		basePropInterfaceMap.put("title", String.class);
+		basePropInterfaceMap.put("link", String.class);
+		basePropInterfaceMap.put("uri", String.class);
+		basePropInterfaceMap.put("description", SyndContent.class);
+		basePropInterfaceMap.put("contents", SyndContent.class);
+		basePropInterfaceMap.put("enclosures", SyndEnclosure.class);
+		basePropInterfaceMap.put("modules", Module.class);
+
+		Map<Class<?>, Class<?>> basePropClassImplMap = new HashMap<Class<?>, Class<?>>();
+		basePropClassImplMap.put(SyndContent.class, SyndContentImpl.class);
+		basePropClassImplMap.put(SyndEnclosure.class, SyndEnclosureImpl.class);
+		basePropClassImplMap.put(DCModule.class, DCModuleImpl.class);
+		basePropClassImplMap.put(SyModule.class, SyModuleImpl.class);
+
+		COPY_FROM_HELPER = new CopyFromHelper(SyndEntry.class,
+				basePropInterfaceMap, basePropClassImplMap);
+	}
+
+	/**
+	 * For implementations extending SyndEntryImpl to be able to use the
+	 * ObjectBean functionality with extended interfaces.
+	 * <p>
+	 * 
+	 * @param beanClass
+	 * @param convenienceProperties
+	 *            set containing the convenience properties of the SyndEntryImpl
+	 *            (the are ignored during cloning, check CloneableBean for
+	 *            details).
+	 * 
+	 */
+	protected SyndEntryImpl(Class<?> beanClass,
+			Set<String> convenienceProperties) {
+		_objBean = new ObjectBean(beanClass, this, convenienceProperties);
+	}
+
+	/**
+	 * Default constructor. All properties are set to <b>null</b>.
+	 * <p>
+	 * 
+	 */
+	public SyndEntryImpl() {
+		this(SyndEntry.class, IGNORE_PROPERTIES);
+	}
+
+	/**
+	 * Creates a deep 'bean' clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return _objBean.clone();
+	}
+
+	/**
+	 * Indicates whether some other object is "equal to" this one as defined by
+	 * the Object equals() method.
+	 * <p>
+	 * 
+	 * @param other
+	 *            he reference object with which to compare.
+	 * @return <b>true</b> if 'this' object is equal to the 'other' object.
+	 * 
+	 */
+	public boolean equals(Object other) {
+		if (other == null) {
+			return false;
+		}
+		// while ObjectBean does this check this method does a cast to obtain
+		// the foreign markup
+		// so we need to check before doing so.
+		if (!(other instanceof SyndEntryImpl)) {
+			return false;
+		}
+		// can't use foreign markup in equals, due to JDOM equals impl
+		List<Object> fm = getForeignMarkup();
+		setForeignMarkup(((SyndEntryImpl) other).getForeignMarkup());
+		boolean ret = _objBean.equals(other);
+		// restore foreign markup
+		setForeignMarkup(fm);
+		return ret;
+	}
+
+	/**
+	 * Returns a hashcode value for the object.
+	 * <p>
+	 * It follows the contract defined by the Object hashCode() method.
+	 * <p>
+	 * 
+	 * @return the hashcode of the bean object.
+	 * 
+	 */
+	public int hashCode() {
+		return _objBean.hashCode();
+	}
+
+	/**
+	 * Returns the String representation for the object.
+	 * <p>
+	 * 
+	 * @return String representation for the object.
+	 * 
+	 */
+	public String toString() {
+		return _objBean.toString();
+	}
+
+	/**
+	 * Returns the entry URI.
+	 * <p>
+	 * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
+	 * the concrete feed type. This is explained in detail in Rome
+	 * documentation, <a
+	 * href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
+	 * entry URI mapping</a>.
+	 * <p>
+	 * The returned URI is a normalized URI as specified in RFC 2396bis.
+	 * <p>
+	 * 
+	 * @return the entry URI, <b>null</b> if none.
+	 * 
+	 */
+	public String getUri() {
+		return _uri;
+	}
+
+	/**
+	 * Sets the entry URI.
+	 * <p>
+	 * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
+	 * the concrete feed type. This is explained in detail in Rome
+	 * documentation, <a
+	 * href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
+	 * entry URI mapping</a>.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the entry URI to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setUri(String uri) {
+		_uri = URINormalizer.normalize(uri);
+	}
+
+	/**
+	 * Returns the entry title.
+	 * <p>
+	 * 
+	 * @return the entry title, <b>null</b> if none.
+	 * 
+	 */
+	public String getTitle() {
+		if (_title != null)
+			return _title.getValue();
+		return null;
+	}
+
+	/**
+	 * Sets the entry title.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the entry title to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setTitle(String title) {
+		if (_title == null)
+			_title = new SyndContentImpl();
+		_title.setValue(title);
+	}
+
+	/**
+	 * Returns the entry title as a text construct.
+	 * <p>
+	 * 
+	 * @return the entry title, <b>null</b> if none.
+	 * 
+	 */
+	public SyndContent getTitleEx() {
+		return _title;
+	}
+
+	/**
+	 * Sets the entry title as a text construct.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the entry title to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setTitleEx(SyndContent title) {
+		_title = title;
+	}
+
+	/**
+	 * Returns the entry link.
+	 * <p>
+	 * 
+	 * @return the entry link, <b>null</b> if none.
+	 * 
+	 */
+	public String getLink() {
+		return _link;
+	}
+
+	/**
+	 * Sets the entry link.
+	 * <p>
+	 * 
+	 * @param link
+	 *            the entry link to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setLink(String link) {
+		_link = link;
+	}
+
+	/**
+	 * Returns the entry description.
+	 * <p>
+	 * 
+	 * @return the entry description, <b>null</b> if none.
+	 * 
+	 */
+	public SyndContent getDescription() {
+		return _description;
+	}
+
+	/**
+	 * Sets the entry description.
+	 * <p>
+	 * 
+	 * @param description
+	 *            the entry description to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setDescription(SyndContent description) {
+		_description = description;
+	}
+
+	/**
+	 * Returns the entry contents.
+	 * <p>
+	 * 
+	 * @return a list of SyndContentImpl elements with the entry contents, an
+	 *         empty list if none.
+	 * 
+	 */
+	public List<SyndContent> getContents() {
+		return (_contents == null) ? (_contents = new ArrayList<SyndContent>())
+				: _contents;
+	}
+
+	/**
+	 * Sets the entry contents.
+	 * <p>
+	 * 
+	 * @param contents
+	 *            the list of SyndContentImpl elements with the entry contents
+	 *            to set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setContents(List<SyndContent> contents) {
+		_contents = contents;
+	}
+
+	/**
+	 * Returns the entry enclosures.
+	 * <p>
+	 * 
+	 * @return a list of SyndEnclosure elements with the entry enclosures, an
+	 *         empty list if none.
+	 * 
+	 */
+	public List<SyndEnclosure> getEnclosures() {
+		return (_enclosures == null) ? (_enclosures = new ArrayList<SyndEnclosure>())
+				: _enclosures;
+	}
+
+	/**
+	 * Sets the entry enclosures.
+	 * <p>
+	 * 
+	 * @param enclosures
+	 *            the list of SyndEnclosure elements with the entry enclosures
+	 *            to set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setEnclosures(List<SyndEnclosure> enclosures) {
+		_enclosures = enclosures;
+	}
+
+	/**
+	 * Returns the entry published date.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * date.
+	 * <p>
+	 * 
+	 * @return the entry published date, <b>null</b> if none.
+	 * 
+	 */
+	public Date getPublishedDate() {
+		return getDCModule().getDate();
+	}
+
+	/**
+	 * Sets the entry published date.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * date.
+	 * <p>
+	 * 
+	 * @param publishedDate
+	 *            the entry published date to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setPublishedDate(Date publishedDate) {
+		getDCModule().setDate(publishedDate);
+	}
+
+	/**
+	 * Returns the entry categories.
+	 * <p>
+	 * 
+	 * @return a list of SyndCategoryImpl elements with the entry categories, an
+	 *         empty list if none.
+	 * 
+	 */
+	public List<SyndCategory> getCategories() {
+		return _categories;
+	}
+
+	/**
+	 * Sets the entry categories.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * subjects.
+	 * <p>
+	 * 
+	 * @param categories
+	 *            the list of SyndCategoryImpl elements with the entry
+	 *            categories to set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setCategories(List<SyndCategory> categories) {
+		_categories = categories;
+	}
+
+	/**
+	 * Returns the entry modules.
+	 * <p>
+	 * 
+	 * @return a list of ModuleImpl elements with the entry modules, an empty
+	 *         list if none.
+	 * 
+	 */
+	public List<Module> getModules() {
+		if (_modules == null) {
+			_modules = new ArrayList<Module>();
+		}
+		if (ModuleUtils.getModule(_modules, DCModule.URI) == null) {
+			_modules.add(new DCModuleImpl());
+		}
+		return _modules;
+	}
+
+	/**
+	 * Sets the entry modules.
+	 * <p>
+	 * 
+	 * @param modules
+	 *            the list of ModuleImpl elements with the entry modules to set,
+	 *            an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setModules(List<Module> modules) {
+		_modules = modules;
+	}
+
+	/**
+	 * Returns the module identified by a given URI.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the URI of the ModuleImpl.
+	 * @return The module with the given URI, <b>null</b> if none.
+	 */
+	public Module getModule(String uri) {
+		return ModuleUtils.getModule(getModules(), uri);
+	}
+
+	/**
+	 * Returns the Dublin Core module of the feed.
+	 * 
+	 * @return the DC module, it's never <b>null</b>
+	 * 
+	 */
+	private DCModule getDCModule() {
+		return (DCModule) getModule(DCModule.URI);
+	}
+
+	public Class<? extends CopyFrom> getInterface() {
+		return SyndEntry.class;
+	}
+
+	public void copyFrom(Object obj) {
+		COPY_FROM_HELPER.copy(this, obj);
+	}
+
+	/**
+	 * Returns the links
+	 * <p>
+	 * 
+	 * @return Returns the links.
+	 */
+	public List<SyndLink> getLinks() {
+		return (_links == null) ? (_links = new ArrayList<SyndLink>()) : _links;
+	}
+
+	/**
+	 * Set the links
+	 * <p>
+	 * 
+	 * @param links
+	 *            The links to set.
+	 */
+	public void setLinks(List<SyndLink> links) {
+		_links = links;
+	}
+
+	/**
+	 * Returns the updatedDate
+	 * <p>
+	 * 
+	 * @return Returns the updatedDate.
+	 */
+	public Date getUpdatedDate() {
+		return _updatedDate;
+	}
+
+	/**
+	 * Set the updatedDate
+	 * <p>
+	 * 
+	 * @param updatedDate
+	 *            The updatedDate to set.
+	 */
+	public void setUpdatedDate(Date updatedDate) {
+		_updatedDate = updatedDate;
+	}
+
+	public List<SyndPerson> getAuthors() {
+		return (_authors == null) ? (_authors = new ArrayList<SyndPerson>())
+				: _authors;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.sun.syndication.feed.synd.SyndEntry#setAuthors(java.util.List)
+	 */
+	public void setAuthors(List<SyndPerson> authors) {
         // Get the DCModule so that we can check to see if "creator" is already
         // set.
-        DCModule dcModule = getDCModule();
-        String currentValue = dcModule.getCreator();
-        
-        if ((currentValue == null) || (currentValue.length() == 0)) {
-            getDCModule().setCreator(author);
-        }
-    }
-    
-    public List getContributors() {
-        return (_contributors==null) ? (_contributors=new ArrayList()) : _contributors;
-    }
-
-    /* (non-Javadoc)
-     * @see com.sun.syndication.feed.synd.SyndEntry#setContributors(java.util.List)
-     */
-    public void setContributors(List contributors) {
-        _contributors = contributors;
-    }
-    
-    public SyndFeed getSource() {
-    	return _source;
-    }
-    
-    public void setSource(SyndFeed source) {
-    	_source = source;
-    }
-    
-    /**
-     * Returns foreign markup found at channel level.
-     * <p>
-     * @return list of JDOM nodes containing channel-level foreign markup,
-     *         an empty list if none.
-     *
-     */
-    public Object getForeignMarkup() {
-        return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
-    }
-
-    /**
-     * Sets foreign markup found at channel level.
-     * <p>
-     * @param foreignMarkup list of JDOM nodes containing channel-level foreign markup,
-     *         an empty list if none.
-     *
-     */
-    public void setForeignMarkup(Object foreignMarkup) {
-        _foreignMarkup = (List)foreignMarkup;
-    }
+		_authors = authors;
+	}
+
+	/**
+	 * Returns the entry author.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * creator.
+	 * <p>
+	 * 
+	 * @return the entry author, <b>null</b> if none.
+	 * 
+	 */
+	public String getAuthor() {
+		String author;
+
+		// Start out looking for one or more authors in _authors. For non-Atom
+		// feeds, _authors may actually be null.
+		if ((_authors != null) && (_authors.size() > 0)) {
+			author = ((SyndPerson) _authors.get(0)).getName();
+		} else {
+			author = getDCModule().getCreator();
+		}
+		if (author == null) {
+			author = "";
+		}
+
+		return author;
+	}
+
+	/**
+	 * Sets the entry author.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * creator.
+	 * <p>
+	 * 
+	 * @param author
+	 *            the entry author to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setAuthor(String author) {
+		// Get the DCModule so that we can check to see if "creator" is already
+		// set.
+		DCModule dcModule = getDCModule();
+		String currentValue = dcModule.getCreator();
+
+		if ((currentValue == null) || (currentValue.length() == 0)) {
+			getDCModule().setCreator(author);
+		}
+	}
+
+	public List<SyndPerson> getContributors() {
+		return (_contributors == null) ? (_contributors = new ArrayList<SyndPerson>())
+				: _contributors;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * com.sun.syndication.feed.synd.SyndEntry#setContributors(java.util.List)
+	 */
+	public void setContributors(List<SyndPerson> contributors) {
+		_contributors = contributors;
+	}
+
+	public SyndFeed getSource() {
+		return _source;
+	}
+
+	public void setSource(SyndFeed source) {
+		_source = source;
+	}
+
+	/**
+	 * Returns foreign markup found at channel level.
+	 * <p>
+	 * 
+	 * @return list of JDOM nodes containing channel-level foreign markup, an
+	 *         empty list if none.
+	 * 
+	 */
+	public List<Object> getForeignMarkup() {
+		return (_foreignMarkup == null) ? (_foreignMarkup = new ArrayList<Object>())
+				: _foreignMarkup;
+	}
+
+	/**
+	 * Sets foreign markup found at channel level.
+	 * <p>
+	 * 
+	 * @param foreignMarkup
+	 *            list of JDOM nodes containing channel-level foreign markup, an
+	 *            empty list if none.
+	 * 
+	 */
+	public void setForeignMarkup(List<Object> foreignMarkup) {
+		_foreignMarkup = foreignMarkup;
+	}
 
 	public Object getWireEntry() {
 		return wireEntry;
-	}    
-	
+	}
+
 	public void setWireEntry(Object wireEntry) {
 		this.wireEntry = wireEntry;
 	}
Index: src/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java,v
retrieving revision 1.4
diff -u -r1.4 SyndCategoryImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java	21 Mar 2005 23:42:56 -0000	1.4
+++ src/java/com/sun/syndication/feed/synd/SyndCategoryImpl.java	30 Sep 2009 06:30:40 -0000
@@ -19,6 +19,7 @@
 import com.sun.syndication.feed.impl.ObjectBean;
 import com.sun.syndication.feed.module.DCSubjectImpl;
 import com.sun.syndication.feed.module.DCSubject;
+import com.sun.syndication.feed.synd.SyndCategory;
 
 import java.util.AbstractList;
 import java.util.List;
@@ -28,249 +29,291 @@
 /**
  * Bean for categories of SyndFeedImpl feeds and entries.
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
-public class SyndCategoryImpl implements Serializable,SyndCategory {
-    private ObjectBean _objBean;
-    private DCSubject _subject;
-
-    /**
-     * For implementations extending SyndContentImpl to be able to use the ObjectBean functionality
-     * with extended interfaces.
-     * <p>
-     * @param subject the DC subject to wrap.
-     */
-    SyndCategoryImpl(DCSubject subject) {
-        _objBean = new ObjectBean(SyndCategory.class,this);
-        _subject = subject;
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        return _objBean.equals(other);
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-    /**
-     * Package private constructor, used by SyndCategoryListFacade.
-     * <p>
-     * @return the DC subject being wrapped.
-     *
-     */
-    DCSubject getSubject() {
-        return _subject;
-    }
-
-    /**
-     * Default constructor. All properties are set to <b>null</b>.
-     * <p>
-     *
-     */
-    public SyndCategoryImpl() {
-        this(new DCSubjectImpl());
-    }
-
-    /**
-     * Returns the category name.
-     * <p>
-     * @return the category name, <b>null</b> if none.
-     *
-     */
-    public String getName() {
-        return _subject.getValue();
-    }
-
-    /**
-     * Sets the category name.
-     * <p>
-     * @param name the category name to set, <b>null</b> if none.
-     *
-     */
-    public void setName(String name) {
-        _subject.setValue(name);
-    }
-
-    /**
-     * Returns the category taxonomy URI.
-     * <p>
-     * @return the category taxonomy URI, <b>null</b> if none.
-     *
-     */
-    public String getTaxonomyUri() {
-        return _subject.getTaxonomyUri();
-    }
-
-    /**
-     * Sets the category taxonomy URI.
-     * <p>
-     * @param taxonomyUri the category taxonomy URI to set, <b>null</b> if none.
-     *
-     */
-    public void setTaxonomyUri(String taxonomyUri) {
-        _subject.setTaxonomyUri(taxonomyUri);
-    }
+public class SyndCategoryImpl implements Serializable, SyndCategory {
 
-}
+	private static final long serialVersionUID = 3216573613339374812L;
+
+	private ObjectBean _objBean;
+
+	private DCSubject _subject;
 
+	/**
+	 * For implementations extending SyndContentImpl to be able to use the
+	 * ObjectBean functionality with extended interfaces.
+	 * <p>
+	 * 
+	 * @param subject
+	 *            the DC subject to wrap.
+	 */
+	SyndCategoryImpl(DCSubject subject) {
+		_objBean = new ObjectBean(SyndCategory.class, this);
+		_subject = subject;
+	}
+
+	/**
+	 * Creates a deep 'bean' clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return _objBean.clone();
+	}
+
+	/**
+	 * Indicates whether some other object is "equal to" this one as defined by
+	 * the Object equals() method.
+	 * <p>
+	 * 
+	 * @param other
+	 *            he reference object with which to compare.
+	 * @return <b>true</b> if 'this' object is equal to the 'other' object.
+	 * 
+	 */
+	public boolean equals(Object other) {
+		return _objBean.equals(other);
+	}
+
+	/**
+	 * Returns a hashcode value for the object.
+	 * <p>
+	 * It follows the contract defined by the Object hashCode() method.
+	 * <p>
+	 * 
+	 * @return the hashcode of the bean object.
+	 * 
+	 */
+	public int hashCode() {
+		return _objBean.hashCode();
+	}
+
+	/**
+	 * Returns the String representation for the object.
+	 * <p>
+	 * 
+	 * @return String representation for the object.
+	 * 
+	 */
+	public String toString() {
+		return _objBean.toString();
+	}
+
+	/**
+	 * Package private constructor, used by SyndCategoryListFacade.
+	 * <p>
+	 * 
+	 * @return the DC subject being wrapped.
+	 * 
+	 */
+	DCSubject getSubject() {
+		return _subject;
+	}
+
+	/**
+	 * Default constructor. All properties are set to <b>null</b>.
+	 * <p>
+	 * 
+	 */
+	public SyndCategoryImpl() {
+		this(new DCSubjectImpl());
+	}
+
+	/**
+	 * Returns the category name.
+	 * <p>
+	 * 
+	 * @return the category name, <b>null</b> if none.
+	 * 
+	 */
+	public String getName() {
+		return _subject.getValue();
+	}
+
+	/**
+	 * Sets the category name.
+	 * <p>
+	 * 
+	 * @param name
+	 *            the category name to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setName(String name) {
+		_subject.setValue(name);
+	}
+
+	/**
+	 * Returns the category taxonomy URI.
+	 * <p>
+	 * 
+	 * @return the category taxonomy URI, <b>null</b> if none.
+	 * 
+	 */
+	public String getTaxonomyUri() {
+		return _subject.getTaxonomyUri();
+	}
+
+	/**
+	 * Sets the category taxonomy URI.
+	 * <p>
+	 * 
+	 * @param taxonomyUri
+	 *            the category taxonomy URI to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setTaxonomyUri(String taxonomyUri) {
+		_subject.setTaxonomyUri(taxonomyUri);
+	}
+
+}
 
 /**
- * List implementation for SyndCategoryImpl elements. To be directly used by the SyndFeedImpl
- * and SyndEntryImpl classes only.
+ * List implementation for SyndCategoryImpl elements. To be directly used by the
+ * SyndFeedImpl and SyndEntryImpl classes only.
  * <p>
- * It acts as a facade on top of the DCSubjectImpl elements of the underlying list
- * and remains in synch with it. It is possible to work on either list, the categories
- * one or the subjects one and they remain in synch.
+ * It acts as a facade on top of the DCSubjectImpl elements of the underlying
+ * list and remains in synch with it. It is possible to work on either list, the
+ * categories one or the subjects one and they remain in synch.
  * <p>
- * This is necessary because the SyndFeedImpl categories are just a convenience to access
- * the DublinCore subjects.
+ * This is necessary because the SyndFeedImpl categories are just a convenience
+ * to access the DublinCore subjects.
  * <P>
- * All this mess to avoid making DCSubjectImpl implement SyndCategory (which it would be odd).
+ * All this mess to avoid making DCSubjectImpl implement SyndCategory (which it
+ * would be odd).
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
-class SyndCategoryListFacade extends AbstractList {
-    private List _subjects;
+class SyndCategoryListFacade extends AbstractList<SyndCategory> {
+	private List<DCSubject> _subjects;
 
-    /**
-     * Default constructor. Creates and empty list.
-     */
-    public SyndCategoryListFacade() {
-        this(new ArrayList());
-    }
-
-    /**
-     * Creates a facade list of categories on top the given subject list.
-     * <P>
-     * @param subjects the list of subjects to create the facade.
-     *
-     */
-    public SyndCategoryListFacade(List subjects) {
-        _subjects = subjects;
-    }
-
-    /**
-     * Gets the category by index.
-     * <p>
-     * @param index the index position to retrieve the category.
-     * @return the SyndCategoryImpl in position index, <b>null</b> if none.
-     *
-     */
-    public Object get(int index) {
-        return new SyndCategoryImpl((DCSubject) _subjects.get(index));
-    }
-
-    /**
-     * Returns the size of the list.
-     * <p>
-     * @return the size of the list.
-     *
-     */
-    public int size() {
-        return _subjects.size();
-    }
-
-    /**
-     * Sets a category in an existing position in the list.
-     * <p>
-     * @param index position to set the category.
-     * @param obj the SyndCategoryImpl object to set.
-     * @return the SyndCategoryImpl object that is being replaced, <b>null</b> if none.
-     *
-     */
-    public Object set(int index,Object obj) {
-        SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
-        DCSubject subject = (sCat!=null) ? sCat.getSubject() : null;
-        subject = (DCSubject) _subjects.set(index,subject);
-        return (subject!=null) ? new SyndCategoryImpl(subject) : null;
-    }
-
-    /**
-    * Adds a category to the list.
-    * <p>
-    * @param index position to add the category.
-    * @param obj the SyndCategoryImpl object to add.
-     *
-     */
-    public void add(int index,Object obj) {
-        SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
-        DCSubject subject = (sCat!=null) ? sCat.getSubject() : null;
-        _subjects.add(index,subject);
-    }
-
-    /**
-     * Removes a category element from a specific position.
-     * <p>
-     * @param index position to remove the category from.
-     * @return the SyndCategoryImpl being removed from position index, <b>null</b> if none.
-     *
-     */
-    public Object remove(int index) {
-        DCSubject subject = (DCSubject) _subjects.remove(index);
-        return (subject!=null) ? new SyndCategoryImpl(subject) : null;
-    }
-
-    /**
-     * Returns a list with the DCSubject elements of the SyndCategoryImpl list facade.
-     * To be used by the SyndFeedImpl class only.
-     * <p>
-     * @param cList the list with SyndCategoryImpl elements to convert to subject list.
-     * @return a list with DCSubject elements corresponding to the categories in the given list.
-     *
-     */
-    public static List convertElementsSyndCategoryToSubject(List cList) {
-        List sList = null;
-        if (cList!=null) {
-            sList = new ArrayList();
-            for (int i=0;i<cList.size();i++) {
-                SyndCategoryImpl sCat = (SyndCategoryImpl) cList.get(i);
-                DCSubject subject = null;
-                if (sCat!=null) {
-                    subject = sCat.getSubject();
-                }
-                sList.add(subject);
-            }
-        }
-        return sList;
-    }
+	/**
+	 * Default constructor. Creates and empty list.
+	 */
+	public SyndCategoryListFacade() {
+		this(new ArrayList<DCSubject>());
+	}
+
+	/**
+	 * Creates a facade list of categories on top the given subject list.
+	 * <P>
+	 * 
+	 * @param subjects
+	 *            the list of subjects to create the facade.
+	 * 
+	 */
+	public SyndCategoryListFacade(List<DCSubject> subjects) {
+		_subjects = subjects;
+	}
+
+	/**
+	 * Gets the category by index.
+	 * <p>
+	 * 
+	 * @param index
+	 *            the index position to retrieve the category.
+	 * @return the SyndCategoryImpl in position index, <b>null</b> if none.
+	 * 
+	 */
+	public SyndCategory get(int index) {
+		return new SyndCategoryImpl(_subjects.get(index));
+	}
+
+	/**
+	 * Returns the size of the list.
+	 * <p>
+	 * 
+	 * @return the size of the list.
+	 * 
+	 */
+	public int size() {
+		return _subjects.size();
+	}
+
+	/**
+	 * Sets a category in an existing position in the list.
+	 * <p>
+	 * 
+	 * @param index
+	 *            position to set the category.
+	 * @param obj
+	 *            the SyndCategoryImpl object to set.
+	 * @return the SyndCategoryImpl object that is being replaced, <b>null</b>
+	 *         if none.
+	 * 
+	 */
+	public SyndCategory set(int index, SyndCategory obj) {
+		SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
+		DCSubject subject = (sCat != null) ? sCat.getSubject() : null;
+		subject = _subjects.set(index, subject);
+		return (subject != null) ? new SyndCategoryImpl(subject) : null;
+	}
+
+	/**
+	 * Adds a category to the list.
+	 * <p>
+	 * 
+	 * @param index
+	 *            position to add the category.
+	 * @param obj
+	 *            the SyndCategoryImpl object to add.
+	 * 
+	 */
+	public void add(int index, SyndCategory obj) {
+		SyndCategoryImpl sCat = (SyndCategoryImpl) obj;
+		DCSubject subject = (sCat != null) ? sCat.getSubject() : null;
+		_subjects.add(index, subject);
+	}
+
+	/**
+	 * Removes a category element from a specific position.
+	 * <p>
+	 * 
+	 * @param index
+	 *            position to remove the category from.
+	 * @return the SyndCategoryImpl being removed from position index,
+	 *         <b>null</b> if none.
+	 * 
+	 */
+	public SyndCategory remove(int index) {
+		DCSubject subject = _subjects.remove(index);
+		return (subject != null) ? new SyndCategoryImpl(subject) : null;
+	}
+
+	/**
+	 * Returns a list with the DCSubject elements of the SyndCategoryImpl list
+	 * facade. To be used by the SyndFeedImpl class only.
+	 * <p>
+	 * 
+	 * @param cList
+	 *            the list with SyndCategoryImpl elements to convert to subject
+	 *            list.
+	 * @return a list with DCSubject elements corresponding to the categories in
+	 *         the given list.
+	 * 
+	 */
+	public static List<DCSubject> convertElementsSyndCategoryToSubject(
+			List<SyndCategory> cList) {
+		List<DCSubject> sList = null;
+		if (cList != null) {
+			sList = new ArrayList<DCSubject>();
+			for (int i = 0; i < cList.size(); i++) {
+				SyndCategoryImpl sCat = (SyndCategoryImpl) cList.get(i);
+				DCSubject subject = null;
+				if (sCat != null) {
+					subject = sCat.getSubject();
+				}
+				sList.add(subject);
+			}
+		}
+		return sList;
+	}
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndFeed.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndFeed.java,v
retrieving revision 1.19
diff -u -r1.19 SyndFeed.java
--- src/java/com/sun/syndication/feed/synd/SyndFeed.java	2 Mar 2009 22:39:05 -0000	1.19
+++ src/java/com/sun/syndication/feed/synd/SyndFeed.java	30 Sep 2009 06:30:41 -0000
@@ -27,490 +27,577 @@
 /**
  * Bean interface for all types of feeds.
  * <p>
- * It handles all RSS versions and Atom 0.3, it normalizes all info, it may lose information.
+ * It handles all RSS versions and Atom 0.3, it normalizes all info, it may lose
+ * information.
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
 public interface SyndFeed extends Cloneable, CopyFrom, Extendable {
 
-    /**
-     * Returns the real feed types the SyndFeedImpl supports when converting from and to.
-     * <p>
-     * @return the real feed type supported.
-     */
-    List getSupportedFeedTypes();
-
-    /**
-     * Creates a real feed containing the information of the SyndFeedImpl.
-     * <p>
-     * The feed type of the created WireFeed is taken from the SyndFeedImpl feedType property.
-     * <p>
-     * @return the real feed.
-     *
-     */
-    WireFeed createWireFeed();
-
-    /**
-     * Creates a real feed containing the information of the SyndFeedImpl.
-     * <p>
-     * @param feedType the feed type for the WireFeed to be created.
-     * @return the real feed.
-     *
-     */
-    WireFeed createWireFeed(String feedType);
-
-    /**
-     * Returns the WireFeed this SyndFeed was created from. 
-     * Will return null if the original feed is not stored or if this SyndFeed was not created from a WireFeed
-     * 
-     * @return The WireFeed this was created from, or null
-     * 
-     */
-    WireFeed originalWireFeed();
-    
-    /**
-     * 
-     * @return true if this SyndFeed preserves the WireFeed it was created from
-     */
-    boolean isPreservingWireFeed(); 
-
-    /**
-     * Returns the wire feed type the feed had/will-have when converted from/to a WireFeed.
-     * <p>
-     * @return the feed type, <b>null</b> if none.
-     *
-     */
-    String getFeedType();
-
-    /**
-     * Sets the wire feed type the feed will-have when coverted to a WireFeed.
-     * <p>
-     * @param feedType the feed type to set, <b>null</b> if none.
-     *
-     */
-    void setFeedType(String feedType);
-
-    /**
-     * Returns the charset encoding of a the feed. This is not set by Rome parsers.
-     * <p>
-     * @return the charset encoding of the feed.
-     *
-     */
-    public String getEncoding();
-
-    /**
-     * Sets the charset encoding of a the feed. This is not set by Rome parsers.
-     * <p>
-     * @param encoding the charset encoding of the feed.
-     *
-     */
-    public void setEncoding(String encoding);
-
-    /**
-     * Returns the feed URI.
-     * <p>
-     * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
-     * the concrete feed type. This is explained in detail in Rome documentation,
-     * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
-     * <p>
-     * The returned URI is a normalized URI as specified in RFC 2396bis.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @return the feed URI, <b>null</b> if none.
-     *
-     */
-    String getUri();
-
-    /**
-     * Sets the feed URI.
-     * <p>
-     * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
-     * the concrete feed type. This is explained in detail in Rome documentation,
-     * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @param uri the feed URI to set, <b>null</b> if none.
-     *
-     */
-    void setUri(String uri);
-
-    /**
-     * Returns the feed title.
-     * <p>
-     * @return the feed title, <b>null</b> if none.
-     *
-     */
-    String getTitle();
-
-    /**
-     * Sets the feed title.
-     * <p>
-     * @param title the feed title to set, <b>null</b> if none.
-     *
-     */
-    void setTitle(String title);
-
-    /**
-     * Returns the feed title.
-     * <p>
-     * @return the feed title, <b>null</b> if none.
-     *
-     */
-    SyndContent getTitleEx();
-
-    /**
-     * Sets the feed title.
-     * <p>
-     * @param title the feed title to set, <b>null</b> if none.
-     *
-     */
-    void setTitleEx(SyndContent title);
-
-    /**
-     * Returns the feed link.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @return the feed link, <b>null</b> if none.
-     *
-     */
-    String getLink();
-
-    /**
-     * Sets the feed link.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @param link the feed link to set, <b>null</b> if none.
-     *
-     */
-    void setLink(String link);
-
-    /**
-     * Returns the entry links
-     * <p>
-     * @return the entry links, <b>null</b> if none.
-     *
-     */
-    List getLinks();
-
-    /**
-     * Sets the entry links.
-     * <p>
-     * @param links the entry links to set, <b>null</b> if none.
-     *
-     */
-    void setLinks(List links);
-
-    /**
-     * Returns the feed description.
-     * <p>
-     * @return the feed description, <b>null</b> if none.
-     *
-     */
-    String getDescription();
-
-    /**
-     * Sets the feed description.
-     * <p>
-     * @param description the feed description to set, <b>null</b> if none.
-     *
-     */
-    void setDescription(String description);
-    
-    /**
-     * Returns the feed description as a text construct.
-     * <p>
-     * @return the feed description, <b>null</b> if none.
-     *
-     */
-    SyndContent getDescriptionEx();
-
-    /**
-     * Sets the feed description as a text construct.
-     * <p>
-     * @param description the feed description to set, <b>null</b> if none.
-     *
-     */
-    void setDescriptionEx(SyndContent description);
-
-    /**
-     * Returns the feed published date.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module date.
-     * <p>
-     * @return the feed published date, <b>null</b> if none.
-     *
-     */
-    Date getPublishedDate();
-
-    /**
-     * Sets the feed published date.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module date.
-     * <p>
-     * @param publishedDate the feed published date to set, <b>null</b> if none.
-     *
-     */
-    void setPublishedDate(Date publishedDate);
-
-    /**
-     * Returns the feed authors.
-     * <p>
-     * For Atom feeds, this returns the authors as a list of SyndPerson objects,
-     * for RSS feeds this method is a convenience method, it maps to the
-     * Dublin Core module creator.
-     * <p>
-     * @return the feed authors, <b>null</b> if none.
-     *
-     */
-    List getAuthors();
-
-    /**
-     * Sets the feed authors.
-     * <p>
-     * For Atom feeds, this sets the authors as a list of SyndPerson
-     * objects, for RSS feeds this method is a convenience method, it maps
-     * to the Dublin Core module creator.
-     * <p>
-     * @param authors the feed authors to set, <b>null</b> if none.
-     *
-     */
-    void setAuthors(List authors);
-
-    /**
-     * Returns the name of the first feed author in the collection of authors.
-     * <p>
-     * For Atom feeds, this returns the authors as a list of SyndPerson objects,
-     * for RSS feeds this method is a convenience method, it maps to the
-     * Dublin Core module creator.
-     * <p>
-     * @return the feed author, <b>null</b> if none.
-     *
-     */
-    String getAuthor();
-
-    /**
-     * Sets the feed author.
-     * <p>
-     * For Atom feeds, this sets the feed author's name, for RSS feeds
-     * this method is a convenience method, it maps to the Dublin Core
-     * module creator.
-     * <p>
-     * @param author the feed author to set, <b>null</b> if none.
-     *
-     */
-    void setAuthor(String author);
-
-    /**
-     * Returns the feed author.
-     * <p>
-     * For Atom feeds, this returns the contributors as a list of
-     * SyndPerson objects
-     * <p>
-     * @return the feed author, <b>null</b> if none.
-     *
-     */
-    public List getContributors();
-
-    /**
-     * Sets the feed author.
-     * <p>
-     * Returns contributors as a list of SyndPerson objects.
-     * <p>
-     * @param contributors the feed contributors to set, <b>null</b> if none.
-     *
-     */
-    void setContributors(List contributors);
-
-    /**
-     * Returns the feed copyright.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module rights.
-     * <p>
-     * @return the feed copyright, <b>null</b> if none.
-     *
-     */
-    String getCopyright();
-
-    /**
-     * Sets the feed copyright.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module rights.
-     * <p>
-     * @param copyright the feed copyright to set, <b>null</b> if none.
-     *
-     */
-    void setCopyright(String copyright);
-
-    /**
-     * Returns the feed image.
-     * <p>
-     * @return the feed image, <b>null</b> if none.
-     *
-     */
-    SyndImage getImage();
-
-    /**
-     * Sets the feed image.
-     * <p>
-     * @param image the feed image to set, <b>null</b> if none.
-     *
-     */
-    void setImage(SyndImage image);
-
-    /**
-     * Returns the feed categories.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module subjects.
-     * <p>
-     * @return a list of SyndCategoryImpl elements with the feed categories,
-     *         an empty list if none.
-     *
-     */
-    List getCategories();
-
-    /**
-     * Sets the feed categories.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module subjects.
-     * <p>
-     * @param categories the list of SyndCategoryImpl elements with the feed categories to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    void setCategories(List categories);
-
-    /**
-     * Returns the feed entries.
-     * <p>
-     * @return a list of SyndEntryImpl elements with the feed entries,
-     *         an empty list if none.
-     *
-     */
-    List getEntries();
-
-    /**
-     * Sets the feed entries.
-     * <p>
-     * @param entries the list of SyndEntryImpl elements with the feed entries to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    void setEntries(List entries);
-
-    /**
-     * Returns the feed language.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module language.
-     * <p>
-     * @return the feed language, <b>null</b> if none.
-     *
-     */
-    String getLanguage();
-
-    /**
-     * Sets the feed language.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module language.
-     * <p>
-     * @param language the feed language to set, <b>null</b> if none.
-     *
-     */
-    void setLanguage(String language);
-
-    /**
-     * Returns the module identified by a given URI.
-     * <p>
-     * @param uri the URI of the ModuleImpl.
-     * @return The module with the given URI, <b>null</b> if none.
-     */
-    public Module getModule(String uri);
-
-    /**
-     * Returns the feed modules.
-     * <p>
-     * @return a list of ModuleImpl elements with the feed modules,
-     *         an empty list if none.
-     *
-     */
-    List getModules();
-
-    /**
-     * Sets the feed modules.
-     * <p>
-     * @param modules the list of ModuleImpl elements with the feed modules to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    void setModules(List modules);
-
-    /**
-     * Returns foreign markup found at channel level.
-     * <p>
-     * @return Opaque object to discourage use
-     *
-     */
-    public Object getForeignMarkup();
-
-    /**
-     * Sets foreign markup found at channel level.
-     * <p>
-     * @param foreignMarkup Opaque object to discourage use
-     *
-     */
-    public void setForeignMarkup(Object foreignMarkup);
-    
-    /**
-     * Creates a deep clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException;
+	/**
+	 * Returns the real feed types the SyndFeedImpl supports when converting
+	 * from and to.
+	 * <p>
+	 * 
+	 * @return the real feed type supported.
+	 */
+	List<String> getSupportedFeedTypes();
+
+	/**
+	 * Creates a real feed containing the information of the SyndFeedImpl.
+	 * <p>
+	 * The feed type of the created WireFeed is taken from the SyndFeedImpl
+	 * feedType property.
+	 * <p>
+	 * 
+	 * @return the real feed.
+	 * 
+	 */
+	WireFeed createWireFeed();
+
+	/**
+	 * Creates a real feed containing the information of the SyndFeedImpl.
+	 * <p>
+	 * 
+	 * @param feedType
+	 *            the feed type for the WireFeed to be created.
+	 * @return the real feed.
+	 * 
+	 */
+	WireFeed createWireFeed(String feedType);
+
+	/**
+	 * Returns the WireFeed this SyndFeed was created from. Will return null if
+	 * the original feed is not stored or if this SyndFeed was not created from
+	 * a WireFeed
+	 * 
+	 * @return The WireFeed this was created from, or null
+	 * 
+	 */
+	WireFeed originalWireFeed();
+
+	/**
+	 * 
+	 * @return true if this SyndFeed preserves the WireFeed it was created from
+	 */
+	boolean isPreservingWireFeed();
+
+	/**
+	 * Returns the wire feed type the feed had/will-have when converted from/to
+	 * a WireFeed.
+	 * <p>
+	 * 
+	 * @return the feed type, <b>null</b> if none.
+	 * 
+	 */
+	String getFeedType();
+
+	/**
+	 * Sets the wire feed type the feed will-have when coverted to a WireFeed.
+	 * <p>
+	 * 
+	 * @param feedType
+	 *            the feed type to set, <b>null</b> if none.
+	 * 
+	 */
+	void setFeedType(String feedType);
+
+	/**
+	 * Returns the charset encoding of a the feed. This is not set by Rome
+	 * parsers.
+	 * <p>
+	 * 
+	 * @return the charset encoding of the feed.
+	 * 
+	 */
+	String getEncoding();
+
+	/**
+	 * Sets the charset encoding of a the feed. This is not set by Rome parsers.
+	 * <p>
+	 * 
+	 * @param encoding
+	 *            the charset encoding of the feed.
+	 * 
+	 */
+	void setEncoding(String encoding);
+
+	/**
+	 * Returns the feed URI.
+	 * <p>
+	 * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
+	 * the concrete feed type. This is explained in detail in Rome
+	 * documentation, <a
+	 * href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
+	 * entry URI mapping</a>.
+	 * <p>
+	 * The returned URI is a normalized URI as specified in RFC 2396bis.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @return the feed URI, <b>null</b> if none.
+	 * 
+	 */
+	String getUri();
+
+	/**
+	 * Sets the feed URI.
+	 * <p>
+	 * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
+	 * the concrete feed type. This is explained in detail in Rome
+	 * documentation, <a
+	 * href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
+	 * entry URI mapping</a>.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the feed URI to set, <b>null</b> if none.
+	 * 
+	 */
+	void setUri(String uri);
+
+	/**
+	 * Returns the feed title.
+	 * <p>
+	 * 
+	 * @return the feed title, <b>null</b> if none.
+	 * 
+	 */
+	String getTitle();
+
+	/**
+	 * Sets the feed title.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the feed title to set, <b>null</b> if none.
+	 * 
+	 */
+	void setTitle(String title);
+
+	/**
+	 * Returns the feed title.
+	 * <p>
+	 * 
+	 * @return the feed title, <b>null</b> if none.
+	 * 
+	 */
+	SyndContent getTitleEx();
+
+	/**
+	 * Sets the feed title.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the feed title to set, <b>null</b> if none.
+	 * 
+	 */
+	void setTitleEx(SyndContent title);
+
+	/**
+	 * Returns the feed link.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @return the feed link, <b>null</b> if none.
+	 * 
+	 */
+	String getLink();
+
+	/**
+	 * Sets the feed link.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @param link
+	 *            the feed link to set, <b>null</b> if none.
+	 * 
+	 */
+	void setLink(String link);
+
+	/**
+	 * Returns the entry links
+	 * <p>
+	 * 
+	 * @return the entry links, <b>null</b> if none.
+	 * 
+	 */
+	List<SyndLink> getLinks();
+
+	/**
+	 * Sets the entry links.
+	 * <p>
+	 * 
+	 * @param links
+	 *            the entry links to set, <b>null</b> if none.
+	 * 
+	 */
+	void setLinks(List<SyndLink> links);
+
+	/**
+	 * Returns the feed description.
+	 * <p>
+	 * 
+	 * @return the feed description, <b>null</b> if none.
+	 * 
+	 */
+	String getDescription();
+
+	/**
+	 * Sets the feed description.
+	 * <p>
+	 * 
+	 * @param description
+	 *            the feed description to set, <b>null</b> if none.
+	 * 
+	 */
+	void setDescription(String description);
+
+	/**
+	 * Returns the feed description as a text construct.
+	 * <p>
+	 * 
+	 * @return the feed description, <b>null</b> if none.
+	 * 
+	 */
+	SyndContent getDescriptionEx();
+
+	/**
+	 * Sets the feed description as a text construct.
+	 * <p>
+	 * 
+	 * @param description
+	 *            the feed description to set, <b>null</b> if none.
+	 * 
+	 */
+	void setDescriptionEx(SyndContent description);
+
+	/**
+	 * Returns the feed published date.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * date.
+	 * <p>
+	 * 
+	 * @return the feed published date, <b>null</b> if none.
+	 * 
+	 */
+	Date getPublishedDate();
+
+	/**
+	 * Sets the feed published date.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * date.
+	 * <p>
+	 * 
+	 * @param publishedDate
+	 *            the feed published date to set, <b>null</b> if none.
+	 * 
+	 */
+	void setPublishedDate(Date publishedDate);
+
+	/**
+	 * Returns the feed authors.
+	 * <p>
+	 * For Atom feeds, this returns the authors as a list of SyndPerson objects,
+	 * for RSS feeds this method is a convenience method, it maps to the Dublin
+	 * Core module creator.
+	 * <p>
+	 * 
+	 * @return the feed authors, <b>null</b> if none.
+	 * 
+	 */
+	List<SyndPerson> getAuthors();
+
+	/**
+	 * Sets the feed authors.
+	 * <p>
+	 * For Atom feeds, this sets the authors as a list of SyndPerson objects,
+	 * for RSS feeds this method is a convenience method, it maps to the Dublin
+	 * Core module creator.
+	 * <p>
+	 * 
+	 * @param authors
+	 *            the feed authors to set, <b>null</b> if none.
+	 * 
+	 */
+	void setAuthors(List<SyndPerson> authors);
+
+	/**
+	 * Returns the name of the first feed author in the collection of authors.
+	 * <p>
+	 * For Atom feeds, this returns the authors as a list of SyndPerson objects,
+	 * for RSS feeds this method is a convenience method, it maps to the Dublin
+	 * Core module creator.
+	 * <p>
+	 * 
+	 * @return the feed author, <b>null</b> if none.
+	 * 
+	 */
+	String getAuthor();
+
+	/**
+	 * Sets the feed author.
+	 * <p>
+	 * For Atom feeds, this sets the feed author's name, for RSS feeds this
+	 * method is a convenience method, it maps to the Dublin Core module
+	 * creator.
+	 * <p>
+	 * 
+	 * @param author
+	 *            the feed author to set, <b>null</b> if none.
+	 * 
+	 */
+	void setAuthor(String author);
+
+	/**
+	 * Returns the feed author.
+	 * <p>
+	 * For Atom feeds, this returns the contributors as a list of SyndPerson
+	 * objects
+	 * <p>
+	 * 
+	 * @return the feed author, <b>null</b> if none.
+	 * 
+	 */
+	List<SyndPerson> getContributors();
+
+	/**
+	 * Sets the feed author.
+	 * <p>
+	 * Returns contributors as a list of SyndPerson objects.
+	 * <p>
+	 * 
+	 * @param contributors
+	 *            the feed contributors to set, <b>null</b> if none.
+	 * 
+	 */
+	void setContributors(List<SyndPerson> contributors);
+
+	/**
+	 * Returns the feed copyright.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * rights.
+	 * <p>
+	 * 
+	 * @return the feed copyright, <b>null</b> if none.
+	 * 
+	 */
+	String getCopyright();
+
+	/**
+	 * Sets the feed copyright.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * rights.
+	 * <p>
+	 * 
+	 * @param copyright
+	 *            the feed copyright to set, <b>null</b> if none.
+	 * 
+	 */
+	void setCopyright(String copyright);
+
+	/**
+	 * Returns the feed image.
+	 * <p>
+	 * 
+	 * @return the feed image, <b>null</b> if none.
+	 * 
+	 */
+	SyndImage getImage();
+
+	/**
+	 * Sets the feed image.
+	 * <p>
+	 * 
+	 * @param image
+	 *            the feed image to set, <b>null</b> if none.
+	 * 
+	 */
+	void setImage(SyndImage image);
+
+	/**
+	 * Returns the feed categories.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * subjects.
+	 * <p>
+	 * 
+	 * @return a list of SyndCategoryImpl elements with the feed categories, an
+	 *         empty list if none.
+	 * 
+	 */
+	List<SyndCategory> getCategories();
+
+	/**
+	 * Sets the feed categories.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * subjects.
+	 * <p>
+	 * 
+	 * @param categories
+	 *            the list of SyndCategoryImpl elements with the feed categories
+	 *            to set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	void setCategories(List<SyndCategory> categories);
+
+	/**
+	 * Returns the feed entries.
+	 * <p>
+	 * 
+	 * @return a list of SyndEntryImpl elements with the feed entries, an empty
+	 *         list if none.
+	 * 
+	 */
+	List<SyndEntry> getEntries();
+
+	/**
+	 * Sets the feed entries.
+	 * <p>
+	 * 
+	 * @param entries
+	 *            the list of SyndEntryImpl elements with the feed entries to
+	 *            set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	void setEntries(List<SyndEntry> entries);
+
+	/**
+	 * Returns the feed language.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * language.
+	 * <p>
+	 * 
+	 * @return the feed language, <b>null</b> if none.
+	 * 
+	 */
+	String getLanguage();
+
+	/**
+	 * Sets the feed language.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * language.
+	 * <p>
+	 * 
+	 * @param language
+	 *            the feed language to set, <b>null</b> if none.
+	 * 
+	 */
+	void setLanguage(String language);
+
+	/**
+	 * Returns the module identified by a given URI.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the URI of the ModuleImpl.
+	 * @return The module with the given URI, <b>null</b> if none.
+	 */
+	public Module getModule(String uri);
+
+	/**
+	 * Returns the feed modules.
+	 * <p>
+	 * 
+	 * @return a list of ModuleImpl elements with the feed modules, an empty
+	 *         list if none.
+	 * 
+	 */
+	List<Module> getModules();
+
+	/**
+	 * Sets the feed modules.
+	 * <p>
+	 * 
+	 * @param modules
+	 *            the list of ModuleImpl elements with the feed modules to set,
+	 *            an empty list or <b>null</b> if none.
+	 * 
+	 */
+	void setModules(List<Module> modules);
+
+	/**
+	 * Returns foreign markup found at channel level.
+	 * <p>
+	 * 
+	 * @return Opaque object to discourage use
+	 * 
+	 */
+	List<Object> getForeignMarkup();
+
+	/**
+	 * Sets foreign markup found at channel level.
+	 * <p>
+	 * 
+	 * @param foreignMarkup
+	 *            Opaque object to discourage use
+	 * 
+	 */
+	void setForeignMarkup(List<Object> foreignMarkup);
+
+	/**
+	 * Creates a deep clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	Object clone() throws CloneNotSupportedException;
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndLink.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndLink.java,v
retrieving revision 1.1
diff -u -r1.1 SyndLink.java
--- src/java/com/sun/syndication/feed/synd/SyndLink.java	15 Nov 2005 20:39:45 -0000	1.1
+++ src/java/com/sun/syndication/feed/synd/SyndLink.java	30 Sep 2009 06:30:41 -0000
@@ -28,7 +28,7 @@
      * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
      *
      */
-    public abstract Object clone() throws CloneNotSupportedException;
+    Object clone() throws CloneNotSupportedException;
 
     /**
      * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
@@ -37,7 +37,7 @@
      * @return <b>true</b> if 'this' object is equal to the 'other' object.
      *
      */
-    public abstract boolean equals(Object other);
+    boolean equals(Object other);
 
     /**
      * Returns a hashcode value for the object.
@@ -47,7 +47,7 @@
      * @return the hashcode of the bean object.
      *
      */
-    public abstract int hashCode();
+    int hashCode();
 
     /**
      * Returns the String representation for the object.
@@ -55,7 +55,7 @@
      * @return String representation for the object.
      *
      */
-    public abstract String toString();
+    String toString();
 
     /**
      * Returns the link rel.
@@ -63,7 +63,7 @@
      * @return the link rel, <b>null</b> if none.
      *
      */
-    public abstract String getRel();
+    String getRel();
 
     /**
      * Sets the link rel.
@@ -71,7 +71,7 @@
      * @param rel the link rel,, <b>null</b> if none.
      *
      */
-    public abstract void setRel(String rel);
+    void setRel(String rel);
 
     /**
      * Returns the link type.
@@ -79,7 +79,7 @@
      * @return the link type, <b>null</b> if none.
      *
      */
-    public abstract String getType();
+    String getType();
 
     /**
      * Sets the link type.
@@ -87,7 +87,7 @@
      * @param type the link type, <b>null</b> if none.
      *
      */
-    public abstract void setType(String type);
+    void setType(String type);
 
     /**
      * Returns the link href.
@@ -95,7 +95,7 @@
      * @return the link href, <b>null</b> if none.
      *
      */
-    public abstract String getHref();
+    String getHref();
 
     /**
      * Sets the link href.
@@ -103,7 +103,7 @@
      * @param href the link href, <b>null</b> if none.
      *
      */
-    public abstract void setHref(String href);
+    void setHref(String href);
 
     /**
      * Returns the link title.
@@ -111,7 +111,7 @@
      * @return the link title, <b>null</b> if none.
      *
      */
-    public abstract String getTitle();
+    String getTitle();
 
     /**
      * Sets the link title.
@@ -119,33 +119,33 @@
      * @param title the link title, <b>null</b> if none.
      *
      */
-    public abstract void setTitle(String title);
+    void setTitle(String title);
 
     /**
      * Returns the hreflang
      * <p>
      * @return Returns the hreflang.
      */
-    public abstract String getHreflang();
+    String getHreflang();
 
     /**
      * Set the hreflang
      * <p>
      * @param hreflang The hreflang to set.
      */
-    public abstract void setHreflang(String hreflang);
+    void setHreflang(String hreflang);
 
     /**
      * Returns the length
      * <p>
      * @return Returns the length.
      */
-    public abstract long getLength();
+    long getLength();
 
     /**
      * Set the length
      * <p>
      * @param length The length to set.
      */
-    public abstract void setLength(long length);
+    void setLength(long length);
 }
\ No newline at end of file
Index: src/java/com/sun/syndication/feed/synd/SyndPersonImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndPersonImpl.java,v
retrieving revision 1.2
diff -u -r1.2 SyndPersonImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndPersonImpl.java	4 Jan 2009 22:40:46 -0000	1.2
+++ src/java/com/sun/syndication/feed/synd/SyndPersonImpl.java	30 Sep 2009 06:30:41 -0000
@@ -16,174 +16,199 @@
  */
 package com.sun.syndication.feed.synd;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
 import com.sun.syndication.feed.impl.ObjectBean;
-import com.sun.syndication.feed.module.DCSubjectImpl;
-import com.sun.syndication.feed.module.DCSubject;
 import com.sun.syndication.feed.module.Module;
 import com.sun.syndication.feed.module.impl.ModuleUtils;
 
-import java.util.AbstractList;
-import java.util.List;
-import java.util.ArrayList;
-import java.io.Serializable;
-
 /**
  * Bean for authors and contributors of SyndFeedImpl feeds and entries.
  * <p>
+ * 
  * @author Dave Johnson
- *
+ * 
  */
 public class SyndPersonImpl implements Serializable, SyndPerson {
-    private ObjectBean _objBean;
-    private String _name;
-    private String _uri;
-    private String _email;
-    private List _modules;
-
-    /**
-     * For implementations extending SyndContentImpl to be able to use the ObjectBean functionality
-     * with extended interfaces.
-     */
-    public SyndPersonImpl() {
-        _objBean = new ObjectBean(SyndPerson.class,this);
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        return _objBean.equals(other);
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-    /**
-     * Returns the person name.
-     * <p>
-     * @return the person name, <b>null</b> if none.
-     *
-     */
-    public String getName() {
-        return _name;
-    }
-
-    /**
-     * Sets the category name.
-     * <p>
-     * @param name the category name to set, <b>null</b> if none.
-     *
-     */
-    public void setName(String name) {
-        _name = name;
-    }
-
-    /**
-     * Returns the person's e-mail address.
-     * <p>
-     * @return the person's e-mail address, <b>null</b> if none.
-     *
-     */
-    public String getEmail() {
-        return _email;
-    }
-
-    /**
-     * Sets the person's e-mail address.
-     * <p>
-     * @param email The person's e-mail address to set, <b>null</b> if none.
-     *
-     */
-    public void setEmail(String email) {
-        _email = email;
-    }
-
-    /**
-     * Returns the person's URI.
-     * <p>
-     * @return the person's URI, <b>null</b> if none.
-     *
-     */
-    public String getUri() {
-        return _uri;
-    }
-
-    /**
-     * Sets the person's URI.
-     * <p>
-     * @param uri the peron's URI to set, <b>null</b> if none.
-     *
-     */
-    public void setUri(String uri) {
-        _uri = uri;
-    }
-
-    /**
-     * Returns the person modules.
-     * <p>
-     * @return a list of ModuleImpl elements with the person modules,
-     *         an empty list if none.
-     */
-    public List getModules()
-    {
-        if  (_modules==null) {
-            _modules=new ArrayList();
-        }
-        return _modules;
-    }
-
-    /**
-     * Sets the person modules.
-     * <p>
-     * @param modules the list of ModuleImpl elements with the person modules to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setModules(List modules) {
-        _modules = modules;
-    }
-
-    /**
-     * Returns the module identified by a given URI.
-     * <p>
-     * @param uri the URI of the ModuleImpl.
-     * @return The module with the given URI, <b>null</b> if none.
-     */
-    public Module getModule(String uri) {
-        return ModuleUtils.getModule(getModules(),uri);
-    }
+
+	private static final long serialVersionUID = 335781496529593422L;
+
+	private ObjectBean _objBean;
+
+	private String _name;
+
+	private String _uri;
+
+	private String _email;
+
+	private List<Module> _modules;
+
+	/**
+	 * For implementations extending SyndContentImpl to be able to use the
+	 * ObjectBean functionality with extended interfaces.
+	 */
+	public SyndPersonImpl() {
+		_objBean = new ObjectBean(SyndPerson.class, this);
+	}
+
+	/**
+	 * Creates a deep 'bean' clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return _objBean.clone();
+	}
+
+	/**
+	 * Indicates whether some other object is "equal to" this one as defined by
+	 * the Object equals() method.
+	 * <p>
+	 * 
+	 * @param other
+	 *            he reference object with which to compare.
+	 * @return <b>true</b> if 'this' object is equal to the 'other' object.
+	 * 
+	 */
+	public boolean equals(Object other) {
+		return _objBean.equals(other);
+	}
+
+	/**
+	 * Returns a hashcode value for the object.
+	 * <p>
+	 * It follows the contract defined by the Object hashCode() method.
+	 * <p>
+	 * 
+	 * @return the hashcode of the bean object.
+	 * 
+	 */
+	public int hashCode() {
+		return _objBean.hashCode();
+	}
+
+	/**
+	 * Returns the String representation for the object.
+	 * <p>
+	 * 
+	 * @return String representation for the object.
+	 * 
+	 */
+	public String toString() {
+		return _objBean.toString();
+	}
+
+	/**
+	 * Returns the person name.
+	 * <p>
+	 * 
+	 * @return the person name, <b>null</b> if none.
+	 * 
+	 */
+	public String getName() {
+		return _name;
+	}
+
+	/**
+	 * Sets the category name.
+	 * <p>
+	 * 
+	 * @param name
+	 *            the category name to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setName(String name) {
+		_name = name;
+	}
+
+	/**
+	 * Returns the person's e-mail address.
+	 * <p>
+	 * 
+	 * @return the person's e-mail address, <b>null</b> if none.
+	 * 
+	 */
+	public String getEmail() {
+		return _email;
+	}
+
+	/**
+	 * Sets the person's e-mail address.
+	 * <p>
+	 * 
+	 * @param email
+	 *            The person's e-mail address to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setEmail(String email) {
+		_email = email;
+	}
+
+	/**
+	 * Returns the person's URI.
+	 * <p>
+	 * 
+	 * @return the person's URI, <b>null</b> if none.
+	 * 
+	 */
+	public String getUri() {
+		return _uri;
+	}
+
+	/**
+	 * Sets the person's URI.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the peron's URI to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setUri(String uri) {
+		_uri = uri;
+	}
+
+	/**
+	 * Returns the person modules.
+	 * <p>
+	 * 
+	 * @return a list of ModuleImpl elements with the person modules, an empty
+	 *         list if none.
+	 */
+	public List<Module> getModules() {
+		if (_modules == null) {
+			_modules = new ArrayList<Module>();
+		}
+		return _modules;
+	}
+
+	/**
+	 * Sets the person modules.
+	 * <p>
+	 * 
+	 * @param modules
+	 *            the list of ModuleImpl elements with the person modules to
+	 *            set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setModules(List<Module> modules) {
+		_modules = modules;
+	}
+
+	/**
+	 * Returns the module identified by a given URI.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the URI of the ModuleImpl.
+	 * @return The module with the given URI, <b>null</b> if none.
+	 */
+	public Module getModule(String uri) {
+		return ModuleUtils.getModule(getModules(), uri);
+	}
 }
Index: src/java/com/sun/syndication/feed/synd/Converter.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/Converter.java,v
retrieving revision 1.3
diff -u -r1.3 Converter.java
--- src/java/com/sun/syndication/feed/synd/Converter.java	4 Aug 2004 02:35:38 -0000	1.3
+++ src/java/com/sun/syndication/feed/synd/Converter.java	30 Sep 2009 06:30:40 -0000
@@ -43,7 +43,7 @@
      * @return the real feed type.
      *
      */
-    public String getType();
+    String getType();
 
     /**
      * Makes a deep copy/conversion of the values of a real feed into a SyndFeedImpl.
@@ -54,7 +54,7 @@
      * @param syndFeed the SyndFeedImpl that will contain the copied/converted values of the real feed.
      *
      */
-    public void copyInto(WireFeed feed,SyndFeed syndFeed);
+    void copyInto(WireFeed feed,SyndFeed syndFeed);
 
     /**
      * Creates real feed with a deep copy/conversion of the values of a SyndFeedImpl.
@@ -63,6 +63,6 @@
      * @return a real feed with copied/converted values of the SyndFeedImpl.
      *
      */
-    public WireFeed createRealFeed(SyndFeed syndFeed);
+    WireFeed createRealFeed(SyndFeed syndFeed);
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndFeedImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndFeedImpl.java,v
retrieving revision 1.19
diff -u -r1.19 SyndFeedImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndFeedImpl.java	2 Mar 2009 22:39:05 -0000	1.19
+++ src/java/com/sun/syndication/feed/synd/SyndFeedImpl.java	30 Sep 2009 06:30:41 -0000
@@ -16,756 +16,890 @@
  */
 package com.sun.syndication.feed.synd;
 
-import com.sun.syndication.feed.impl.ObjectBean;
-import com.sun.syndication.feed.impl.CopyFromHelper;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.syndication.feed.CopyFrom;
 import com.sun.syndication.feed.WireFeed;
-import com.sun.syndication.feed.module.*;
+import com.sun.syndication.feed.impl.CopyFromHelper;
+import com.sun.syndication.feed.impl.ObjectBean;
+import com.sun.syndication.feed.module.DCModule;
+import com.sun.syndication.feed.module.DCModuleImpl;
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.feed.module.SyModule;
+import com.sun.syndication.feed.module.SyModuleImpl;
 import com.sun.syndication.feed.module.impl.ModuleUtils;
 import com.sun.syndication.feed.synd.impl.Converters;
 import com.sun.syndication.feed.synd.impl.URINormalizer;
 
-import java.util.*;
-import java.io.Serializable;
-
 /**
  * Bean for all types of feeds.
  * <p>
- * It handles all RSS versions, Atom 0.3 and Atom 1.0, it normalizes all info, it may lose information.
+ * It handles all RSS versions, Atom 0.3 and Atom 1.0, it normalizes all info,
+ * it may lose information.
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
 public class SyndFeedImpl implements Serializable, SyndFeed {
-    
-    private ObjectBean _objBean;
-    
-    private String    _encoding;
-    private String    _uri;
-    private SyndContent _title;
-    private SyndContent _description;
-    private String    _feedType;
-    private String    _link;
-    private List      _links;
-    private SyndImage _image;
-    private List      _entries;
-    private List      _modules;
-    private List      _authors;
-    private List      _contributors;
-    private List      _foreignMarkup;
-    
-    private WireFeed wireFeed = null;
-    private boolean preserveWireFeed = false;
-
-    private static final Converters CONVERTERS = new Converters();
-
-    private static final Set IGNORE_PROPERTIES = new HashSet();
-
-    /**
-     * Unmodifiable Set containing the convenience properties of this class.
-     * <p>
-     * Convenience properties are mapped to Modules, for cloning the convenience properties
-     * can be ignored as the will be copied as part of the module cloning.
-     */
-
-    public static final Set CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
-
-    static {
-        IGNORE_PROPERTIES.add("publishedDate");
-        IGNORE_PROPERTIES.add("author");
-        IGNORE_PROPERTIES.add("copyright");
-        IGNORE_PROPERTIES.add("categories");
-        IGNORE_PROPERTIES.add("language");
-    }
-
-    /**
-     * Returns the real feed types the SyndFeedImpl supports when converting from and to.
-     * <p>
-     * @return the real feed type supported.
-     */
-    public List getSupportedFeedTypes() {
-        return CONVERTERS.getSupportedFeedTypes();
-    }
-
-    /**
-     * For implementations extending SyndFeedImpl to be able to use the ObjectBean functionality
-     * with extended interfaces.
-     * <p>
-     * @param beanClass
-     * @param convenienceProperties set containing the convenience properties of the SyndEntryImpl
-     * (the are ignored during cloning, check CloneableBean for details).
-     *
-     */
-    protected SyndFeedImpl(Class beanClass,Set convenienceProperties) {
-        _objBean = new ObjectBean(beanClass,this,convenienceProperties);
-    }
-
-    /**
-     * Default constructor. All properties are set to <b>null</b>.
-     * <p>
-     *
-     */
-    public SyndFeedImpl() {
-        this(null);
-    }
-
-    /**
-     * Creates a SyndFeedImpl and populates all its properties out of the
-     * given RSS Channel or Atom Feed properties.
-     * <p>
-     * @param feed the RSS Channel or the Atom Feed to populate the properties from.
-     *
-     */
-    public SyndFeedImpl(WireFeed feed) {
-        this(feed, false);
-    }
-    
-    /**
-     * Creates a SyndFeedImpl and populates all its properties out of the
-     * given RSS Channel or Atom Feed properties, while optionally preserving
-     * the WireFeed for access via the orignalWireFeed() method.
-     * 
-     * @param feed
-     * @param preserveWireFeed
-     */
-    public SyndFeedImpl(WireFeed feed, boolean preserveWireFeed) {    	
-        this(SyndFeed.class,IGNORE_PROPERTIES);
-
-    	if (preserveWireFeed) {    		
-    		this.wireFeed = feed;
-    		this.preserveWireFeed = preserveWireFeed;
-    	}
-                
-        if (feed!=null) {
-            _feedType = feed.getFeedType();
-            Converter converter = CONVERTERS.getConverter(_feedType);
-            if (converter==null) {
-                throw new IllegalArgumentException("Invalid feed type ["+_feedType+"]");
-            }
-            converter.copyInto(feed,this);
-        }
-        
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        if (other == null) {
-            return false;
-        }
-        // can't use foreign markup in equals, due to JDOM equals impl
-        Object fm = getForeignMarkup();
-        setForeignMarkup(((SyndFeedImpl)other).getForeignMarkup());       
-        boolean ret = _objBean.equals(other);
-        // restore foreign markup
-        setForeignMarkup(fm);
-        return ret;
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-    /**
-     * Creates a real feed containing the information of the SyndFeedImpl.
-     * <p>
-     * The feed type of the created WireFeed is taken from the SyndFeedImpl feedType property.
-     * <p>
-     * @return the real feed.
-     *
-     */
-    public WireFeed createWireFeed() {
-        return createWireFeed(_feedType);
-    }
-
-    /**
-     * Creates a real feed containing the information of the SyndFeedImpl.
-     * <p>
-     * @param feedType the feed type for the WireFeed to be created.
-     * @return the real feed.
-     *
-     */
-    public WireFeed createWireFeed(String feedType) {
-        if (feedType==null) {
-            throw new IllegalArgumentException("Feed type cannot be null");
-        }
-        Converter converter = CONVERTERS.getConverter(feedType);
-        if (converter==null) {
-            throw new IllegalArgumentException("Invalid feed type ["+feedType+"]");
-        }
-        return converter.createRealFeed(this);
-    }
-    
-    /**
-     * Returns the WireFeed this SyndFeed was created from. 
-     * Will return null if the original feed is not stored or if this SyndFeed was not created from a WireFeed.
-     * <br />
-     * Note: The wire feed returned here will NOT contain any modifications done on this SyndFeed since it was created.
-     * That is in contrast to the createWireFeed method, which will reflect the current state of the SyndFeed
-     * 
-     * @return The WireFeed this was created from, or null
-     * 
-     */    
-    public WireFeed originalWireFeed() {
-    	return wireFeed;
-    }
-
-    /**
-     * Returns the wire feed type the feed had/will-have when coverted from/to a WireFeed.
-     * <p>
-     * @return the feed type, <b>null</b> if none.
-     *
-     */
-    public String getFeedType() {
-        return _feedType;
-    }
-
-    /**
-     * Sets the wire feed type the feed will-have when coverted to a WireFeed.
-     * <p>
-     * @param feedType the feed type to set, <b>null</b> if none.
-     *
-     */
-    public void setFeedType(String feedType) {
-        _feedType = feedType;
-    }
-
-    /**
-     * Returns the charset encoding of a the feed. This is not set by Rome parsers.
-     * <p>
-     * @return the charset encoding of the feed.
-     *
-     */
-    public String getEncoding() {
-        return _encoding;
-    }
-
-    /**
-     * Sets the charset encoding of a the feed. This is not set by Rome parsers.
-     * <p>
-     * @param encoding the charset encoding of the feed.
-     *
-     */
-    public void setEncoding(String encoding) {
-        _encoding = encoding;
-    }
-
-    /**
-     * Returns the feed URI.
-     * <p>
-     * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
-     * the concrete feed type. This is explained in detail in Rome documentation,
-     * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
-     * <p>
-     * The returned URI is a normalized URI as specified in RFC 2396bis.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @return the feed URI, <b>null</b> if none.
-     *
-     */
-    public String getUri() {
-        return _uri;
-    }
-
-    /**
-     * Sets the feed URI.
-     * <p>
-     * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
-     * the concrete feed type. This is explained in detail in Rome documentation,
-     * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @param uri the feed URI to set, <b>null</b> if none.
-     *
-     */
-    public void setUri(String uri) {
-        _uri = URINormalizer.normalize(uri);
-    }
-
-    /**
-     * Returns the feed title.
-     * <p>
-     * @return the feed title, <b>null</b> if none.
-     *
-     */
-    public String getTitle() {
-        if (_title != null) return _title.getValue();
-        return null;
-    }
-
-    /**
-     * Sets the feed title.
-     * <p>
-     * @param title the feed title to set, <b>null</b> if none.
-     *
-     */
-    public void setTitle(String title) {
-        if (_title == null) _title = new SyndContentImpl();
-        _title.setValue(title);
-    }
-
-    /**
-     * Returns the feed title as a text construct.
-     * <p>
-     * @return the feed title, <b>null</b> if none.
-     *
-     */
-    public SyndContent getTitleEx() {
-        return _title;
-    }
-
-    /**
-     * Sets the feed title as a text construct.
-     * <p>
-     * @param title the feed title to set, <b>null</b> if none.
-     *
-     */
-    public void setTitleEx(SyndContent title) {
-        _title = title;
-    }
-
-    /**
-     * Returns the feed link.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @return the feed link, <b>null</b> if none.
-     *
-     */
-    public String getLink() {
-        return _link;
-    }
-
-    /**
-     * Sets the feed link.
-     * <p>
-     * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
-     * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link
-     * is the URL that the item is accessible under, the URI is the
-     * permanent identifier which the aggregator should use to reference
-     * this item. Often the URI will use some standardized identifier scheme
-     * such as DOI's so that items can be identified even if they appear in
-     * multiple feeds with different "links" (they might be on different
-     * hosting platforms but be the same item). Also, though rare, there
-     * could be multiple items with the same link but a different URI and
-     * associated metadata which need to be treated as distinct entities.
-     * In the RSS 1.0 case the URI must be a valid RDF URI reference.
-     * <p>
-     * @param link the feed link to set, <b>null</b> if none.
-     *
-     */
-    public void setLink(String link) {
-        _link = link;
-    }
-
-    /**
-     * Returns the feed description.
-     * <p>
-     * @return the feed description, <b>null</b> if none.
-     *
-     */
-    public String getDescription() {
-        if (_description != null) return _description.getValue();
-        return null;
-    }
-
-    /**
-     * Sets the feed description.
-     * <p>
-     * @param description the feed description to set, <b>null</b> if none.
-     *
-     */
-    public void setDescription(String description) {
-        if (_description == null) _description = new SyndContentImpl();
-        _description.setValue(description);
-    }
-    
-    /**
-     * Returns the feed description as a text construct.
-     * <p>
-     * @return the feed description, <b>null</b> if none.
-     *
-     */
-    public SyndContent getDescriptionEx() {
-        return _description;
-    }
-
-    /**
-     * Sets the feed description as a text construct.
-     * <p>
-     * @param description the feed description to set, <b>null</b> if none.
-     *
-     */
-    public void setDescriptionEx(SyndContent description) {
-        _description = description;
-    }
-
-    /**
-     * Returns the feed published date.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module date.
-     * <p>
-     * @return the feed published date, <b>null</b> if none.
-     *
-     */
-    public Date getPublishedDate() {
-        return getDCModule().getDate();
-    }
-
-    /**
-     * Sets the feed published date.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module date.
-     * <p>
-     * @param publishedDate the feed published date to set, <b>null</b> if none.
-     *
-     */
-    public void setPublishedDate(Date publishedDate) {
-        getDCModule().setDate(publishedDate);
-    }
-
-    /**
-     * Returns the feed copyright.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module rights.
-     * <p>
-     * @return the feed copyright, <b>null</b> if none.
-     *
-     */
-    public String getCopyright() {
-        return getDCModule().getRights();
-    }
-
-    /**
-     * Sets the feed copyright.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module rights.
-     * <p>
-     * @param copyright the feed copyright to set, <b>null</b> if none.
-     *
-     */
-    public void setCopyright(String copyright) {
-        getDCModule().setRights(copyright);
-    }
-
-    /**
-     * Returns the feed image.
-     * <p>
-     * @return the feed image, <b>null</b> if none.
-     *
-     */
-    public SyndImage getImage() {
-        return _image;
-    }
-
-    /**
-     * Sets the feed image.
-     * <p>
-     * @param image the feed image to set, <b>null</b> if none.
-     *
-     */
-    public void setImage(SyndImage image) {
-        _image = image;
-    }
-
-    /**
-     * Returns the feed categories.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module subjects.
-     * <p>
-     * @return a list of SyndCategoryImpl elements with the feed categories,
-     *         an empty list if none.
-     *
-     */
-    public List getCategories() {
-        return new SyndCategoryListFacade(getDCModule().getSubjects());
-    }
-
-    /**
-     * Sets the feed categories.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module subjects.
-     * <p>
-     * @param categories the list of SyndCategoryImpl elements with the feed categories to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setCategories(List categories) {
-        getDCModule().setSubjects(SyndCategoryListFacade.convertElementsSyndCategoryToSubject(categories));
-    }
-
-    /**
-     * Returns the feed entries.
-     * <p>
-     * @return a list of SyndEntryImpl elements with the feed entries,
-     *         an empty list if none.
-     *
-     */
-    public List getEntries() {
-        return (_entries==null) ? (_entries=new ArrayList()) : _entries;
-    }
-
-    /**
-     * Sets the feed entries.
-     * <p>
-     * @param entries the list of SyndEntryImpl elements with the feed entries to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setEntries(List entries) {
-        _entries = entries;
-    }
-
-    /**
-     * Returns the feed language.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module language.
-     * <p>
-     * @return the feed language, <b>null</b> if none.
-     *
-     */
-    public String getLanguage() {
-        return getDCModule().getLanguage();
-    }
-
-    /**
-     * Sets the feed language.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module language.
-     * <p>
-     * @param language the feed language to set, <b>null</b> if none.
-     *
-     */
-    public void setLanguage(String language) {
-        getDCModule().setLanguage(language);
-    }
-
-    /**
-     * Returns the feed modules.
-     * <p>
-     * @return a list of ModuleImpl elements with the feed modules,
-     *         an empty list if none.
-     *
-     */
-    public List getModules() {
-        if  (_modules==null) {
-            _modules=new ArrayList();
-        }
-        if (ModuleUtils.getModule(_modules,DCModule.URI)==null) {
-            _modules.add(new DCModuleImpl());
-        }
-        return _modules;
-    }
-
-
-    /**
-     * Sets the feed modules.
-     * <p>
-     * @param modules the list of ModuleImpl elements with the feed modules to set,
-     *        an empty list or <b>null</b> if none.
-     *
-     */
-    public void setModules(List modules) {
-        _modules = modules;
-    }
-
-    /**
-     * Returns the module identified by a given URI.
-     * <p>
-     * @param uri the URI of the ModuleImpl.
-     * @return The module with the given URI, <b>null</b> if none.
-     */
-    public Module getModule(String uri) {
-        return ModuleUtils.getModule(getModules(),uri);
-    }
-
-    /**
-     * Returns the Dublin Core module of the feed.
-     * @return the DC module, it's never <b>null</b>
-     *
-     */
-    private DCModule getDCModule() {
-        return (DCModule) getModule(DCModule.URI);
-    }
-
-    public Class getInterface() {
-        return SyndFeed.class;
-    }
-
-    public void copyFrom(Object obj) {
-        COPY_FROM_HELPER.copy(this,obj);
-    }
-
-
-    // TODO We need to find out how to refactor this one in a nice reusable way.
-
-    private static final CopyFromHelper COPY_FROM_HELPER;
-
-    static {
-        Map basePropInterfaceMap = new HashMap();
-        basePropInterfaceMap.put("feedType",String.class);
-        basePropInterfaceMap.put("encoding",String.class);
-        basePropInterfaceMap.put("uri",String.class);
-        basePropInterfaceMap.put("title",String.class);
-        basePropInterfaceMap.put("link",String.class);
-        basePropInterfaceMap.put("description",String.class);
-        basePropInterfaceMap.put("image",SyndImage.class);
-        basePropInterfaceMap.put("entries",SyndEntry.class);
-        basePropInterfaceMap.put("modules",Module.class);
-
-        Map basePropClassImplMap = new HashMap();
-        basePropClassImplMap.put(SyndEntry.class,SyndEntryImpl.class);
-        basePropClassImplMap.put(SyndImage.class,SyndImageImpl.class);
-        basePropClassImplMap.put(DCModule.class,DCModuleImpl.class);
-        basePropClassImplMap.put(SyModule.class,SyModuleImpl.class);
-
-        COPY_FROM_HELPER = new CopyFromHelper(SyndFeed.class,basePropInterfaceMap,basePropClassImplMap);
-    }
-
-    /**
-     * Returns the links
-     * <p>
-     * @return Returns the links.
-     */
-    public List getLinks() {
-        return (_links==null) ? (_links=new ArrayList()) : _links;
-    }
-    
-    /**
-     * Set the links
-     * <p>
-     * @param links The links to set.
-     */
-    public void setLinks(List links) {
-        _links = links;
-    }
-
-    public List getAuthors() {
-        return (_authors==null) ? (_authors=new ArrayList()) : _authors;
-    }
-
-    public void setAuthors(List authors) {
-        this._authors = authors;
-    }
-
-    /**
-     * Returns the feed author.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module creator.
-     * <p>
-     * @return the feed author, <b>null</b> if none.
-     *
-     */
-    public String getAuthor() {
-        return getDCModule().getCreator();
-    }
-
-    /**
-     * Sets the feed author.
-     * <p>
-     * This method is a convenience method, it maps to the Dublin Core module creator.
-     * <p>
-     * @param author the feed author to set, <b>null</b> if none.
-     *
-     */
-    public void setAuthor(String author) {
-        getDCModule().setCreator(author);
-    }    
-    
-    public List getContributors() {
-        return (_contributors==null) ? (_contributors=new ArrayList()) : _contributors;
-    }
-
-    public void setContributors(List contributors) {
-        this._contributors = contributors;
-    }
-
-    /**
-     * Returns foreign markup found at channel level.
-     * <p>
-     * @return Opaque object to discourage use
-     *
-     */
-    public Object getForeignMarkup() {
-        return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
-    }
-
-    /**
-     * Sets foreign markup found at channel level.
-     * <p>
-     * @param foreignMarkup Opaque object to discourage use
-     *
-     */
-    public void setForeignMarkup(Object foreignMarkup) {
-        _foreignMarkup = (List)foreignMarkup;
-    }
 
-	public boolean isPreservingWireFeed() {		
+	private static final long serialVersionUID = -6806739790723380855L;
+
+	private ObjectBean _objBean;
+
+	private String _encoding;
+
+	private String _uri;
+
+	private SyndContent _title;
+
+	private SyndContent _description;
+
+	private String _feedType;
+
+	private String _link;
+
+	private List<SyndLink> _links;
+
+	private SyndImage _image;
+
+	private List<SyndEntry> _entries;
+
+	private List<Module> _modules;
+
+	private List<SyndPerson> _authors;
+
+	private List<SyndPerson> _contributors;
+
+	private List<Object> _foreignMarkup;
+
+	private WireFeed wireFeed = null;
+
+	private boolean preserveWireFeed = false;
+
+	private static final Converters CONVERTERS = new Converters();
+
+	private static final Set<String> IGNORE_PROPERTIES = new HashSet<String>();
+
+	/**
+	 * Unmodifiable Set containing the convenience properties of this class.
+	 * <p>
+	 * Convenience properties are mapped to Modules, for cloning the convenience
+	 * properties can be ignored as the will be copied as part of the module
+	 * cloning.
+	 */
+
+	public static final Set<String> CONVENIENCE_PROPERTIES = Collections
+			.unmodifiableSet(IGNORE_PROPERTIES);
+
+	static {
+		IGNORE_PROPERTIES.add("publishedDate");
+		IGNORE_PROPERTIES.add("author");
+		IGNORE_PROPERTIES.add("copyright");
+		IGNORE_PROPERTIES.add("categories");
+		IGNORE_PROPERTIES.add("language");
+	}
+
+	private static final CopyFromHelper COPY_FROM_HELPER;
+
+	static {
+		Map<String, Class<?>> basePropInterfaceMap = new HashMap<String, Class<?>>();
+		basePropInterfaceMap.put("feedType", String.class);
+		basePropInterfaceMap.put("encoding", String.class);
+		basePropInterfaceMap.put("uri", String.class);
+		basePropInterfaceMap.put("title", String.class);
+		basePropInterfaceMap.put("link", String.class);
+		basePropInterfaceMap.put("description", String.class);
+		basePropInterfaceMap.put("image", SyndImage.class);
+		basePropInterfaceMap.put("entries", SyndEntry.class);
+		basePropInterfaceMap.put("modules", Module.class);
+
+		Map<Class<?>, Class<?>> basePropClassImplMap = new HashMap<Class<?>, Class<?>>();
+		basePropClassImplMap.put(SyndEntry.class, SyndEntryImpl.class);
+		basePropClassImplMap.put(SyndImage.class, SyndImageImpl.class);
+		basePropClassImplMap.put(DCModule.class, DCModuleImpl.class);
+		basePropClassImplMap.put(SyModule.class, SyModuleImpl.class);
+
+		COPY_FROM_HELPER = new CopyFromHelper(SyndFeed.class,
+				basePropInterfaceMap, basePropClassImplMap);
+	}
+
+	/**
+	 * Returns the real feed types the SyndFeedImpl supports when converting
+	 * from and to.
+	 * <p>
+	 * 
+	 * @return the real feed type supported.
+	 */
+	public List<String> getSupportedFeedTypes() {
+		return CONVERTERS.getSupportedFeedTypes();
+	}
+
+	/**
+	 * For implementations extending SyndFeedImpl to be able to use the
+	 * ObjectBean functionality with extended interfaces.
+	 * <p>
+	 * 
+	 * @param beanClass
+	 * @param convenienceProperties
+	 *            set containing the convenience properties of the SyndEntryImpl
+	 *            (the are ignored during cloning, check CloneableBean for
+	 *            details).
+	 * 
+	 */
+	protected SyndFeedImpl(Class<?> beanClass, Set<String> convenienceProperties) {
+		_objBean = new ObjectBean(beanClass, this, convenienceProperties);
+	}
+
+	/**
+	 * Default constructor. All properties are set to <b>null</b>.
+	 * <p>
+	 * 
+	 */
+	public SyndFeedImpl() {
+		this(null);
+	}
+
+	/**
+	 * Creates a SyndFeedImpl and populates all its properties out of the given
+	 * RSS Channel or Atom Feed properties.
+	 * <p>
+	 * 
+	 * @param feed
+	 *            the RSS Channel or the Atom Feed to populate the properties
+	 *            from.
+	 * 
+	 */
+	public SyndFeedImpl(WireFeed feed) {
+		this(feed, false);
+	}
+
+	/**
+	 * Creates a SyndFeedImpl and populates all its properties out of the given
+	 * RSS Channel or Atom Feed properties, while optionally preserving the
+	 * WireFeed for access via the orignalWireFeed() method.
+	 * 
+	 * @param feed
+	 * @param preserveWireFeed
+	 */
+	public SyndFeedImpl(WireFeed feed, boolean preserveWireFeed) {
+		this(SyndFeed.class, IGNORE_PROPERTIES);
+
+		if (preserveWireFeed) {
+			this.wireFeed = feed;
+			this.preserveWireFeed = preserveWireFeed;
+		}
+
+		if (feed != null) {
+			_feedType = feed.getFeedType();
+			Converter converter = CONVERTERS.getConverter(_feedType);
+			if (converter == null) {
+				throw new IllegalArgumentException("Invalid feed type ["
+						+ _feedType + "]");
+			}
+			converter.copyInto(feed, this);
+		}
+
+	}
+
+	/**
+	 * Creates a deep 'bean' clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return _objBean.clone();
+	}
+
+	/**
+	 * Indicates whether some other object is "equal to" this one as defined by
+	 * the Object equals() method.
+	 * <p>
+	 * 
+	 * @param other
+	 *            he reference object with which to compare.
+	 * @return <b>true</b> if 'this' object is equal to the 'other' object.
+	 * 
+	 */
+	public boolean equals(Object other) {
+		if (other == null) {
+			return false;
+		}
+		// can't use foreign markup in equals, due to JDOM equals impl
+		List<Object> fm = getForeignMarkup();
+		setForeignMarkup(((SyndFeedImpl) other).getForeignMarkup());
+		boolean ret = _objBean.equals(other);
+		// restore foreign markup
+		setForeignMarkup(fm);
+		return ret;
+	}
+
+	/**
+	 * Returns a hashcode value for the object.
+	 * <p>
+	 * It follows the contract defined by the Object hashCode() method.
+	 * <p>
+	 * 
+	 * @return the hashcode of the bean object.
+	 * 
+	 */
+	public int hashCode() {
+		return _objBean.hashCode();
+	}
+
+	/**
+	 * Returns the String representation for the object.
+	 * <p>
+	 * 
+	 * @return String representation for the object.
+	 * 
+	 */
+	public String toString() {
+		return _objBean.toString();
+	}
+
+	/**
+	 * Creates a real feed containing the information of the SyndFeedImpl.
+	 * <p>
+	 * The feed type of the created WireFeed is taken from the SyndFeedImpl
+	 * feedType property.
+	 * <p>
+	 * 
+	 * @return the real feed.
+	 * 
+	 */
+	public WireFeed createWireFeed() {
+		return createWireFeed(_feedType);
+	}
+
+	/**
+	 * Creates a real feed containing the information of the SyndFeedImpl.
+	 * <p>
+	 * 
+	 * @param feedType
+	 *            the feed type for the WireFeed to be created.
+	 * @return the real feed.
+	 * 
+	 */
+	public WireFeed createWireFeed(String feedType) {
+		if (feedType == null) {
+			throw new IllegalArgumentException("Feed type cannot be null");
+		}
+		Converter converter = CONVERTERS.getConverter(feedType);
+		if (converter == null) {
+			throw new IllegalArgumentException("Invalid feed type [" + feedType
+					+ "]");
+		}
+		return converter.createRealFeed(this);
+	}
+
+	/**
+	 * Returns the WireFeed this SyndFeed was created from. Will return null if
+	 * the original feed is not stored or if this SyndFeed was not created from
+	 * a WireFeed. <br />
+	 * Note: The wire feed returned here will NOT contain any modifications done
+	 * on this SyndFeed since it was created. That is in contrast to the
+	 * createWireFeed method, which will reflect the current state of the
+	 * SyndFeed
+	 * 
+	 * @return The WireFeed this was created from, or null
+	 * 
+	 */
+	public WireFeed originalWireFeed() {
+		return wireFeed;
+	}
+
+	/**
+	 * Returns the wire feed type the feed had/will-have when coverted from/to a
+	 * WireFeed.
+	 * <p>
+	 * 
+	 * @return the feed type, <b>null</b> if none.
+	 * 
+	 */
+	public String getFeedType() {
+		return _feedType;
+	}
+
+	/**
+	 * Sets the wire feed type the feed will-have when coverted to a WireFeed.
+	 * <p>
+	 * 
+	 * @param feedType
+	 *            the feed type to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setFeedType(String feedType) {
+		_feedType = feedType;
+	}
+
+	/**
+	 * Returns the charset encoding of a the feed. This is not set by Rome
+	 * parsers.
+	 * <p>
+	 * 
+	 * @return the charset encoding of the feed.
+	 * 
+	 */
+	public String getEncoding() {
+		return _encoding;
+	}
+
+	/**
+	 * Sets the charset encoding of a the feed. This is not set by Rome parsers.
+	 * <p>
+	 * 
+	 * @param encoding
+	 *            the charset encoding of the feed.
+	 * 
+	 */
+	public void setEncoding(String encoding) {
+		_encoding = encoding;
+	}
+
+	/**
+	 * Returns the feed URI.
+	 * <p>
+	 * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
+	 * the concrete feed type. This is explained in detail in Rome
+	 * documentation, <a
+	 * href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
+	 * entry URI mapping</a>.
+	 * <p>
+	 * The returned URI is a normalized URI as specified in RFC 2396bis.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @return the feed URI, <b>null</b> if none.
+	 * 
+	 */
+	public String getUri() {
+		return _uri;
+	}
+
+	/**
+	 * Sets the feed URI.
+	 * <p>
+	 * How the feed URI maps to a concrete feed type (RSS or Atom) depends on
+	 * the concrete feed type. This is explained in detail in Rome
+	 * documentation, <a
+	 * href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and
+	 * entry URI mapping</a>.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the feed URI to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setUri(String uri) {
+		_uri = URINormalizer.normalize(uri);
+	}
+
+	/**
+	 * Returns the feed title.
+	 * <p>
+	 * 
+	 * @return the feed title, <b>null</b> if none.
+	 * 
+	 */
+	public String getTitle() {
+		if (_title != null)
+			return _title.getValue();
+		return null;
+	}
+
+	/**
+	 * Sets the feed title.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the feed title to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setTitle(String title) {
+		if (_title == null)
+			_title = new SyndContentImpl();
+		_title.setValue(title);
+	}
+
+	/**
+	 * Returns the feed title as a text construct.
+	 * <p>
+	 * 
+	 * @return the feed title, <b>null</b> if none.
+	 * 
+	 */
+	public SyndContent getTitleEx() {
+		return _title;
+	}
+
+	/**
+	 * Sets the feed title as a text construct.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the feed title to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setTitleEx(SyndContent title) {
+		_title = title;
+	}
+
+	/**
+	 * Returns the feed link.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @return the feed link, <b>null</b> if none.
+	 * 
+	 */
+	public String getLink() {
+		return _link;
+	}
+
+	/**
+	 * Sets the feed link.
+	 * <p>
+	 * Note: The URI is the unique identifier, in the RSS 2.0/atom case this is
+	 * the GUID, for RSS 1.0 this is the URI attribute of the item. The Link is
+	 * the URL that the item is accessible under, the URI is the permanent
+	 * identifier which the aggregator should use to reference this item. Often
+	 * the URI will use some standardized identifier scheme such as DOI's so
+	 * that items can be identified even if they appear in multiple feeds with
+	 * different "links" (they might be on different hosting platforms but be
+	 * the same item). Also, though rare, there could be multiple items with the
+	 * same link but a different URI and associated metadata which need to be
+	 * treated as distinct entities. In the RSS 1.0 case the URI must be a valid
+	 * RDF URI reference.
+	 * <p>
+	 * 
+	 * @param link
+	 *            the feed link to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setLink(String link) {
+		_link = link;
+	}
+
+	/**
+	 * Returns the feed description.
+	 * <p>
+	 * 
+	 * @return the feed description, <b>null</b> if none.
+	 * 
+	 */
+	public String getDescription() {
+		if (_description != null)
+			return _description.getValue();
+		return null;
+	}
+
+	/**
+	 * Sets the feed description.
+	 * <p>
+	 * 
+	 * @param description
+	 *            the feed description to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setDescription(String description) {
+		if (_description == null)
+			_description = new SyndContentImpl();
+		_description.setValue(description);
+	}
+
+	/**
+	 * Returns the feed description as a text construct.
+	 * <p>
+	 * 
+	 * @return the feed description, <b>null</b> if none.
+	 * 
+	 */
+	public SyndContent getDescriptionEx() {
+		return _description;
+	}
+
+	/**
+	 * Sets the feed description as a text construct.
+	 * <p>
+	 * 
+	 * @param description
+	 *            the feed description to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setDescriptionEx(SyndContent description) {
+		_description = description;
+	}
+
+	/**
+	 * Returns the feed published date.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * date.
+	 * <p>
+	 * 
+	 * @return the feed published date, <b>null</b> if none.
+	 * 
+	 */
+	public Date getPublishedDate() {
+		return getDCModule().getDate();
+	}
+
+	/**
+	 * Sets the feed published date.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * date.
+	 * <p>
+	 * 
+	 * @param publishedDate
+	 *            the feed published date to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setPublishedDate(Date publishedDate) {
+		getDCModule().setDate(publishedDate);
+	}
+
+	/**
+	 * Returns the feed copyright.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * rights.
+	 * <p>
+	 * 
+	 * @return the feed copyright, <b>null</b> if none.
+	 * 
+	 */
+	public String getCopyright() {
+		return getDCModule().getRights();
+	}
+
+	/**
+	 * Sets the feed copyright.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * rights.
+	 * <p>
+	 * 
+	 * @param copyright
+	 *            the feed copyright to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setCopyright(String copyright) {
+		getDCModule().setRights(copyright);
+	}
+
+	/**
+	 * Returns the feed image.
+	 * <p>
+	 * 
+	 * @return the feed image, <b>null</b> if none.
+	 * 
+	 */
+	public SyndImage getImage() {
+		return _image;
+	}
+
+	/**
+	 * Sets the feed image.
+	 * <p>
+	 * 
+	 * @param image
+	 *            the feed image to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setImage(SyndImage image) {
+		_image = image;
+	}
+
+	/**
+	 * Returns the feed categories.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * subjects.
+	 * <p>
+	 * 
+	 * @return a list of SyndCategoryImpl elements with the feed categories, an
+	 *         empty list if none.
+	 * 
+	 */
+	public List<SyndCategory> getCategories() {
+		return new SyndCategoryListFacade(getDCModule().getSubjects());
+	}
+
+	/**
+	 * Sets the feed categories.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * subjects.
+	 * <p>
+	 * 
+	 * @param categories
+	 *            the list of SyndCategoryImpl elements with the feed categories
+	 *            to set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setCategories(List<SyndCategory> categories) {
+		getDCModule().setSubjects(
+				SyndCategoryListFacade
+						.convertElementsSyndCategoryToSubject(categories));
+	}
+
+	/**
+	 * Returns the feed entries.
+	 * <p>
+	 * 
+	 * @return a list of SyndEntryImpl elements with the feed entries, an empty
+	 *         list if none.
+	 * 
+	 */
+	public List<SyndEntry> getEntries() {
+		return (_entries == null) ? (_entries = new ArrayList<SyndEntry>())
+				: _entries;
+	}
+
+	/**
+	 * Sets the feed entries.
+	 * <p>
+	 * 
+	 * @param entries
+	 *            the list of SyndEntryImpl elements with the feed entries to
+	 *            set, an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setEntries(List<SyndEntry> entries) {
+		_entries = entries;
+	}
+
+	/**
+	 * Returns the feed language.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * language.
+	 * <p>
+	 * 
+	 * @return the feed language, <b>null</b> if none.
+	 * 
+	 */
+	public String getLanguage() {
+		return getDCModule().getLanguage();
+	}
+
+	/**
+	 * Sets the feed language.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * language.
+	 * <p>
+	 * 
+	 * @param language
+	 *            the feed language to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setLanguage(String language) {
+		getDCModule().setLanguage(language);
+	}
+
+	/**
+	 * Returns the feed modules.
+	 * <p>
+	 * 
+	 * @return a list of ModuleImpl elements with the feed modules, an empty
+	 *         list if none.
+	 * 
+	 */
+	public List<Module> getModules() {
+		if (_modules == null) {
+			_modules = new ArrayList<Module>();
+		}
+		if (ModuleUtils.getModule(_modules, DCModule.URI) == null) {
+			_modules.add(new DCModuleImpl());
+		}
+		return _modules;
+	}
+
+	/**
+	 * Sets the feed modules.
+	 * <p>
+	 * 
+	 * @param modules
+	 *            the list of ModuleImpl elements with the feed modules to set,
+	 *            an empty list or <b>null</b> if none.
+	 * 
+	 */
+	public void setModules(List<Module> modules) {
+		_modules = modules;
+	}
+
+	/**
+	 * Returns the module identified by a given URI.
+	 * <p>
+	 * 
+	 * @param uri
+	 *            the URI of the ModuleImpl.
+	 * @return The module with the given URI, <b>null</b> if none.
+	 */
+	public Module getModule(String uri) {
+		return ModuleUtils.getModule(getModules(), uri);
+	}
+
+	/**
+	 * Returns the Dublin Core module of the feed.
+	 * 
+	 * @return the DC module, it's never <b>null</b>
+	 * 
+	 */
+	private DCModule getDCModule() {
+		return (DCModule) getModule(DCModule.URI);
+	}
+
+	public Class<? extends CopyFrom> getInterface() {
+		return SyndFeed.class;
+	}
+
+	public void copyFrom(Object obj) {
+		COPY_FROM_HELPER.copy(this, obj);
+	}
+
+	/**
+	 * Returns the links
+	 * <p>
+	 * 
+	 * @return Returns the links.
+	 */
+	public List<SyndLink> getLinks() {
+		return (_links == null) ? (_links = new ArrayList<SyndLink>()) : _links;
+	}
+
+	/**
+	 * Set the links
+	 * <p>
+	 * 
+	 * @param links
+	 *            The links to set.
+	 */
+	public void setLinks(List<SyndLink> links) {
+		_links = links;
+	}
+
+	public List<SyndPerson> getAuthors() {
+		return (_authors == null) ? (_authors = new ArrayList<SyndPerson>())
+				: _authors;
+	}
+
+	public void setAuthors(List<SyndPerson> authors) {
+		this._authors = authors;
+	}
+
+	/**
+	 * Returns the feed author.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * creator.
+	 * <p>
+	 * 
+	 * @return the feed author, <b>null</b> if none.
+	 * 
+	 */
+	public String getAuthor() {
+		return getDCModule().getCreator();
+	}
+
+	/**
+	 * Sets the feed author.
+	 * <p>
+	 * This method is a convenience method, it maps to the Dublin Core module
+	 * creator.
+	 * <p>
+	 * 
+	 * @param author
+	 *            the feed author to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setAuthor(String author) {
+		getDCModule().setCreator(author);
+	}
+
+	public List<SyndPerson> getContributors() {
+		return (_contributors == null) ? (_contributors = new ArrayList<SyndPerson>())
+				: _contributors;
+	}
+
+	public void setContributors(List<SyndPerson> contributors) {
+		this._contributors = contributors;
+	}
+
+	/**
+	 * Returns foreign markup found at channel level.
+	 * <p>
+	 * 
+	 * @return Opaque object to discourage use
+	 * 
+	 */
+	public List<Object> getForeignMarkup() {
+		return (_foreignMarkup == null) ? (_foreignMarkup = new ArrayList<Object>())
+				: _foreignMarkup;
+	}
+
+	/**
+	 * Sets foreign markup found at channel level.
+	 * <p>
+	 * 
+	 * @param foreignMarkup
+	 *            Opaque object to discourage use
+	 * 
+	 */
+	public void setForeignMarkup(List<Object> foreignMarkup) {
+		_foreignMarkup = foreignMarkup;
+	}
+
+	public boolean isPreservingWireFeed() {
 		return preserveWireFeed;
 	}
 }
Index: src/java/com/sun/syndication/feed/synd/SyndEnclosureImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndEnclosureImpl.java,v
retrieving revision 1.1
diff -u -r1.1 SyndEnclosureImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndEnclosureImpl.java	15 Sep 2005 16:54:45 -0000	1.1
+++ src/java/com/sun/syndication/feed/synd/SyndEnclosureImpl.java	30 Sep 2009 06:30:40 -0000
@@ -1,7 +1,9 @@
 package com.sun.syndication.feed.synd;
 
+import com.sun.syndication.feed.CopyFrom;
 import com.sun.syndication.feed.impl.ObjectBean;
 import com.sun.syndication.feed.impl.CopyFromHelper;
+import com.sun.syndication.feed.synd.SyndEnclosure;
 
 import java.io.Serializable;
 import java.util.Map;
@@ -11,144 +13,161 @@
 /**
  * @author Alejandro Abdelnur
  */
-public class SyndEnclosureImpl implements Serializable,SyndEnclosure {
-    private ObjectBean _objBean;
-    private String _url;
-    private String _type;
-    private long   _length;
-
-    /**
-     * Default constructor. All properties are set to <b>null</b>.
-     * <p>
-     *
-     */
-    public SyndEnclosureImpl() {
-        _objBean = new ObjectBean(SyndEnclosure.class,this);
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        return _objBean.equals(other);
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-    /**
-     * Returns the enclosure URL.
-     * <p/>
-     *
-     * @return the enclosure URL, <b>null</b> if none.
-     */
-    public String getUrl() {
-        return _url;
-    }
-
-    /**
-     * Sets the enclosure URL.
-     * <p/>
-     *
-     * @param url the enclosure URL to set, <b>null</b> if none.
-     */
-    public void setUrl(String url) {
-        _url = url;
-    }
-
-    /**
-     * Returns the enclosure length.
-     * <p/>
-     *
-     * @return the enclosure length, <b>null</b> if none.
-     */
-    public long getLength() {
-        return _length;
-    }
-
-    /**
-     * Sets the enclosure length.
-     * <p/>
-     *
-     * @param length the enclosure length to set, <b>null</b> if none.
-     */
-    public void setLength(long length) {
-        _length = length;
-    }
-
-    /**
-     * Returns the enclosure type.
-     * <p/>
-     *
-     * @return the enclosure type, <b>null</b> if none.
-     */
-    public String getType() {
-        return _type;
-    }
-
-    /**
-     * Sets the enclosure type.
-     * <p/>
-     *
-     * @param type the enclosure type to set, <b>null</b> if none.
-     */
-    public void setType(String type) {
-        _type = type;
-    }
-
-    public Class getInterface() {
-        return SyndEnclosure.class;
-    }
-
-    public void copyFrom(Object obj) {
-        COPY_FROM_HELPER.copy(this,obj);
-    }
-
-    private static final CopyFromHelper COPY_FROM_HELPER;
-
-    static {
-        Map basePropInterfaceMap = new HashMap();
-        basePropInterfaceMap.put("url",String.class);
-        basePropInterfaceMap.put("type",String.class);
-        basePropInterfaceMap.put("length",Long.TYPE);
+public class SyndEnclosureImpl implements Serializable, SyndEnclosure {
 
-        Map basePropClassImplMap = Collections.EMPTY_MAP;
+	private static final long serialVersionUID = -5706250685111326886L;
 
-        COPY_FROM_HELPER = new CopyFromHelper(SyndEnclosure.class,basePropInterfaceMap,basePropClassImplMap);
-    }
+	private ObjectBean _objBean;
+	
+	private String _url;
+	
+	private String _type;
+	
+	private long _length;
+
+	private static final CopyFromHelper COPY_FROM_HELPER;
+
+	static {
+		Map<String, Class<?>> basePropInterfaceMap = new HashMap<String, Class<?>>();
+		basePropInterfaceMap.put("url", String.class);
+		basePropInterfaceMap.put("type", String.class);
+		basePropInterfaceMap.put("length", Long.TYPE);
+
+		Map<Class<?>,Class<?>> basePropClassImplMap = Collections.emptyMap();
+
+		COPY_FROM_HELPER = new CopyFromHelper(SyndEnclosure.class,
+				basePropInterfaceMap, basePropClassImplMap);
+	}
+
+	/**
+	 * Default constructor. All properties are set to <b>null</b>.
+	 * <p>
+	 * 
+	 */
+	public SyndEnclosureImpl() {
+		_objBean = new ObjectBean(SyndEnclosure.class, this);
+	}
+
+	/**
+	 * Creates a deep 'bean' clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return _objBean.clone();
+	}
+
+	/**
+	 * Indicates whether some other object is "equal to" this one as defined by
+	 * the Object equals() method.
+	 * <p>
+	 * 
+	 * @param other
+	 *            he reference object with which to compare.
+	 * @return <b>true</b> if 'this' object is equal to the 'other' object.
+	 * 
+	 */
+	public boolean equals(Object other) {
+		return _objBean.equals(other);
+	}
+
+	/**
+	 * Returns a hashcode value for the object.
+	 * <p>
+	 * It follows the contract defined by the Object hashCode() method.
+	 * <p>
+	 * 
+	 * @return the hashcode of the bean object.
+	 * 
+	 */
+	public int hashCode() {
+		return _objBean.hashCode();
+	}
+
+	/**
+	 * Returns the String representation for the object.
+	 * <p>
+	 * 
+	 * @return String representation for the object.
+	 * 
+	 */
+	public String toString() {
+		return _objBean.toString();
+	}
+
+	/**
+	 * Returns the enclosure URL.
+	 * <p/>
+	 * 
+	 * @return the enclosure URL, <b>null</b> if none.
+	 */
+	public String getUrl() {
+		return _url;
+	}
+
+	/**
+	 * Sets the enclosure URL.
+	 * <p/>
+	 * 
+	 * @param url
+	 *            the enclosure URL to set, <b>null</b> if none.
+	 */
+	public void setUrl(String url) {
+		_url = url;
+	}
+
+	/**
+	 * Returns the enclosure length.
+	 * <p/>
+	 * 
+	 * @return the enclosure length, <b>null</b> if none.
+	 */
+	public long getLength() {
+		return _length;
+	}
+
+	/**
+	 * Sets the enclosure length.
+	 * <p/>
+	 * 
+	 * @param length
+	 *            the enclosure length to set, <b>null</b> if none.
+	 */
+	public void setLength(long length) {
+		_length = length;
+	}
+
+	/**
+	 * Returns the enclosure type.
+	 * <p/>
+	 * 
+	 * @return the enclosure type, <b>null</b> if none.
+	 */
+	public String getType() {
+		return _type;
+	}
+
+	/**
+	 * Sets the enclosure type.
+	 * <p/>
+	 * 
+	 * @param type
+	 *            the enclosure type to set, <b>null</b> if none.
+	 */
+	public void setType(String type) {
+		_type = type;
+	}
+
+	public Class<? extends CopyFrom> getInterface() {
+		return SyndEnclosure.class;
+	}
+
+	public void copyFrom(Object obj) {
+		COPY_FROM_HELPER.copy(this, obj);
+	}
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndImageImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndImageImpl.java,v
retrieving revision 1.5
diff -u -r1.5 SyndImageImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndImageImpl.java	21 Mar 2005 23:55:18 -0000	1.5
+++ src/java/com/sun/syndication/feed/synd/SyndImageImpl.java	30 Sep 2009 06:30:41 -0000
@@ -16,8 +16,10 @@
  */
 package com.sun.syndication.feed.synd;
 
+import com.sun.syndication.feed.CopyFrom;
 import com.sun.syndication.feed.impl.ObjectBean;
 import com.sun.syndication.feed.impl.CopyFromHelper;
+import com.sun.syndication.feed.synd.SyndImage;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -27,169 +29,197 @@
 /**
  * Bean for images of SyndFeedImpl feeds.
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
-public class SyndImageImpl implements Serializable,SyndImage {
-    private ObjectBean _objBean;
-    private String _title;
-    private String _url;
-    private String _link;
-    private String _description;
-
-    /**
-     * Default constructor. All properties are set to <b>null</b>.
-     * <p>
-     *
-     */
-    public SyndImageImpl() {
-        _objBean = new ObjectBean(SyndImage.class,this);
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        return _objBean.equals(other);
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-    /**
-     * Returns the image title.
-     * <p>
-     * @return the image title, <b>null</b> if none.
-     *
-     */
-    public String getTitle() {
-        return _title;
-    }
-
-    /**
-     * Sets the image title.
-     * <p>
-     * @param title the image title to set, <b>null</b> if none.
-     *
-     */
-    public void setTitle(String title) {
-        _title = title;
-    }
-
-    /**
-     * Returns the image URL.
-     * <p>
-     * @return the image URL, <b>null</b> if none.
-     *
-     */
-    public String getUrl() {
-        return _url;
-    }
-
-    /**
-     * Sets the image URL.
-     * <p>
-     * @param url the image URL to set, <b>null</b> if none.
-     *
-     */
-    public void setUrl(String url) {
-        _url = url;
-    }
-
-    /**
-     * Returns the image link.
-     * <p>
-     * @return the image link, <b>null</b> if none.
-     *
-     */
-    public String getLink() {
-        return _link;
-    }
-
-    /**
-     * Sets the image link.
-     * <p>
-     * @param link the image link to set, <b>null</b> if none.
-     *
-     */
-    public void setLink(String link) {
-        _link = link;
-    }
-
-    /**
-     * Returns the image description.
-     * <p>
-     * @return the image description, <b>null</b> if none.
-     *
-     */
-    public String getDescription() {
-        return _description;
-    }
-
-    /**
-     * Sets the image description.
-     * <p>
-     * @param description the image description to set, <b>null</b> if none.
-     *
-     */
-    public void setDescription(String description) {
-        _description = description;
-    }
-
-    public Class getInterface() {
-        return SyndImage.class;
-    }
-
-    public void copyFrom(Object syndImage) {
-        COPY_FROM_HELPER.copy(this,syndImage);
-    }
-
-    private static final CopyFromHelper COPY_FROM_HELPER;
-
-    static {
-        Map basePropInterfaceMap = new HashMap();
-        basePropInterfaceMap.put("title",String.class);
-        basePropInterfaceMap.put("url",String.class);
-        basePropInterfaceMap.put("link",String.class);
-        basePropInterfaceMap.put("description",String.class);
+public class SyndImageImpl implements Serializable, SyndImage {
 
-        Map basePropClassImplMap = Collections.EMPTY_MAP;
+	private static final long serialVersionUID = 8041499569062688906L;
 
-        COPY_FROM_HELPER = new CopyFromHelper(SyndImage.class,basePropInterfaceMap,basePropClassImplMap);
-    }
+	private ObjectBean _objBean;
+
+	private String _title;
+
+	private String _url;
+
+	private String _link;
+
+	private String _description;
+
+	private static final CopyFromHelper COPY_FROM_HELPER;
+
+	static {
+		Map<String, Class<?>> basePropInterfaceMap = new HashMap<String, Class<?>>();
+		basePropInterfaceMap.put("title", String.class);
+		basePropInterfaceMap.put("url", String.class);
+		basePropInterfaceMap.put("link", String.class);
+		basePropInterfaceMap.put("description", String.class);
+
+		Map<Class<?>, Class<?>> basePropClassImplMap = Collections.emptyMap();
+
+		COPY_FROM_HELPER = new CopyFromHelper(SyndImage.class,
+				basePropInterfaceMap, basePropClassImplMap);
+	}
+
+	/**
+	 * Default constructor. All properties are set to <b>null</b>.
+	 * <p>
+	 * 
+	 */
+	public SyndImageImpl() {
+		_objBean = new ObjectBean(SyndImage.class, this);
+	}
+
+	/**
+	 * Creates a deep 'bean' clone of the object.
+	 * <p>
+	 * 
+	 * @return a clone of the object.
+	 * @throws CloneNotSupportedException
+	 *             thrown if an element of the object cannot be cloned.
+	 * 
+	 */
+	public Object clone() throws CloneNotSupportedException {
+		return _objBean.clone();
+	}
+
+	/**
+	 * Indicates whether some other object is "equal to" this one as defined by
+	 * the Object equals() method.
+	 * <p>
+	 * 
+	 * @param other
+	 *            he reference object with which to compare.
+	 * @return <b>true</b> if 'this' object is equal to the 'other' object.
+	 * 
+	 */
+	public boolean equals(Object other) {
+		return _objBean.equals(other);
+	}
+
+	/**
+	 * Returns a hashcode value for the object.
+	 * <p>
+	 * It follows the contract defined by the Object hashCode() method.
+	 * <p>
+	 * 
+	 * @return the hashcode of the bean object.
+	 * 
+	 */
+	public int hashCode() {
+		return _objBean.hashCode();
+	}
+
+	/**
+	 * Returns the String representation for the object.
+	 * <p>
+	 * 
+	 * @return String representation for the object.
+	 * 
+	 */
+	public String toString() {
+		return _objBean.toString();
+	}
+
+	/**
+	 * Returns the image title.
+	 * <p>
+	 * 
+	 * @return the image title, <b>null</b> if none.
+	 * 
+	 */
+	public String getTitle() {
+		return _title;
+	}
+
+	/**
+	 * Sets the image title.
+	 * <p>
+	 * 
+	 * @param title
+	 *            the image title to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setTitle(String title) {
+		_title = title;
+	}
+
+	/**
+	 * Returns the image URL.
+	 * <p>
+	 * 
+	 * @return the image URL, <b>null</b> if none.
+	 * 
+	 */
+	public String getUrl() {
+		return _url;
+	}
+
+	/**
+	 * Sets the image URL.
+	 * <p>
+	 * 
+	 * @param url
+	 *            the image URL to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setUrl(String url) {
+		_url = url;
+	}
+
+	/**
+	 * Returns the image link.
+	 * <p>
+	 * 
+	 * @return the image link, <b>null</b> if none.
+	 * 
+	 */
+	public String getLink() {
+		return _link;
+	}
+
+	/**
+	 * Sets the image link.
+	 * <p>
+	 * 
+	 * @param link
+	 *            the image link to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setLink(String link) {
+		_link = link;
+	}
+
+	/**
+	 * Returns the image description.
+	 * <p>
+	 * 
+	 * @return the image description, <b>null</b> if none.
+	 * 
+	 */
+	public String getDescription() {
+		return _description;
+	}
+
+	/**
+	 * Sets the image description.
+	 * <p>
+	 * 
+	 * @param description
+	 *            the image description to set, <b>null</b> if none.
+	 * 
+	 */
+	public void setDescription(String description) {
+		_description = description;
+	}
+
+	public Class<? extends CopyFrom> getInterface() {
+		return SyndImage.class;
+	}
+
+	public void copyFrom(Object syndImage) {
+		COPY_FROM_HELPER.copy(this, syndImage);
+	}
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndPerson.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndPerson.java,v
retrieving revision 1.2
diff -u -r1.2 SyndPerson.java
--- src/java/com/sun/syndication/feed/synd/SyndPerson.java	4 Jan 2009 22:40:46 -0000	1.2
+++ src/java/com/sun/syndication/feed/synd/SyndPerson.java	30 Sep 2009 06:30:41 -0000
@@ -30,32 +30,32 @@
     /**
      * Returns  name of person
      */
-    public String getName();
+    String getName();
     
     /**
      * Sets name of person.
      */
-    public void setName(String name);
+    void setName(String name);
     
     /**
      * Returns URI of person.
      */
-    public String getUri();
+    String getUri();
     
     /** 
      * Sets URI of person.
      */
-    public void setUri(String uri);
+    void setUri(String uri);
     
     /** 
      * Returns email of person.
      */
-    public String getEmail();
+    String getEmail();
     
     /**
      * Sets email of person.
      */
-    public void setEmail(String email);
+    void setEmail(String email);
     
     
     /**
@@ -65,6 +65,6 @@
      * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
      *
      */
-    public Object clone() throws CloneNotSupportedException;
+    Object clone() throws CloneNotSupportedException;
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndImage.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndImage.java,v
retrieving revision 1.5
diff -u -r1.5 SyndImage.java
--- src/java/com/sun/syndication/feed/synd/SyndImage.java	21 Mar 2005 23:55:17 -0000	1.5
+++ src/java/com/sun/syndication/feed/synd/SyndImage.java	30 Sep 2009 06:30:41 -0000
@@ -96,6 +96,6 @@
      * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
      *
      */
-    public Object clone() throws CloneNotSupportedException;
+    Object clone() throws CloneNotSupportedException;
 
 }
Index: src/java/com/sun/syndication/feed/synd/SyndContentImpl.java
===================================================================
RCS file: /cvs/rome/src/java/com/sun/syndication/feed/synd/SyndContentImpl.java,v
retrieving revision 1.7
diff -u -r1.7 SyndContentImpl.java
--- src/java/com/sun/syndication/feed/synd/SyndContentImpl.java	4 Jan 2009 22:47:14 -0000	1.7
+++ src/java/com/sun/syndication/feed/synd/SyndContentImpl.java	30 Sep 2009 06:30:40 -0000
@@ -16,8 +16,10 @@
  */
 package com.sun.syndication.feed.synd;
 
+import com.sun.syndication.feed.CopyFrom;
 import com.sun.syndication.feed.impl.ObjectBean;
 import com.sun.syndication.feed.impl.CopyFromHelper;
+import com.sun.syndication.feed.synd.SyndContent;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -27,150 +29,175 @@
 /**
  * Bean for content of SyndFeedImpl entries.
  * <p>
+ * 
  * @author Alejandro Abdelnur
- *
+ * 
  */
-public class SyndContentImpl implements Serializable,SyndContent {
-    private ObjectBean _objBean;
-    private String _type;
-    private String _value;
-    private String _mode;
-
-
-    /**
-     * Default constructor. All properties are set to <b>null</b>.
-     * <p>
-     *
-     */
-    public SyndContentImpl() {
-        _objBean = new ObjectBean(SyndContent.class,this);
-    }
-
-    /**
-     * Creates a deep 'bean' clone of the object.
-     * <p>
-     * @return a clone of the object.
-     * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
-     *
-     */
-    public Object clone() throws CloneNotSupportedException {
-        return _objBean.clone();
-    }
-
-    /**
-     * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
-     * <p>
-     * @param other he reference object with which to compare.
-     * @return <b>true</b> if 'this' object is equal to the 'other' object.
-     *
-     */
-    public boolean equals(Object other) {
-        return _objBean.equals(other);
-    }
-
-    /**
-     * Returns a hashcode value for the object.
-     * <p>
-     * It follows the contract defined by the Object hashCode() method.
-     * <p>
-     * @return the hashcode of the bean object.
-     *
-     */
-    public int hashCode() {
-        return _objBean.hashCode();
-    }
-
-    /**
-     * Returns the String representation for the object.
-     * <p>
-     * @return String representation for the object.
-     *
-     */
-    public String toString() {
-        return _objBean.toString();
-    }
-
-    /**
-     * Returns the content type.
-     * <p>
-     * When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed.
-     * <p>
-     * @return the content type, <b>null</b> if none.
-     *
-     */
-    public String getType() {
-        return _type;
-    }
-
-    /**
-     * Sets the content type.
-     * <p>
-     * When used for the description of an entry, if <b>null</b> 'text/plain' must be assumed.
-     * <p>
-     * @param type the content type to set, <b>null</b> if none.
-     *
-     */
-    public void setType(String type) {
-        _type = type;
-    }
-
-    /**
-     * Returns the content mode.
-     * @return the content mode, <b>null</b> if none.
-     *
-     */
-    public String getMode() {
-        return _mode;
-    }
-
-    /**
-     * Sets the content mode.
-     * @param mode the content mode to set, <b>null</b> if none.
-     *
-     */
-    public void setMode(String mode) {
-        _mode = mode;
-    }
-
-    /**
-     * Returns the content value.
-     * <p>
-     * @return the content value, <b>null</b> if none.
-     *
-     */
-    public String getValue() {
-        return _value;
-    }
-
-    /**
-     * Sets the content value.
-     * <p>
-     * @param value the content value to set, <b>null</b> if none.
-     *
-     */
-    public void setValue(String value) {
-        _value = value;
-    }
-
-
-    public Class getInterface() {
-      