diff --git a/guest/deep-jsf/README.md b/guest/deep-jsf/README.md
new file mode 100644
index 0000000000..b5f532535b
--- /dev/null
+++ b/guest/deep-jsf/README.md
@@ -0,0 +1,15 @@
+## Building
+
+To build the module, use Maven's `package` goal:
+
+```
+mvn clean package
+```
+
+The `war` file will be available at `target/deep-jsf.war`
+
+## Running
+
+The `war` application is deployed to a Java EE 7 compliant application server, for example, to GlassFish 4 or later.
+
+The example then will be accessible at http://localhost:8080/deep-jsf/index.xhtml
\ No newline at end of file
diff --git a/guest/deep-jsf/pom.xml b/guest/deep-jsf/pom.xml
new file mode 100644
index 0000000000..68801ba010
--- /dev/null
+++ b/guest/deep-jsf/pom.xml
@@ -0,0 +1,40 @@
+
+ 4.0.0
+
+ com.stackify
+ deep-jsf
+ 0.0.1-SNAPSHOT
+ war
+
+
+ false
+
+
+
+
+
+ javax
+ javaee-api
+ 7.0
+ provided
+
+
+
+
+
+ deep-jsf
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.7.0
+
+
+ 1.8
+
+
+
+
+
+
\ No newline at end of file
diff --git a/guest/deep-jsf/src/main/java/com/stackify/deepjsf/GreetControllerBean.java b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/GreetControllerBean.java
new file mode 100644
index 0000000000..7f5cf99781
--- /dev/null
+++ b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/GreetControllerBean.java
@@ -0,0 +1,14 @@
+package com.stackify.deepjsf;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
+
+@ManagedBean
+@RequestScoped
+public class GreetControllerBean {
+
+ public String greet() {
+ return "greet";
+ }
+
+}
diff --git a/guest/deep-jsf/src/main/java/com/stackify/deepjsf/PhaseListenerBean.java b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/PhaseListenerBean.java
new file mode 100644
index 0000000000..d4f6a6e815
--- /dev/null
+++ b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/PhaseListenerBean.java
@@ -0,0 +1,47 @@
+package com.stackify.deepjsf;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitResult;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.servlet.http.HttpServletRequest;
+
+@ManagedBean
+@RequestScoped
+public class PhaseListenerBean {
+
+ public void beforeListener(PhaseEvent event) {
+ if (!event.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
+ return;
+ }
+ UIViewRoot root = event.getFacesContext().getViewRoot();
+
+ boolean showNewFeature = showNewFeatureForIp(event);
+
+ processComponentTree(root, event, showNewFeature);
+ }
+
+ private boolean showNewFeatureForIp(PhaseEvent event) {
+ HttpServletRequest request = (HttpServletRequest) event.getFacesContext()
+ .getExternalContext().getRequest();
+ String ip = request.getRemoteAddr();
+ return !ip.startsWith("127.0");
+ }
+
+ private void processComponentTree(UIComponent component, PhaseEvent event, boolean show) {
+ component.visitTree(VisitContext.createVisitContext(event.getFacesContext()),
+ (context, target) -> {
+ if (target.getId() != null
+ && target.getId().startsWith("new-feature-")
+ && !show) {
+ target.setRendered(false);
+ }
+ return VisitResult.ACCEPT;
+ });
+ }
+
+}
diff --git a/guest/deep-jsf/src/main/java/com/stackify/deepjsf/UserBean.java b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/UserBean.java
new file mode 100644
index 0000000000..f6c94e87b8
--- /dev/null
+++ b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/UserBean.java
@@ -0,0 +1,48 @@
+package com.stackify.deepjsf;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+import javax.faces.event.ValueChangeEvent;
+
+@ManagedBean
+@SessionScoped
+public class UserBean {
+
+ private String name = "";
+
+ private String lastName = "";
+
+ private String proposedLogin = "";
+
+ public void nameChanged(ValueChangeEvent event) {
+ this.proposedLogin = event.getNewValue() + "-" + lastName;
+ }
+
+ public void lastNameChanged(ValueChangeEvent event) {
+ this.proposedLogin = name + "-" + event.getNewValue();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getProposedLogin() {
+ return proposedLogin;
+ }
+
+ public void setProposedLogin(String proposedLogin) {
+ this.proposedLogin = proposedLogin;
+ }
+}
diff --git a/guest/deep-jsf/src/main/java/com/stackify/deepjsf/UserControllerBean.java b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/UserControllerBean.java
new file mode 100644
index 0000000000..c2a46a019a
--- /dev/null
+++ b/guest/deep-jsf/src/main/java/com/stackify/deepjsf/UserControllerBean.java
@@ -0,0 +1,14 @@
+package com.stackify.deepjsf;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
+
+@ManagedBean
+@RequestScoped
+public class UserControllerBean {
+
+ public String register() {
+ return "register-success";
+ }
+
+}
diff --git a/guest/deep-jsf/src/main/webapp/WEB-INF/faces-config.xml b/guest/deep-jsf/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 0000000000..264e60065c
--- /dev/null
+++ b/guest/deep-jsf/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ /register.xhtml
+
+ register-success
+ /hello.xhtml
+
+
+
+
\ No newline at end of file
diff --git a/guest/deep-jsf/src/main/webapp/greet.xhtml b/guest/deep-jsf/src/main/webapp/greet.xhtml
new file mode 100644
index 0000000000..50c79c64e1
--- /dev/null
+++ b/guest/deep-jsf/src/main/webapp/greet.xhtml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/guest/deep-jsf/src/main/webapp/hello.xhtml b/guest/deep-jsf/src/main/webapp/hello.xhtml
new file mode 100644
index 0000000000..f9c3745dca
--- /dev/null
+++ b/guest/deep-jsf/src/main/webapp/hello.xhtml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/guest/deep-jsf/src/main/webapp/index.xhtml b/guest/deep-jsf/src/main/webapp/index.xhtml
new file mode 100644
index 0000000000..de99b89815
--- /dev/null
+++ b/guest/deep-jsf/src/main/webapp/index.xhtml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/guest/deep-jsf/src/main/webapp/register.xhtml b/guest/deep-jsf/src/main/webapp/register.xhtml
new file mode 100644
index 0000000000..ba1b8e0233
--- /dev/null
+++ b/guest/deep-jsf/src/main/webapp/register.xhtml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+