You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2011/07/06 22:33:07 UTC

svn commit: r1143549 - in /wicket/trunk/wicket-core/src: main/java/org/apache/wicket/markup/html/border/ main/java/org/apache/wicket/markup/html/form/ main/java/org/apache/wicket/markup/html/panel/ test/java/org/apache/wicket/markup/html/border/ test/j...

Author: jdonnerstag
Date: Wed Jul  6 20:33:06 2011
New Revision: 1143549

URL: http://svn.apache.org/viewvc?rev=1143549&view=rev
Log:
re-factored markup sourcing strategies a bit, removing redundancies etc. without changing the API; added javadoc. Added a BorderPanel component which is based on Panel and an explicit body component. It's implementation is much simpler than Border, less magic. Added test cases.

Added:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Body.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderBehavior.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderPanel.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.html
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.html
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.html
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.html
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.html
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyTextField.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage_2134.java
Modified:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/MarkupComponentBorder.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/DefaultMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/border/BoxBorderTest.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Body.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Body.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Body.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Body.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.border;
+
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * This is a simple Container component which can be used to build Border like components.
+ * <p>
+ * Example:
+ * 
+ * <pre>
+ * <u>Panel Markup:</u>
+ * ..
+ * &lt;div wicket:id="myPanel"&gt;
+ *   My Panels body
+ * &lt;/div&gt;
+ * ..
+ * 
+ * <u>Panel associated Markup:</u>
+ * &lt;wicket:panel&gt;
+ *   ..
+ *   &lt;div wicket:id="myBody"/&gt;
+ *   ..
+ * &lt;/wicket:panel&gt;
+ * 
+ * <u>Panel Java code:</u>
+ * class MyPanel extends Panel
+ * {
+ *   ..
+ *   public MyPanel(String id)
+ *   {
+ *      add(new Body("myBody", this);
+ *   }
+ *   ..
+ * }
+ * </pre>
+ * 
+ * There can be any number of containers between the Panel and Body. You must only remember to
+ * provide the correct markup provider to the Body.
+ * 
+ * @author Juergen Donnerstag
+ */
+public class Body extends WebMarkupContainer
+{
+	private static final long serialVersionUID = 1L;
+
+	private final MarkupContainer markupProvider;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 * @param model
+	 * @param markupProvider
+	 *            Usually a Panel
+	 */
+	public Body(final String id, final IModel<?> model, final MarkupContainer markupProvider)
+	{
+		super(id, model);
+
+		Args.notNull(markupProvider, "markupProvider");
+		this.markupProvider = markupProvider;
+	}
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 * @param markupProvider
+	 */
+	public Body(String id, final MarkupContainer markupProvider)
+	{
+		this(id, null, markupProvider);
+	}
+
+	@Override
+	public IMarkupFragment getMarkup()
+	{
+		// Panel.getMarkup() returns the "calling" markup. Which is what we want. We do not want the
+		// <wicket:panel> markup.
+		return markupProvider.getMarkup();
+	}
+}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/Border.java Wed Jul  6 20:33:06 2011
@@ -128,6 +128,9 @@ import org.apache.wicket.util.lang.Args;
  * Other methods like {@link #remove()}, {@link #get(int)}, {@link #iterator()}, etc. are not
  * aliased to work on the border's body and attention must be paid when they need to be used.
  * 
+ * @see PanelBorder An alternative implementation based on Panel
+ * @see BorderBehavior A behavior which add (raw) markup before and after the component
+ * 
  * @author Jonathan Locke
  * @author Juergen Donnerstag
  */

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderBehavior.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderBehavior.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderBehavior.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderBehavior.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.border;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.ContainerInfo;
+import org.apache.wicket.markup.IMarkupFragment;
+import org.apache.wicket.markup.MarkupElement;
+import org.apache.wicket.markup.MarkupFactory;
+import org.apache.wicket.markup.MarkupResourceStream;
+import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.MarkupType;
+import org.apache.wicket.markup.WicketTag;
+import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.locator.IResourceStreamLocator;
+
+/**
+ * This is a behavior implementation that can be used if you have markup that should be around a
+ * component. It works just like {@link Border} so you have to have a <wicket:border>HTML
+ * before<wicket:body/>HTML after</wicket:border> in the html of your subclass. But different than
+ * Border you can not add components to the Border markup, only to the BorderBody.
+ * 
+ * @author jcompagner
+ */
+public class BorderBehavior extends Behavior
+{
+	static
+	{
+		// register "wicket:border" and "wicket:body"
+		WicketTagIdentifier.registerWellKnownTagName(Border.BORDER);
+		WicketTagIdentifier.registerWellKnownTagName(Border.BODY);
+	}
+
+	private static final long serialVersionUID = 1L;
+
+	// markup stream associated with this border. bonus of keeping a reference
+	// is that when renderAfter starts the stream will be very close to its
+	// needed position because renderBefore has executed
+	private transient MarkupStream markupStream;
+
+	@Override
+	public void beforeRender(final Component component)
+	{
+		final MarkupStream stream = getMarkupStream(component);
+		final Response response = component.getResponse();
+		stream.setCurrentIndex(0);
+
+		boolean insideBorderMarkup = false;
+		while (stream.hasMore())
+		{
+			MarkupElement elem = stream.get();
+			stream.next();
+			if (elem instanceof WicketTag)
+			{
+				WicketTag wTag = (WicketTag)elem;
+				if (!insideBorderMarkup)
+				{
+					if (wTag.isBorderTag() && wTag.isOpen())
+					{
+						insideBorderMarkup = true;
+						continue;
+					}
+					else
+					{
+						throw new WicketRuntimeException(
+							"Unexpected tag encountered in markup of component border " +
+								getClass().getName() + ". Tag: " + wTag.toString() +
+								", expected tag: <wicket:border>");
+					}
+				}
+				else
+				{
+					if (wTag.isBodyTag())
+					{
+						break;
+					}
+					else
+					{
+						throw new WicketRuntimeException(
+							"Unexpected tag encountered in markup of component border " +
+								getClass().getName() + ". Tag: " + wTag.toString() +
+								", expected tag: <wicket:body> or </wicket:body>");
+					}
+				}
+			}
+			if (insideBorderMarkup)
+			{
+				response.write(elem.toCharSequence());
+			}
+		}
+
+		if (!stream.hasMore())
+		{
+			throw new WicketRuntimeException("Markup for component border " + getClass().getName() +
+				" ended prematurely, was expecting </wicket:border>");
+		}
+	}
+
+	@Override
+	public void afterRender(final Component component)
+	{
+		final MarkupStream stream = getMarkupStream(component);
+		final Response response = component.getResponse();
+
+		while (stream.hasMore())
+		{
+			MarkupElement elem = stream.get();
+			stream.next();
+			if (elem instanceof WicketTag)
+			{
+				WicketTag wTag = (WicketTag)elem;
+				if (wTag.isBorderTag() && wTag.isClose())
+				{
+					break;
+				}
+				else
+				{
+					throw new WicketRuntimeException(
+						"Unexpected tag encountered in markup of component border " +
+							getClass().getName() + ". Tag: " + wTag.toString() +
+							", expected tag: </wicket:border>");
+				}
+			}
+			response.write(elem.toCharSequence());
+		}
+	}
+
+	/**
+	 * 
+	 * @param component
+	 * @return markup stream
+	 */
+	private MarkupStream getMarkupStream(final Component component)
+	{
+		if (markupStream == null)
+		{
+			markupStream = findMarkupStream(component);
+		}
+		return markupStream;
+	}
+
+	/**
+	 * 
+	 * @param owner
+	 * @return markup stream
+	 */
+	private MarkupStream findMarkupStream(final Component owner)
+	{
+		final MarkupType markupType = getMarkupType(owner);
+		if (markupType == null)
+		{
+			return null;
+		}
+
+		// TODO we need to expose this functionality for any class not just for
+		// markupcontainers in markupcache so we don't have to replicate this
+		// logic here
+
+		// Get locator to search for the resource
+		final IResourceStreamLocator locator = Application.get()
+			.getResourceSettings()
+			.getResourceStreamLocator();
+
+		final String style = owner.getStyle();
+		final String variation = owner.getVariation();
+		final Locale locale = owner.getLocale();
+
+		MarkupResourceStream markupResourceStream = null;
+		Class<?> containerClass = getClass();
+
+		while (!(containerClass.equals(BorderBehavior.class)))
+		{
+			String path = containerClass.getName().replace('.', '/');
+			IResourceStream resourceStream = locator.locate(containerClass, path, style, variation,
+				locale, markupType.getExtension(), false);
+
+			// Did we find it already?
+			if (resourceStream != null)
+			{
+				ContainerInfo ci = new ContainerInfo(containerClass, locale, style, variation,
+					markupType);
+				markupResourceStream = new MarkupResourceStream(resourceStream, ci, containerClass);
+				break;
+			}
+
+			// Walk up the class hierarchy one level, if markup has not
+			// yet been found
+			containerClass = containerClass.getSuperclass();
+		}
+
+		if (markupResourceStream == null)
+		{
+			throw new WicketRuntimeException("Could not find markup for component border `" +
+				getClass().getName() + "`");
+		}
+
+		try
+		{
+			IMarkupFragment markup = MarkupFactory.get()
+				.newMarkupParser(markupResourceStream)
+				.parse();
+
+			return new MarkupStream(markup);
+		}
+		catch (Exception e)
+		{
+			throw new WicketRuntimeException(
+				"Could not parse markup from markup resource stream: " +
+					markupResourceStream.toString());
+		}
+		finally
+		{
+			try
+			{
+				markupResourceStream.close();
+			}
+			catch (IOException e)
+			{
+				throw new WicketRuntimeException("Cannot close markup resource stream: " +
+					markupResourceStream, e);
+			}
+		}
+	}
+
+	/**
+	 * 
+	 * @param component
+	 * @return markup type
+	 */
+	private MarkupType getMarkupType(final Component component)
+	{
+		final MarkupType markupType;
+		if (component instanceof MarkupContainer)
+		{
+			markupType = ((MarkupContainer)component).getMarkupType();
+		}
+		else
+		{
+			markupType = component.getParent().getMarkupType();
+		}
+		return markupType;
+	}
+}

Added: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderPanel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderPanel.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderPanel.java (added)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/BorderPanel.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.border;
+
+import org.apache.wicket.markup.html.panel.IMarkupSourcingStrategy;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.markup.html.panel.PanelMarkupSourcingStrategy;
+import org.apache.wicket.model.IModel;
+
+/**
+ * Whereas a Panel replaces the body markup with the associated markup file, a BorderPanel assumes a
+ * that Body component renders the body markup including any number of Wicket Components.
+ * <p>
+ * Example:
+ * 
+ * <pre>
+ * <u>MyPage.html</u>
+ * ...
+ * &lt;div wicket:id="myPanel"&gt;
+ *   ...
+ *   &lt;div wicket:id="body"/&gt;
+ *   ...
+ * &lt;/div&gt;
+ * 
+ * <u>MyPage.java</u>
+ * ...
+ * public MyPage extends WebPage {
+ *   ...
+ *   public MyPage() { 
+ *     ...
+ *     add(new MyPanel("myPanel"));
+ *     ...
+ *   }
+ *   ...
+ * }
+ * 
+ * <u>MyPanel.java</u>
+ * ...
+ * public MyPanel extends PanelBorder {
+ *   ...
+ *   public MyPanel(final String id) {
+ *     super(id);
+ *     ...
+ *     add(newBody("body"));
+ *     ...
+ *   }
+ * }
+ * </pre>
+ * 
+ * @see BorderBehavior A behavior which add (raw) markup before and after the component
+ * 
+ * @author Juergen Donnerstag
+ */
+public abstract class BorderPanel extends Panel
+{
+	private static final long serialVersionUID = 1L;
+
+	private Body body;
+
+	/**
+	 * @see org.apache.wicket.Component#Component(String)
+	 */
+	public BorderPanel(final String id)
+	{
+		this(id, null);
+	}
+
+	/**
+	 * @see org.apache.wicket.Component#Component(String, IModel)
+	 */
+	public BorderPanel(final String id, final IModel<?> model)
+	{
+		super(id, model);
+	}
+
+	@Override
+	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
+	{
+		return new PanelMarkupSourcingStrategy(true);
+	}
+
+	/**
+	 * Sets the body container
+	 * 
+	 * @param body
+	 * @return The body component
+	 */
+	public final Body setBodyContainer(final Body body)
+	{
+		this.body = body;
+		return body;
+	}
+
+	/**
+	 * Provide easy access to the Body component.
+	 * 
+	 * @return The body container
+	 */
+	public final Body getBodyContainer()
+	{
+		return body;
+	}
+
+	/**
+	 * Create a new body container identified by id in the panel's markup
+	 * 
+	 * @param id
+	 * @return Body component
+	 */
+	public final Body newBodyContainer(final String id)
+	{
+		body = new Body(id, this);
+		return body;
+	}
+}

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/MarkupComponentBorder.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/MarkupComponentBorder.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/MarkupComponentBorder.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/border/MarkupComponentBorder.java Wed Jul  6 20:33:06 2011
@@ -16,251 +16,12 @@
  */
 package org.apache.wicket.markup.html.border;
 
-import java.io.IOException;
-import java.util.Locale;
-
-import org.apache.wicket.Application;
-import org.apache.wicket.Component;
-import org.apache.wicket.MarkupContainer;
-import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.behavior.Behavior;
-import org.apache.wicket.markup.ContainerInfo;
-import org.apache.wicket.markup.IMarkupFragment;
-import org.apache.wicket.markup.MarkupElement;
-import org.apache.wicket.markup.MarkupFactory;
-import org.apache.wicket.markup.MarkupResourceStream;
-import org.apache.wicket.markup.MarkupStream;
-import org.apache.wicket.markup.MarkupType;
-import org.apache.wicket.markup.WicketTag;
-import org.apache.wicket.markup.parser.filter.WicketTagIdentifier;
-import org.apache.wicket.request.Response;
-import org.apache.wicket.util.resource.IResourceStream;
-import org.apache.wicket.util.resource.locator.IResourceStreamLocator;
 
 /**
- * This is a behavior implementation that can be used if you have markup that should be around a
- * component. It works just like {@link Border} so you have to have a <wicket:border>HTML
- * before<wicket:body/>HTML after</wicket:border> in the html of your subclass. But different than
- * Border you can not add components to the Border markup, only to the BorderBody.
- * 
- * @author jcompagner
+ * @deprecated Please use {@link BorderBehavior} instead.
  */
-public class MarkupComponentBorder extends Behavior
+@Deprecated
+public class MarkupComponentBorder extends BorderBehavior
 {
-	static
-	{
-		// register "wicket:border" and "wicket:body"
-		WicketTagIdentifier.registerWellKnownTagName(Border.BORDER);
-		WicketTagIdentifier.registerWellKnownTagName(Border.BODY);
-	}
-
 	private static final long serialVersionUID = 1L;
-
-	// markup stream associated with this border. bonus of keeping a reference
-	// is that when renderAfter starts the stream will be very close to its
-	// needed position because renderBefore has executed
-	private transient MarkupStream markupStream;
-
-	@Override
-	public void beforeRender(final Component component)
-	{
-		final MarkupStream stream = getMarkupStream(component);
-		final Response response = component.getResponse();
-		stream.setCurrentIndex(0);
-
-		boolean insideBorderMarkup = false;
-		while (stream.hasMore())
-		{
-			MarkupElement elem = stream.get();
-			stream.next();
-			if (elem instanceof WicketTag)
-			{
-				WicketTag wTag = (WicketTag)elem;
-				if (!insideBorderMarkup)
-				{
-					if (wTag.isBorderTag() && wTag.isOpen())
-					{
-						insideBorderMarkup = true;
-						continue;
-					}
-					else
-					{
-						throw new WicketRuntimeException(
-							"Unexpected tag encountered in markup of component border " +
-								getClass().getName() + ". Tag: " + wTag.toString() +
-								", expected tag: <wicket:border>");
-					}
-				}
-				else
-				{
-					if (wTag.isBodyTag())
-					{
-						break;
-					}
-					else
-					{
-						throw new WicketRuntimeException(
-							"Unexpected tag encountered in markup of component border " +
-								getClass().getName() + ". Tag: " + wTag.toString() +
-								", expected tag: <wicket:body> or </wicket:body>");
-					}
-				}
-			}
-			if (insideBorderMarkup)
-			{
-				response.write(elem.toCharSequence());
-			}
-		}
-
-		if (!stream.hasMore())
-		{
-			throw new WicketRuntimeException("Markup for component border " + getClass().getName() +
-				" ended prematurely, was expecting </wicket:border>");
-		}
-	}
-
-	@Override
-	public void afterRender(final Component component)
-	{
-		final MarkupStream stream = getMarkupStream(component);
-		final Response response = component.getResponse();
-
-		while (stream.hasMore())
-		{
-			MarkupElement elem = stream.get();
-			stream.next();
-			if (elem instanceof WicketTag)
-			{
-				WicketTag wTag = (WicketTag)elem;
-				if (wTag.isBorderTag() && wTag.isClose())
-				{
-					break;
-				}
-				else
-				{
-					throw new WicketRuntimeException(
-						"Unexpected tag encountered in markup of component border " +
-							getClass().getName() + ". Tag: " + wTag.toString() +
-							", expected tag: </wicket:border>");
-				}
-			}
-			response.write(elem.toCharSequence());
-		}
-	}
-
-	/**
-	 * 
-	 * @param component
-	 * @return markup stream
-	 */
-	private MarkupStream getMarkupStream(final Component component)
-	{
-		if (markupStream == null)
-		{
-			markupStream = findMarkupStream(component);
-		}
-		return markupStream;
-	}
-
-	/**
-	 * 
-	 * @param owner
-	 * @return markup stream
-	 */
-	private MarkupStream findMarkupStream(final Component owner)
-	{
-		final MarkupType markupType = getMarkupType(owner);
-		if (markupType == null)
-		{
-			return null;
-		}
-
-		// TODO we need to expose this functionality for any class not just for
-		// markupcontainers in markupcache so we don't have to replicate this
-		// logic here
-
-		// Get locator to search for the resource
-		final IResourceStreamLocator locator = Application.get()
-			.getResourceSettings()
-			.getResourceStreamLocator();
-
-		final String style = owner.getStyle();
-		final String variation = owner.getVariation();
-		final Locale locale = owner.getLocale();
-
-		MarkupResourceStream markupResourceStream = null;
-		Class<?> containerClass = getClass();
-
-		while (!(containerClass.equals(MarkupComponentBorder.class)))
-		{
-			String path = containerClass.getName().replace('.', '/');
-			IResourceStream resourceStream = locator.locate(containerClass, path, style, variation,
-				locale, markupType.getExtension(), false);
-
-			// Did we find it already?
-			if (resourceStream != null)
-			{
-				ContainerInfo ci = new ContainerInfo(containerClass, locale, style, variation,
-					markupType);
-				markupResourceStream = new MarkupResourceStream(resourceStream, ci, containerClass);
-				break;
-			}
-
-			// Walk up the class hierarchy one level, if markup has not
-			// yet been found
-			containerClass = containerClass.getSuperclass();
-		}
-
-		if (markupResourceStream == null)
-		{
-			throw new WicketRuntimeException("Could not find markup for component border `" +
-				getClass().getName() + "`");
-		}
-
-		try
-		{
-			IMarkupFragment markup = MarkupFactory.get()
-				.newMarkupParser(markupResourceStream)
-				.parse();
-
-			return new MarkupStream(markup);
-		}
-		catch (Exception e)
-		{
-			throw new WicketRuntimeException(
-				"Could not parse markup from markup resource stream: " +
-					markupResourceStream.toString());
-		}
-		finally
-		{
-			try
-			{
-				markupResourceStream.close();
-			}
-			catch (IOException e)
-			{
-				throw new WicketRuntimeException("Cannot close markup resource stream: " +
-					markupResourceStream, e);
-			}
-		}
-	}
-
-	/**
-	 * 
-	 * @param component
-	 * @return markup type
-	 */
-	private MarkupType getMarkupType(final Component component)
-	{
-		final MarkupType markupType;
-		if (component instanceof MarkupContainer)
-		{
-			markupType = ((MarkupContainer)component).getMarkupType();
-		}
-		else
-		{
-			markupType = component.getParent().getMarkupType();
-		}
-		return markupType;
-	}
 }

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/form/FormComponentPanel.java Wed Jul  6 20:33:06 2011
@@ -159,7 +159,7 @@ public abstract class FormComponentPanel
 	@Override
 	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		return new PanelMarkupSourcingStrategy();
+		return new PanelMarkupSourcingStrategy(false);
 	}
 
 	/**

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AbstractMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -26,13 +26,22 @@ import org.apache.wicket.markup.html.int
 import org.apache.wicket.markup.parser.XmlTag.TagType;
 
 /**
- * Implements boiler plate as needed by most markup sourcing strategies.
+ * Implements boilerplate as needed by many markup sourcing strategies.
  * 
  * @author Juergen Donnerstag
  */
 public abstract class AbstractMarkupSourcingStrategy implements IMarkupSourcingStrategy
 {
 	/**
+	 * Construct.
+	 */
+	public AbstractMarkupSourcingStrategy()
+	{
+	}
+
+	public abstract IMarkupFragment getMarkup(final MarkupContainer container, final Component child);
+
+	/**
 	 * Make sure we open up open-close tags to open-body-close
 	 */
 	public void onComponentTag(final Component component, final ComponentTag tag)
@@ -44,7 +53,8 @@ public abstract class AbstractMarkupSour
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Skip the components body which is expected to be raw markup only (no wicket components). It
+	 * will be replaced by the associated markup.
 	 */
 	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
 		final ComponentTag openTag)
@@ -55,19 +65,20 @@ public abstract class AbstractMarkupSour
 			markupStream.skipRawMarkup();
 			if (markupStream.get().closes(openTag) == false)
 			{
-				throw new MarkupException(markupStream, "Close tag not found for tag: " +
-					openTag.toString() + ". Component: " + component.toString());
+				throw new MarkupException(
+					markupStream,
+					"Close tag not found for tag: " +
+						openTag.toString() +
+						". For " +
+						component.getClass().getSimpleName() +
+						" Components only raw markup is allow in between the tags but not other Wicket Component." +
+						". Component: " + component.toString());
 			}
 		}
 	}
 
 	/**
-	 * {@inheritDoc}
-	 */
-	public abstract IMarkupFragment getMarkup(final MarkupContainer container, final Component child);
-
-	/**
-	 * {@inheritDoc}
+	 * Empty. Nothing to be added to the response by default.
 	 */
 	public void renderHead(final Component component, HtmlHeaderContainer container)
 	{

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/AssociatedMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -23,16 +23,19 @@ import org.apache.wicket.markup.Componen
 import org.apache.wicket.markup.IMarkupFragment;
 import org.apache.wicket.markup.MarkupElement;
 import org.apache.wicket.markup.MarkupException;
+import org.apache.wicket.markup.MarkupNotFoundException;
 import org.apache.wicket.markup.MarkupStream;
 import org.apache.wicket.markup.TagUtils;
 import org.apache.wicket.markup.WicketTag;
 import org.apache.wicket.markup.html.HeaderPartContainer;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
+import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Classes;
 
 /**
- * Boiler plate for markup sourcing strategy which retrieve the markup from associated markup files.
+ * Boilerplate for a markup sourcing strategy which retrieves the markup from associated markup
+ * files.
  * 
  * @author Juergen Donnerstag
  */
@@ -41,11 +44,17 @@ public abstract class AssociatedMarkupSo
 	/** <wicket:head> is only allowed before <body>, </head>, <wicket:panel> etc. */
 	private boolean noMoreWicketHeadTagsAllowed = false;
 
+	private final String tagName;
+
 	/**
 	 * Constructor.
+	 * 
+	 * @param tagName
+	 *            Either "panel" or "border"
 	 */
-	public AssociatedMarkupSourcingStrategy()
+	public AssociatedMarkupSourcingStrategy(final String tagName)
 	{
+		this.tagName = Args.notNull(tagName, "tagName");
 	}
 
 	@Override
@@ -58,6 +67,95 @@ public abstract class AssociatedMarkupSo
 	}
 
 	/**
+	 * Render the associated markup markup
+	 * 
+	 * @param component
+	 */
+	protected final void renderAssociatedMarkup(final Component component)
+	{
+		((MarkupContainer)component).renderAssociatedMarkup(tagName, "Markup for a " + tagName +
+			" component must begin a tag like '<wicket:" + tagName + ">'");
+	}
+
+	/**
+	 * Search for the child's markup in the associated markup file.
+	 * 
+	 * @param parent
+	 *            The container expected to contain the markup for child
+	 * @param child
+	 *            The child component to find the markup for
+	 * @return The markup associated with the child
+	 */
+	@Override
+	public IMarkupFragment getMarkup(final MarkupContainer parent, final Component child)
+	{
+		Args.notNull(tagName, "tagName");
+
+		IMarkupFragment associatedMarkup = parent.getAssociatedMarkup();
+		if (associatedMarkup == null)
+		{
+			throw new MarkupNotFoundException("Failed to find markup file associated. " +
+				parent.getClass().getSimpleName() + ": " + parent.toString());
+		}
+
+		// Find <wicket:panel>
+		IMarkupFragment markup = findStartTag(associatedMarkup);
+		if (markup == null)
+		{
+			throw new MarkupNotFoundException("Expected to find <wicket:" + tagName +
+				"> in associated markup file. Markup: " + associatedMarkup.toString());
+		}
+
+		// If child == null, than return the markup fragment starting with <wicket:panel>
+		if (child == null)
+		{
+			return markup;
+		}
+
+		// Find the markup for the child component
+		associatedMarkup = markup.find(child.getId());
+		if (associatedMarkup != null)
+		{
+			return associatedMarkup;
+		}
+
+		return findMarkupInAssociatedFileHeader(parent, child);
+	}
+
+	/**
+	 * Search for &lt;wicket:panel ...&gt; on the same level.
+	 * 
+	 * @param markup
+	 * @return null, if not found
+	 */
+	private final IMarkupFragment findStartTag(final IMarkupFragment markup)
+	{
+		MarkupStream stream = new MarkupStream(markup);
+
+		while (stream.skipUntil(ComponentTag.class))
+		{
+			ComponentTag tag = stream.getTag();
+			if (tag.isOpen() || tag.isOpenClose())
+			{
+				if (tag instanceof WicketTag)
+				{
+					WicketTag wtag = (WicketTag)tag;
+					if (tagName.equalsIgnoreCase(wtag.getName()))
+					{
+						return stream.getMarkupFragment();
+					}
+				}
+
+				stream.skipToMatchingCloseTag(tag);
+			}
+
+			stream.next();
+		}
+
+		return null;
+	}
+
+	/**
 	 * Search the child's markup in the header section of the markup
 	 * 
 	 * @param container

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/BorderMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -20,10 +20,11 @@ import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.IMarkupFragment;
-import org.apache.wicket.markup.MarkupException;
 import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.html.border.Border;
 
 /**
+ * The Border component's markup sourcing strategy
  * 
  * @author Juergen Donnerstag
  */
@@ -34,39 +35,20 @@ public class BorderMarkupSourcingStrateg
 	 */
 	public BorderMarkupSourcingStrategy()
 	{
+		super(Border.BORDER);
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void onComponentTag(Component component, ComponentTag tag)
-	{
-		if (tag.isOpen() == false)
-		{
-			throw new MarkupException(
-				"The border tag must be an open tag. Open-close is not allowed: " + tag.toString());
-		}
-
-		super.onComponentTag(component, tag);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public void onComponentTagBody(Component component, MarkupStream markupStream,
 		ComponentTag openTag)
 	{
-		// Render the associated markup
-		((MarkupContainer)component).renderAssociatedMarkup("border",
-			"Markup for a border component must begin a tag like '<wicket:border>'");
+		renderAssociatedMarkup(component);
 
 		markupStream.skipToMatchingCloseTag(openTag);
 	}
 
 	/**
-	 * Return null and thus use <code>component.getMarkup(child)</code> to provide the Markup
+	 * Return null and thus use <code>Border.getMarkup(child)</code> to provide the Markup
 	 */
 	@Override
 	public IMarkupFragment getMarkup(final MarkupContainer container, final Component child)

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/DefaultMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/DefaultMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/DefaultMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/DefaultMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -28,7 +28,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This is a no-op sourcing strategy.
+ * This is a no-op sourcing strategy implementing the default behavior for most components.
  * 
  * @author Juergen Donnerstag
  */
@@ -56,14 +56,14 @@ public final class DefaultMarkupSourcing
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Nothing to add to the response by default
 	 */
 	public void onComponentTag(final Component component, final ComponentTag tag)
 	{
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Invoke the component's onComponentTagBody().
 	 */
 	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
 		final ComponentTag openTag)
@@ -72,7 +72,7 @@ public final class DefaultMarkupSourcing
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Get the markup for the child component, which is assumed to be a child of 'container'.
 	 */
 	public IMarkupFragment getMarkup(final MarkupContainer container, final Component child)
 	{
@@ -154,7 +154,7 @@ public final class DefaultMarkupSourcing
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Empty: nothing will be added to the header by default
 	 */
 	public void renderHead(final Component component, HtmlHeaderContainer container)
 	{

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/FragmentMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -26,6 +26,7 @@ import org.apache.wicket.markup.MarkupSt
 import org.apache.wicket.util.lang.Args;
 
 /**
+ * A markup sourcing strategy suitable for Fragment components.
  * 
  * @author Juergen Donnerstag
  */
@@ -55,12 +56,17 @@ public class FragmentMarkupSourcingStrat
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Skip the body markup associated with the 'component'. The body markup is expected to be raw
+	 * markup only, not containing an wicket component. The body markup may serve documentary
+	 * purposes for the developer / designer.
+	 * <p>
+	 * Than search for the markup of the fragment, effectively replacing the original markup.
 	 */
 	@Override
 	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
 		final ComponentTag openTag)
 	{
+		// Skip the body markup making sure it contains only raw markup
 		super.onComponentTagBody(component, markupStream, openTag);
 
 		// Get the fragments open tag
@@ -70,8 +76,7 @@ public class FragmentMarkupSourcingStrat
 		// if it is an open close tag, skip this fragment.
 		if (!fragmentOpenTag.isOpenClose())
 		{
-			// We'll completely ignore the fragments open tag. It'll not be
-			// rendered
+			// We'll completely ignore the fragments open tag. It'll not be rendered
 			stream.next();
 
 			// Render the body of the fragment
@@ -102,7 +107,7 @@ public class FragmentMarkupSourcingStrat
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Search for the child's markup in the fragment markup.
 	 */
 	@Override
 	public IMarkupFragment getMarkup(final MarkupContainer container, final Component child)

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/IMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -79,9 +79,9 @@ public interface IMarkupSourcingStrategy
 	 * @see MarkupContainer#getMarkup(Component)
 	 * 
 	 * @param container
-	 *            The parent containing the child.
+	 *            The parent containing the child. (@TODO Is container ever != child.getParent()??)
 	 * @param child
-	 *            The componen to find the markup for.
+	 *            The component to find the markup for.
 	 * @return markup fragment
 	 */
 	IMarkupFragment getMarkup(final MarkupContainer container, final Component child);

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/Panel.java Wed Jul  6 20:33:06 2011
@@ -85,6 +85,6 @@ public abstract class Panel extends WebM
 	@Override
 	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		return new PanelMarkupSourcingStrategy();
+		return new PanelMarkupSourcingStrategy(false);
 	}
 }

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/panel/PanelMarkupSourcingStrategy.java Wed Jul  6 20:33:06 2011
@@ -17,107 +17,98 @@
 package org.apache.wicket.markup.html.panel;
 
 import org.apache.wicket.Component;
-import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.IMarkupFragment;
-import org.apache.wicket.markup.MarkupNotFoundException;
+import org.apache.wicket.markup.MarkupException;
 import org.apache.wicket.markup.MarkupStream;
-import org.apache.wicket.markup.WicketTag;
 
 /**
+ * The Panel components markup sourcing strategy.
+ * <p>
+ * The strategy supports two modes on how to handle the body markup. A typical Panel will ignore the
+ * body markup and replace it with the associated markup. The body markup is allowed to have raw
+ * markup only and no Wicket components. But e.g. a Border component will associate the body markup
+ * with a Body component which renders the markup including all any number of child Components.
  * 
  * @author Juergen Donnerstag
  */
 public class PanelMarkupSourcingStrategy extends AssociatedMarkupSourcingStrategy
 {
+	// False for Panel and true for Border components.
+	private final boolean allowWicketComponentsInBodyMarkup;
+
 	/**
 	 * Constructor.
+	 * 
+	 * @param wicketTagName
+	 *            The tag name for <code>&lt;wicket:'name' ..&gt;</code>. Please note that any such
+	 *            tag must have been registed via
+	 *            <code>WicketTagIdentifier.registerWellKnownTagName('name');</code>
+	 * @param allowWicketComponentsInBodyMarkup
+	 *            False for Panel and true for Border components. If Panel than the body markup
+	 *            should only contain raw markup, which is ignored (removed), but no Wicket
+	 *            Component. With Border components, the body markup will be associated with the
+	 *            Body Component.
 	 */
-	public PanelMarkupSourcingStrategy()
+	public PanelMarkupSourcingStrategy(final String wicketTagName,
+		final boolean allowWicketComponentsInBodyMarkup)
 	{
+		super(wicketTagName);
+
+		this.allowWicketComponentsInBodyMarkup = allowWicketComponentsInBodyMarkup;
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Constructor.
+	 * 
+	 * @param allowWicketComponentsInBodyMarkup
+	 *            False for Panel and true for Border components. If Panel than the body markup
+	 *            should only contain raw markup, which is ignored (removed), but no Wicket
+	 *            Component. With Border components, the body markup will be associated with the
+	 *            Body Component.
 	 */
-	@Override
-	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
-		final ComponentTag openTag)
+	public PanelMarkupSourcingStrategy(final boolean allowWicketComponentsInBodyMarkup)
 	{
-		super.onComponentTagBody(component, markupStream, openTag);
-
-		// Render the associated markup
-		((MarkupContainer)component).renderAssociatedMarkup(Panel.PANEL,
-			"Markup for a panel component has to contain part '<wicket:panel>'");
+		this(Panel.PANEL, allowWicketComponentsInBodyMarkup);
 	}
 
 	/**
-	 * {@inheritDoc}
+	 * Skip the panel's body markup which is expected to contain raw markup only (no wicket
+	 * components) and which will be ignored / removed. It'll be replaced with the content of the
+	 * associated markup file.
 	 */
 	@Override
-	public IMarkupFragment getMarkup(final MarkupContainer parent, final Component child)
+	public void onComponentTagBody(final Component component, final MarkupStream markupStream,
+		final ComponentTag openTag)
 	{
-		IMarkupFragment markup = parent.getAssociatedMarkup();
-		if (markup == null)
-		{
-			throw new MarkupNotFoundException("Failed to find markup file associated. " +
-				parent.getClass().getSimpleName() + ": " + parent.toString());
-		}
-
-		// Find <wicket:panel>
-		IMarkupFragment panelMarkup = findPanelTag(markup);
-		if (panelMarkup == null)
+		if (allowWicketComponentsInBodyMarkup)
 		{
-			throw new MarkupNotFoundException(
-				"Expected to find <wicket:panel> in associated markup file. Markup: " +
-					markup.toString());
+			// Skip the body markup. Will be picked up by the Body component.
+			markupStream.skipToMatchingCloseTag(openTag);
 		}
-
-		// If child == null, than return the markup fragment starting with <wicket:panel>
-		if (child == null)
+		else
 		{
-			return panelMarkup;
-		}
-
-		// Find the markup for the child component
-		markup = panelMarkup.find(child.getId());
-		if (markup != null)
-		{
-			return markup;
-		}
-
-		return findMarkupInAssociatedFileHeader(parent, child);
-	}
-
-	/**
-	 * Search for &lt;wicket:panel ...&gt; on the same level.
-	 * 
-	 * @param markup
-	 * @return null, if not found
-	 */
-	private final static IMarkupFragment findPanelTag(final IMarkupFragment markup)
-	{
-		MarkupStream stream = new MarkupStream(markup);
-
-		while (stream.skipUntil(ComponentTag.class))
-		{
-			ComponentTag tag = stream.getTag();
-			if (tag.isOpen() || tag.isOpenClose())
+			// Skip the components body. Like with Panels or Fragments, it'll be replaced with the
+			// associated markup
+			if (markupStream.getPreviousTag().isOpen())
 			{
-				if (tag instanceof WicketTag)
+				markupStream.skipRawMarkup();
+				if (markupStream.get().closes(openTag) == false)
 				{
-					WicketTag wtag = (WicketTag)tag;
-					if (wtag.isPanelTag())
-					{
-						return stream.getMarkupFragment();
-					}
+					StringBuilder msg = new StringBuilder();
+
+					msg.append("Close tag not found for tag: ")
+						.append(openTag.toString())
+						.append(". For ")
+						.append(component.getClass().getSimpleName())
+						.append(" Components only raw markup is allow in between the tags but not ")
+						.append("other Wicket Component. Component: ")
+						.append(component.toString());
+
+					throw new MarkupException(markupStream, msg.toString());
 				}
-				stream.skipToMatchingCloseTag(tag);
 			}
-
-			stream.next();
 		}
 
-		return null;
+		renderAssociatedMarkup(component);
 	}
 }

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/border/BoxBorderTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/border/BoxBorderTest.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/border/BoxBorderTest.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/border/BoxBorderTest.java Wed Jul  6 20:33:06 2011
@@ -24,6 +24,7 @@ import org.apache.wicket.markup.MarkupEx
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.settings.IMarkupSettings;
+import org.junit.Test;
 
 /**
  * Test the component: PageView
@@ -174,23 +175,10 @@ public class BoxBorderTest extends Wicke
 	/**
 	 * @throws Exception
 	 */
+	@Test(expected = WicketRuntimeException.class)
 	public void test10() throws Exception
 	{
-		Exception e = null;
-		try
-		{
-			executeTest(BoxBorderTestPage_10.class, "BoxBorderTestPage_ExpectedResult_10.html");
-		}
-		catch (WicketRuntimeException ex)
-		{
-			if (ex.getMessage().startsWith("The border tag must be an open tag."))
-			{
-				e = ex;
-			}
-		}
-		assertNotNull(
-			"Expected a WicketRuntimeException. Border tag must be open tags. Open-close tags are not allowed",
-			e);
+		executeTest(BoxBorderTestPage_10.class, "BoxBorderTestPage_ExpectedResult_10.html");
 	}
 
 	/**

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.html?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.html (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.html Wed Jul  6 20:33:06 2011
@@ -0,0 +1,4 @@
+
+<wicket:panel>
+    <span wicket:id="body" />
+</wicket:panel>

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonBorder.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.markup.html.border.BorderPanel;
+
+
+/**
+ *
+ */
+public class CommonBorder extends BorderPanel
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 */
+	public CommonBorder(String id)
+	{
+		super(id);
+
+		add(newBodyContainer("body"));
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.html?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.html (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.html Wed Jul  6 20:33:06 2011
@@ -0,0 +1,14 @@
+<html>
+<body>
+   <div wicket:id="border">
+       <form wicket:id="form1">
+           <input wicket:id="quantity1" /><br/>
+           <input type="submit" value="Quantity1" />
+       </form><br/>
+       <form wicket:id="form2">
+           <input wicket:id="quantity2" /><br/>
+           <input type="submit" value="Quantity2" />
+       </form><br/>
+   </div>
+</body>
+</html>
\ No newline at end of file

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/CommonModelPage.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.PropertyModel;
+
+/**
+ * 
+ */
+public class CommonModelPage extends WebPage
+{
+	private static final long serialVersionUID = 1L;
+
+	int quantity1;
+	int quantity2;
+
+	/**
+	 * Construct.
+	 */
+	public CommonModelPage()
+	{
+		CommonBorder border = new CommonBorder("border");
+		add(border);
+
+		Form<Void> form1 = new Form<Void>("form1");
+		border.getBodyContainer().add(form1);
+
+		form1.add(new TextField<Integer>("quantity1", new PropertyModel<Integer>(this, "quantity1")));
+
+		Form<Void> form2 = new Form<Void>("form2");
+		border.getBodyContainer().add(form2);
+
+		form2.add(new TextField<Integer>("quantity2", new PropertyModel<Integer>(this, "quantity2")));
+	}
+
+	/**
+	 * @return quantity1
+	 */
+	public int getQuantity1()
+	{
+		return quantity1;
+	}
+
+	/**
+	 * @param quantity1
+	 */
+	public void setQuantity1(int quantity1)
+	{
+		this.quantity1 = quantity1;
+	}
+
+	/**
+	 * @return quantity2
+	 */
+	public int getQuantity2()
+	{
+		return quantity2;
+	}
+
+	/**
+	 * @param quantity2
+	 */
+	public void setQuantity2(int quantity2)
+	{
+		this.quantity2 = quantity2;
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.html?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.html (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.html Wed Jul  6 20:33:06 2011
@@ -0,0 +1,17 @@
+<html>
+    <head>
+        <title>Wicket Quickstart Archetype Homepage</title>
+    </head>
+    <body>
+        <strong>Wicket Quickstart Archetype Homepage</strong>
+        <br/><br/>
+        <span wicket:id="message">message will be here</span>
+
+		<div wicket:id="border">
+			teste<br />
+			<input wicket:id="textfield" /> - <span wicket:id="lbltextfield" /><br />
+			<input wicket:id="datefield" /> - <span wicket:id="lbldatefield" /><br />
+            <span wicket:id="datefield2"></span> - <span wicket:id="lbldatefield2" /><br />
+		</div>
+    </body>
+</html>

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/HomePage.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.border.Body;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+/**
+ * Homepage
+ */
+public class HomePage extends WebPage
+{
+	private static final long serialVersionUID = 1L;
+
+	private String textfield;
+	private String datefield;
+	private String datefield2;
+
+	String getTextfield()
+	{
+		return textfield;
+	}
+
+	void setTextfield(String textfield)
+	{
+		this.textfield = textfield;
+	}
+
+	String getDatefield()
+	{
+		return datefield;
+	}
+
+	void setDatefield(String datefield)
+	{
+		this.datefield = datefield;
+	}
+
+	String getDatefield2()
+	{
+		return datefield2;
+	}
+
+	void setDatefield2(String datefield)
+	{
+		datefield2 = datefield;
+	}
+
+	/**
+	 * Constructor that is invoked when page is invoked without a session.
+	 * 
+	 * @param parameters
+	 *            Page parameters
+	 */
+	public HomePage(final PageParameters parameters)
+	{
+		// Add the simplest type of label
+		add(new Label("message",
+			"If you see this message wicket is properly configured and running"));
+
+		MyBorder border = new MyBorder("border");
+		add(border);
+
+		Body body = border.getBodyContainer();
+		body.add(new TextField<String>("textfield", new PropertyModel<String>(this, "textfield")));
+		body.add(new Label("lbltextfield", new PropertyModel<String>(this, "textfield")));
+		body.add(new MyTextField("datefield", new PropertyModel<String>(this, "datefield")).setOutputMarkupId(true));
+		body.add(new Label("lbldatefield", new PropertyModel<String>(this, "datefield")));
+		body.add(new MyDateField("datefield2", new PropertyModel<String>(this, "datefield2")).setOutputMarkupId(true));
+		body.add(new Label("lbldatefield2", new PropertyModel<String>(this, "datefield2")));
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.html?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.html (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.html Wed Jul  6 20:33:06 2011
@@ -0,0 +1,10 @@
+
+<head>
+</head>
+
+<wicket:panel>
+  <form wicket:id="form">
+	<span wicket:id="body" />
+	<button wicket:id="submit" type="submit">submit</button>
+  </form>
+</wicket:panel>

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyBorder.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
+import org.apache.wicket.markup.html.border.BorderPanel;
+import org.apache.wicket.markup.html.form.Form;
+
+
+/**
+ */
+public class MyBorder extends BorderPanel
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 */
+	public MyBorder(String id)
+	{
+		super(id);
+
+		final Form<Void> form = new Form<Void>("form");
+		form.setOutputMarkupId(true);
+		add(form);
+
+		form.add(newBodyContainer("body"));
+
+		form.add(new AjaxSubmitLink("submit")
+		{
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void onSubmit(AjaxRequestTarget target, Form<?> form)
+			{
+				target.add(form);
+			}
+
+			@Override
+			protected void onError(AjaxRequestTarget target, Form<?> form)
+			{
+			}
+		});
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.html?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.html (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.html Wed Jul  6 20:33:06 2011
@@ -0,0 +1,6 @@
+
+<wicket:panel>
+  <span style="white-space: nowrap;">
+    <input type="text" wicket:id="date" size="8" />
+  </span>
+</wicket:panel>
\ No newline at end of file

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyDateField.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+
+/**
+ * This is not a real DateField. It only servers some testing purposes (derived from
+ * FormComponentPanel)
+ */
+public class MyDateField extends FormComponentPanel<String>
+{
+	private static final long serialVersionUID = 1L;
+
+	private String date;
+
+	private final TextField<String> dateField;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 */
+	public MyDateField(String id)
+	{
+		this(id, null);
+	}
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 * @param model
+	 */
+	public MyDateField(String id, IModel<String> model)
+	{
+		super(id, model);
+		setType(String.class);
+		PropertyModel<String> dateFieldModel = new PropertyModel<String>(this, "date");
+		add(dateField = new TextField<String>("date", dateFieldModel));
+	}
+
+	/**
+	 * Gets date.
+	 * 
+	 * @return date
+	 */
+	public String getDate()
+	{
+		return date;
+	}
+
+	/**
+	 * Sets date.
+	 * 
+	 * @param date
+	 *            date
+	 */
+	public void setDate(String date)
+	{
+		this.date = date;
+		setDefaultModelObject(date);
+	}
+
+	/**
+	 * Sets the converted input. In this case, we're really just interested in the nested date
+	 * field, as that is the element that receives the real user input. So we're just passing that
+	 * on.
+	 * <p>
+	 * Note that overriding this method is a better option than overriding {@link #updateModel()}
+	 * like the first versions of this class did. The reason for that is that this method can be
+	 * used by form validators without having to depend on the actual model being updated, and this
+	 * method is called by the default implementation of {@link #updateModel()} anyway (so we don't
+	 * have to override that anymore).
+	 * </p>
+	 * 
+	 * @see org.apache.wicket.markup.html.form.FormComponent#convertInput()
+	 */
+	@Override
+	protected void convertInput()
+	{
+		setConvertedInput(dateField.getConvertedInput() + "-converted");
+	}
+
+	/**
+	 * @see org.apache.wicket.Component#onBeforeRender()
+	 */
+	@Override
+	protected void onBeforeRender()
+	{
+		dateField.setRequired(isRequired());
+
+		String d = (String)getDefaultModelObject();
+		if (d != null)
+		{
+			date = d;
+		}
+		else
+		{
+			date = null;
+		}
+
+		super.onBeforeRender();
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyTextField.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyTextField.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyTextField.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/MyTextField.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+
+/**
+ * 
+ */
+public class MyTextField extends TextField<String>
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 */
+	public MyTextField(String id)
+	{
+		this(id, null);
+	}
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 * @param model
+	 */
+	public MyTextField(String id, IModel<String> model)
+	{
+		super(id, model);
+		setType(String.class);
+	}
+
+	/**
+	 * 
+	 * @see org.apache.wicket.markup.html.form.FormComponent#convertInput()
+	 */
+	@Override
+	protected void convertInput()
+	{
+		super.setConvertedInput(getInput() + "-converted");
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.util.tester.FormTester;
+
+/**
+ * Simple test using the WicketTester
+ */
+public class TestHomePage extends WicketTestCase
+{
+	/**
+	 * 
+	 */
+	public void testWithBorder2()
+	{
+		tester.startPage(HomePage.class);
+		tester.assertRenderedPage(HomePage.class);
+
+		FormTester formTester = tester.newFormTester("border:form");
+
+		// formTester.setValue("..:textfield1", "testxxx");
+		@SuppressWarnings("unchecked")
+		TextField<String> textfield = (TextField<String>)tester.getLastRenderedPage().get(
+			"border:form:body:textfield");
+		tester.getRequest()
+			.getPostParameters()
+			.setParameterValue(textfield.getInputName(), "abcde");
+
+		MyTextField datefield = (MyTextField)tester.getLastRenderedPage().get(
+			"border:form:body:datefield");
+		tester.getRequest()
+			.getPostParameters()
+			.setParameterValue(datefield.getInputName(), "aaabbb");
+
+		MyDateField datefield2 = (MyDateField)tester.getLastRenderedPage().get(
+			"border:form:body:datefield2");
+		@SuppressWarnings("unchecked")
+		TextField<String> date = (TextField<String>)datefield2.get("date");
+		tester.getRequest().getPostParameters().setParameterValue(date.getInputName(), "abcdef");
+
+		formTester.submit();
+		tester.assertNoErrorMessage();
+
+		HomePage page = (HomePage)tester.getLastRenderedPage();
+		assertEquals("abcde", page.getTextfield());
+		assertEquals("aaabbb-converted", page.getDatefield());
+		assertEquals("abcdef-converted", page.getDatefield2());
+
+		assertEquals("abcde", page.get("border:form:body:lbltextfield")
+			.getDefaultModelObjectAsString());
+		assertEquals("aaabbb-converted", page.get("border:form:body:lbldatefield")
+			.getDefaultModelObjectAsString());
+		assertEquals("abcdef-converted", page.get("border:form:body:lbldatefield2")
+			.getDefaultModelObjectAsString());
+	}
+}

Added: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage_2134.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage_2134.java?rev=1143549&view=auto
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage_2134.java (added)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/form/panelBorder/TestHomePage_2134.java Wed Jul  6 20:33:06 2011
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.markup.html.form.panelBorder;
+
+import org.apache.wicket.WicketTestCase;
+import org.apache.wicket.util.tester.FormTester;
+
+/**
+ * Simple test using the WicketTester
+ */
+public class TestHomePage_2134 extends WicketTestCase
+{
+	/**
+	 * WICKET-2134: two forms inside a border throw a ConversionException error
+	 */
+	public void testRenderMyPage()
+	{
+		// start and render the test page
+		tester.startPage(CommonModelPage.class);
+
+		// assert rendered page class
+		tester.assertRenderedPage(CommonModelPage.class);
+
+		FormTester formTester = tester.newFormTester("border:body:form1");
+		formTester.submit();
+
+		CommonModelPage page = (CommonModelPage)tester.getLastRenderedPage();
+		assertEquals(0, page.quantity1);
+		assertEquals(0, page.quantity2);
+	}
+
+	/**
+	 * WICKET-2134: two forms inside a border throw a ConversionException error
+	 */
+	public void testRenderMyPage2()
+	{
+		// start and render the test page
+		tester.startPage(CommonModelPage.class);
+
+		// assert rendered page class
+		tester.assertRenderedPage(CommonModelPage.class);
+
+		FormTester formTester = tester.newFormTester("border:body:form1");
+		formTester.setValue("quantity1", "123");
+		// formTester.setValue("quantity2", "44");
+		formTester.submit();
+
+		CommonModelPage page = (CommonModelPage)tester.getLastRenderedPage();
+		assertEquals(123, page.quantity1);
+		assertEquals(0, page.quantity2);
+	}
+
+	/**
+	 * WICKET-2134: two forms inside a border throw a ConversionException error
+	 */
+	public void testRenderMyPage3()
+	{
+		// start and render the test page
+		tester.startPage(CommonModelPage.class);
+
+		// assert rendered page class
+		tester.assertRenderedPage(CommonModelPage.class);
+
+		FormTester formTester = tester.newFormTester("border:body:form2");
+		// formTester.setValue("quantity1", "123");
+		formTester.setValue("quantity2", "44");
+		formTester.submit();
+
+		CommonModelPage page = (CommonModelPage)tester.getLastRenderedPage();
+		assertEquals(0, page.quantity1);
+		assertEquals(44, page.quantity2);
+	}
+}

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java?rev=1143549&r1=1143548&r2=1143549&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/parser/filter/HeaderSectionMyLabel.java Wed Jul  6 20:33:06 2011
@@ -59,7 +59,7 @@ public class HeaderSectionMyLabel extend
 	@Override
 	protected IMarkupSourcingStrategy newMarkupSourcingStrategy()
 	{
-		return new PanelMarkupSourcingStrategy()
+		return new PanelMarkupSourcingStrategy(false)
 		{
 			@Override
 			public IMarkupFragment getMarkup(final MarkupContainer parent, final Component child)