diff --git a/pom.xml b/pom.xml
index 7b0149f..aeeea7b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,9 +10,13 @@
     <version>1.0-SNAPSHOT</version>
     <name>${project.artifactId} : ${project.version}</name>
     <description>Htmlunit sandbox</description>
-    <url></url>
-    <packaging>pom</packaging>
+    <packaging>jar</packaging>
 
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.build.outputEncoding>UTF-8</project.build.outputEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
 
     <dependencies>
         <dependency>
@@ -43,5 +47,12 @@
         </plugins>
     </build>
 
+    <distributionManagement>
+        <repository>
+            <id>bernard.labno.pl</id>
+            <name>MyCo Internal Repository</name>
+            <url>http://bernard.labno.pl/artifactory/libs-snapshot-local</url>
+        </repository>
+    </distributionManagement>
 
 </project>
diff --git a/src/main/java/pl/labno/bernard/htmlunified/AlertLogger.java b/src/main/java/pl/labno/bernard/htmlunified/AlertLogger.java
new file mode 100644
index 0000000..4e5423d
--- /dev/null
+++ b/src/main/java/pl/labno/bernard/htmlunified/AlertLogger.java
@@ -0,0 +1,15 @@
+package pl.labno.bernard.htmlunified;
+
+import com.gargoylesoftware.htmlunit.AlertHandler;
+import com.gargoylesoftware.htmlunit.Page;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class AlertLogger implements AlertHandler {
+
+    private static final Log LOG = LogFactory.getLog(AlertLogger.class);
+
+    public void handleAlert(Page page, String message) {
+        LOG.info("Alert message:" + message);
+    }
+}
diff --git a/src/main/java/pl/labno/bernard/htmlunified/DomChangeLogger.java b/src/main/java/pl/labno/bernard/htmlunified/DomChangeLogger.java
new file mode 100644
index 0000000..b809ca9
--- /dev/null
+++ b/src/main/java/pl/labno/bernard/htmlunified/DomChangeLogger.java
@@ -0,0 +1,43 @@
+package pl.labno.bernard.htmlunified;
+
+import com.gargoylesoftware.htmlunit.html.DomChangeEvent;
+import com.gargoylesoftware.htmlunit.html.DomChangeListener;
+import com.gargoylesoftware.htmlunit.html.DomNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.w3c.dom.Node;
+
+public class DomChangeLogger implements DomChangeListener {
+
+    private static final Log LOG = LogFactory.getLog(DomChangeLogger.class);
+
+    public void nodeAdded(DomChangeEvent event) {
+        logEvent(event, "added");
+    }
+
+    public void nodeDeleted(DomChangeEvent event) {
+        logEvent(event, "removed");
+    }
+
+    private void logEvent(DomChangeEvent event, String action) {
+        String changed;
+        final DomNode changedNode = event.getChangedNode();
+        try {
+            changed = changedNode.toString();
+        } catch (Exception e) {
+            changed = changedNode.getNodeName() + "[id=" + changedNode.getAttributes().getNamedItem("id") + ("#text".equals(changedNode.getNodeName()) ? ";value=" + changedNode.getTextContent() : "") + "]";
+        }
+        String parent;
+        final DomNode parentNode = event.getParentNode();
+        try {
+            parent = parentNode.toString();
+        } catch (Exception e) {
+            parent = parentNode.getNodeName() + "[id=" + parentNode.getAttributes().getNamedItem("id") + ("#text".equals(parentNode.getNodeName()) ? ";value=" + parentNode.getTextContent() : "") + "]";
+        }
+        LOG.info("DomChangeEvent[action=" + action + ";changedElement=" + changed + ";source=" + event.getSource() + ";parent=" + parent + "]");
+        final Node id = event.getChangedNode().getAttributes().getNamedItem("id");
+        if (id != null && "searchClass:searchStudent".equals(id.getTextContent())) {
+            LOG.info(event.getChangedNode().asXml());
+        }
+    }
+}
diff --git a/src/main/java/pl/labno/bernard/htmlunified/HtmlAttributeChangeLogger.java b/src/main/java/pl/labno/bernard/htmlunified/HtmlAttributeChangeLogger.java
new file mode 100644
index 0000000..0c0dcf0
--- /dev/null
+++ b/src/main/java/pl/labno/bernard/htmlunified/HtmlAttributeChangeLogger.java
@@ -0,0 +1,27 @@
+package pl.labno.bernard.htmlunified;
+
+import com.gargoylesoftware.htmlunit.html.HtmlAttributeChangeEvent;
+import com.gargoylesoftware.htmlunit.html.HtmlAttributeChangeListener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class HtmlAttributeChangeLogger implements HtmlAttributeChangeListener {
+
+    private static final Log LOG = LogFactory.getLog(HtmlAttributeChangeLogger.class);
+
+    public void attributeAdded(HtmlAttributeChangeEvent event) {
+        log(event, "added");
+    }
+
+    public void attributeRemoved(HtmlAttributeChangeEvent event) {
+        log(event, "removed");
+    }
+
+    public void attributeReplaced(HtmlAttributeChangeEvent event) {
+        log(event, "replaced");
+    }
+
+    private void log(HtmlAttributeChangeEvent event, String action) {
+        LOG.info("HtmlAttributeChangeEvent[" + action + ":" + event.getName() + "=" + event.getValue() + ";source=" + event.getSource() + "]");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/pl/labno/bernard/htmlunified/RequestResponseLogger.java b/src/main/java/pl/labno/bernard/htmlunified/RequestResponseLogger.java
new file mode 100644
index 0000000..d11b3c8
--- /dev/null
+++ b/src/main/java/pl/labno/bernard/htmlunified/RequestResponseLogger.java
@@ -0,0 +1,38 @@
+package pl.labno.bernard.htmlunified;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.WebRequest;
+import com.gargoylesoftware.htmlunit.WebResponse;
+import com.gargoylesoftware.htmlunit.util.WebConnectionWrapper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.IOException;
+
+public class RequestResponseLogger extends WebConnectionWrapper {
+
+    private static final Log LOG = LogFactory.getLog(RequestResponseLogger.class);
+
+    private boolean active = true;
+
+    public RequestResponseLogger(WebClient webClient) throws IllegalArgumentException {
+        super(webClient);
+    }
+
+    @Override
+    public WebResponse getResponse(WebRequest request) throws IOException {
+        final WebResponse response = super.getResponse(request);
+        if (active) {
+            LOG.info("request=" + request.getRequestBody() + "\nresponse=" + response.getContentAsString());
+        }
+        return response;
+    }
+
+    public void off() {
+        active = false;
+    }
+
+    public void on() {
+        active = true;
+    }
+}
diff --git a/src/test/java/pl/labno/bernard/htmlunified/WebClientUtils.java b/src/main/java/pl/labno/bernard/htmlunified/WebClientUtils.java
index 0ff45b3..8c23130 100644
--- a/src/test/java/pl/labno/bernard/htmlunified/WebClientUtils.java
+++ b/src/main/java/pl/labno/bernard/htmlunified/WebClientUtils.java
@@ -30,24 +30,24 @@ public class WebClientUtils {
     }
 
     public static int waitForJSJob(WebClient webClient) {
-        return waitForJSJob(webClient, webClient.waitForBackgroundJavaScript(10) - 1, defaultCheckInterval, defaultTimeout);
+        return waitForJSJob(webClient, webClient.waitForBackgroundJavaScript(10) - 1);
     }
 
     public static int waitForJSJob(WebClient webClient, int initialJobCount) {
-        return waitForJSJob(webClient, initialJobCount, defaultCheckInterval, defaultTimeout);
+        return waitForJSJob(webClient, initialJobCount, defaultTimeout);
     }
 
     public static int waitForJSJob(WebClient webClient, int initialJobCount, long timeout) {
-        return waitForJSJob(webClient, initialJobCount, defaultCheckInterval, timeout);
+        return waitForJSJob(webClient, initialJobCount, timeout, defaultCheckInterval);
     }
 
-    public static int waitForJSJob(WebClient webClient, int initialJobCount, long checkInterval, long timeout) {
+    public static int waitForJSJob(WebClient webClient, int initialJobCount, long timeout, long checkInterval) {
         int jobs;
         long startTime = System.currentTimeMillis();
         do {
             jobs = webClient.waitForBackgroundJavaScript(checkInterval);
             if (startTime + timeout < System.currentTimeMillis()) {
-                throw new RuntimeException("Number of JavaScript jobs doesn't drop to initial level for 10000 seconds. It's memory leak in your JavaScript rather then request taking so long!");
+                throw new RuntimeException("Number of JavaScript jobs doesn't drop to initial level for " + timeout + " seconds. It's memory leak in your JavaScript rather then request taking so long!");
             }
         } while (jobs > initialJobCount);
         System.out.println("Waiting took: " + (System.currentTimeMillis() - startTime) + "ms");
@@ -74,4 +74,18 @@ public class WebClientUtils {
         }
         return suggestions;
     }
+
+    public static void forceWait(int timeout) {
+        final long startTime = System.currentTimeMillis();
+        do {
+            try {
+                final long millis = startTime + timeout - System.currentTimeMillis();
+                if (millis > 0) {
+                    Thread.sleep(millis);
+                }
+            } catch (InterruptedException ignore) {
+            } catch (IllegalArgumentException ignore) {
+            }
+        } while (startTime + timeout > System.currentTimeMillis());
+    }
 }
diff --git a/src/test/java/pl/labno/bernard/htmlunified/SandboxTest.java b/src/test/java/pl/labno/bernard/htmlunified/SandboxTest.java
new file mode 100644
index 0000000..22a4039
--- /dev/null
+++ b/src/test/java/pl/labno/bernard/htmlunified/SandboxTest.java
@@ -0,0 +1,23 @@
+package pl.labno.bernard.htmlunified;
+
+import com.gargoylesoftware.htmlunit.BrowserVersion;
+import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class SandboxTest {
+
+    @Test
+    public void test() throws IOException {
+        final WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
+        client.setAjaxController(new NicelyResynchronizingAjaxController());
+        HtmlPage page = (HtmlPage) client.getPage("file:./target/test-classes/sandbox.html");
+        Assert.assertEquals("elementToHide", page.getElementById("elementToHide").asText());
+        page.getElementById("close").click();
+        Assert.assertEquals("", page.getElementById("elementToHide").asText());
+    }
+}
diff --git a/src/test/java/pl/labno/bernard/htmlunified/ScheduleTest.java b/src/test/java/pl/labno/bernard/htmlunified/ScheduleTest.java
index 395a95b..f906a31 100644
--- a/src/test/java/pl/labno/bernard/htmlunified/ScheduleTest.java
+++ b/src/test/java/pl/labno/bernard/htmlunified/ScheduleTest.java
@@ -1,7 +1,6 @@
 package pl.labno.bernard.htmlunified;
 
 import com.gargoylesoftware.htmlunit.BrowserVersion;
-import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
 import com.gargoylesoftware.htmlunit.WebClient;
 import com.gargoylesoftware.htmlunit.html.HtmlElement;
 import com.gargoylesoftware.htmlunit.html.HtmlInput;
@@ -16,83 +15,137 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+/**
+ * NicelyResynchronizingAjaxController is EVIL! Don't use it!
+ */
 public class ScheduleTest {
 
-    //    @Test
+    @Test
     public void accessEventTitles() throws IOException {
         WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
-        //login-----------------------------------
-        HtmlPage page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");
-        ((HtmlInput) page.getElementById("loginForm:email")).setValueAttribute("s4237@pjwstk.edu.pl");
-        ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa");
-        HtmlPage oldPage = page;
-        page = page.getElementById("loginForm:submit").click();
-//        This assert would fail (when page redidrects than you need to obtain new page)
-//        Assert.assertEquals(page,oldPage);
-        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
-        //----------------------------------------
-
+        HtmlPage page = login(client);
+        @SuppressWarnings("unchecked")
         final List<HtmlSpan> titleElements = (List<HtmlSpan>) page.getElementById("results:schedule").getByXPath(".//span[@class='fc-event-title']");
         List<String> titles = new ArrayList<String>(titleElements.size());
         for (HtmlSpan o : titleElements) {
             titles.add(o.asText());
         }
-        Assert.assertEquals(2, titles.size());
+        Assert.assertEquals(4, titles.size());
     }
 
     @Test
-    public void clickSuggestionBox() throws IOException {
+    public void clickStudentSuggestionBox() throws IOException {
         WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
-        client.setAjaxController(new NicelyResynchronizingAjaxController());
-        //login-----------------------------------
-        HtmlPage page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");
-        ((HtmlInput) page.getElementById("loginForm:email")).setValueAttribute("s4237@pjwstk.edu.pl");
-        ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa");
-        HtmlPage oldPage = page;
-        page = page.getElementById("loginForm:submit").click();
-//        This assert would fail (when page redidrects than you need to obtain new page)
-//        Assert.assertEquals(page,oldPage);
-        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
-        //----------------------------------------
-        final HtmlInput studentInput = (HtmlInput) page.getElementById("searchClass:student_i");
-        int initialJobs = client.waitForBackgroundJavaScript(10);
-
+        HtmlPage page = login(client);
+        page.addDomChangeListener(new DomChangeLogger());
+        page.getElementById("searchClass:sS").addHtmlAttributeChangeListener(new HtmlAttributeChangeLogger());
+        HtmlInput studentInput = (HtmlInput) page.getElementById("searchClass:student_i");
         studentInput.type('w');
         studentInput.type('i');
         Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
 //        Here the suggestionBox is still hidden
-//        System.out.println(page.asXml());
-
-        int jobs = WebClientUtils.waitForJSJob(client, 0, 30000);
+        WebClientUtils.waitForJSJob(client, 0, 30000);
 //        Here suggestionBox is visible
-//        System.out.println(page.asXml());
-        System.out.println(page.getElementById("searchClass:sS").asXml());
-        System.out.println("initialJobs:" + initialJobs);
-        System.out.println("jobs:" + jobs);
         Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
-         synchronized (page) {
-            try {
-                page.wait(1000);
-            } catch (InterruptedException e) {
-                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-            }
-        }
         Map<String, HtmlTableCell> suggestions = WebClientUtils.getSuggestions(page.getElementById("searchClass:sS"), 0);
         Assert.assertEquals(1, suggestions.size());
         System.out.println(suggestions);
         HtmlTableCell cell = suggestions.get("Willis Bruce");
         Assert.assertNotNull(cell);
-        initialJobs = client.waitForBackgroundJavaScript(10);
-        System.out.println("initial jobs:"+initialJobs);
         cell.click();
-        System.out.println("Starting jobs:"+client.waitForBackgroundJavaScriptStartingBefore(3000));
-        System.out.println("Running jobs:"+client.waitForBackgroundJavaScript(10));
-//        studentInput.type('\t');
-        jobs = WebClientUtils.waitForJSJob(client,initialJobs, 30000);
-        System.out.println("initialJobs:" + initialJobs);
-        System.out.println("jobs:" + jobs);
-        System.out.println(page.asXml());
-        Assert.assertEquals("Willis Bruce",((HtmlElement)page.getByXPath("//*[@id='searchClass:searchStudent']").get(0)).asText());
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+        Assert.assertEquals("Willis Bruce", ((HtmlElement) page.getByXPath("//*[@id='searchClass:searchStudent']").get(0)).asText());
+        System.out.println("Success!");
+
+
+//            page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
+        studentInput = (HtmlInput) page.getElementById("searchClass:student_i");
+        studentInput.setValueAttribute("");
+        studentInput.type('l');
+        studentInput.type('i');
+        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
+//        WebClientUtils.forceWait(2000);
+//        Here the suggestionBox is still hidden
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+//        Here suggestionBox is visible
+        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
+        suggestions = WebClientUtils.getSuggestions(page.getElementById("searchClass:sS"), 0);
+        Assert.assertEquals(1, suggestions.size());
+        System.out.println(suggestions);
+        cell = suggestions.get("Linda Bogusław");
+        Assert.assertNotNull(cell);
+        cell.click();
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+        Assert.assertEquals("Linda Bogusław", ((HtmlElement) page.getByXPath("//*[@id='searchClass:searchStudent']").get(0)).asText());
+        System.out.println("Success2!");
+    }
+
+    @Test
+    public void switchBetwenScheduleAndTableMode() throws IOException {
+        WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
+        HtmlPage page = login(client);
+        page.getElementById("j_id2118:j_id2119:0").click();
+        page.getElementById("j_id2118:j_id2119:0").blur();
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+//        System.out.println(page.getElementById("results").asXml());
+        Assert.assertNotNull(page.getElementById("results:table"));
+        page.getElementById("j_id2118:j_id2119:1").click();
+        page.getElementById("j_id2118:j_id2119:1").blur();
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+//        System.out.println(page.getElementById("results").asXml());
+        Assert.assertNotNull(page.getElementById("results:schedule"));
+        page.getElementById("j_id2118:j_id2119:0").click();
+        page.getElementById("j_id2118:j_id2119:0").blur();
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+//        System.out.println(page.getElementById("results").asXml());
+        Assert.assertNotNull(page.getElementById("results:table"));
+    }
+
+    @Test
+    public void selectStudentSuggestionByTab() throws IOException {
+        final WebClient client = new WebClient(BrowserVersion.FIREFOX_3_6);
+        final RequestResponseLogger requestResponseLogger = new RequestResponseLogger(client);
+        requestResponseLogger.off();
+        HtmlPage page = login(client);
+        final HtmlInput studentInput = (HtmlInput) page.getElementById("searchClass:student_i");
+        studentInput.type('w');
+        studentInput.type('i');
+        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
+//        Here the suggestionBox is still hidden
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+//        Here suggestionBox is visible
+        Map<String, HtmlTableCell> suggestions = WebClientUtils.getSuggestions(page.getElementById("searchClass:sS"), 0);
+        Assert.assertEquals(1, suggestions.size());
+//        System.out.println(suggestions);
+        HtmlTableCell cell = suggestions.get("Willis Bruce");
+        Assert.assertNotNull(cell);
+        studentInput.type('\t');
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+        Assert.assertEquals("Willis Bruce", page.getElementById("searchClass:searchStudent").asText());
+
+//        requestResponseLogger.on();
+//        client.setAlertHandler(new AlertLogger());
+//        page.addDomChangeListener(new DomChangeLogger());
+        final HtmlElement element = page.getElementById("searchClass:searchStudent").getElementsByTagName("img").get(0);
+        element.click();
+        WebClientUtils.waitForJSJob(client, 0, 30000);
+        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
+        Assert.assertEquals("", page.getElementById("searchClass:searchStudent").asText());
+
+    }
+
+    private HtmlPage login(WebClient client) throws IOException {
+        HtmlPage page = (HtmlPage) client.getPage("http://localhost:8080/schoolmanager/view/class/current.seam?networkId=salsafactory");
+        ((HtmlInput) page.getElementById("loginForm:email")).setValueAttribute("s4237@pjwstk.edu.pl");
+        ((HtmlInput) page.getElementById("loginForm:password")).setValueAttribute("aaaaa");
+        HtmlPage oldPage = page;
+        page = page.getElementById("loginForm:submit").click();
+//        This assert would fail (when page redidrects than you need to obtain new page)
+//        Assert.assertEquals(page,oldPage);
+        Assert.assertEquals(client.getCurrentWindow().getEnclosedPage(), page);
+        return page;
     }
 
 }
diff --git a/src/test/resources/sandbox.html b/src/test/resources/sandbox.html
new file mode 100644
index 0000000..52e19db
--- /dev/null
+++ b/src/test/resources/sandbox.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+    <title></title>
+</head>
+<body>
+<img id="close" onclick="var e = document.getElementById('elementToHide');e.removeChild(e.firstChild)" alt="close"/>
+
+<div id="elementToHide">elementToHide</div>
+</body>
+</html>
\ No newline at end of file