You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2019/01/18 11:29:23 UTC

[myfaces] branch master updated: MYFACES-4265: first complex integration test moved over from my github tests, the protocol test which is independend of jsf in the backend (servlet generates various protocol testcases where the client has to react upon)

This is an automated email from the ASF dual-hosted git repository.

werpu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/master by this push:
     new 559a492  MYFACES-4265: first complex integration test moved over from my github tests, the protocol test which is independend of jsf in the backend (servlet generates various protocol testcases where the client has to react upon)
559a492 is described below

commit 559a492be7cbc40565c9b7683cda7d7b9b5aadbe
Author: Werner Punz <we...@gmail.com>
AuthorDate: Fri Jan 18 12:28:57 2019 +0100

    MYFACES-4265: first complex integration test moved
    over from my github tests, the protocol test
    which is independend of jsf in the backend (servlet
    generates various protocol testcases where
    the client has to react upon)
---
 integration-tests/ajax/pom.xml                     |  24 +
 integration-tests/ajax/readme.txt                  |   2 +
 .../ajax/{ => basic}/TestBean.java                 |   4 +
 .../ajax/test1Protocol/DeferredScriptMockup.java   |  66 +++
 .../ajax/test1Protocol/JSF21Simulation.java        | 109 +++++
 .../ajax/test1Protocol/ResponseMockup.java         | 428 +++++++++++++++++
 .../ajax/test1Protocol/ResponseMockup22.java       |  70 +++
 .../jsfxmlnodes/Attribute.java}                    |  38 +-
 .../ajax/test1Protocol/jsfxmlnodes/Attributes.java |  53 +++
 .../jsfxmlnodes/Change.java}                       |  28 +-
 .../jsfxmlnodes/Changes.java}                      |  40 +-
 .../jsfxmlnodes/Delete.java}                       |  45 +-
 .../test1Protocol/jsfxmlnodes/ErrorResponse.java   |  55 +++
 .../jsfxmlnodes/Eval.java}                         |  35 +-
 .../ajax/test1Protocol/jsfxmlnodes/Insert.java     |  65 +++
 .../ajax/test1Protocol/jsfxmlnodes/Insert2.java    |  76 +++
 .../jsfxmlnodes/PartialResponse.java}              |  40 +-
 .../jsfxmlnodes/Update.java}                       |  39 +-
 .../test1Protocol/responseWriter/ArrayUtils.java   | 234 ++++++++++
 .../ajax/test1Protocol/responseWriter/HTML.java    | 508 +++++++++++++++++++++
 .../responseWriter/MockupResponseWriter.java       | 162 +++++++
 .../responseWriter/PartialResponseWriterImpl.java  | 371 +++++++++++++++
 .../PartialResponseWriterMockup.java               | 239 ++++++++++
 .../ajax/src/main/webapp/WEB-INF/web.xml           |  10 +
 integration-tests/ajax/src/main/webapp/index.xhtml |  11 +-
 .../ajax/src/main/webapp/scripts/testhelpers.js    |  96 ++++
 .../ajax/src/main/webapp/test1-protocol.xhtml      | 102 +++++
 .../integrationtests/ajax/IntegrationTest.java     | 129 +++++-
 28 files changed, 2962 insertions(+), 117 deletions(-)

diff --git a/integration-tests/ajax/pom.xml b/integration-tests/ajax/pom.xml
index a9dfd03..9f48225 100644
--- a/integration-tests/ajax/pom.xml
+++ b/integration-tests/ajax/pom.xml
@@ -30,6 +30,30 @@
     <groupId>org.apache.myfaces.core.integration-tests</groupId>
     <artifactId>ajax</artifactId>
     <name>Apache MyFaces Core 3.0 - Integration Tests - ajax</name>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
     <packaging>war</packaging>
 
+    <dependencies>
+
+
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+            <version>9.0.12</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+
 </project>
diff --git a/integration-tests/ajax/readme.txt b/integration-tests/ajax/readme.txt
new file mode 100644
index 0000000..723a191
--- /dev/null
+++ b/integration-tests/ajax/readme.txt
@@ -0,0 +1,2 @@
+run integration test manually  mvn clean integration-test -Ptomcat-embedded-9
+run jetty: mvn clean package jetty:run-exploded
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/basic/TestBean.java
similarity index 94%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/basic/TestBean.java
index 6cbdfcc..017560e 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/basic/TestBean.java
@@ -37,4 +37,8 @@ public class TestBean {
     public void setSayHello(String sayHello) {
         this.sayHello = sayHello;
     }
+
+    public void doAction() {
+        sayHello = "Action Performed";
+    }
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/DeferredScriptMockup.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/DeferredScriptMockup.java
new file mode 100644
index 0000000..a6099d8
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/DeferredScriptMockup.java
@@ -0,0 +1,66 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol;
+
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.responseWriter.PartialResponseWriterImpl;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author werpu
+ *
+ * code to test script deferring if a script
+ * and script src tag is discovered
+ */
+public class DeferredScriptMockup
+{
+
+    public String testScriptMockup() throws IOException {
+        PartialResponseWriterImpl writer = new PartialResponseWriterImpl();
+        writer.startDocument();
+        writer.startUpdate(PartialResponseWriterImpl.RENDER_ALL_MARKER);
+        writer.startElement("h1", null);
+        writer.write("Dies ist ein text");
+        writer.endElement("h1");
+        
+        writer.startElement("script",null);
+        writer.writeAttribute("type", "text/javascript", null);
+        writer.write("alert('hello world');");
+        writer.endElement("script");
+
+        writer.startElement("h1", null);
+        writer.write("Dies ist ein text");
+        writer.endElement("h1");
+
+
+        writer.startEval();
+        writer.write("alert('hello world from eval');");
+        writer.endEval();
+
+        writer.endUpdate();
+
+        writer.endDocument();
+
+        return writer.toString();
+
+    }
+
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/JSF21Simulation.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/JSF21Simulation.java
new file mode 100644
index 0000000..a167b49
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/JSF21Simulation.java
@@ -0,0 +1,109 @@
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol;
+
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Changes;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.ErrorResponse;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.PartialResponse;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Update;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class JSF21Simulation extends HttpServlet {
+
+    static int TIMEOUT_REQS = 0;
+    static int QUEUESIZE_REQS = 0;
+
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        process(request, response);
+    }
+
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        process(request, response);
+    }
+
+    private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        response.setContentType("text/xml;charset=UTF-8");
+
+        PrintWriter out = response.getWriter();
+        try {
+            org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.PartialResponse root = new PartialResponse();
+            if (request.getParameter("op") != null && request.getParameter("op").equals("timeout")) {
+                renderTimeout(out, root);
+            } else if (request.getParameter("op") != null && request.getParameter("op").equals("cleardelay")) {
+                TIMEOUT_REQS = 0;
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "delayoutput", "<div id='delayoutput'>Number of requests so far " + TIMEOUT_REQS + "  </div>"));
+                root.addElement(changes);
+                out.println(root.toString());
+                out.flush();
+            } else if (request.getParameter("op") != null && request.getParameter("op").equals("delay")) {
+                TIMEOUT_REQS++;
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "delayoutput", "<div id='delayoutput'>Number of requests so far " + TIMEOUT_REQS + "  </div>"));
+                root.addElement(changes);
+                out.println(root.toString());
+                out.flush();
+            } else if (request.getParameter("op") != null && request.getParameter("op").equals("queuesize")) {
+                QUEUESIZE_REQS++;
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "queuesizeoutput", "<div id='queuesizeoutput'>Number of requests so far " + QUEUESIZE_REQS + "  </div>"));
+                root.addElement(changes);
+                sleep(300);
+                out.println(root.toString());
+                out.flush();
+            } else if (request.getParameter("op") != null && request.getParameter("op").equals("pps")) {
+                QUEUESIZE_REQS++;
+                Changes changes = new Changes(root);
+                boolean validPPS = request.getParameter("ppsControl") != null && request.getParameter("queuesizecontrol") == null;
+                String validPPSString = (validPPS)? "is a valid partial page submit" : "is a full post submit";
+                changes.addChild(new Update(changes, "ppsoutput", "<div id='ppsoutput'>" + validPPSString + "  </div>"));
+                root.addElement(changes);
+                out.println(root.toString());
+                out.flush();
+            } else if (request.getParameter("op") != null && request.getParameter("op").equals("pps2")) {
+                QUEUESIZE_REQS++;
+                Changes changes = new Changes(root);
+                boolean validPPS = request.getParameter("ppsControl3") != null && request.getParameter("queuesizecontrol") == null;
+                String validPPSString = (validPPS)? "is a valid partial page submit" : "is a full post submit";
+                changes.addChild(new Update(changes, "ppsoutput2", "<div id='ppsoutput2'>" + validPPSString + "  </div>"));
+                root.addElement(changes);
+                out.println(root.toString());
+                out.flush();
+            }
+
+
+
+
+        } finally {
+            out.close();
+
+        }
+
+    }
+
+    private void renderTimeout(PrintWriter out, PartialResponse root) {
+        sleep(3000);
+
+        root.addElement(new ErrorResponse(root, "This error should be displayed only if you run the long running request", "NoTrigger"));
+        out.println(root.toString());
+        out.flush();
+
+    }
+
+    private void sleep(int len) {
+        try {
+            Thread.sleep(len);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/ResponseMockup.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/ResponseMockup.java
new file mode 100644
index 0000000..bb70ebe
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/ResponseMockup.java
@@ -0,0 +1,428 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol;
+
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Attribute;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Attributes;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Changes;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Delete;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.ErrorResponse;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Eval;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Insert;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Insert2;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.PartialResponse;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Update;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author werpu
+ */
+public class ResponseMockup extends HttpServlet
+{
+
+    int cnt = 0;
+    int elemCnt = 0;
+    int red = 0;
+    String defaultResponse = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
+            "<partial-response><changes><update id=\"out1\"><![CDATA[<span id=\"out1\">2</span>]]></update><update id" +
+            "=\"javax.faces.ViewState\"><![CDATA[j_id1:j_id3]]></update></changes></partial-response>";
+
+    /**
+     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
+     *
+     * @param request  servlet request
+     * @param response servlet response
+     * @throws javax.servlet.ServletException if a servlet-specific error occurs
+     * @throws java.io.IOException            if an I/O error occurs
+     */
+    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException
+    {
+        response.setContentType("text/xml;charset=UTF-8");
+        PrintWriter out = response.getWriter();
+
+        String op = (String) request.getParameter("op");
+
+        PartialResponse root = new PartialResponse();
+
+        /**
+         * field ids needed in form:
+         * changesArea
+         * deleteable
+         * attributeChange
+         *
+         */
+        try
+        {
+
+            if (op == null || op.isEmpty())
+            {
+                out.println(defaultResponse);
+            } else if (op.trim().toLowerCase().equals("eval1"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Eval(changes, "document.getElementById('evalarea1').innerHTML = 'eval test succeeded';"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("updateinsert1"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "changesArea", "<div id='changesArea'>update succeeded " + (cnt++) + "</div><script type='text/javascript'>document.getElementById('evalarea2').innerHTML='embedded script at update succeed';</script>"));
+                changes.addChild(new Insert(changes, "inserted1", "<div id='insertbefore'>insert before succeeded should display before test1</div><script type='text/javascript'>document.getElementById('evalarea3').innerHTML='embedded script at insert succeed';</script>", "changesArea", null));
+                changes.addChild(new Insert(changes, "inserted2", "<div  id='insertafter'>insert after succeeded should display after test1</div>", null, "changesArea"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("updateinsert2"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "changesArea", "<div id='changesArea'>update succeeded " + (cnt++) + "</div><script type='text/javascript'>document.getElementById('evalarea2').innerHTML='embedded script at update succeed';</script>"));
+                changes.addChild(new Insert2(changes, "inserted1", "<div id='insertbefore'>insert2 before succeeded " +
+                        "should display before test1</div><script type='text/javascript'>document.getElementById('evalarea3').innerHTML='embedded script at insert succeed';</script>", "changesArea", null));
+                changes.addChild(new Insert2(changes, "inserted2", "<div  id='insertafter'>insert2 after succeeded " +
+                        "should display after test1</div>", null, "changesArea"));
+                root.addElement(changes);
+                out.println(root.toString());
+
+            } else if (op.trim().toLowerCase().equals("delete1"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Delete(changes, "deleteable"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("viewstate"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "javax.faces.ViewState", "hello world"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("attributes"))
+            {
+                Changes changes = new Changes(root);
+                Attributes attr = new Attributes(changes, "attributeChange");
+                attr.addAttribute(new Attribute("style", "color:rgb(" + ((red += 10) % 255) + ",100,100);"));
+                attr.addAttribute(new Attribute("style", "border:1px solid black"));
+                attr.addAttribute(new Attribute("onclick", "document.getElementById('evalarea4').innerHTML = 'attributes onclick succeeded';"));
+
+                changes.addChild(attr);
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("errors"))
+            {
+                root.addElement(new ErrorResponse(root, "Error1", "Error1 Text"));
+                root.addElement(new ErrorResponse(root, "Error2", "Error2 Text"));
+
+                out.println(root.toString());
+            } else if (op.trim().equals("illegalResponse"))
+            {
+                out.println(">>>> xxxx >YYYY-!->>>");
+            } else if (op.trim().toLowerCase().equals("body"))
+            {
+                //we omit our xml builder for now
+                StringBuilder replacement = new StringBuilder();
+
+                replacement.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">" +
+                        "<head>");
+                replacement.append("    <title></title>");
+                replacement.append("    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
+                replacement.append("    <script type=\"text/javascript\" src=\"./myfaces/_impl/core/_Runtime.js\"></script>");
+
+                replacement.append("    <script type=\"text/javascript\" src=\"./myfaces/_impl/_util/_Lang.js\"></script>");
+                replacement.append("</head>" +
+                        "<body class=\"tundra\">  <div id=\"myfaces.logging\">\n" +
+                        "    </div>" +
+                        "    <div id = \"centerDiv\">\n" +
+                        "        <h1>Selenium Test for body change done</h1>\n" +
+                        "        <div id = \"testResults\">\n" +
+                        "            <h3>Body replacement test  successful</h3>" +
+                        "<div id='scriptreceiver'></div>\n" +
+                        "        " +
+                        "   <script type='text/javascript'>var b = true && true; document.getElementById" +
+                        "('scriptreceiver').innerHTML=" +
+                        "'hello from embedded script & in the body'; " +
+                        "</script>            </div>" +
+                        "    </div>" +
+                        "</body>" +
+                        "</html>");
+
+                Changes changes = new Changes(root);
+                root.addElement(changes);
+                changes.addChild(new Update(changes, "javax.faces.ViewBody", replacement.toString()));
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("body2"))
+            {
+                //we omit our xml builder for now
+                StringBuilder replacement = new StringBuilder();
+
+                replacement.append("<body class=\"tundra\"> " +
+                        "    <div id=\"myfaces.logging\"><div id = \"centerDiv\">\n" +
+                        "        <h1>Selenium Test for body change done</h1>\n");
+                for (int cnt = 0; cnt < 300; cnt++)
+                {
+                    replacement.append("        <div id = \"testResults" + cnt + "\" ></div>\n");
+                }
+                replacement.append("            <h3>Body replacement test successful</h3>\n" +
+                        //             "   <script type='text/javascript'>alert('hello from embedded script in replacement body');</script>            </div>" +
+                        "    </div>" +
+                        "</body>");
+
+                Changes changes = new Changes(root);
+                root.addElement(changes);
+                changes.addChild(new Update(changes, "javax.faces.ViewBody", replacement.toString()));
+                out.println(root.toString());
+
+            } else if (op.trim().toLowerCase().equals("body3"))
+            {
+
+                File fIn = new File("/Users/werpu/development/workspace/TestRI20/TestRI20/src/main/webapp/34beta.html.html");
+                FileReader fRead = new FileReader(fIn);
+                BufferedReader reader = new BufferedReader(fRead);
+                String line = null;
+                StringBuilder replacement = new StringBuilder();
+                do
+                {
+                    line = reader.readLine();
+                    if (line != null)
+                    {
+                        replacement.append(line);
+                        replacement.append("\n");
+                    }
+                } while (line != null);
+                Changes changes = new Changes(root);
+                root.addElement(changes);
+                changes.addChild(new Update(changes, "javax.faces.ViewRoot", replacement.toString()));
+                out.println(root.toString());
+
+            } else if (op.trim().toLowerCase().equals("serversideresponsewriter"))
+            {
+                DeferredScriptMockup scriptMockup = new DeferredScriptMockup();
+                Changes changes = new Changes(root);
+                changes.addChild(new Eval(changes, "alert('the output is on the server console');"));
+                root.addElement(changes);
+                out.println(root.toString());
+                // table tests
+            } else if (op.trim().toLowerCase().equals("illegalResponse"))
+            {
+                out.println("blablabl this is an illegal reponse, you should see an error");
+            } else if (op.trim().toLowerCase().equals("table_replace_head"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "head1", "<thead id=\"head1\">" +
+                        "<tr id=\"head_row1\">" +
+                        "<td id=\"head_col1\"><div id=\"col1_head\">column1 in line1 replaced</div></td>" +
+                        "<td id=\"head_col2\">colum2 in line1 replaced<script " +
+                        "type=\"text/javascript\">document.getElementById(\"head_col1\").innerHTML = document" +
+                        ".getElementById(\"head_col1\").innerHTML+\"<div class='eval_result'>script evaled" + (cnt++)
+                        + "</div>\";" +
+                        "</script></td>" +
+                        "</tr>" +
+                        "</thead>"));
+
+                root.addElement(changes);
+                out.println(root.toString());
+
+            } else if (op.trim().toLowerCase().equals("table_replace_body"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "tbody1", "<tbody id=\"tbody1\">" +
+                        "<tr id=\"body_row1\">" +
+                        "<td id=\"body_row1_col1\"><div id=\"col1_body\">column1 in line1 replaced</div></td>" +
+                        "<td id=\"body_row1_col2\">colum2 in line1 replaced<script " +
+                        "type=\"text/javascript\">document.getElementById(\"body_row1_col1\").innerHTML = document" +
+                        ".getElementById(\"body_row1_col1\").innerHTML+\"<div class='eval_result'>script " +
+                        "evaled" + (cnt++) + "</div>\";" +
+                        "</script></td>" +
+                        "</tr>" +
+                        "</tbody>"));
+
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("table_insert_row_head"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Insert2(changes, "head_row1", " <tr class='insert_before' id=\"head_row1_" + (elemCnt++) + "\">\n" +
+                        "                <td id=\"head_col1_" + elemCnt + "\">column1 in line1 inserted " +
+                        "before</td>\n" +
+                        "                <td id=\"head_col2_" + elemCnt + "\">colum2 in line2 inserted before</td>\n" +
+                        "            </tr>", "head_row1", null));
+                changes.addChild(new Insert2(changes, "head_row2", " <tr class='insert_after' id=\"head_row" +
+                        (elemCnt++) + "\">\n" +
+                        "                <td id=\"head_col1_" + elemCnt + "\">column1 in line1 inserted after" +
+                        "                </td>" +
+                        "                <td id=\"head_col2_" + elemCnt + "\">" +
+                        "                  colum2 in line2 inserted after" +
+                        "                  <script type=\"text/javascript\">" +
+                        "                       document.getElementById(\"head_col1_" + elemCnt + "\").innerHTML = " +
+                        "                       document.getElementById(\"head_col1_" + elemCnt + "\")" +
+                        ".innerHTML+\"<div class='eval_result'>script " +
+                        "                       evaled" + (cnt++) + "</div>\"; " +
+                        "                  </script>" +
+                        "               </td>\n" +
+                        "            </tr>", null, "head_row1"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("table_insert_row_body"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Insert2(changes, "body_row1", " <tr class='insert_before' id=\"body_row1_" +
+                        (elemCnt++) +
+                        "\">\n" +
+                        "                <td id=\"body_row1_" + elemCnt + "_col1\">column1 in " +
+                        "line1 inserted before</td>\n" +
+                        "                <td id=\"body_row1_" + elemCnt + "_col2\">colum2 in line2 inserted " +
+                        "before</td>\n" +
+                        "            </tr>", "body_row1", null));
+                changes.addChild(new Insert2(changes, "body_row2", " <tr class='insert_after' id=\"body_row1_" +
+                        (elemCnt++) + "\">\n" +
+                        "                <td id=\"body_row1_" + elemCnt + "_col1\">column1 in line1 inserted after" +
+                        "                </td>" +
+                        "                <td id=\"body_row1_" + elemCnt + "_col2\">" +
+                        "                  colum2 in line2 inserted after" +
+                        "                  <script type=\"text/javascript\">" +
+                        "                       document.getElementById(\"body_row1_col1\").innerHTML = " +
+                        "                       document.getElementById(\"body_row1_" + elemCnt + "_col1\")" +
+                        ".innerHTML+\"<div class='eval_result'>script " +
+                        "                       evaled" + (cnt++) + "</div>\"; " +
+                        "                  </script>" +
+                        "               </td>\n" +
+                        "            </tr>", null, "body_row1"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("table_insert_column_head"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Insert2(changes, "head_col1", "<td id='head_col1_1_" + (elemCnt++) + "'>inserted " +
+                        "before" + elemCnt + "</td>" + "<td id='head_col1_1_" + (elemCnt++) + "'>inserted " +
+                        "before " + elemCnt + "</td>",
+                        "head_col1",
+                        null));
+                changes.addChild(new Insert2(changes, "head_col1", "<td id='head_col1_1_" + (elemCnt++) + "'>inserted " +
+                        "after" + elemCnt + "</td>" + "<td id='head_col1_1_" + (elemCnt++) + "'>inserted " +
+                        "after" + elemCnt + "</td>",
+                        null,
+                        "head_col2"));
+
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("table_insert_column_body"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Insert2(changes, "body_row1_col1", "<td id='body_row1_col1_1_" + (elemCnt++) +
+                        "'>inserted " +
+                        "before" + elemCnt + "</td>" + "<td id='body_row1_col1_1_" + (elemCnt++) + "'>inserted " +
+                        "before " + elemCnt + "</td>",
+                        "body_row1_col1",
+                        null));
+                changes.addChild(new Insert2(changes, "body_row1_col1", "<td id='body_row1_col1_1_" + (elemCnt++) +
+                        "'>inserted " +
+                        "after" + elemCnt + "</td>" + "<td id='body_row1_col1_1_" + (elemCnt++) + "'>inserted " +
+                        "after" + elemCnt + "</td>",
+                        null,
+                        "body_row1_col2"));
+
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("table_insert_footer"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Insert2(changes, "body_row1_col1", "<tfooter>footer inserted</tfooter>",
+                        null,
+                        "tbody1"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("table_insert_body"))
+            {
+                Changes changes = new Changes(root);
+                changes.addChild(new Insert2(changes, "body_row1_col1",
+                        "<tbody><tr><td colspan='2'>second body added</td></tr></tbody>",
+                        null,
+                        "tbody1"));
+                root.addElement(changes);
+                out.println(root.toString());
+            } else if (op.trim().toLowerCase().equals("executenone"))
+            {
+                boolean execute = request.getParameter("javax.faces.partial.execute") != null;
+                boolean render = request.getParameter("javax.faces.partial.render") != null;
+
+                Changes changes = new Changes(root);
+                changes.addChild(new Update(changes, "result",(!execute && !render) ?  "<div " +
+                        "id='result'>success</div>" :  "<div " +
+                                                "id='result'>fail</div>"));
+                root.addElement(changes);
+                out.println(root.toString());
+            }
+
+        }
+        finally
+        {
+            out.close();
+        }
+    }
+
+    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
+
+    /**
+     * Handles the HTTP <code>GET</code> method.
+     *
+     * @param request  servlet request
+     * @param response servlet response
+     * @throws javax.servlet.ServletException if a servlet-specific error occurs
+     * @throws java.io.IOException            if an I/O error occurs
+     */
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException
+    {
+        processRequest(request, response);
+    }
+
+    /**
+     * Handles the HTTP <code>POST</code> method.
+     *
+     * @param request  servlet request
+     * @param response servlet response
+     * @throws javax.servlet.ServletException if a servlet-specific error occurs
+     * @throws java.io.IOException            if an I/O error occurs
+     */
+    @Override
+    protected void doPost(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException
+    {
+        processRequest(request, response);
+    }
+
+    /**
+     * Returns a short description of the servlet.
+     *
+     * @return a String containing servlet description
+     */
+    @Override
+    public String getServletInfo()
+    {
+        return "Short description";
+    }// </editor-fold>
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/ResponseMockup22.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/ResponseMockup22.java
new file mode 100644
index 0000000..b0e72d6
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/ResponseMockup22.java
@@ -0,0 +1,70 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol;
+
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Changes;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.PartialResponse;
+import org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes.Update;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ *          JSF 2.2 response mockup which simulates the changed viewstate behavior
+ */
+public class ResponseMockup22 extends ResponseMockup
+{
+
+    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException
+    {
+        response.setContentType("text/xml;charset=UTF-8");
+        PrintWriter out = response.getWriter();
+        String op = (String) request.getParameter("op");
+
+
+        PartialResponse root = new PartialResponse();
+        if (op.equals("newviewstate"))
+        {
+            Changes changes = new Changes(root);
+            changes.addChild(new Update(changes, "javax.faces.ViewState",
+                    "update1"));
+            root.addElement(changes);
+            out.println(root.toString());
+
+        }
+        else if (op.equals("newviewstate2"))
+        {
+            Changes changes = new Changes(root);
+            changes.addChild(new Update(changes, "form2:javax.faces.ViewState",
+                    "update2"));
+            root.addElement(changes);
+            out.println(root.toString());
+
+        } else
+        {
+            super.processRequest(request, response);
+        }
+
+    }
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Attribute.java
similarity index 54%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Attribute.java
index 6cbdfcc..5d1299b 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Attribute.java
@@ -16,25 +16,33 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
-
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.1 $ $Date: 2009/04/16 15:45:19 $
+ */
+public class Attribute {
+    String name = "";
+    String value = "";
 
-    public String getSayHello() {
-        return sayHello;
+    public Attribute(String name, String value) {
+        this.name = name;
+        this.value = value;
     }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<attribute name='");
+        retVal.append(name);
+        retVal.append("' value='");
+        retVal.append(value.replaceAll("'","\""));
+        retVal.append("' />");
+
+        return retVal.toString();
     }
+
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Attributes.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Attributes.java
new file mode 100644
index 0000000..7c2e23e
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Attributes.java
@@ -0,0 +1,53 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.1 $ $Date: 2009/04/16 15:45:19 $
+ */
+public class Attributes implements Change {
+
+    String id = "";
+    List<Attribute> attributes = new LinkedList<Attribute>();
+
+    public Attributes(Changes parent, String id) {
+        this.id = id;
+    }
+
+    public void addAttribute(Attribute attr) {
+        attributes.add(attr);
+    }
+
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<attributes id='");
+        retVal.append(id);
+        retVal.append("'>");
+        for (Attribute attribute : attributes) {
+            retVal.append(attribute.toString());
+        }
+        retVal.append("</attributes>");
+
+        return retVal.toString();
+    }
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Change.java
similarity index 60%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Change.java
index 6cbdfcc..719a9e7 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Change.java
@@ -16,25 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
-
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+/**
+ *
+ * @author werpu
+ *
+ * interface implementable by all nodes which have to reside under
+ * changes
+ * 
+ */
+public interface Change {
 
-    public String getSayHello() {
-        return sayHello;
-    }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
-    }
+    
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Changes.java
similarity index 50%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Changes.java
index 6cbdfcc..23ddd82 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Changes.java
@@ -16,25 +16,37 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+import java.util.LinkedList;
+import java.util.List;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.1 $ $Date: 2009/04/16 15:45:19 $
+ */
+public class Changes {
 
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+    PartialResponse parent;
+    List<Change> childs = new LinkedList<Change>();
+
+    public Changes(PartialResponse parent) {
+        this.parent = parent;
+    }
 
-    public String getSayHello() {
-        return sayHello;
+    public void addChild(Change child) {
+        childs.add(child);
     }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<changes>");
+        for (Change child : childs) {
+            retVal.append(child.toString());
+        }
+        retVal.append("</changes>");
+        return retVal.toString();
     }
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Delete.java
similarity index 51%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Delete.java
index 6cbdfcc..306d03f 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Delete.java
@@ -16,25 +16,42 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.1 $ $Date: 2009/04/16 15:45:19 $
+ */
+public class Delete implements Change {
+
+    private String id = "";
 
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+    public Delete(Changes parent, String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return the id
+     */
+    public String getId() {
+        return id;
+    }
 
-    public String getSayHello() {
-        return sayHello;
+    /**
+     * @param id the id to set
+     */
+    public void setId(String id) {
+        this.id = id;
     }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<delete id='");
+        retVal.append(id);
+        retVal.append("'/>");
+        return retVal.toString();
     }
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/ErrorResponse.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/ErrorResponse.java
new file mode 100644
index 0000000..3a461fb
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/ErrorResponse.java
@@ -0,0 +1,55 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
+
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.1 $ $Date: 2009/04/17 10:27:53 $
+ */
+public class ErrorResponse {
+
+    String errorMessage = "";
+    String errorName = "";
+
+    public ErrorResponse(PartialResponse parent, String errorMessage, String errorName) {
+        this.errorMessage = errorMessage;
+        this.errorName = errorName;
+    }
+
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<error>");
+        retVal.append("<error-name>");
+        retVal.append(errorName);
+        retVal.append("</error-name>");
+
+        retVal.append("<error-message><![CDATA[");
+        retVal.append(errorMessage);
+        retVal.append("]]></error-message>");
+        retVal.append("</error>");
+
+        return retVal.toString();
+    }
+
+
+
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Eval.java
similarity index 56%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Eval.java
index 6cbdfcc..bcc1612 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Eval.java
@@ -16,25 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.3 $ $Date: 2009/04/17 10:53:30 $
+ */
+public class Eval implements Change
+{
 
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+    String javascriptText = "";
 
-    public String getSayHello() {
-        return sayHello;
+    public Eval(Changes parent, String javascript) {
+        javascriptText = javascript;
     }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<eval><![CDATA[");
+        retVal.append(javascriptText);
+        retVal.append("]]></eval>");
+        
+        return retVal.toString();
     }
+
+
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Insert.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Insert.java
new file mode 100644
index 0000000..fe529a6
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Insert.java
@@ -0,0 +1,65 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
+
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.2 $ $Date: 2009/04/17 10:53:30 $
+ */
+public class Insert implements Change {
+
+    String id = "";
+    String before = "";
+    String after = "";
+    String data = "";
+
+    public Insert(Changes parent, String id, String data, String before, String after) {
+        super();
+        this.id = id;
+        this.before = before;
+        this.after = after;
+        this.data = data;
+    }
+
+    
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        
+        builder.append("<insert id='");
+        builder.append(id);
+        builder.append("' ");
+        if (before != null && !before.trim().equals("")) {
+            builder.append(" before='");
+            builder.append(before);
+            builder.append("' >");
+        } else {
+            builder.append(" after='");
+            builder.append(after);
+            builder.append("' >");
+        }
+        builder.append("<![CDATA[");
+        builder.append(data);
+        builder.append("]]>");
+        builder.append("</insert>");
+
+        return builder.toString();
+    }
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Insert2.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Insert2.java
new file mode 100644
index 0000000..c752c07
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Insert2.java
@@ -0,0 +1,76 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+
+
+/**
+ *
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.2 $ $Date: 2009/04/17 10:53:30 $
+ */
+public class Insert2 implements Change {
+
+    String id = "";
+    String before = "";
+    String after = "";
+    String data = "";
+
+    public Insert2(Changes parent, String id, String data, String before, String after) {
+        super();
+        this.id = id;
+        this.before = before;
+        this.after = after;
+        this.data = data;
+    }
+
+
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+
+        builder.append("<insert>");
+        if (before != null && !before.trim().equals("")) {
+            builder.append("<before id='");
+            builder.append(before);
+            builder.append("'>");
+        } else {
+            builder.append("<after id='");
+            builder.append(after);
+            builder.append("' >");
+        }
+        builder.append("<![CDATA[");
+        builder.append(data);
+        builder.append("]]>");
+        if (before != null && !before.trim().equals("")) {
+            builder.append("</before>");
+        } else {
+            builder.append("</after>");
+        }
+        builder.append("</insert>");
+
+        return builder.toString();
+    }
+}
+
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/PartialResponse.java
similarity index 50%
copy from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
copy to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/PartialResponse.java
index 6cbdfcc..ff1a155 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/PartialResponse.java
@@ -16,25 +16,37 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+import java.util.LinkedList;
+import java.util.List;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.2 $ $Date: 2009/04/17 10:27:53 $
+ */
+public class PartialResponse {
 
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+    List<Object> elements = new LinkedList<Object>();
 
-    public String getSayHello() {
-        return sayHello;
+    public void addElement(Object element) {
+        elements.add(element);
     }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
+
+    public String toString() {
+        StringBuilder retVal = new StringBuilder();
+        retVal.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+        retVal.append("<partial-response>");
+
+        for (Object element : elements) {
+            retVal.append(element.toString());
+        }
+
+        retVal.append("</partial-response>");
+
+        return retVal.toString();
     }
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Update.java
similarity index 53%
rename from integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
rename to integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Update.java
index 6cbdfcc..d2a4d8f 100644
--- a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/TestBean.java
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/jsfxmlnodes/Update.java
@@ -16,25 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.core.integrationtests.ajax;
 
-import javax.enterprise.context.RequestScoped;
-import javax.faces.annotation.FacesConfig;
-import javax.inject.Named;
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.jsfxmlnodes;
 
-import static javax.faces.annotation.FacesConfig.Version.JSF_2_3;
-
-@Named
-@RequestScoped
-@FacesConfig(version = JSF_2_3)
-public class TestBean {
-    private String sayHello = "hello world from bean";
+/**
+ * 
+ *
+ * @author Werner Punz(latest modification by $Author: werpu $)
+ * @version $Revision: 1.2 $ $Date: 2009/04/17 10:53:30 $
+ */
+public class Update implements Change{
+    String id = "";
+    String data = "";
 
-    public String getSayHello() {
-        return sayHello;
+    public Update(Changes parent, String id, String data) {
+        this.id = id;
+        this.data = data;
     }
 
-    public void setSayHello(String sayHello) {
-        this.sayHello = sayHello;
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("<update id='");
+        builder.append(id);
+        builder.append("'><![CDATA[");
+        builder.append(data);
+        builder.append("]]></update>");
+        return builder.toString();
     }
+
+
+
 }
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/ArrayUtils.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/ArrayUtils.java
new file mode 100644
index 0000000..7f93ebb
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/ArrayUtils.java
@@ -0,0 +1,234 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.responseWriter;
+
+
+import java.lang.reflect.Array;
+
+/**
+ * Utility class for managing arrays
+ *
+ * @author Anton Koinov (latest modification by $Author: matzew $)
+ * @version $Revision: 557350 $ $Date: 2007-07-18 13:19:50 -0500 (Wed, 18 Jul 2007) $
+ */
+@SuppressWarnings("unchecked")
+public class ArrayUtils
+{
+    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+    public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    //~ Constructors -------------------------------------------------------------------------------
+
+    protected ArrayUtils()
+    {
+        // hide from public access
+    }
+
+    //~ Methods ------------------------------------------------------------------------------------
+
+    public static Class commonClass(Class c1, Class c2)
+    {
+        if (c1 == c2)
+        {
+            return c1;
+        }
+
+        if ((c1 == Object.class) || c1.isAssignableFrom(c2))
+        {
+            return c1;
+        }
+
+        if (c2.isAssignableFrom(c1))
+        {
+            return c2;
+        }
+
+        if (c1.isPrimitive() || c2.isPrimitive())
+        {
+            // REVISIT: we could try to autoconvert to Object or something appropriate
+            throw new IllegalArgumentException("incompatible types " + c1 + " and " + c2);
+        }
+
+        // REVISIT: we could try to find a common supper class or interface
+        return Object.class;
+    }
+
+    /**
+     * Concatenates two arrays into one. If arr1 is null or empty, returns arr2.
+     * If arr2 is null or empty, returns arr1. May return null if both arrays are null,
+     * or one is empty and the other null. <br>
+     * The concatenated array has componentType which is compatible with both input arrays (or Object[])
+     *
+     * @param arr1 input array
+     * @param arr2 input array
+     *
+     * @return Object the concatenated array, elements of arr1 first
+     */
+    public static Object concat(Object arr1, Object arr2)
+    {
+        int len1 = (arr1 == null) ? (-1) : Array.getLength(arr1);
+
+        if (len1 <= 0)
+        {
+            return arr2;
+        }
+
+        int len2 = (arr2 == null) ? (-1) : Array.getLength(arr2);
+
+        if (len2 <= 0)
+        {
+            return arr1;
+        }
+
+        Class  commonComponentType =
+            commonClass(arr1.getClass().getComponentType(), arr2.getClass().getComponentType());
+        Object newArray = Array.newInstance(commonComponentType, len1 + len2);
+        System.arraycopy(arr1, 0, newArray, 0, len1);
+        System.arraycopy(arr2, 0, newArray, len1, len2);
+
+        return newArray;
+    }
+
+    /**
+     * Concatenates arrays into one. Any null or empty arrays are ignored.
+     * If all arrays are null or empty, returns null.
+     * Elements will be ordered in the order in which the arrays are supplied.
+     *
+     * @param arrs array of arrays
+     * @return the concatenated array
+     */
+    public static Object concat(Object[] arrs)
+    {
+        int   totalLen            = 0;
+        Class commonComponentType = null;
+        for (int i = 0, len = arrs.length; i < len; i++)
+        {
+            // skip all null arrays
+            if (arrs[i] == null)
+            {
+                continue;
+            }
+
+            int arrayLen = Array.getLength(arrs[i]);
+
+            // skip all empty arrays
+            if (arrayLen == 0)
+            {
+                continue;
+            }
+
+            totalLen += arrayLen;
+
+            Class componentType = arrs[i].getClass().getComponentType();
+            commonComponentType =
+                (commonComponentType == null) ? componentType
+                                              : commonClass(commonComponentType, componentType);
+        }
+
+        if (commonComponentType == null)
+        {
+            return null;
+        }
+
+        return concat(Array.newInstance(commonComponentType, totalLen), totalLen, arrs);
+    }
+
+    public static Object concat(Object toArray, int totalLen, Object[] arrs)
+    {
+        if (totalLen == 0)
+        {
+            // Should we allocate an empty array instead?
+            return toArray;
+        }
+
+        if (totalLen > Array.getLength(toArray))
+        {
+            toArray = Array.newInstance(toArray.getClass().getComponentType(), totalLen);
+        }
+
+        for (int i = 0, len = arrs.length, offset = 0; i < len; i++)
+        {
+            final Object arr = arrs[i];
+            if (arr != null)
+            {
+                int arrayLen = Array.getLength(arr);
+                if (arrayLen > 0)
+                {
+                    System.arraycopy(arr, 0, toArray, offset, arrayLen);
+                    offset += arrayLen;
+                }
+            }
+        }
+
+        return toArray;
+    }
+
+    public static Object concat(Object arr1, Object arr2, Object arr3)
+    {
+        return concat(new Object[] {arr1, arr2, arr3});
+    }
+
+    public static Object concat(Object arr1, Object arr2, Object arr3, Object arr4)
+    {
+        return concat(new Object[] {arr1, arr2, arr3, arr4});
+    }
+
+    public static Object concat(Object arr1, Object arr2, Object arr3, Object arr4, Object arr5)
+    {
+        return concat(new Object[] {arr1, arr2, arr3, arr4, arr5});
+    }
+
+    public static Object concatSameType(Object toArray, Object[] arrs)
+    {
+        int totalLen = 0;
+        for (int i = 0, len = arrs.length; i < len; i++)
+        {
+            if (arrs[i] != null)
+            {
+                totalLen += Array.getLength(arrs[i]);
+            }
+        }
+
+        return concat(toArray, totalLen, arrs);
+    }
+
+
+
+    public static boolean contains(Object[] array, Object value)
+    {
+        if (array == null || array.length == 0)
+        {
+            return false;
+        }
+
+        for (int i = 0; i < array.length; i++)
+        {
+            Object o = array[i];
+            if ((o == null && value == null) ||
+                (o != null && o.equals(value)))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/HTML.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/HTML.java
new file mode 100644
index 0000000..fb3b67d
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/HTML.java
@@ -0,0 +1,508 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.responseWriter;
+
+
+
+/**
+ * Constant declarations for HTML rendering.
+ * @author Manfred Geiler
+ * @author Anton Koinov
+ * @version $Revision: 700618 $ $Date: 2008-09-30 17:40:59 -0500 (Tue, 30 Sep 2008) $
+ */
+public interface HTML
+{
+    // Deprecated attributes
+    @Deprecated String DATAFLD_ATTR = "datafld";
+    @Deprecated String DATASRC_ATTR = "datasrc";
+    @Deprecated String DATAFORMATAS_ATTR = "dataformatas";
+
+    // Common attributes
+    String ALIGN_ATTR = "align";
+    String BORDER_ATTR = "border";
+    String WIDTH_ATTR = "width";
+    String READONLY_ATTR = "readonly";
+    String FILE_ATTR = "file";
+    String ACCEPT_ATTR = "accept";
+
+    // Common event handler attributes
+    String ONCLICK_ATTR     = "onclick";
+    String ONDBLCLICK_ATTR  = "ondblclick";
+    String ONMOUSEDOWN_ATTR = "onmousedown";
+    String ONMOUSEUP_ATTR   = "onmouseup";
+    String ONMOUSEOVER_ATTR = "onmouseover";
+    String ONMOUSEMOVE_ATTR = "onmousemove";
+    String ONMOUSEOUT_ATTR  = "onmouseout";
+    String ONKEYPRESS_ATTR  = "onkeypress";
+    String ONKEYDOWN_ATTR   = "onkeydown";
+    String ONKEYUP_ATTR     = "onkeyup";
+    String ONFOCUS_ATTR = "onfocus";
+    String ONBLUR_ATTR = "onblur";
+    String[] EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK =
+    {
+        ONDBLCLICK_ATTR,
+        ONMOUSEDOWN_ATTR,
+        ONMOUSEUP_ATTR,
+        ONMOUSEOVER_ATTR,
+        ONMOUSEMOVE_ATTR,
+        ONMOUSEOUT_ATTR,
+        ONKEYPRESS_ATTR,
+        ONKEYDOWN_ATTR,
+        ONKEYUP_ATTR
+    };
+    String[] EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT =
+    {
+        ONDBLCLICK_ATTR,
+        ONMOUSEDOWN_ATTR,
+        ONMOUSEUP_ATTR,
+        ONMOUSEMOVE_ATTR,
+        ONKEYPRESS_ATTR,
+        ONKEYDOWN_ATTR,
+        ONKEYUP_ATTR,
+        ONCLICK_ATTR
+    };
+    String[] EVENT_HANDLER_ATTRIBUTES =
+            (String[]) ArrayUtils.concat(
+                    EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK,
+                    new String[]{ONCLICK_ATTR});
+
+    // Input field event handler attributes
+    String ONSELECT_ATTR = "onselect";
+    String ONCHANGE_ATTR = "onchange";
+    String[] COMMON_FIELD_EVENT_ATTRIBUTES =
+    {
+        ONFOCUS_ATTR,
+        ONBLUR_ATTR,
+        ONSELECT_ATTR,
+        ONCHANGE_ATTR
+    };
+
+    String[] COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONFOCUS =
+    {
+        ONBLUR_ATTR,
+        ONSELECT_ATTR,
+        ONCHANGE_ATTR
+    };
+
+    String[] COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE =
+    {
+        ONFOCUS_ATTR,
+        ONBLUR_ATTR
+    };
+
+    // universal attributes
+    String DIR_ATTR   = "dir";
+    String LANG_ATTR  = "lang";
+    String STYLE_ATTR = "style";
+    String TITLE_ATTR = "title";
+    String STYLE_CLASS_ATTR = "styleClass"; //"class" cannot be used as property name
+
+    String[] UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE =
+    {
+        DIR_ATTR,
+        LANG_ATTR,
+        TITLE_ATTR,
+
+        //NOTE: if changed, please verify universal attributes in HtmlMessageRenderer !
+    };
+    String[] UNIVERSAL_ATTRIBUTES =
+            (String[]) ArrayUtils.concat(
+                    UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE,
+                    new String[]{STYLE_ATTR, STYLE_CLASS_ATTR});
+
+    //universal, but not the same property-name -
+    //styleClass attribute is rendered as such
+    String CLASS_ATTR = "class";
+
+    // common form field attributes
+    String ACCESSKEY_ATTR   = "accesskey";
+    String TABINDEX_ATTR    = "tabindex";
+    String DISABLED_ATTR = "disabled";
+    String[] COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED =
+    {
+        ACCESSKEY_ATTR,
+        TABINDEX_ATTR
+    };
+    String[] COMMON_FIELD_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED,
+                new String[]{DISABLED_ATTR});
+
+    // Common Attributes
+    String[] COMMON_PASSTROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                EVENT_HANDLER_ATTRIBUTES,
+                UNIVERSAL_ATTRIBUTES);
+    String[] COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE =
+        (String[]) ArrayUtils.concat(
+                EVENT_HANDLER_ATTRIBUTES,
+                UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE);
+    String[] COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONCLICK =
+        (String[]) ArrayUtils.concat(
+                EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK,
+                UNIVERSAL_ATTRIBUTES);
+    String[] COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE =
+        (String[]) ArrayUtils.concat(
+                EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONCLICK,
+                UNIVERSAL_ATTRIBUTES_WITHOUT_STYLE);
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED =
+        (String[]) ArrayUtils.concat(
+                COMMON_PASSTROUGH_ATTRIBUTES,
+                COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED,
+                COMMON_FIELD_EVENT_ATTRIBUTES);
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE =
+        (String[]) ArrayUtils.concat(
+                COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE,
+                COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED,
+                COMMON_FIELD_EVENT_ATTRIBUTES);
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS =
+        (String[]) ArrayUtils.concat(
+                COMMON_PASSTROUGH_ATTRIBUTES,
+                COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED,
+                COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONFOCUS);
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK =
+        (String[]) ArrayUtils.concat(
+                COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONCLICK,
+                COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED,
+                COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONFOCUS);
+    String[] COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONCLICK =
+        (String[]) ArrayUtils.concat(
+                COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONCLICK,
+                COMMON_FIELD_ATTRIBUTES_WITHOUT_DISABLED,
+                COMMON_FIELD_EVENT_ATTRIBUTES);
+    String[] COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT =
+        (String[]) ArrayUtils.concat(
+                EVENT_HANDLER_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT,
+                UNIVERSAL_ATTRIBUTES);
+
+    // <a>
+    String TARGET_ATTR = "target";  //used by <a> and <form>
+    String CHARSET_ATTR     = "charset";
+    String COORDS_ATTR      = "coords";
+    String HREF_ATTR    = "href";
+    String HREFLANG_ATTR    = "hreflang";
+    String REL_ATTR         = "rel";
+    String REV_ATTR         = "rev";
+    String SHAPE_ATTR       = "shape";
+    String TYPE_ATTR        = "type";
+    String[] ANCHOR_ATTRIBUTES =
+    {
+        ACCESSKEY_ATTR,
+        CHARSET_ATTR,
+        COORDS_ATTR,
+        HREFLANG_ATTR,
+        REL_ATTR,
+        REV_ATTR,
+        SHAPE_ATTR,
+        TABINDEX_ATTR,
+        TARGET_ATTR,
+        TYPE_ATTR
+    };
+    String[] ANCHOR_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                ANCHOR_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES,
+                COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+    String[] ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_STYLE =
+        (String[]) ArrayUtils.concat(
+                ANCHOR_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE,
+                COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+    String[] ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE =
+        (String[]) ArrayUtils.concat(
+                ANCHOR_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE,
+                COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
+
+    // <form>
+    String ACCEPT_CHARSET_ATTR = "accept-charset";
+    String ENCTYPE_ATTR = "enctype";
+    String ONRESET_ATTR = "onreset";
+    String ONSUMBIT_ATTR = "onsubmit";
+    String[] FORM_ATTRIBUTES =
+    {
+        ACCEPT_ATTR,
+        ACCEPT_CHARSET_ATTR,
+        ENCTYPE_ATTR,
+        ONRESET_ATTR,
+        ONSUMBIT_ATTR,
+        TARGET_ATTR,
+    };
+    String[] FORM_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                FORM_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES);
+
+    // <img>
+    String SRC_ATTR = "src";
+    String ALT_ATTR = "alt";
+    String HEIGHT_ATTR = "height";
+    String HSPACE_ATTR = "hspace";
+    String ISMAP_ATTR = "ismap";
+    String LONGDESC_ATTR = "longdesc";
+    String USEMAP_ATTR = "usemap";
+    String VSPACE_ATTR = "vspace";
+
+    String[] IMG_ATTRIBUTES =
+    {
+        ALIGN_ATTR,
+        ALT_ATTR,
+        BORDER_ATTR,
+        HEIGHT_ATTR,
+        HSPACE_ATTR,
+        ISMAP_ATTR,
+        LONGDESC_ATTR,
+        USEMAP_ATTR,
+        VSPACE_ATTR,
+        WIDTH_ATTR
+    };
+    String[] IMG_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                IMG_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES);
+    String[] IMG_PASSTHROUGH_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT =
+        (String[]) ArrayUtils.concat(
+                IMG_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_ONMOUSEOVER_AND_ONMOUSEOUT);
+    // <input>
+    String SIZE_ATTR = "size";
+    String AUTOCOMPLETE_ATTR = "autocomplete";
+    String CHECKED_ATTR = "checked";
+    String MAXLENGTH_ATTR = "maxlength";
+
+    String[] INPUT_ATTRIBUTES = {
+        ALIGN_ATTR,
+        ALT_ATTR,
+        CHECKED_ATTR,
+        MAXLENGTH_ATTR,
+        READONLY_ATTR,
+        SIZE_ATTR
+    };
+    String[] INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED =
+        (String[]) ArrayUtils.concat(
+                INPUT_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+    String[] INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE =
+        (String[]) ArrayUtils.concat(
+                INPUT_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
+
+    String[] INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK =
+        (String[]) ArrayUtils.concat(
+                INPUT_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK);
+
+    //values for input-type attribute
+    String INPUT_TYPE_SUBMIT = "submit";
+    String INPUT_TYPE_IMAGE = "image";
+    String INPUT_TYPE_HIDDEN = "hidden";
+    String INPUT_TYPE_CHECKBOX = "checkbox";
+    String INPUT_TYPE_PASSWORD = "password";
+    String INPUT_TYPE_TEXT = "text";
+    String INPUT_TYPE_RADIO = "radio";
+    String INPUT_TYPE_BUTTON = "button";
+
+    // <button>
+    String[] BUTTON_ATTRIBUTES =
+    {
+        ALIGN_ATTR,
+        ALT_ATTR,
+    };
+    String[] BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED =
+        (String[]) ArrayUtils.concat(
+                BUTTON_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+    String[] BUTTON_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONCLICK =
+        (String[]) ArrayUtils.concat(
+                BUTTON_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONCLICK);
+
+    // <iframe>
+    String FRAMEBORDER_ATTR = "frameborder";
+    String SCROLLING_ATTR = "scrolling";
+
+    // <label>
+    String FOR_ATTR = "for";
+    String[] LABEL_ATTRIBUTES =
+    {
+        ACCESSKEY_ATTR,
+        ONBLUR_ATTR,
+        ONFOCUS_ATTR
+        //FOR_ATTR is no pass through !
+    };
+    String[] LABEL_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                LABEL_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES);
+
+    // <select>
+    String MULTIPLE_ATTR = "multiple";
+
+    String[] SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED =
+            COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED;
+
+    // <table>
+    String BGCOLOR_ATTR = "bgcolor";
+    String CELLPADDING_ATTR = "cellpadding";
+    String CELLSPACING_ATTR = "cellspacing";
+    String FRAME_ATTR = "frame";
+    String RULES_ATTR = "rules";
+    String SUMMARY_ATTR = "summary";
+    String[] TABLE_ATTRIBUTES = {
+        ALIGN_ATTR,
+        BGCOLOR_ATTR,
+        BORDER_ATTR,
+        CELLPADDING_ATTR,
+        CELLSPACING_ATTR,
+        FRAME_ATTR,
+        RULES_ATTR,
+        SUMMARY_ATTR,
+        WIDTH_ATTR
+    };
+    String[] TABLE_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                TABLE_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES);
+
+    // <textarea>
+    String COLS_ATTR = "cols";
+    String ROWS_ATTR = "rows";
+    String WRAP_ATTR = "wrap";
+    String[] TEXTAREA_ATTRIBUTES =
+    {
+        COLS_ATTR,
+        READONLY_ATTR,
+        ROWS_ATTR,
+        WRAP_ATTR
+    };
+    String[] TEXTAREA_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED =
+        (String[]) ArrayUtils.concat(
+                TEXTAREA_ATTRIBUTES,
+                COMMON_FIELD_PASSTROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+
+    // <input type=file>
+    String[] INPUT_FILE_UPLOAD_ATTRIBUTES =
+    {
+        ACCEPT_ATTR
+    };
+    String[] INPUT_FILE_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED =
+        (String[]) ArrayUtils.concat(
+                INPUT_FILE_UPLOAD_ATTRIBUTES,
+                INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+
+
+    /*
+    String[] MESSAGE_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+            new String[] {DIR_ATTR, LANG_ATTR, TITLE_ATTR, STYLE_ATTR, STYLE_CLASS_ATTR},
+            EVENT_HANDLER_ATTRIBUTES);
+            */
+
+    String[] MESSAGE_PASSTHROUGH_ATTRIBUTES_WITHOUT_TITLE_STYLE_AND_STYLE_CLASS =
+        (String[]) ArrayUtils.concat(
+                new String[]{DIR_ATTR, LANG_ATTR},
+                EVENT_HANDLER_ATTRIBUTES);
+
+
+    // selectOne/Many table
+    String[] SELECT_TABLE_PASSTHROUGH_ATTRIBUTES =
+        new String[] {STYLE_ATTR, STYLE_CLASS_ATTR, BORDER_ATTR};
+
+    String COMPACT_ATTR = "compact";
+    String[] UL_ATTRIBUTES = {
+        COMPACT_ATTR,
+        TYPE_ATTR
+    };
+    String[] UL_PASSTHROUGH_ATTRIBUTES =
+        (String[]) ArrayUtils.concat(
+                UL_ATTRIBUTES,
+                COMMON_PASSTROUGH_ATTRIBUTES);
+
+
+    //HTML attributes needed for renderding only
+    String ID_ATTR = "id";
+    String NAME_ATTR = "name";
+    String VALUE_ATTR = "value";
+    String METHOD_ATTR = "method";
+    String ACTION_ATTR = "action";
+    String COLSPAN_ATTR = "colspan";
+    String SCOPE_ATTR = "scope";
+    String LABEL_ATTR = "label";
+    String SELECTED_ATTR = "selected";
+
+    //HTML attributes values
+    String SCOPE_COLGROUP_VALUE = "colgroup";
+
+    //HTML element constants
+    String SPAN_ELEM = "span";
+    String DIV_ELEM = "div";
+    String INPUT_ELEM = "input";
+    String BUTTON_ELEM = "button";
+    String SELECT_ELEM = "select";
+    String OPTION_ELEM = "option";
+    String OPTGROUP_ELEM = "optgroup";
+    String TEXTAREA_ELEM = "textarea";
+    String FORM_ELEM = "form";
+    String ANCHOR_ELEM = "a";
+    String H1_ELEM = "h1";
+    String H2_ELEM = "h2";
+    String H3_ELEM = "h3";
+    String H4_ELEM = "h4";
+    String H5_ELEM = "h5";
+    String H6_ELEM = "h6";
+    String IFRAME_ELEM = "iframe";
+    String IMG_ELEM = "img";
+    String LABEL_ELEM = "label";
+    String TABLE_ELEM = "table";
+    String CAPTION_ELEM = "caption";
+    String TR_ELEM = "tr";
+    String TH_ELEM = "th";
+    String TD_ELEM = "td";
+    String TBODY_ELEM = "tbody";
+    String TFOOT_ELEM = "tfoot";
+    String THEAD_ELEM = "thead";
+    String STYLE_ELEM = "style";
+    String SCRIPT_ELEM = "script";
+    String SCRIPT_TYPE_ATTR = "type";
+    String SCRIPT_TYPE_TEXT_JAVASCRIPT = "text/javascript";
+    String STYLE_TYPE_TEXT_CSS = "text/css";
+    String SCRIPT_LANGUAGE_ATTR = "language";
+    String SCRIPT_LANGUAGE_JAVASCRIPT = "JavaScript";
+    String SCRIPT_ELEM_DEFER_ATTR = "defer";
+    String LINK_ELEM = "link";
+    String STYLESHEET_VALUE = "stylesheet";
+    String UL_ELEM = "ul";
+    String OL_ELEM = "ol";
+    String LI_ELEM = "li";
+
+
+    //HTML simple element constants
+    String BR_ELEM = "br";
+
+
+    //HTML entities
+    String NBSP_ENTITY = "&#160;";
+
+    String HREF_PATH_SEPARATOR = "/";
+    String HREF_PATH_FROM_PARAM_SEPARATOR = "?";
+    //removed because wrong for XHTML and not used anyway: String HREF_PARAM_SEPARATOR = "&";
+    String HREF_PARAM_NAME_FROM_VALUE_SEPARATOR = "=";
+
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/MockupResponseWriter.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/MockupResponseWriter.java
new file mode 100644
index 0000000..7a29250
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/MockupResponseWriter.java
@@ -0,0 +1,162 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.responseWriter;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ *
+ * @author werpu
+ */
+public class MockupResponseWriter extends ResponseWriter {
+
+    StringBuilder target = new StringBuilder();
+    boolean _openTag = false;
+
+    @Override
+    public String getContentType() {
+        return "text/xml";
+    }
+
+    @Override
+    public String getCharacterEncoding() {
+        return "utf-8";
+    }
+
+    @Override
+    public void flush() throws IOException {
+    }
+
+    
+
+    @Override
+    public void startDocument() throws IOException {
+        target.append("<html><head></head><body>\n");
+    }
+
+    @Override
+    public void endDocument() throws IOException {
+        target.append("</body></html>");
+
+    }
+
+    @Override
+    public void startElement(String arg0, UIComponent arg1) throws IOException {
+        if (_openTag) {
+            target.append(">");
+
+        }
+
+        target.append("<");
+        target.append(arg0);
+        _openTag = true;
+    }
+
+    @Override
+    /*for testing purposes this is not 100% correct we have to use the nesting depth
+     to check for
+     but it is ok for testing*/
+    public void endElement(String arg0) throws IOException {
+        if(_openTag) {
+            target.append("/>");
+        } else {
+            target.append("</");
+            target.append(arg0);
+            target.append("/>");
+        }
+    }
+
+    @Override
+    public void writeAttribute(String arg0, Object arg1, String arg2) throws IOException {
+        if(arg1 instanceof String) {
+            target.append(" ");
+            target.append(arg0);
+            target.append("=");
+            target.append("'");
+            target.append(arg1);
+            target.append("'");
+            target.append(" ");
+        } else {
+            target.append(" ");
+            target.append(arg0);
+            target.append("=");
+            target.append(arg1.toString());
+            target.append(" ");
+        }
+    }
+
+    @Override
+    public void writeURIAttribute(String arg0, Object arg1, String arg2) throws IOException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void writeComment(Object arg0) throws IOException {
+       if(_openTag) {
+           _openTag = false;
+           target.append(">");
+       }
+       target.append("<!--");
+       target.append(arg0.toString());
+       target.append("//-->");
+    }
+
+    @Override
+    public void writeText(Object arg0, String arg1) throws IOException {
+       if(_openTag) {
+           _openTag = false;
+           target.append(">");
+       }
+
+       target.append(arg1.toString());
+     
+    }
+
+    @Override
+    public void writeText(char[] arg0, int arg1, int arg2) throws IOException {
+       if(_openTag) {
+           _openTag = false;
+           target.append(">");
+       }
+       target.append(arg0);
+
+    }
+
+    @Override
+    public ResponseWriter cloneWithWriter(Writer arg0) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        target.append(cbuf);
+    }
+
+    @Override
+    public void close() throws IOException {
+    }
+
+    public StringBuilder getTarget() {
+        return target;
+    }
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/PartialResponseWriterImpl.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/PartialResponseWriterImpl.java
new file mode 100644
index 0000000..a148547
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/PartialResponseWriterImpl.java
@@ -0,0 +1,371 @@
+/*
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+package org.apache.myfaces.core.integrationtests.ajax.test1Protocol.responseWriter;
+
+import javax.faces.component.UIComponent;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * An implementation of the partial response writer
+ * which pushes the scripting part of a component
+ * into a separate data structure so that in the long
+ * run we can deal with it in a separate eval stage.
+ *
+ * This is needed to be able to handle the eval properly
+ * Although we can deal with scripts also by inline parsing
+ * (which we make turnoffable for performance reasons)
+ * the proper way is to resolve this over a ResponseWriter
+ *
+ * We use a wrapper here for now!
+ *
+ * NOTE the class is a work in progress it is not finished yet
+ * and therefore not combined with the rest of the codebase
+ *
+ * Flow UIViewRoot: insert or update -> eval  javascripts must be deferred
+ * until the insert update or delete is done
+ *
+ * insert or update -> script src type="text/javascript"
+ * also must be delayed until the insert
+ * or update is done!
+ *
+ * single elements startElement no script -> passthrough
+ * script wait for end...
+ *
+ * Note our evals are directly stored in a stringbuilder, we have
+ * to assume that write access is single threaded the JEE spec
+ * definitely disallows multithreaded writes (the server has to provide
+ * threading facilities, threads in servlets writing on the responsewriter
+ * have to assume that the response writer itself is not thread safe!)
+ *
+ *
+ */
+public class PartialResponseWriterImpl extends PartialResponseWriterMockup
+{
+
+    private StringBuilder _evals = new StringBuilder();
+    StringBuilder _scriptBuffer = null;
+    ScriptHandler _scriptEntry = null;
+    boolean _deferEval = false;
+
+    public PartialResponseWriterImpl() {
+        super();
+    }
+
+    @Override
+    public void startError(String errorName) throws IOException {
+        super.startError(errorName);
+        _deferEval = true;
+    }
+
+    @Override
+    public void startExtension(Map<String, String> attributes) throws IOException {
+        super.startExtension(attributes);
+        _deferEval = true;
+    }
+
+    @Override
+    public void startInsertAfter(String targetId) throws IOException {
+        super.startInsertAfter(targetId);
+        _deferEval = true;
+    }
+
+    @Override
+    public void startInsertBefore(String targetId) throws IOException {
+        super.startInsertBefore(targetId);
+        _deferEval = true;
+    }
+
+    @Override
+    public void startUpdate(String targetId) throws IOException {
+        super.startUpdate(targetId);
+        _deferEval = true;
+    }
+
+    public void startEval() throws IOException {
+        if (!_deferEval) {
+            super.startEval();
+            writeEvals();
+        } else {
+            //we are already in an insert update or delete
+            //lets open a deferrence element
+            _scriptEntry = new ScriptHandler();
+
+        }
+    }
+
+    public void endEval() throws IOException {
+        if (_scriptEntry != null) {
+            _evals.append(_scriptEntry.toString());
+            _scriptEntry = null;
+        }
+        if (!_deferEval) {
+            super.endEval();
+        }
+    }
+
+
+
+    public void endInsert() throws IOException {
+        super.endInsert();
+        flushEvals();
+    }
+
+    public void endUpdate() throws IOException {
+        super.endUpdate();
+        flushEvals();
+    }
+
+    /**
+     * flushes the eval into a separate part
+     * of the xhr response cycle
+     * so that embedded scripts
+     * are properly set in their corresponding
+     * eval section
+     * @throws java.io.IOException
+     */
+    private void flushEvals() throws IOException {
+        if (_evals.length() == 0) {
+            return;
+        }
+        super.startEval();
+        writeEvals();
+        super.endEval();
+    }
+
+    public void startElement(String name, UIComponent component) throws IOException {
+        //it is either <script type="text/javascript>" or <script>
+
+        if (isScript(name)) {
+            _scriptEntry = new ScriptHandler();
+            _scriptEntry.setComponent(component);
+        } else {
+            super.startElement(name, component);
+        }
+    }
+
+    public void write(String str) throws IOException {
+
+        if (_scriptEntry != null) {
+            _scriptEntry.append(str);
+        } else {
+            super.write(str);
+        }
+    }
+
+    public void endElement(String name) throws IOException {
+        //We can probably replace this with a simple scriptBuffer check!
+        if (isScript(name) && _scriptEntry != null) {
+            _evals.append(_scriptEntry.toString());
+            _scriptEntry = null;
+        } else {
+            super.endElement(name);
+        }
+    }
+
+    public void writeAttribute(String name, Object value, String property) throws IOException {
+        if (_scriptEntry != null && isType(name)) {
+            _scriptEntry.setScriptType(value.toString());
+            return;
+        } else if (_scriptEntry != null && isSource(name)) {
+            _scriptEntry.setSource(value.toString());
+            return;
+        } else if (_scriptEntry != null && isDefer(name)) {
+            _scriptEntry.setDefer(value.toString());
+            return;
+        } else if (_scriptEntry != null && isCharset(name)) {
+            _scriptEntry.setCharSet(value.toString());
+            return;
+
+        } else if (_scriptEntry != null) {
+            //condition reached which we cannot eval, which means usually
+            //a script tag outside of what we can process in javascript
+            startElement(HTML.SCRIPT_ELEM, _scriptEntry.getComponent());
+
+            if (_scriptEntry.getScriptType() != null) {
+                writeAttribute(HTML.TYPE_ATTR, _scriptEntry.getScriptType(), null);
+                _scriptEntry.setScriptType(null);
+            }
+
+            if (_scriptEntry.getSource() != null) {
+                writeAttribute(HTML.SRC_ATTR, _scriptEntry.getSource(), null);
+                _scriptEntry.setSource(null);
+            }
+
+            if (_scriptEntry.getDefer() != null) {
+                writeAttribute("defer", _scriptEntry.getDefer(), null);
+                _scriptEntry.setSource(null);
+            }
+
+            if (_scriptEntry.getCharSet() != null) {
+                writeAttribute(HTML.CHARSET_ATTR, _scriptEntry.getCharSet(), null);
+                _scriptEntry.setSource(null);
+            }
+
+            /*no eval condition reached*/
+            _scriptEntry = null;
+        }
+
+        super.writeAttribute(name, value, property);
+    }
+
+    private boolean isDefer(String theType) {
+        return theType.equalsIgnoreCase("defer");
+    }
+
+    private boolean isCharset(String theType) {
+        return theType.equalsIgnoreCase(HTML.CHARSET_ATTR);
+    }
+
+    private boolean isSource(String theType) {
+        return theType.equalsIgnoreCase(HTML.SRC_ATTR);
+    }
+
+    private boolean isType(String theType) {
+        return theType.equalsIgnoreCase(HTML.TYPE_ATTR);
+    }
+
+    private boolean isScript(String name) {
+        return name.equalsIgnoreCase(HTML.SCRIPT_ELEM);
+    }
+
+    /**
+     * @return the _evals
+     */
+    public String getEvals() {
+        return _evals.toString();
+    }
+
+    /**
+     * @param evals the _evals to set
+     */
+    public void setEvals(String evals) {
+        this._evals = new StringBuilder(evals);
+    }
+
+    private void writeEvals() throws IOException {
+        super.write(_evals.toString());
+        _evals = new StringBuilder();
+    }
+
+    public String toString() {
+       return super.getTarget().toString();
+    }
+
+
+    private class ScriptHandler {
+
+        private String _scriptType = HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT;
+        private String _source = null;
+        private String _charSet = null;
+        private String _defer = null;
+        StringBuilder _content = new StringBuilder();
+        private UIComponent _component = null;
+
+        public void append(String content) {
+            _content.append(content);
+        }
+
+        public String toString() {
+            StringBuilder retVal = new StringBuilder(128);
+            if (getSource() != null) {
+                //TODO replace this with a utils method in one of our utils sections
+                retVal.append("myfaces._impl._util._Utils.loadScript('");
+                retVal.append(getSource());
+                retVal.append("','");
+                retVal.append(getScriptType());
+                retVal.append("'");
+                retVal.append(",");
+                retVal.append((getDefer() != null) ? getDefer() : "null");
+                retVal.append(",'");
+                retVal.append((getCharSet() != null) ? getCharSet() : "null");
+                retVal.append("'");
+                retVal.append(");");
+            }
+            retVal.append(_content);
+            return retVal.toString();
+        }
+
+        /**
+         * @return the _scriptType
+         */
+        public String getScriptType() {
+            return _scriptType;
+        }
+
+        /**
+         * @param scriptType the _scriptType to set
+         */
+        public void setScriptType(String scriptType) {
+            this._scriptType = scriptType;
+        }
+
+        /**
+         * @return the _source
+         */
+        public String getSource() {
+            return _source;
+        }
+
+        /**
+         * @param source the _source to set
+         */
+        public void setSource(String source) {
+            this._source = source;
+        }
+
+        /**
+         * @return the _component
+         */
+        public UIComponent getComponent() {
+            return _component;
+        }
+
+        /**
+         * @param component the _component to set
+         */
+        public void setComponent(UIComponent component) {
+            this._component = component;
+        }
+
+        /**
+         * @return the _charSet
+         */
+        public String getCharSet() {
+            return _charSet;
+        }
+
+        /**
+         * @param charSet the _charSet to set
+         */
+        public void setCharSet(String charSet) {
+            this._charSet = charSet;
+        }
+
+        /**
+         * @return the _defer
+         */
+        public String getDefer() {
+            return _defer;
+        }
+
+        /**
+         * @param defer the _defer to set
+         */
+        public void setDefer(String defer) {
+            this._defer = defer;
+        }
+    }
+}
diff --git a/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/PartialResponseWriterMockup.java b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/PartialResponseWriterMockup.java
new file mode 100644
index 0000000..9d0d61d
--- /dev/null
+++ b/integration-tests/ajax/src/main/java/org/apache/myfaces/core/integrationtests/ajax/test1Protocol/responseWriter/PartialResponseWriterMockup.java
@@ -0,0 +1,239 @@
+/*
+ * 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.myfaces.core.integrationtests.ajax.test1Protocol.responseWriter;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ *
+ * @author werpu
+ */
+public class PartialResponseWriterMockup extends MockupResponseWriter {
+
+    public static final String RENDER_ALL_MARKER = "javax.faces.ViewRoot";
+    public static final String VIEW_STATE_MARKER = "javax.faces.ViewState";
+    private boolean hasChanges;
+    private String insertType;
+
+    public void delete(String targetId) throws IOException {
+        startChanges();
+
+        super.startElement("delete", null);
+        super.writeAttribute("id", targetId, null);
+        super.endElement("delete");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void endDocument() throws IOException {
+        if (hasChanges) {
+            // Close the <insert> element, if any.
+
+            endInsert();
+
+            super.endElement("changes");
+
+            hasChanges = false;
+        }
+
+        super.endElement("partial-response");
+    }
+
+    public void endError() throws IOException {
+        // Close open <error-message> element.
+
+        endCDATA();
+        super.endElement("error-message");
+        super.endElement("error");
+    }
+
+    public void endEval() throws IOException {
+        // Close open <eval> element.
+
+        endCDATA();
+        super.endElement("eval");
+    }
+
+    public void endExtension() throws IOException {
+        super.endElement("extension");
+    }
+
+    public void endInsert() throws IOException {
+        if (insertType == null) {
+            // No insert started; ignore.
+
+            return;
+        }
+
+        // Close open <insert> element.
+
+        endCDATA();
+        super.endElement(insertType);
+        super.endElement("insert");
+
+        insertType = null;
+    }
+
+    public void endUpdate() throws IOException {
+        endCDATA();
+        super.endElement("update");
+    }
+
+    public void redirect(String url) throws IOException {
+        super.startElement("redirect", null);
+        super.writeAttribute("url", url, null);
+        super.endElement("redirect");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void startDocument() throws IOException {
+        super.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+
+        super.startElement("partial-response", null);
+    }
+
+    public void startError(String errorName) throws IOException {
+        super.startElement("error", null);
+
+        super.startElement("error-name", null);
+        super.write(errorName);
+        super.endElement("error-name");
+
+        super.startElement("error-message", null);
+        startCDATA();
+
+        // Leave open; caller will write message.
+    }
+
+    public void startEval() throws IOException {
+        startChanges();
+
+        super.startElement("eval", null);
+        startCDATA();
+
+        // Leave open; caller will write statements.
+    }
+
+    public void startExtension(Map<String, String> attributes) throws IOException {
+        Iterator<String> attrNames;
+
+        startChanges();
+
+        super.startElement("extension", null);
+
+        // Write out extension attributes.
+        // TODO: schema mentions "id" attribute; not used?
+
+        attrNames = attributes.keySet().iterator();
+
+        while (attrNames.hasNext()) {
+            String attrName = attrNames.next();
+
+            super.writeAttribute(attrName, attributes.get(attrName), null);
+        }
+
+        // Leave open; caller will write extension elements.
+    }
+
+    public void startInsertAfter(String targetId) throws IOException {
+        startInsertCommon("after", targetId);
+    }
+
+    public void startInsertBefore(String targetId) throws IOException {
+        startInsertCommon("before", targetId);
+    }
+
+    public void startUpdate(String targetId) throws IOException {
+        startChanges();
+
+        super.startElement("update", null);
+        super.writeAttribute("id", targetId, null);
+        startCDATA();
+
+        // Leave open; caller will write content.
+    }
+
+    public void updateAttributes(String targetId, Map<String, String> attributes) throws IOException {
+        Iterator<String> attrNames;
+
+        startChanges();
+
+        super.startElement("attributes", null);
+        super.writeAttribute("id", targetId, null);
+
+        attrNames = attributes.keySet().iterator();
+
+        while (attrNames.hasNext()) {
+            String attrName = attrNames.next();
+
+            super.startElement("attribute", null);
+            super.writeAttribute("name", attrName, null);
+            super.writeAttribute("value", attributes.get(attrName), null);
+            super.endElement("attribute");
+        }
+
+        super.endElement("attributes");
+    }
+
+    private void startChanges() throws IOException {
+        if (!hasChanges) {
+            super.startElement("changes", null);
+
+            hasChanges = true;
+        }
+    }
+
+    private void startInsertCommon(String type, String targetId) throws IOException {
+        if (insertType != null) {
+            // An insert has already been started; ignore.
+
+            return;
+        }
+
+        insertType = type;
+
+        startChanges();
+
+        super.startElement("insert", null);
+        super.startElement(insertType, null);
+        super.writeAttribute("id", targetId, null);
+        startCDATA();
+
+        // Leave open; caller will write content.
+    }
+
+    /*
+     * These methods are needed since we can't be sure that the data written by the caller will not
+     * contain reserved characters.
+     */
+    public void endCDATA() throws IOException {
+        super.write("]]>");
+    }
+
+    public void startCDATA() throws IOException {
+        super.write("<![CDATA[");
+    }
+}
diff --git a/integration-tests/ajax/src/main/webapp/WEB-INF/web.xml b/integration-tests/ajax/src/main/webapp/WEB-INF/web.xml
index 7395030..043580f 100644
--- a/integration-tests/ajax/src/main/webapp/WEB-INF/web.xml
+++ b/integration-tests/ajax/src/main/webapp/WEB-INF/web.xml
@@ -35,6 +35,7 @@
         <param-value>false</param-value>
     </context-param>
 
+
     <listener>
         <listener-class>org.apache.webbeans.servlet.WebBeansConfigurationListener</listener-class>
     </listener>
@@ -42,6 +43,15 @@
         <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
     </listener>
 
+    <servlet>
+        <servlet-name>MockupServlet</servlet-name>
+        <servlet-class>org.apache.myfaces.core.integrationtests.ajax.test1Protocol.ResponseMockup22</servlet-class>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>MockupServlet</servlet-name>
+        <url-pattern>*.mockup</url-pattern>
+    </servlet-mapping>
+
     <session-config>
         <tracking-mode>COOKIE</tracking-mode>
     </session-config>
diff --git a/integration-tests/ajax/src/main/webapp/index.xhtml b/integration-tests/ajax/src/main/webapp/index.xhtml
index 4f1c78e..23af088 100644
--- a/integration-tests/ajax/src/main/webapp/index.xhtml
+++ b/integration-tests/ajax/src/main/webapp/index.xhtml
@@ -26,18 +26,23 @@
 
     <h:head>
         <title>test</title>
-        <h:outputScript library="javax.faces" name="jsf.fs" />
+        <h:outputScript library="javax.faces" name="jsf.js" />
 
     </h:head>
 
     <h:body>
-        <h:form>
+        <h:form id="mainForm">
             #{testBean.sayHello}
 
+            <h:commandLink id="press" action="#{testBean.doAction}" styleClass="press">Press Me
+                <f:ajax execute="@this" render="@form"></f:ajax>
+            </h:commandLink>
             <script type="text/javascript">
             //<!--
                 if(window.jsf && window.jsf.ajax) {
-                    document.body.innerHTML = document.body.innerHTML + "_ajax_found";
+                    let node = document.createElement("span");
+                    node.innerHTML = "_ajax_found";
+                    document.body.append(node);
                 }
             //-->
             </script>
diff --git a/integration-tests/ajax/src/main/webapp/scripts/testhelpers.js b/integration-tests/ajax/src/main/webapp/scripts/testhelpers.js
new file mode 100644
index 0000000..1f11aa3
--- /dev/null
+++ b/integration-tests/ajax/src/main/webapp/scripts/testhelpers.js
@@ -0,0 +1,96 @@
+/**
+ 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.
+ */
+/**
+ * varius helper scripts to ease our testing
+ */
+
+/**
+ * /**
+ * ppr emitting function, which encapsules
+ * jsf.ajax.request with additioonal helpers
+ *
+ * @param source the source item triggering the event
+ * @param event an outer html event object
+ * @param action the action to perform on the jsf side (additional parameter which can be interpreted on the server)
+ * @param formName formName for the issuing form
+ * @param target the action target (ootional)
+ * @param onError onError handler
+ * @param onEvent onEvent handler
+ */
+function emitPPR(source, event, action, formName,  target, onError, onEvent) {
+
+    document.getElementById(formName || "form1").action = target || "test.mockup";
+
+    try {
+        jsf.ajax.request(/*String|Dom Node*/ source, /*|EVENT|*/ (window.event) ? window.event : event, /*{|OPTIONS|}*/ {
+            op: action,
+            onerror: onError || function (data) {
+                /*
+                * generic error check, all the error data coming in is dumped into a special entry
+                * the exception are http errors which are handled by the browser only for now
+                * */
+                processError(data);
+            }
+        });
+    } catch (e) {
+        console.error(e);
+    }
+
+}
+
+
+/**
+ * special element holding the processed errors
+ */
+var processError = function (data) {
+    if (document.querySelectorAll("#processedErrror").length == 0) {
+        var element = document.createElement("div");
+        element.id = "processedErrror";
+        document.body.append(element);
+    }
+    let logElement = document.querySelectorAll("#processedErrror")[0];
+    logElement.innerText = logElement.innerText + JSON.stringify(data);
+};
+
+/**
+ * error log inframe simulation for further processing
+ */
+var logError = function () {
+    if (document.querySelectorAll("#logError").length == 0) {
+        var element = document.createElement("div");
+        element.id = "logError";
+        document.body.append(element);
+    }
+    let logElement = document.querySelectorAll("#logError")[0];
+    logElement.innerText = logElement.innerText + arguments[0];
+};
+
+/**
+ * we log our console error output into an array
+ * to have later referemnces to that one
+ * @type {Array}
+ */
+
+if(console.error) {
+    var oldErrorFunc = console.error;
+    console.error = function() {
+        logError(JSON.stringify(arguments[0]));
+        oldErrorFunc.apply(console, arguments);
+    }
+}
\ No newline at end of file
diff --git a/integration-tests/ajax/src/main/webapp/test1-protocol.xhtml b/integration-tests/ajax/src/main/webapp/test1-protocol.xhtml
new file mode 100644
index 0000000..ff7a67c
--- /dev/null
+++ b/integration-tests/ajax/src/main/webapp/test1-protocol.xhtml
@@ -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.
+-->
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:h="http://xmlns.jcp.org/jsf/html"
+>
+
+<h:head>
+    <title>test</title>
+    <h:outputScript library="javax.faces" name="jsf.js" />
+    <script type="text/javascript" src="./scripts/testhelpers.js"></script>
+
+
+</h:head>
+
+<h:body>
+
+
+    <script type="text/javascript">
+    //<!--
+    var illegalResponseFired = function(data) {
+        processError(data);
+    }
+    //-->
+    </script>
+
+    <h2>protocol testcase1</h2>
+
+    <div id="centerDiv">
+        <h1>Selenium Testprobe for insert update delete and attribute change</h1>
+
+        <h2>This test tests all aspects of the protocol, under xhr and iframe conditions</h2>
+
+
+        <div id="testResults">
+            <h3>Test Results</h3>
+
+            <div id="evalarea1">eval area 1 triggered by eval</div>
+            <div id="evalarea2">eval area 2 triggered by update</div>
+            <div id="evalarea3">eval area 3 triggered by insert</div>
+            <div id="evalarea4">eval area 4 triggered by a click on the changed attributes area</div>
+
+            <div id="changesArea">update insert area</div>
+            <div id="deleteable">delete area will be deleted once you press the delete button</div>
+            <div id="attributeChange">attributes changes area</div>
+            <div id="processedErrror"></div>
+        </div>
+
+
+        <h2>Call actions via normal ppr</h2>
+
+        <form id="form1" action="boog.html">
+            <input type="button" id="cmd_eval" value="eval"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'eval1');"/>
+            <input type="button" id="cmd_update_insert" value="update insert"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'updateinsert1');"/>
+            <input type="button" id="cmd_update_insert2" value="update insert second protocol path"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'updateinsert2');"/>
+
+            <input type="button" id="cmd_delete" value="delete"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'delete1');"/>
+            <input type="button" id="cmd_attributeschange" value="change attributes"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'attributes');"/>
+            <input type="button" id="cmd_illegalresponse" value="illegal response, error trigger"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'illegalResponse', null, null, illegalResponseFired);"/>
+
+            <input type="button" id="cmd_error" value="Server error with error response"
+                   onclick="emitPPR(this, ('undefined' == typeof event)? null: event, 'errors', null, null, illegalResponseFired);"/>
+
+            <input type="button" id="cmd_error_component" value="Error: no component given"
+                   onclick="emitPPR(null, event, {}, null, null, illegalResponseFired); return false"/>
+
+
+
+        </form>
+        <br/>
+
+        <script type="text/javascript">
+            document.getElementById("evalarea1").innerHTML = "booga";
+        </script>
+
+    </div>
+
+
+</h:body>
+</html>
\ No newline at end of file
diff --git a/integration-tests/ajax/src/test/java/org/apache/myfaces/core/integrationtests/ajax/IntegrationTest.java b/integration-tests/ajax/src/test/java/org/apache/myfaces/core/integrationtests/ajax/IntegrationTest.java
index c95cdd6..2557178 100644
--- a/integration-tests/ajax/src/test/java/org/apache/myfaces/core/integrationtests/ajax/IntegrationTest.java
+++ b/integration-tests/ajax/src/test/java/org/apache/myfaces/core/integrationtests/ajax/IntegrationTest.java
@@ -21,6 +21,8 @@ package org.apache.myfaces.core.integrationtests.ajax;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.container.test.api.RunAsClient;
 import org.jboss.arquillian.drone.api.annotation.Drone;
+import org.jboss.arquillian.graphene.javascript.JavaScript;
+import org.jboss.arquillian.graphene.request.RequestGuard;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.arquillian.test.api.ArquillianResource;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -30,18 +32,30 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.openqa.selenium.JavascriptExecutor;
 import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ByIdOrName;
 
 import java.io.File;
 import java.net.URL;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+
+import static org.jboss.arquillian.graphene.Graphene.waitAjax;
+
 
 @RunWith(Arquillian.class)
 @RunAsClient
-public class IntegrationTest
-{
+public class IntegrationTest {
+
+    public static final String IB_1 = "insert before succeeded should display before test1";
+    public static final String IB_2 = "insert2 before succeeded should display before test1";
+    public static final String IA_2 = "insert2 after succeeded should display after test1";
+    public static final String IA_1 = "insert after succeeded should display after test1";
+    public static final String IEL = "update succeeded 1";
+
     @Deployment(testable = false)
-    public static WebArchive createDeployment()
-    {
+    public static WebArchive createDeployment() {
         WebArchive webArchive = (WebArchive) EmbeddedMaven.forProject(new File("pom.xml"))
                 .useMaven3Version("3.3.9")
                 .setGoals("package")
@@ -59,24 +73,117 @@ public class IntegrationTest
     @ArquillianResource
     protected URL contextPath;
 
+    @ArquillianResource
+    JavascriptExecutor executor;
+
+
+    @JavaScript
+    RequestGuard guard;
+
+
     @Before
-    public void before()
-    {
+    public void before() {
     }
 
     @After
-    public void after()
-    {
+    public void after() {
         webDriver.manage().deleteAllCookies();
     }
 
+
     @Test
-    public void testAjaxPresent()
-    {
-        webDriver.get(contextPath + "index.xhtml");
+    public void testAjaxPresent() {
+        webDriver.get(contextPath + "index.jsf");
+
 
+        webDriver.findElement(new ByIdOrName("mainForm:press")).click();
+        waitAjax().withTimeout(10, TimeUnit.SECONDS).until(new Function<WebDriver, Object>() {
 
+            public Object apply(WebDriver webDriver) {
+                return webDriver.getPageSource().contains("Action Performed");
+            }
+        });
         Assert.assertTrue(webDriver.getPageSource().contains("ViewState"));
         Assert.assertTrue(webDriver.getPageSource().contains("_ajax_found"));
+        Assert.assertTrue(webDriver.getPageSource().contains("Action Performed"));
+    }
+
+
+    /**
+     * Second test, test various aspects of the xhr protocol
+     * and the response handling
+     */
+    @Test
+    public void testProtocol() {
+        webDriver.get(contextPath + "test1-protocol.jsf");
+
+        //simple eval
+        trigger("cmd_eval", webDriver -> webDriver.getPageSource().contains("eval test succeeded"));
+
+        //simple update insert with embedded js
+        trigger("cmd_update_insert", webDriver ->  {
+            String pageSource = webDriver.getPageSource();
+            return pageSource.contains("embedded script at update succeed") &&
+                    pageSource.contains("embedded script at insert succeed");
+        });
+
+        //update, insert with the correct order
+        trigger("cmd_update_insert2", webDriver ->  {
+            String pageSource = webDriver.getPageSource();
+            return updateInsertElementsPresent(pageSource) &&
+                    correctInsertUpdatePos(pageSource);
+        });
+
+        //delete command
+        trigger("cmd_delete", webDriver ->  !webDriver.getPageSource().contains("deleteable"));
+
+
+        //attributes change
+        trigger("cmd_attributeschange", webDriver ->  webDriver.getPageSource().contains("1px solid black"));
+
+        //illegal response just triggers a normal error which goes into the log
+        trigger("cmd_illegalresponse", webDriver -> webDriver.findElement(new ByIdOrName("logError")).isDisplayed() &&
+                webDriver.findElement(new ByIdOrName("logError")).getText().contains("malformedXML"));
+
+        //server error, should trigger our error chain, no log error
+        trigger("cmd_error", webDriver -> webDriver.findElement(new ByIdOrName("processedErrror")).isDisplayed() &&
+                webDriver.findElement(new ByIdOrName("processedErrror")).getText().contains("serverError"));
+
+        //component error, client side, only log error
+        trigger("cmd_error_component", webDriver -> webDriver.findElement(new ByIdOrName("logError")).isDisplayed() &&
+                webDriver.findElement(new ByIdOrName("logError")).getText().contains("ArgNotSet"));
+
+    }
+
+
+    /**
+     * recurring trigger, wait until ajax processing is done function
+     *
+     * @param id the trigger element id
+     * @param condition a condition resolver which should return true if the condition is met
+     */
+    void trigger(String id, Function<WebDriver, Object> condition) {
+        webDriver.findElement(new ByIdOrName(id)).click();
+        waitAjax()
+                .withTimeout(10, TimeUnit.SECONDS)
+                .until(condition);
+    }
+
+
+    //some page state condition helpers
+    private boolean updateInsertElementsPresent(String pageSource) {
+        return pageSource.contains(IB_1) &&
+                pageSource.contains(IB_2) &&
+                pageSource.contains(IA_2) &&
+                pageSource.contains(IA_1) &&
+                pageSource.contains(IEL);
+    }
+
+
+    private boolean correctInsertUpdatePos(String pageSource) {
+        return pageSource.indexOf(IB_1) < pageSource.indexOf(IB_2) &&
+                pageSource.indexOf(IB_2) < pageSource.indexOf(IEL) &&
+                pageSource.indexOf(IEL) < pageSource.indexOf(IA_2) &&
+                pageSource.indexOf(IA_2) < pageSource.indexOf(IA_1);
     }
 }