From 5dd02b8fd6fd3dc9214c1d8f15a9783d9072531c Mon Sep 17 00:00:00 2001
From: Farhan <han.majid2004@gmail.com>
Date: Tue, 29 Nov 2016 09:56:16 +0700
Subject: [PATCH] add chat service

---
 ChatServer/chat-server.php                    |  161 ++
 Client2/build.xml                             |   71 +
 Client2/build/web/META-INF/MANIFEST.MF        |    2 +
 Client2/build/web/META-INF/context.xml        |    2 +
 .../WEB-INF/classes/.netbeans_automatic_build |    0
 .../classes/.netbeans_update_resources        |    0
 Client2/build/web/WEB-INF/glassfish-web.xml   |   10 +
 Client2/build/web/catalog.jsp                 |  113 ++
 Client2/build/web/chat.js                     |  235 +++
 Client2/build/web/gfv3ee6.dpf                 |    0
 Client2/build/web/index.html                  |  344 ++++
 Client2/build/web/login.jsp                   |   31 +
 Client2/build/web/logout.jsp                  |   24 +
 Client2/build/web/manifest.json               |    5 +
 Client2/dist/Client2.war                      |  Bin 0 -> 17514 bytes
 Client2/manifest.json                         |    5 +
 Client2/nbproject/ant-deploy.xml              |  150 ++
 Client2/nbproject/build-impl.xml              | 1441 +++++++++++++++++
 Client2/nbproject/genfiles.properties         |    8 +
 Client2/nbproject/private/private.properties  |   10 +
 Client2/nbproject/project.properties          |   88 +
 Client2/nbproject/project.xml                 |   18 +
 Client2/src/conf/MANIFEST.MF                  |    2 +
 Client2/web/META-INF/context.xml              |    2 +
 Client2/web/catalog.jsp                       |  113 ++
 Client2/web/chat.js                           |  235 +++
 Client2/web/index.html                        |  344 ++++
 Client2/web/login.jsp                         |   31 +
 Client2/web/logout.jsp                        |   24 +
 Client2/web/manifest.json                     |    5 +
 30 files changed, 3474 insertions(+)
 create mode 100644 ChatServer/chat-server.php
 create mode 100644 Client2/build.xml
 create mode 100644 Client2/build/web/META-INF/MANIFEST.MF
 create mode 100644 Client2/build/web/META-INF/context.xml
 create mode 100644 Client2/build/web/WEB-INF/classes/.netbeans_automatic_build
 create mode 100644 Client2/build/web/WEB-INF/classes/.netbeans_update_resources
 create mode 100644 Client2/build/web/WEB-INF/glassfish-web.xml
 create mode 100644 Client2/build/web/catalog.jsp
 create mode 100644 Client2/build/web/chat.js
 create mode 100644 Client2/build/web/gfv3ee6.dpf
 create mode 100644 Client2/build/web/index.html
 create mode 100644 Client2/build/web/login.jsp
 create mode 100644 Client2/build/web/logout.jsp
 create mode 100644 Client2/build/web/manifest.json
 create mode 100644 Client2/dist/Client2.war
 create mode 100644 Client2/manifest.json
 create mode 100644 Client2/nbproject/ant-deploy.xml
 create mode 100644 Client2/nbproject/build-impl.xml
 create mode 100644 Client2/nbproject/genfiles.properties
 create mode 100644 Client2/nbproject/private/private.properties
 create mode 100644 Client2/nbproject/project.properties
 create mode 100644 Client2/nbproject/project.xml
 create mode 100644 Client2/src/conf/MANIFEST.MF
 create mode 100644 Client2/web/META-INF/context.xml
 create mode 100644 Client2/web/catalog.jsp
 create mode 100644 Client2/web/chat.js
 create mode 100644 Client2/web/index.html
 create mode 100644 Client2/web/login.jsp
 create mode 100644 Client2/web/logout.jsp
 create mode 100644 Client2/web/manifest.json

diff --git a/ChatServer/chat-server.php b/ChatServer/chat-server.php
new file mode 100644
index 0000000..b713aec
--- /dev/null
+++ b/ChatServer/chat-server.php
@@ -0,0 +1,161 @@
+<?php
+header('Access-Control-Allow-Origin: *');
+header('Access-Control-Allow-Methods: GET, POST');
+
+require_once('db.php');
+
+function broadcastTopic() {
+  $url = 'https://fcm.googleapis.com/fcm/send';
+  $data = array("data" => array(
+      "message"=> "Someone login"
+    ),
+    "to" => '/topics/movies'
+  );
+  $options = array(
+    'http' => array(
+      'method'  => 'POST',
+      'content' => json_encode( $data ),
+      'header'=>  "Content-Type: application/json\r\n" .
+                  "Authorization:key=AAAAQx0rFL4:APA91bHitlPibrVEsCmaPoG29F-09VbBjjuS6y7YQYA0hrFrk3lx4BCVC_nEL6eZbxZ5HVNE-49G8wJbooAgZGi3WLnqYN6QTFxdY8cojghR2-Mq04JzXfO1i0_xSotTpgFAKtDN9JZoqirw9lsYOVKZzGy4jNujDQ\r\n"
+      )
+  );
+  $context  = stream_context_create( $options );
+  $result = file_get_contents( $url, false, $context );
+  $response = json_decode( $result );
+  echo $result;
+}
+
+function listenTopic($token) {
+  $url = ('https://iid.googleapis.com/iid/v1/'.$token.'/rel/topics/movies');
+  // echo $url;
+  $data = array();
+  $options = array(
+    'http' => array(
+      'method'  => 'POST',
+      'content' => json_encode($data),
+      'header'=>  "Content-Type: application/json\r\n" .
+                  "Authorization:key=AAAAQx0rFL4:APA91bHitlPibrVEsCmaPoG29F-09VbBjjuS6y7YQYA0hrFrk3lx4BCVC_nEL6eZbxZ5HVNE-49G8wJbooAgZGi3WLnqYN6QTFxdY8cojghR2-Mq04JzXfO1i0_xSotTpgFAKtDN9JZoqirw9lsYOVKZzGy4jNujDQ\r\n"
+      )
+  );
+  $context  = stream_context_create( $options );
+  $result = file_get_contents( $url, false, $context );
+  $response = json_decode( $result );
+  echo $result;
+}
+
+function checkIfUserExists($username) {
+  $conn = connect_db();
+
+  $sql = "SELECT * FROM chat_user WHERE username = '$username'";
+  $result = mysqli_query($conn,$sql);
+  if (mysqli_num_rows($result) != 0) {
+     return true;
+  }
+  else {
+    return false;
+  }
+  $conn->close();
+}
+
+if($_GET['code'] == 'registerClient') {
+    $token = $_GET['token'];
+    $username = $_GET['username'];
+    $email = $_GET['email'];
+
+    broadcastTopic();
+    listenTopic($token);
+
+    if(checkIfUserExists($username)) {
+      // echo 'user exists';
+      $conn = connect_db();
+
+      $sql = "UPDATE chat_user SET status='1', token='$token' WHERE username = '$username'";
+      $result = mysqli_query($conn,$sql);
+      if ($result) {
+         echo $_GET['callback'] . '(' . "{'response' : 'OKE1'}" . ')';
+      }
+      else {
+        echo $_GET['callback'] . '(' . "{'response' : 'error mysql'}" . ')';
+      }
+      $conn->close();
+    }
+    else {
+      // echo 'user not exists';
+      $conn = connect_db();
+
+      $sql = "INSERT INTO chat_user (username, email, token, status) VALUES ('$username', '$email', '$token', '1')";
+      $result = mysqli_query($conn,$sql);
+      if ($result) {
+         echo $_GET['callback'] . '(' . "{'response' : 'OKE2'}" . ')';
+      }
+      else {
+        echo $_GET['callback'] . '(' . "{'response' : 'error mysql'}" . ')';
+      }
+      $conn->close();
+    }
+}
+if($_GET['code'] == 'checkingOnlineUsers') {
+  $username = $_GET['username'];
+  $conn = connect_db();
+  $sql = "SELECT * FROM chat_user WHERE status = '1' AND username != '$username'";
+  $result = mysqli_query($conn,$sql);
+  if ($result) {
+      $data = array();
+      if ($result->num_rows > 0) {
+          // output data of each row
+          while($row = $result->fetch_assoc()) {
+              $x = array("username" => $row['username'], "token" => $row['token']);
+              array_push($data, $x);
+          }
+      } else {
+          // echo "0 results";
+      }
+      $response = array("data" => $data,
+        "response" => 'OKE'
+      );
+     echo json_encode( $response['data'] );
+
+  }
+  else {
+    echo $_GET['callback'] . '(' . "{'response' : 'error mysql'}" . ')';
+  }
+}
+if($_GET['code'] == 'sendChat') {
+  $to = $_GET['to'];
+  $message = $_GET['message'];
+  $senderUsername = $_GET['senderUsername'];
+  $url = 'https://fcm.googleapis.com/fcm/send';
+  $data = array("data" => array(
+      "message"=> $message,
+      "username" => $senderUsername,
+      "time" => date('Y-m-d H:i'),
+    ),
+    "to" => $to
+  );
+  $options = array(
+    'http' => array(
+      'method'  => 'POST',
+      'content' => json_encode( $data ),
+      'header'=>  "Content-Type: application/json\r\n" .
+                  "Authorization:key=AAAAQx0rFL4:APA91bHitlPibrVEsCmaPoG29F-09VbBjjuS6y7YQYA0hrFrk3lx4BCVC_nEL6eZbxZ5HVNE-49G8wJbooAgZGi3WLnqYN6QTFxdY8cojghR2-Mq04JzXfO1i0_xSotTpgFAKtDN9JZoqirw9lsYOVKZzGy4jNujDQ\r\n"
+      )
+  );
+
+  $context  = stream_context_create( $options );
+  $result = file_get_contents( $url, false, $context );
+  $response = json_decode( $result );
+}
+if($_GET['code'] == 'deleteOnlineUser') {
+    $token = $_GET['token'];
+    $conn = connect_db();
+
+    $sql = "UPDATE chat_user SET status='0' WHERE token='$token'";
+    $result = mysqli_query($conn,$sql);
+    if ($result) {
+       echo $_GET['callback'] . '(' . "{'response' : 'OKE1'}" . ')';
+    }
+    else {
+      echo $_GET['callback'] . '(' . "{'response' : 'error mysql'}" . ')';
+    }
+    $conn->close();
+}
diff --git a/Client2/build.xml b/Client2/build.xml
new file mode 100644
index 0000000..f29cf5b
--- /dev/null
+++ b/Client2/build.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="Client2" default="default" basedir=".">
+    <description>Builds, tests, and runs the project Client2.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties 
+      -post-init:                called after initialization of project properties 
+      -pre-compile:              called before javac compilation 
+      -post-compile:             called after javac compilation 
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-dist:                 called before archive building 
+      -post-dist:                called after archive building 
+      -post-clean:               called after cleaning build products 
+      -pre-run-deploy:           called before deploying
+      -post-run-deploy:          called after deploying
+
+    Example of pluging an obfuscator after the compilation could look like 
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Other way how to customize the build is by overriding existing main targets.
+    The target of interest are: 
+
+      init-macrodef-javac:    defines macro for javac compilation
+      init-macrodef-junit:   defines macro for junit execution
+      init-macrodef-debug:    defines macro for class debugging
+      do-dist:                archive building
+      run:                    execution of project 
+      javadoc-build:          javadoc generation 
+
+    Example of overriding the target for project execution could look like 
+
+        <target name="run" depends="<PROJNAME>-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that overridden target depends on jar target and not only on 
+    compile target as regular run target does. Again, for list of available 
+    properties which you can use check the target you are overriding in 
+    nbproject/build-impl.xml file. 
+
+    -->
+</project>
diff --git a/Client2/build/web/META-INF/MANIFEST.MF b/Client2/build/web/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/Client2/build/web/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/Client2/build/web/META-INF/context.xml b/Client2/build/web/META-INF/context.xml
new file mode 100644
index 0000000..7ecfab3
--- /dev/null
+++ b/Client2/build/web/META-INF/context.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context path="/Client2"/>
diff --git a/Client2/build/web/WEB-INF/classes/.netbeans_automatic_build b/Client2/build/web/WEB-INF/classes/.netbeans_automatic_build
new file mode 100644
index 0000000..e69de29
diff --git a/Client2/build/web/WEB-INF/classes/.netbeans_update_resources b/Client2/build/web/WEB-INF/classes/.netbeans_update_resources
new file mode 100644
index 0000000..e69de29
diff --git a/Client2/build/web/WEB-INF/glassfish-web.xml b/Client2/build/web/WEB-INF/glassfish-web.xml
new file mode 100644
index 0000000..13e0059
--- /dev/null
+++ b/Client2/build/web/WEB-INF/glassfish-web.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
+<glassfish-web-app error-url="">
+  <class-loader delegate="true"/>
+  <jsp-config>
+    <property name="keepgenerated" value="true">
+      <description>Keep a copy of the generated servlet class' java code.</description>
+    </property>
+  </jsp-config>
+</glassfish-web-app>
diff --git a/Client2/build/web/catalog.jsp b/Client2/build/web/catalog.jsp
new file mode 100644
index 0000000..9a806e1
--- /dev/null
+++ b/Client2/build/web/catalog.jsp
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>TODO supply a title</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        
+        <!--Manifest-->
+        <link rel="manifest" href="manifest.json">
+        
+        <!--AngularJS-->
+        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
+    </head>
+    <body >
+        <%
+            String username = "";
+            if (session.getAttribute("username") == null) {
+                response.sendRedirect("login.jsp");
+            }
+            else {
+                username = (String)session.getAttribute("username");
+            }
+        %>
+        <h1>Client Server</h1>
+        <div id="username" value="<%out.print(username);%>"></div>
+        <!-- Container for the Table of content -->
+        <div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
+          <div class="mdl-card__supporting-text mdl-color-text--grey-600">
+            <h3>Messages</h3>
+            <div id="messages"></div>
+            <h3>Online Users</h3>
+            <div id="onlineUsers"></div>
+            <div ng-app="clientApp" ng-controller="clientController">
+                <ul>
+                <li ng-repeat="x in onlineUsers">
+                    <input type="checkbox" ng-model="x.show">
+                    {{ x.show+ x.username + '('+x.token+')' }}
+                    <div ng-show="x.show">
+                        <form>
+                            <div id="box-{{x.username}}"></div>
+                            <input ng-model="x.message" id="message-{{x.username}}"></input>
+                            <button ng-click="sendChat(x.token, x.message, x.username)">send</button>
+                        </form>
+                    </div>
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+        <a href="logout.jsp" >logout</a></p>
+        
+        <!--Scripts-->
+        <!--Jquery-->
+        <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
+
+        <!-- Firebase -->
+        <!-- ********************************************************
+             * TODO(DEVELOPER): Update Firebase initialization code:
+                1. Go to the Firebase console: https://console.firebase.google.com/
+                2. Choose a Firebase project you've created
+                3. Click "Add Firebase to your web app"
+                4. Replace the following initialization code with the code from the Firebase console:
+        -->
+        <!-- START INITIALIZATION CODE -->
+        <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
+       
+        
+        <script>
+            var app = angular.module("clientApp", []);
+            app.controller("clientController", function($scope, $http) {
+                var cUsername = $('#username').attr('value');
+                console.log('checking online users');                
+                $http.get("http://localhost:8083/chat-server.php?code=checkingOnlineUsers&callback=?&username="+cUsername)
+                    .then(function (response) {
+                        $scope.onlineUsers = response.data;
+                    });
+                
+                $scope.sendChat = function(token, message, username) {
+                    $('#box-'+username).append("You: "+message);
+                    $('#message-'+username).val("");
+                    console.log('sending message...');
+                    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                        code: "sendChat",
+                        to: token,
+                        message: message,
+                        senderUsername: $('#username').attr('value'),
+                      },function(res){
+                          alert('Response: '+res.response);
+                    });
+                };
+                
+                $scope.updateOnlineUsers = function() {
+                    console.log('updating online users');
+                    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                        code: "checkingOnlineUsers",
+                        token: cToken,
+                      },function(res){
+                          console.log("response: "+res.data);
+                          $scope.$apply(function(){
+                            $scope.onlineUsers = res.data;
+                          });
+                    });
+                }
+            });
+        </script>
+        <script type="text/javascript" src="chat.js"></script>
+    </body>
+</html>
diff --git a/Client2/build/web/chat.js b/Client2/build/web/chat.js
new file mode 100644
index 0000000..50853aa
--- /dev/null
+++ b/Client2/build/web/chat.js
@@ -0,0 +1,235 @@
+// Initialize Firebase
+var config = {
+  apiKey: "AIzaSyAdh562gpCPSX-WYPLUmZuFhXZMMJPvD2M",
+  authDomain: "my-app-ac59b.firebaseapp.com",
+  databaseURL: "https://my-app-ac59b.firebaseio.com",
+  storageBucket: "my-app-ac59b.appspot.com",
+  messagingSenderId: "288252171454"
+};
+firebase.initializeApp(config);
+ var cToken = "";
+// [START get_messaging_object]
+// Retrieve Firebase Messaging object.
+const messaging = firebase.messaging();
+// [END get_messaging_object]
+// IDs of divs that display Instance ID token UI or request permission UI.
+const tokenDivId = 'token_div';
+const permissionDivId = 'permission_div';
+// [START refresh_token]
+// Callback fired if Instance ID token is updated.
+messaging.onTokenRefresh(function() {
+  messaging.getToken()
+  .then(function(refreshedToken) {
+    console.log('Token refreshed.');
+    // Indicate that the new Instance ID token has not yet been sent to the
+    // app server.
+    setTokenSentToServer(false);
+    // Send Instance ID token to app server.
+    sendTokenToServer(refreshedToken);
+    // [START_EXCLUDE]
+    // Display new Instance ID token and clear UI of all previous messages.
+    resetUI();
+    // [END_EXCLUDE]
+  })
+  .catch(function(err) {
+    console.log('Unable to retrieve refreshed token ', err);
+    showToken('Unable to retrieve refreshed token ', err);
+  });
+});
+// [END refresh_token]
+// [START receive_message]
+// Handle incoming messages. Called when:
+// - a message is received while the app has focus
+// - the user clicks on an app notification created by a sevice worker
+//   `messaging.setBackgroundMessageHandler` handler.
+messaging.onMessage(function(payload) {
+  console.log("Message received. ", payload);
+  // [START_EXCLUDE]
+  // Update the UI to include the received message.
+  appendMessage(payload);
+  // [END_EXCLUDE]
+});
+// [END receive_message]
+function resetUI() {
+  clearMessages();
+  showToken('loading...');
+  // [START get_token]
+  // Get Instance ID token. Initially this makes a network call, once retrieved
+  // subsequent calls to getToken will return from cache.
+  messaging.getToken()
+  .then(function(currentToken) {
+    if (currentToken) {
+      sendTokenToServer(currentToken);
+      updateUIForPushEnabled(currentToken);
+    } else {
+      // Show permission request.
+      console.log('No Instance ID token available. Request permission to generate one.');
+      // Show permission UI.
+      updateUIForPushPermissionRequired();
+      setTokenSentToServer(false);
+    }
+  })
+  .catch(function(err) {
+    console.log('An error occurred while retrieving token. ', err);
+    showToken('Error retrieving Instance ID token. ', err);
+    setTokenSentToServer(false);
+  });
+}
+// [END get_token]
+function showToken(currentToken) {
+  // Show token in console and UI.
+//  var tokenElement = document.querySelector('#token');
+//  tokenElement.textContent = currentToken;
+}
+// Send the Instance ID token your application server, so that it can:
+// - send messages back to this app
+// - subscribe/unsubscribe the token from topics
+function sendTokenToServer(currentToken) {
+  if (!isTokenSentToServer()) {
+    console.log('Sending token to server...');
+    // TODO(developer): Send the current token to your server.
+    // Send the data using post
+    console.log('sending...');              
+    console.log($('#username').attr('value'));
+    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+        code: "registerClient",
+        token: currentToken,
+        username: $('#username').attr('value'),
+        email: "null",
+      },function(res){
+        alert('Response '+res.response);
+    });
+    cToken = currentToken;
+
+    setTokenSentToServer(true);
+  } else {
+    console.log('Token already sent to server so won\'t send it again ' +
+        'unless it changes');
+  }
+}
+function isTokenSentToServer() {
+  if (window.localStorage.getItem('sentToServer') == 1) {
+        return true;
+  }
+  return false;
+}
+function setTokenSentToServer(sent) {
+  if (sent) {
+    window.localStorage.setItem('sentToServer', 1);
+  } else {
+    window.localStorage.setItem('sentToServer', 0);
+  }
+}
+function showHideDiv(divId, show) {
+  const div = document.querySelector('#' + divId);
+  if (show) {
+    div.style = "display: visible";
+  } else {
+    div.style = "display: none";
+  }
+}
+function requestPermission() {
+  console.log('Requesting permission...');
+  // [START request_permission]
+  messaging.requestPermission()
+  .then(function() {
+    console.log('Notification permission granted.');
+    // TODO(developer): Retrieve an Instance ID token for use with FCM.
+    // [START_EXCLUDE]
+    // In many cases once an app has been granted notification permission, it
+    // should update its UI reflecting this.
+    resetUI();
+    // [END_EXCLUDE]
+  })
+  .catch(function(err) {
+    console.log('Unable to get permission to notify.', err);
+  });
+  // [END request_permission]
+}
+function deleteToken() {
+  // Delete Instance ID token.
+  // [START delete_token]
+  messaging.getToken()
+  .then(function(currentToken) {
+    messaging.deleteToken(currentToken)
+    .then(function() {
+      console.log('Token deleted.');
+      setTokenSentToServer(false);
+      // [START_EXCLUDE]
+      // Once token is deleted update UI.
+//      resetUI();
+      // [END_EXCLUDE]
+        console.log('deleting token from database');
+        $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+            code: "deleteOnlineUser",
+            token: currentToken,
+          },function(res){
+            alert('Response '+res.response);
+        });
+    })
+    .catch(function(err) {
+      console.log('Unable to delete token. ', err);
+    });
+    // [END delete_token]
+  })
+  .catch(function(err) {
+    console.log('Error retrieving Instance ID token. ', err);
+    showToken('Error retrieving Instance ID token. ', err);
+  });
+}
+// Add a message to the messages element.
+function appendMessage(payload) {
+  var username = payload.data.username;
+//  const dataElement = document.createElement('p');
+  const dataElement2 = document.createElement('p');
+//  dataElement.textContent = payload.data.time;
+  dataElement2.textContent = username+": "+payload.data.message;
+//  $("#box-"+payload.data.username).append(dataElement);
+  $("#box-"+payload.data.username).append(dataElement2);
+//  const dataHeaderELement = document.createElement('h5');
+//  const dataElement = document.createElement('pre');
+//  dataElement.style = 'overflow-x:hidden;'
+//  dataHeaderELement.textContent = 'Received message:';
+//  dataElement.textContent = JSON.stringify(payload, null, 2);
+}
+// Clear the messages element of all children.
+function clearMessages() {
+  const messagesElement = document.querySelector('#messages');
+  while (messagesElement.hasChildNodes()) {
+    messagesElement.removeChild(messagesElement.lastChild);
+  }
+}
+function updateUIForPushEnabled(currentToken) {
+//  showHideDiv(tokenDivId, true);
+//  showHideDiv(permissionDivId, false);
+//  showToken(currentToken);
+}
+function updateUIForPushPermissionRequired() {
+//  showHideDiv(tokenDivId, false);
+//  showHideDiv(permissionDivId, true);
+}
+resetUI();
+
+
+function checkOnlineUsers(currentToken) {
+    console.log('checking online users...');               
+    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+        code: "checkingOnlineUsers",
+        token: cToken,
+      },function(res){
+        console.log('hell');
+        displayOnlineUsers(res);
+        alert('Response '+res.response);
+    });
+}
+
+function displayOnlineUsers(payload) {
+    const onlineUsersElement = document.querySelector('#onlineUsers');
+    const dataHeaderELement = document.createElement('h5');
+    const dataElement = document.createElement('pre');
+    dataElement.style = 'overflow-x:hidden;'
+    dataHeaderELement.textContent = 'Received message:';
+    dataElement.textContent = JSON.stringify(payload, null, 2);
+    onlineUsersElement.appendChild(dataHeaderELement);
+    onlineUsersElement.appendChild(dataElement);
+}
\ No newline at end of file
diff --git a/Client2/build/web/gfv3ee6.dpf b/Client2/build/web/gfv3ee6.dpf
new file mode 100644
index 0000000..e69de29
diff --git a/Client2/build/web/index.html b/Client2/build/web/index.html
new file mode 100644
index 0000000..1e12903
--- /dev/null
+++ b/Client2/build/web/index.html
@@ -0,0 +1,344 @@
+<!DOCTYPE html>
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>TODO supply a title</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        
+        <!--Manifest-->
+        <link rel="manifest" href="manifest.json">
+        
+        <!--AngularJS-->
+        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
+    </head>
+    <body >
+        <h1>Client Server</h1>
+        <!-- Container for the Table of content -->
+        <div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
+          <div class="mdl-card__supporting-text mdl-color-text--grey-600">
+            <!-- div to display the generated Instance ID token -->
+            <div id="token_div" style="display: none;">
+              <h4>Instance ID Token</h4>
+              <p id="token" style="word-break: break-all;"></p>
+              <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
+                      onclick="deleteToken()">Delete Token</button>
+            </div>
+            <!-- div to display the UI to allow the request for permission to
+                 notify the user. This is shown if the app has not yet been
+                 granted permission to notify. -->
+            <div id="permission_div" style="display: none;">
+              <h4>Needs Permission</h4>
+              <p id="token"></p>
+              <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
+                      onclick="requestPermission()">Request Permission</button>
+            </div>
+            <button onclick="checkOnlineUsers()">Check Online Users</button>
+            <!-- div to display messages received by this app. -->
+            <h3>Messages</h3>
+            <div id="messages"></div>
+            <h3>Online Users</h3>
+            <div id="onlineUsers"></div>
+            <div ng-app="clientApp" ng-controller="clientController">
+                <ul>
+                <li ng-repeat="x in onlineUsers">
+                  {{ x.username + '('+x.token+')' }}
+                  
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+        
+        
+        <!--Scripts-->
+        <!--Jquery-->
+        <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
+        
+        <script>
+            var app = angular.module("clientApp", []);
+            app.controller("clientController", function($scope, $http) {
+//                console.log('checking online users');
+//                $scope.onlineUsers = "a";
+//                var y = 's';
+//                $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+//                    code: "checkingOnlineUsers",
+//                    token: cToken,
+//                  },function(res){
+//                      
+//                      console.log("response: "+res.data);
+//                      var x = String(res.data);
+//                      y = x.split(",");
+//                      $scope.$apply(function(){
+//                        $scope.onlineUsers = res.data;
+//                      });
+//                      console.log(y);
+//                      $scope.onlineUsers = y;
+//                });
+//                console.log(y);
+//                $scope.onlineUsers = y;
+                
+                $http.get("http://localhost:8083/chat-server.php?code=checkingOnlineUsers&callback=?")
+                    .then(function (response) {
+                        $scope.onlineUsers = response.data;
+                    });
+                
+                $scope.sendChat = function(token) {
+                    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                        code: "sendChat",
+                        to: token,
+                      },function(res){
+                          alert('Response: '+res.response);
+                    });
+                };
+            });
+        </script>
+
+        <!-- Firebase -->
+        <!-- ********************************************************
+             * TODO(DEVELOPER): Update Firebase initialization code:
+                1. Go to the Firebase console: https://console.firebase.google.com/
+                2. Choose a Firebase project you've created
+                3. Click "Add Firebase to your web app"
+                4. Replace the following initialization code with the code from the Firebase console:
+        -->
+        <!-- START INITIALIZATION CODE -->
+        <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
+        <script>
+            // Initialize Firebase
+            var config = {
+              apiKey: "AIzaSyAdh562gpCPSX-WYPLUmZuFhXZMMJPvD2M",
+              authDomain: "my-app-ac59b.firebaseapp.com",
+              databaseURL: "https://my-app-ac59b.firebaseio.com",
+              storageBucket: "my-app-ac59b.appspot.com",
+              messagingSenderId: "288252171454"
+            };
+            firebase.initializeApp(config);
+        </script>
+        
+        
+        <!-- END INITIALIZATION CODE -->
+        <!-- ******************************************************** -->
+        <script>
+            var cToken = "";
+            // [START get_messaging_object]
+            // Retrieve Firebase Messaging object.
+            const messaging = firebase.messaging();
+            // [END get_messaging_object]
+            // IDs of divs that display Instance ID token UI or request permission UI.
+            const tokenDivId = 'token_div';
+            const permissionDivId = 'permission_div';
+            // [START refresh_token]
+            // Callback fired if Instance ID token is updated.
+            messaging.onTokenRefresh(function() {
+              messaging.getToken()
+              .then(function(refreshedToken) {
+                console.log('Token refreshed.');
+                // Indicate that the new Instance ID token has not yet been sent to the
+                // app server.
+                setTokenSentToServer(false);
+                // Send Instance ID token to app server.
+                sendTokenToServer(refreshedToken);
+                // [START_EXCLUDE]
+                // Display new Instance ID token and clear UI of all previous messages.
+                resetUI();
+                // [END_EXCLUDE]
+              })
+              .catch(function(err) {
+                console.log('Unable to retrieve refreshed token ', err);
+                showToken('Unable to retrieve refreshed token ', err);
+              });
+            });
+            // [END refresh_token]
+            // [START receive_message]
+            // Handle incoming messages. Called when:
+            // - a message is received while the app has focus
+            // - the user clicks on an app notification created by a sevice worker
+            //   `messaging.setBackgroundMessageHandler` handler.
+            messaging.onMessage(function(payload) {
+              console.log("Message received. ", payload);
+              // [START_EXCLUDE]
+              // Update the UI to include the received message.
+              appendMessage(payload);
+              // [END_EXCLUDE]
+            });
+            // [END receive_message]
+            function resetUI() {
+              clearMessages();
+              showToken('loading...');
+              // [START get_token]
+              // Get Instance ID token. Initially this makes a network call, once retrieved
+              // subsequent calls to getToken will return from cache.
+              messaging.getToken()
+              .then(function(currentToken) {
+                if (currentToken) {
+                  sendTokenToServer(currentToken);
+                  updateUIForPushEnabled(currentToken);
+                } else {
+                  // Show permission request.
+                  console.log('No Instance ID token available. Request permission to generate one.');
+                  // Show permission UI.
+                  updateUIForPushPermissionRequired();
+                  setTokenSentToServer(false);
+                }
+              })
+              .catch(function(err) {
+                console.log('An error occurred while retrieving token. ', err);
+                showToken('Error retrieving Instance ID token. ', err);
+                setTokenSentToServer(false);
+              });
+            }
+            // [END get_token]
+            function showToken(currentToken) {
+              // Show token in console and UI.
+              var tokenElement = document.querySelector('#token');
+              tokenElement.textContent = currentToken;
+            }
+            // Send the Instance ID token your application server, so that it can:
+            // - send messages back to this app
+            // - subscribe/unsubscribe the token from topics
+            function sendTokenToServer(currentToken) {
+              if (!isTokenSentToServer()) {
+                console.log('Sending token to server...');
+                // TODO(developer): Send the current token to your server.
+                // Send the data using post
+                var url = 'http://localhost:8083/chat-server.php';
+                console.log('sending...');               
+                $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                    code: "registerClient",
+                    token: currentToken,
+                    username: "user1",
+                    email: "user1@gmail.com",
+                  },function(res){
+                    alert('Response '+res.response);
+                });
+                cToken = currentToken;
+                
+                setTokenSentToServer(true);
+              } else {
+                console.log('Token already sent to server so won\'t send it again ' +
+                    'unless it changes');
+              }
+            }
+            function isTokenSentToServer() {
+              if (window.localStorage.getItem('sentToServer') == 1) {
+                    return true;
+              }
+              return false;
+            }
+            function setTokenSentToServer(sent) {
+              if (sent) {
+                window.localStorage.setItem('sentToServer', 1);
+              } else {
+                window.localStorage.setItem('sentToServer', 0);
+              }
+            }
+            function showHideDiv(divId, show) {
+              const div = document.querySelector('#' + divId);
+              if (show) {
+                div.style = "display: visible";
+              } else {
+                div.style = "display: none";
+              }
+            }
+            function requestPermission() {
+              console.log('Requesting permission...');
+              // [START request_permission]
+              messaging.requestPermission()
+              .then(function() {
+                console.log('Notification permission granted.');
+                // TODO(developer): Retrieve an Instance ID token for use with FCM.
+                // [START_EXCLUDE]
+                // In many cases once an app has been granted notification permission, it
+                // should update its UI reflecting this.
+                resetUI();
+                // [END_EXCLUDE]
+              })
+              .catch(function(err) {
+                console.log('Unable to get permission to notify.', err);
+              });
+              // [END request_permission]
+            }
+            function deleteToken() {
+              // Delete Instance ID token.
+              // [START delete_token]
+              messaging.getToken()
+              .then(function(currentToken) {
+                messaging.deleteToken(currentToken)
+                .then(function() {
+                  console.log('Token deleted.');
+                  setTokenSentToServer(false);
+                  // [START_EXCLUDE]
+                  // Once token is deleted update UI.
+                  resetUI();
+                  // [END_EXCLUDE]
+                })
+                .catch(function(err) {
+                  console.log('Unable to delete token. ', err);
+                });
+                // [END delete_token]
+              })
+              .catch(function(err) {
+                console.log('Error retrieving Instance ID token. ', err);
+                showToken('Error retrieving Instance ID token. ', err);
+              });
+            }
+            // Add a message to the messages element.
+            function appendMessage(payload) {
+              const messagesElement = document.querySelector('#messages');
+              const dataHeaderELement = document.createElement('h5');
+              const dataElement = document.createElement('pre');
+              dataElement.style = 'overflow-x:hidden;'
+              dataHeaderELement.textContent = 'Received message:';
+              dataElement.textContent = JSON.stringify(payload, null, 2);
+              messagesElement.appendChild(dataHeaderELement);
+              messagesElement.appendChild(dataElement);
+            }
+            // Clear the messages element of all children.
+            function clearMessages() {
+              const messagesElement = document.querySelector('#messages');
+              while (messagesElement.hasChildNodes()) {
+                messagesElement.removeChild(messagesElement.lastChild);
+              }
+            }
+            function updateUIForPushEnabled(currentToken) {
+              showHideDiv(tokenDivId, true);
+              showHideDiv(permissionDivId, false);
+              showToken(currentToken);
+            }
+            function updateUIForPushPermissionRequired() {
+              showHideDiv(tokenDivId, false);
+              showHideDiv(permissionDivId, true);
+            }
+            resetUI();
+        </script>
+        <script>
+            function checkOnlineUsers(currentToken) {
+                console.log('checking online users...');               
+                $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                    code: "checkingOnlineUsers",
+                    token: cToken,
+                  },function(res){
+                    console.log('hell');
+                    displayOnlineUsers(res);
+                    alert('Response '+res.response);
+                });
+            }
+            
+            function displayOnlineUsers(payload) {
+                const onlineUsersElement = document.querySelector('#onlineUsers');
+                const dataHeaderELement = document.createElement('h5');
+                const dataElement = document.createElement('pre');
+                dataElement.style = 'overflow-x:hidden;'
+                dataHeaderELement.textContent = 'Received message:';
+                dataElement.textContent = JSON.stringify(payload, null, 2);
+                onlineUsersElement.appendChild(dataHeaderELement);
+                onlineUsersElement.appendChild(dataElement);
+            }
+        </script>
+    </body>
+</html>
diff --git a/Client2/build/web/login.jsp b/Client2/build/web/login.jsp
new file mode 100644
index 0000000..3b582c3
--- /dev/null
+++ b/Client2/build/web/login.jsp
@@ -0,0 +1,31 @@
+<%-- 
+    Document   : login2
+    Created on : Nov 29, 2016, 5:49:15 AM
+    Author     : YUKI
+--%>
+
+<%@page contentType="text/html" pageEncoding="UTF-8"%>
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <title>JSP Page</title>
+    </head>
+    <body>
+        <form method="POST" action="login.jsp" id="loginForm">
+            Email or Username<br><input type="text" name="username" /><br>
+            Password<br><input type="password" name="password"  /><br>
+            <input type="submit" value="LOGIN" name="login" />
+        </form>
+    </body>
+</html>
+<% 
+    if("POST".equalsIgnoreCase(request.getMethod())) {
+        String username = request.getParameter("username");
+        
+        session.setAttribute("username", username);
+//        session.setAttribute("firebaseToken", firebaseToken);
+        response.sendRedirect("catalog.jsp");
+    }
+%>
+        
\ No newline at end of file
diff --git a/Client2/build/web/logout.jsp b/Client2/build/web/logout.jsp
new file mode 100644
index 0000000..c9a81d2
--- /dev/null
+++ b/Client2/build/web/logout.jsp
@@ -0,0 +1,24 @@
+<%-- 
+    Document   : logout
+    Created on : Nov 29, 2016, 6:53:05 AM
+    Author     : YUKI
+--%>
+
+<%@page contentType="text/html" pageEncoding="UTF-8"%>
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <title>JSP Page</title>
+    </head>
+    <body>
+        <h1>Hello World!</h1>
+    </body>
+    <!--Jquery-->
+    <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
+    <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
+    <script type="text/javascript" src="chat.js"></script>
+    <script>
+        deleteToken();
+    </script>
+</html>
diff --git a/Client2/build/web/manifest.json b/Client2/build/web/manifest.json
new file mode 100644
index 0000000..51ef539
--- /dev/null
+++ b/Client2/build/web/manifest.json
@@ -0,0 +1,5 @@
+{
+  "//": "Some browsers will use this to enable push notifications.",
+  "//": "It is the same for all projects, this is not your project's sender ID",
+  "gcm_sender_id": "103953800507"
+}
\ No newline at end of file
diff --git a/Client2/dist/Client2.war b/Client2/dist/Client2.war
new file mode 100644
index 0000000000000000000000000000000000000000..68729146cc6d6f93ba36df4d02fd5117c9492d16
GIT binary patch
literal 17514
zcmeHPOLH4Za>nk?+G~UrvEkUm9!u~>0NhnKNJ^aHa7c|QJ~Ytq6(TrK%bZ4c0cf$&
zh3#$-!i*K+IXc3B!Vz=y#Rp$(AAPa+<R9USBla&i{AE>FSHD0}qxB;;gc*oHcU4wq
zR#sN#m(@7?_($(F8;zed8rOGT_8Pg@A2r@-93S*|t=`FD_rLzF(KySR&d~Jl-nsny
z5t`HcXLx5#k9SXchX?0<`}pwK3H>3D6YCQm#l8r)*qXh1r@0&EuIx@7cgz{C;pY4H
zdv}_95qA>qS&tUfe$!sPe6VT_);Cz^G;-X4vpo?_MdT!)xN@g?r)d}~%K)(&pB_At
zA}nw9(_AYzaN?N9-D2y1{*9PDLMwU~gmp!j@E3{wViIhBh=16%l60p9Nn4DEuJHVD
zw9~riA6lEO4<9zS_f!`)b&~N;tGgHYJWSSG-G?PPHvfI{k6-<`(V+KTjGHNV=tq3u
z#N3+jICe%LZ^d)_dED)?FVFkCPy5Ud{ls?y|7(7!8(;e2Wjue@M5D+4HD?KQ9`oqh
zcR8Dj=!!?oaa|B(iC~B62<%voU{l8vkx)k`VGA*1t`jm51`9Tec})*C<`KWg1O|%C
z?Z6*IPUQ2L=s6K*p-7l>?f8K+z|8t#4P$oGpJ2X|b2sv*N!)3VlVloib-VNV+#baV
z48gTsG3jbqp^E$VhP|F$u$<`>3Tm%>@aCj4rKbc*kY1*5$$q9j3|lV}8!RyYag4c3
z8xWa{^f?bb9`!uCsYSBQl<rQaoo||qwJXirTdcjlxw*cvzV_bQgN+C6=1WLSl%Mhh
zO2@Qg&ioK63o-3tXyzrGXch}K#eO1Zc<h88CT8HcSEESGLeDVDW4j6aj}yZ<+hG~U
z8G9Wt0Uo|QIN8VGOD&Vy^oG*3=3*9jEby;jZi2b9I1v*VGZ~9N^j*2~VW?z@WJ3{m
zIc(a?snYPvI-l|ZlQR)BHxMz}iAdTVtZfj9IhFw%3XHNsvlmJZ;xVy6EW!2yKEV>j
zO+RL0N^ZvqAagPnm?4r(tvWO2rP5mTteGjnj(PGZQ=(Eg|41q~>I`S0OJqA!XAua;
zTVXW8q+1biI}oEz`%A6Y@~VG^$xX#K45Tx{S^FOBOws%RB*E-ntv2OqO~*_MdhYuP
z=6{E^4fm;A;7s0Y6Jccs`T04Oii**bWMOO|JoxiEDs;zg-;=F;5JD@nav{91r{SoL
z+b?0v46~igq7cq27}^mZ`EjDQ0vmHShl|QAq?2byvZ}^l1^H4wVWYHIXg0}CjVjGt
z7Po}FduDLYdYf4`PsUDeSOaME);qt6qc`hKxqInUGM_{1+xWb<-kD;Dx84~_c<Y^i
zkG=EH;ho=l<+m|2Vu!ae^V^sidE48V`Tr(nzO!=Yul~YrH0TY`so^8dePNFifG2nN
zPxtztpB*sz29)HkWi|WA{g6qG2y{T|6#%OUfi;Y|gY5Vo?g?ab>?pnbk-QvJ5_lGg
z=iE)`@03Rg;0C))EaAxO05c(94FFT5wE98>G5br_Pw&P}WN66wkQGwsm~~2V3hw!d
zi0r0ifn&uur8?Wh;X|3v$gc^dP!Id3`=>0PO{aiN944=AchxP^6j`N1LPtm!HE5Kh
zByWe#gzvPjeLg2tq(!+`g8X!+HTOM0N**Ur$C6*}>4e*gT_@l>1WFllW>{!D!|EUl
zaZRu7zz?sGa0NT9Nebn)*f`=t^Bt>6gelGKt`U5jvbr3l@!CU$bg^@wPCP=}wcKqm
z09Y?f96yxVcqH}Rm!J@Eic~~KidL+FInTdFLJt%L+<1ZII+4fdLp*joF}JLBZz{jL
zJV3fmE%3pz*48aoR4-Tw4F)Wu)X?&He3gi4PH**NUtZGWVnzs%BT!J05`l>1SIZhj
zd||!2nx6uxWfGo*0oLL9G0buyr5|zVf{;+)ODSa2+ef1-SYuuhk_Pqny`7f4eTi=^
z7AFf#c`GHkg{(K^9~8upJ;x6o=IQr|K4#~E(X`U|Hn1!`Kt>$Up=S*M*j{Y`OTiz@
z2?7kV-JMqY4`xXs!u*t_S4id0V=MPfeYC8|@d>Y?2Ko}_PDI>mWp<#r)BlRlg`c>B
z*c`LTr8J$D*28`Im8H@tVnq(OyU<$c(vq3E=+Rt3QZbh^74cus0CNLHiWnTu#0Rnm
zNfS|JQeqNneu0}tHtUmX!~cX{0Gu02f|Qz$omiq&3mD~q^RP;56ggP=UU5hTZY=EO
zCSo{zT{}79+>6;+CgCg1<o|&kq;q4KCTn<_PMEp6-F*X_P^bfs4H5}_SMFJu$Qx!t
z_oMYvGQQG<($~xuvJbRjrT}@~H_+uLFwSUExEf0+oyC#6)6!@<Diz#*F55~pU469f
z+iUo5;)n3`Eo>(VA4Pt$*lEGdu5Y|+jX(J${M_+(_n-Dp*U!Gbcs!XMJ&86S9bKG1
zf86^b-v9jZr1#|LdVR3DgS{#eaV#Pq$iq&{fk#?Q#4INH6-#FQ5$6W0DR57Be)&CL
znZl&Q_$8xVxwC)p$-&X-*}>D5Ep{>WC@eVCC6ElQlc+OxB9CtsiGb3Y%^m|cC+Ixa
z6}uJzxLb&6RKX&>VC!tu9tkl5!t0`VQK7kRvpp5zIEI^P8rh%#(*~UHs!~~{?|t+o
zH^^GMo@aW4L3E7RTp{9BANs%snv4wy)d7-ZD9FXBB1MYZ8!fQ8pNwTQ(g_<zVp1=D
z#$9C+6>i=;>GgZNN4+n0`@Pc>ws*RJP;g$`b=G=g?dM&4EklsWZ0pRcY;R-_fM0tC
zEYv2D@lQ>zort25p+CxyZMv*p&eZ>y1Lbb*_P%z`7rWkg<K6Yqbnoo^GwajO&yFr8
zU(622pM7zB{N(I<fBm?n0qKmuEE(^M38EknnJlPoWjXG~`-9A6$f3YoDm`Je4iyD2
zo*tpAHn>_6zNn>uB1`0q_@kM7#gp>z7&e}Yq_$&*x$3eNI_Jw!MKc44ucf8G*;2^X
z8Q(>LOQ{%uylz`{5ZSHlgLD~$-oMhK-o%5{*`{$@#IJ$+M?AUA)N?5Yl$AWo_)Xhp
z#W`(ortHd87rW4fyvS{8Zd!GkCDP2T80zh#&NZZvG%d2}s5BoZ%0QDL5<<+Q;~x`Q
z;6@$OveUkQ-SeoTB)?G%B1=eyT_vC)mUS?fYI+&1BSDFHJie6lE9%}u+(zXcX?my`
z4r{_|#A7qL51_zj_+qBeX^XH=f$~!|l&RpU(p`NYC|`E!tQ3ecX2aQrhDORi_hjoT
z#ZqZdw!$1pp}A*MnLEz_eU_fhqtYpPcGOMDy@z~WBYQdSM5T?2pK@=jqYKv{PZA)Q
zt=vWyE4hPbzz3E2b%st5^Lif1gVeA@!S;=#gi2M}5ScQR25a@9s<xL0pY0u8>>m`(
zBvsjdnvK;fil6};N5O_bt6)g^0Gme0z7f&r0xW=s@>IYyd2-RCx=Z;MnJ`xAGM-*m
z><07cj*a2)D0-!}T!b>IhDuRLRfhsHZDE!vxkS;JC{_8R97Srh)BgTssLYxdy!<^?
zf;Q+St2nK>r=|bY$@1bXf|9DRBW%T<NpXyhxDg*=x{y1~vGR)X9C}#*XwsIHnq}t;
z=3{_Ga_Nvc(n68v1`6WH?zFlny@P!q3WGNd>Es1<%GacI_(rEe9IT<-VVp8a#=gq-
zk(-KDUx6z+uu)ozrmqN(<(VFCtVSOYNDK95ZpaVo0|>3OTc!+~wTfp8OuyU?xXhHH
zr8LkcRjGU$lN8JlNz#=}<%)A&UPe$QT!j`zOHec{#m3V0wA}9Gaf*7A(kC^*V7iK{
zS|gW`au!!td2S8SQ4cCU+BGg43QA3!wrsgBi^eUbdkk!#vMJlRB%^fzjWP+HI9JF`
z9r*i%j(Xu-PY~c_7M%goKENv&oTMGk1~H|{aQ@Um9t_hv7-D}oyYwW6jQm|X#aEss
zHF+eW?)a*$&z(h)+$-RR>RcIi>&~m%Fxs(78$zK^*-XfC)pmc;I~38`EFK?7FX<J>
zs`h)yIQFuN2@pX{;5po79-K+Tq_UQ%b$+R}PegT6%^^8T(G=Wd!Xet8HC%{^<uwMi
zgr{<xM$IbPILi<p8XB3gSG8;E_FCKh%aY0cPIkB5khU&_q{5X`P7a=Yc53Ie1<18z
z-)fUPkfd^bYu4KG&GPoKPuUd}RYR^o$L=+bAahB^vlOhoVx8JDB`qqKq{fFW%B#ff
zD&v(+57KjRJIuprIXV(&OSI@5(5j2%vD5xj*{&LY=DXVjjqj<F1(JX~tHt$IQGyH(
zX>+K|f<iU0Ct$aA=pbDhklrhuW~|xh$yMmRK9<M6RH%z>AM^?)3cXn<;0y>k81U{a
z%s$I4OQ}=AAY$sfaiO!BrJH?IWwyxU-Sy)>MP|@|38Po){A0n7kis&HC$SKbp!8C^
z-$;ig!7$X1ctCYCfMJ=+(`izRhe$~rDWz8sl>7i$80nQJi+~BlLd3^Z#7U(s0V=a7
zpnQ-}3moeW1ooRT+HP&GZr<;r8kSh;NYn9@4gwZmzp$O>&I@@aws?cSf%F#MWuQeh
zB;K~Zk&s?n9VO(Es#0N9%lX_Y80gF8WcrIKfW9_W!=~sA4bV|Um)~Vi&QDLy*fucB
zGu8o|#v>OvO*xcT48=2f2760eONZ#Kd{YrwwU&zZFs;dKI8<;PwPzh!o`eO{Kr--*
zB4<%QB2hwRFiJYDb2WIY6rby{mIyE1tzq~EX47G$Q(ZcU8m%mF*+EjPa+~_yCy8d&
zTyyERU06PH$w4{5SiJ?Pt1MVqA~}}12>-mD&<&snIEg%Rp!YWWRfRF)wml02I$cl4
zs%1@Eo<^rT=2i4~#c$dokdM^3f?BTu;1+dI93RGVI#=Kx#bG^Eu{&)NN2kl}6}Gd(
z*6RETF_(sUq{*U(#);gLtU4m348Pd6*fNu*Hew*&s?3lhtiQux`&Cgvx<=G{kh91c
zq*xZky$;#cD%pZ^mMH)+;zz#6fpK+!g!Me^S-4acpG-56W#Sw5UsxYC>3J1qr1okF
zGwNZ>VlkYsDHmV+v5$&)>(<(;Cqq@|DvjHyCJmQO@Y$)?icV46X<RI~nk-_i-R<C>
zGXO!x(w8QdepcWukNMRwRBBrS@~Zq+B7JjQJ)bG0mEGDf9=uof>8BdX0m@K~j;Jh6
z59!E)&Eej0H37-=u`FMgTTL%yI0mwi+X`VC$RATwgP;(qQ8QhVF2Ec{w>XbdjQ}t>
zOrD<jP)Qit!~_WdmZHE?MldLnSGmq|@Un?YZvPjNG<eng>>)f-Wqv%>P>ZBhw=<dm
zit$quTWXF=yh!1&LuE4n@$~pZ#Wu=H%?yDllJ&^L?>?_L6!W6wlY?sba*M@QT5f7b
zS0mKp<gb~-DnpZH%;hUbHaex%B11|-6jK(o!Ph6@H<<S;4IG<VjlymR7nhV~kY2^L
zlH!I0x@z4SyEj@@g=716{1$??H%r;EK}s9xwBLYES^nah#R{XEyaAZuEhtY?D*!kh
zvT2!H7q*rxV5$c`D@$HQ3!3IFGI!myn!Klh2T~<<!t&rqJr0)(L)0;ZbQC<Fxp5Pf
z8fHrUQADW{pj<8OnguIufpm6=oXUE!HTFG^haZ&FL+V!GyM#X=Xh@%)OEs`nDn=qa
z%8gtEFDSJGGZD5Zf4I<3@7-hJi~!d4N)V=%tmROXxd(*G>r@zh?cOQXQooAz?a7i=
zoyqAUmP-r)hAnOmnF-38*RiT10O0<gv^@phb;^1}xFMBxf`cdEpvr=d+IXy09q|c_
zMX9<>4rfRcd8eeha(+`(Wu}kYK*tp&QIN0Wez`5|tKh#jU(Gi*!BpC#zMM*3lq)N2
zqQyw*b^@6IoC0ix{@z-i<=koMD+1N1pvY*=##lTag2R0B^fAsS%G2b<CpVw{!{2`R
zPdI%}?>l(wqs{Ut^EYt2t!}r4Gc4y~f(M_~1H!SYcu*8AODb^MToqEMs1_8eda*4J
z=cGh>3GMf^+F~5rmM272omiewj{!5K=RXlKDo`yw;?>5HP#_DaA@=qa!I3+;RF^J&
zj~HBAz5o8k{ms?Yjn(&B&6j5%|KNu|`_b|rbAYIL{j~AhUHY5-oPhdi2h+9g#~r8x
zy}tYQSNJ#Un)|7Tn+B&}VNfp`{9o`<KP-DwFZxvm^`c(?iI2LM`Hcp{HU08K`Bxfr
z|L?y2`44hjV?)!w*-#!o|4=Xe=7N5G_wC>0Dd<B><!7;PBF8i>{Dm6-(1`PWsL?ZR
z`t{wn|N6(vpKvSlRDK4-P`Uh*{1X}Fe&tnT`u)eBmDbSN$3Ol9y4}QofBnNo<2Taa
F{u?8H$v^-A

literal 0
HcmV?d00001

diff --git a/Client2/manifest.json b/Client2/manifest.json
new file mode 100644
index 0000000..51ef539
--- /dev/null
+++ b/Client2/manifest.json
@@ -0,0 +1,5 @@
+{
+  "//": "Some browsers will use this to enable push notifications.",
+  "//": "It is the same for all projects, this is not your project's sender ID",
+  "gcm_sender_id": "103953800507"
+}
\ No newline at end of file
diff --git a/Client2/nbproject/ant-deploy.xml b/Client2/nbproject/ant-deploy.xml
new file mode 100644
index 0000000..5d33e0d
--- /dev/null
+++ b/Client2/nbproject/ant-deploy.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright (c) 2008, 2016 Oracle and/or its affiliates. All rights reserved.
+
+Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+Other names may be trademarks of their respective owners.
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+
+Contributor(s):
+-->
+<project default="-deploy-ant" basedir=".">
+    <target name="-init-cl-deployment-env" if="deploy.ant.enabled">
+        <property file="${deploy.ant.properties.file}" />
+        <available file="${deploy.ant.docbase.dir}/WEB-INF/sun-web.xml" property="sun.web.present"/>
+        <available file="${deploy.ant.docbase.dir}/WEB-INF/glassfish-web.xml" property="glassfish.web.present"/>
+        <available file="${deploy.ant.resource.dir}" property="has.setup"/>
+        <tempfile prefix="gfv3" property="gfv3.password.file" destdir="${java.io.tmpdir}"/>  <!-- do not forget to delete this! -->
+        <echo message="AS_ADMIN_PASSWORD=${gfv3.password}" file="${gfv3.password.file}"/>
+    </target>
+
+    <target name="-parse-sun-web" depends="-init-cl-deployment-env" if="sun.web.present">
+        <tempfile prefix="gfv3" property="temp.sun.web" destdir="${java.io.tmpdir}"/>
+        <copy file="${deploy.ant.docbase.dir}/WEB-INF/sun-web.xml" tofile="${temp.sun.web}"/>
+        <!-- The doctype triggers resolution which can fail -->
+        <replace file="${temp.sun.web}">
+            <replacetoken><![CDATA[<!DOCTYPE]]></replacetoken>
+            <replacevalue><![CDATA[<!-- <!DOCTYPE]]></replacevalue>
+        </replace>
+        <replace file="${temp.sun.web}">
+            <replacetoken><![CDATA[<sun-web-app]]></replacetoken>
+            <replacevalue><![CDATA[--> <sun-web-app]]></replacevalue>
+        </replace>
+        <xmlproperty file="${temp.sun.web}" validate="false">
+        </xmlproperty>    
+        <delete file="${temp.sun.web}"/>
+        <condition property="deploy.ant.client.url" value="${gfv3.url}${sun-web-app.context-root}" else="${gfv3.url}/${ant.project.name}">
+            <isset property="sun-web-app.context-root"/>
+        </condition>
+        <condition property="deploy.context.root.argument" value="&amp;contextroot=${sun-web-app.context-root}" else="/${ant.project.name}">
+            <isset property="sun-web-app.context-root"/>
+        </condition>
+    </target>
+    <target name="-parse-glassfish-web" depends="-init-cl-deployment-env" if="glassfish.web.present">
+        <tempfile prefix="gfv3" property="temp.gf.web" destdir="${java.io.tmpdir}"/>
+        <copy file="${deploy.ant.docbase.dir}/WEB-INF/glassfish-web.xml" tofile="${temp.gf.web}"/>
+        <!-- The doctype triggers resolution which can fail -->
+        <replace file="${temp.gf.web}">
+            <replacetoken><![CDATA[<!DOCTYPE]]></replacetoken>
+            <replacevalue><![CDATA[<!-- <!DOCTYPE]]></replacevalue>
+        </replace>
+        <replace file="${temp.gf.web}">
+            <replacetoken><![CDATA[<glassfish-web-app]]></replacetoken>
+            <replacevalue><![CDATA[--> <glassfish-web-app]]></replacevalue>
+        </replace>
+        <xmlproperty file="${temp.gf.web}" validate="false">
+        </xmlproperty>
+        <delete file="${temp.gf.web}"/>
+        <condition property="deploy.ant.client.url" value="${gfv3.url}${glassfish-web-app.context-root}" else="${gfv3.url}/${ant.project.name}">
+            <isset property="glassfish-web-app.context-root"/>
+        </condition>
+        <condition property="deploy.context.root.argument" value="&amp;contextroot=${glassfish-web-app.context-root}" else="/${ant.project.name}">
+            <isset property="glassfish-web-app.context-root"/>
+        </condition>
+    </target>
+    <target name="-no-parse-sun-web" depends="-init-cl-deployment-env" unless="sun.web.present">
+        <property name="deploy.context.root.argument" value=""/>
+    </target>
+    <target name="-add-resources" depends="-init-cl-deployment-env" if="has.setup">
+        <tempfile prefix="gfv3" property="gfv3.resources.dir" destdir="${java.io.tmpdir}"/>
+        <mkdir dir="${gfv3.resources.dir}"/>
+        <mkdir dir="${gfv3.resources.dir}/META-INF"/>
+        <copy todir="${gfv3.resources.dir}/META-INF">
+            <fileset dir="${deploy.ant.resource.dir}"/>
+        </copy>
+        <jar destfile="${deploy.ant.archive}" update="true">
+            <fileset dir="${gfv3.resources.dir}"/>
+        </jar>
+        <delete dir="${gfv3.resources.dir}"/>
+    </target>
+    <target name="-deploy-ant" depends="-parse-glassfish-web, -parse-sun-web, -no-parse-sun-web,-add-resources" if="deploy.ant.enabled">
+        <antcall target="-deploy-without-pw"/>
+        <antcall target="-deploy-with-pw"/>
+    </target>
+
+    <target name="-deploy-without-pw" unless="gfv3.password">
+        <echo message="Deploying ${deploy.ant.archive}"/>
+        <tempfile prefix="gfv3" property="gfv3.results.file" destdir="${java.io.tmpdir}"/>  <!-- do not forget to delete this! -->
+        <property name="full.deploy.ant.archive" location="${deploy.ant.archive}"/>
+        <get src="${gfv3.admin.url}/__asadmin/deploy?path=${full.deploy.ant.archive}${deploy.context.root.argument}&amp;force=true&amp;name=${ant.project.name}"
+            dest="${gfv3.results.file}"/>
+        <delete file="${gfv3.results.file}"/>    
+    </target>
+    <target name="-deploy-with-pw" if="gfv3.password">
+        <echo message="Deploying ${deploy.ant.archive}"/>
+        <tempfile prefix="gfv3" property="gfv3.results.file" destdir="${java.io.tmpdir}"/>  <!-- do not forget to delete this! -->
+        <property name="full.deploy.ant.archive" location="${deploy.ant.archive}"/>
+        <get username="${gfv3.username}" password="${gfv3.password}" src="${gfv3.admin.url}/__asadmin/deploy?path=${full.deploy.ant.archive}${deploy.context.root.argument}&amp;force=true&amp;name=${ant.project.name}"
+            dest="${gfv3.results.file}"/>
+        <delete file="${gfv3.results.file}"/>
+    </target>
+    <target name="-undeploy-ant" depends="-init-cl-deployment-env" if="deploy.ant.enabled">
+        <antcall target="-undeploy-without-pw"/>
+        <antcall target="-undeploy-with-pw"/>
+    </target>
+
+    <target name="-undeploy-without-pw" unless="gfv3.password">
+        <echo message="Undeploying ${deploy.ant.archive}"/>
+        <tempfile prefix="gfv3" property="gfv3.results.file" destdir="${java.io.tmpdir}"/>  <!-- do not forget to delete this! -->
+        <get src="${gfv3.admin.url}/__asadmin/undeploy?name=${ant.project.name}"
+            dest="${gfv3.results.file}"/>
+        <delete file="${gfv3.results.file}"/>    
+    </target>
+    <target name="-undeploy-with-pw" if="gfv3.password">
+        <echo message="Undeploying ${deploy.ant.archive}"/>
+        <tempfile prefix="gfv3" property="gfv3.results.file" destdir="${java.io.tmpdir}"/>  <!-- do not forget to delete this! -->
+        <get username="${gfv3.username}" password="${gfv3.password}" src="${gfv3.admin.url}/__asadmin/undeploy?name=${ant.project.name}"
+            dest="${gfv3.results.file}"/>
+        <delete file="${gfv3.results.file}"/>
+    </target>
+</project>
diff --git a/Client2/nbproject/build-impl.xml b/Client2/nbproject/build-impl.xml
new file mode 100644
index 0000000..7812fc3
--- /dev/null
+++ b/Client2/nbproject/build-impl.xml
@@ -0,0 +1,1441 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+        *** GENERATED FROM project.xml - DO NOT EDIT  ***
+        ***         EDIT ../build.xml INSTEAD         ***
+
+        For the purpose of easier reading the script
+        is divided into following sections:
+        - initialization
+        - compilation
+        - dist
+        - execution
+        - debugging
+        - javadoc
+        - test compilation
+        - test execution
+        - test debugging
+        - cleanup
+
+        -->
+<project xmlns:webproject1="http://www.netbeans.org/ns/web-project/1" xmlns:webproject2="http://www.netbeans.org/ns/web-project/2" xmlns:webproject3="http://www.netbeans.org/ns/web-project/3" basedir=".." default="default" name="Client2-impl">
+    <import file="ant-deploy.xml"/>
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="dist,javadoc" description="Build whole project." name="default"/>
+    <!--
+                INITIALIZATION SECTION
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.4"/>
+        <property name="default.javac.target" value="1.4"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" if="dist.ear.dir" name="-do-ear-init"/>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+        <condition property="have.tests">
+            <or>
+                <available file="${test.src.dir}"/>
+            </or>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <isfalse value="${javadoc.preview}"/>
+        </condition>
+        <property name="javac.compilerargs" value=""/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <condition property="no.dist.ear.dir">
+            <not>
+                <isset property="dist.ear.dir"/>
+            </not>
+        </condition>
+        <property name="build.web.excludes" value="${build.classes.excludes}"/>
+        <condition property="do.compile.jsps">
+            <istrue value="${compile.jsps}"/>
+        </condition>
+        <condition property="do.debug.server">
+            <or>
+                <not>
+                    <isset property="debug.server"/>
+                </not>
+                <istrue value="${debug.server}"/>
+                <and>
+                    <not>
+                        <istrue value="${debug.server}"/>
+                    </not>
+                    <not>
+                        <istrue value="${debug.client}"/>
+                    </not>
+                </and>
+            </or>
+        </condition>
+        <condition property="do.debug.client">
+            <istrue value="${debug.client}"/>
+        </condition>
+        <condition property="do.display.browser">
+            <istrue value="${display.browser}"/>
+        </condition>
+        <condition property="do.display.browser.debug.old">
+            <and>
+                <isset property="do.display.browser"/>
+                <not>
+                    <isset property="do.debug.client"/>
+                </not>
+                <not>
+                    <isset property="browser.context"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.display.browser.debug">
+            <and>
+                <isset property="do.display.browser"/>
+                <not>
+                    <isset property="do.debug.client"/>
+                </not>
+                <isset property="browser.context"/>
+            </and>
+        </condition>
+        <available file="${conf.dir}/MANIFEST.MF" property="has.custom.manifest"/>
+        <available file="${persistence.xml.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="do.war.package.with.custom.manifest">
+            <isset property="has.custom.manifest"/>
+        </condition>
+        <condition property="do.war.package.without.custom.manifest">
+            <not>
+                <isset property="has.custom.manifest"/>
+            </not>
+        </condition>
+        <condition property="do.tmp.war.package.with.custom.manifest">
+            <and>
+                <isset property="has.custom.manifest"/>
+                <or>
+                    <isfalse value="${directory.deployment.supported}"/>
+                    <isset property="dist.ear.dir"/>
+                </or>
+            </and>
+        </condition>
+        <condition property="do.tmp.war.package.without.custom.manifest">
+            <and>
+                <not>
+                    <isset property="has.custom.manifest"/>
+                </not>
+                <or>
+                    <isfalse value="${directory.deployment.supported}"/>
+                    <isset property="dist.ear.dir"/>
+                </or>
+            </and>
+        </condition>
+        <condition property="do.tmp.war.package">
+            <or>
+                <isfalse value="${directory.deployment.supported}"/>
+                <isset property="dist.ear.dir"/>
+            </or>
+        </condition>
+        <property name="build.meta.inf.dir" value="${build.web.dir}/META-INF"/>
+        <condition else="" property="application.args.param" value="${application.args}">
+            <and>
+                <isset property="application.args"/>
+                <not>
+                    <equals arg1="${application.args}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="runmain.jvmargs" value=""/>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <length length="0" string="${endorsed.classpath}" when="greater"/>
+            </and>
+        </condition>
+        <condition else="false" property="jdkBug6558476">
+            <and>
+                <matches pattern="1\.[56]" string="${java.specification.version}"/>
+                <not>
+                    <os family="unix"/>
+                </not>
+            </and>
+        </condition>
+        <property name="javac.fork" value="${jdkBug6558476}"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+    </target>
+    <target depends="init" name="-init-cos" unless="deploy.on.save">
+        <condition property="deploy.on.save" value="true">
+            <or>
+                <istrue value="${j2ee.deploy.on.save}"/>
+                <istrue value="${j2ee.compile.on.save}"/>
+            </or>
+        </condition>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.dir">Must set src.dir</fail>
+        <fail unless="test.src.dir">Must set test.src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="build.web.dir">Must set build.web.dir</fail>
+        <fail unless="build.generated.dir">Must set build.generated.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.war">Must set dist.war</fail>
+        <condition property="missing.j2ee.server.home">
+            <and>
+                <matches pattern="j2ee.server.home" string="${j2ee.platform.classpath}"/>
+                <not>
+                    <isset property="j2ee.server.home"/>
+                </not>
+            </and>
+        </condition>
+        <fail if="missing.j2ee.server.home">
+The Java EE server classpath is not correctly set up - server home directory is missing.
+Either open the project in the IDE and assign the server or setup the server classpath manually.
+For example like this:
+   ant -Dj2ee.server.home=&lt;app_server_installation_directory&gt;
+                </fail>
+        <fail unless="j2ee.platform.classpath">
+The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}.
+Either open the project in the IDE and assign the server or setup the server classpath manually.
+For example like this:
+   ant -Duser.properties.file=&lt;path_to_property_file&gt; (where you put the property "j2ee.platform.classpath" in a .properties file)
+or ant -Dj2ee.platform.classpath=&lt;server_classpath&gt; (where no properties file is used)
+                </fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" srcdir="@{srcdir}" target="${javac.target}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" srcdir="@{srcdir}" target="${javac.target}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete file="${javac.includesfile.binary}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${java.io.tmpdir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="run.jvmargs.ide" value=""/>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set">
+                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
+                        <filename name="@{testincludes}"/>
+                    </fileset>
+                </union>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="Client2" testname="TestNG tests" workingDir="${basedir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <webproject2:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </webproject2:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <webproject2:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </webproject2:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <webproject2:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${runmain.jvmargs}"/>
+                    </customize>
+                </webproject2:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${java.io.tmpdir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="run.jvmargs.ide" value=""/>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <webproject2:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </webproject2:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename Client2 -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <webproject1:debug args="${testng.cmd.args}" classname="org.testng.TestNG" classpath="${debug.test.classpath}:${j2ee.platform.embeddableejb.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                    </customize>
+                </webproject1:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <webproject2:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </webproject2:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <webproject2:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${runmain.jvmargs}"/>
+                    </customize>
+                </webproject2:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <webproject2:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </webproject2:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <target name="-init-macrodef-java">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${runmain.jvmargs}"/>
+                    <classpath>
+                        <path path="@{classpath}:${j2ee.platform.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-nbjsdebug">
+        <macrodef name="nbjsdebugstart" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${client.url}" name="webUrl"/>
+            <sequential>
+                <nbjsdebugstart urlPart="${client.urlPart}" webUrl="@{webUrl}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" transport="${debug-transport}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdaappreloaded" uri="http://www.netbeans.org/ns/web-project/1">
+            <sequential>
+                <nbjpdaappreloaded/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>
+        <condition property="have-jdk-older-than-1.4">
+            <or>
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
+            </or>
+        </condition>
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+            <istrue value="${have-jdk-older-than-1.4}"/>
+        </condition>
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <attribute default="${application.args.param}" name="args"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg line="${runmain.jvmargs}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <arg line="@{args}"/>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-taskdefs">
+        <fail unless="libs.CopyLibs.classpath">
+The libs.CopyLibs.classpath property is not set up.
+This property must point to 
+org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part
+of NetBeans IDE installation and is usually located at 
+&lt;netbeans_installation&gt;/java&lt;version&gt;/ant/extra folder.
+Either open the project in the IDE and make sure CopyLibs library
+exists or setup the property manually. For example like this:
+ ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar
+                </fail>
+        <taskdef classpath="${libs.CopyLibs.classpath}" resource="org/netbeans/modules/java/j2seproject/copylibstask/antlib.xml"/>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-java,-init-macrodef-nbjpda,-init-macrodef-nbjsdebug,-init-macrodef-debug,-init-taskdefs,-init-ap-cmdline" name="init"/>
+    <!--
+                COMPILATION SECTION
+            -->
+    <target depends="init" if="no.dist.ear.dir" name="deps-module-jar" unless="no.deps"/>
+    <target depends="init" if="dist.ear.dir" name="deps-ear-jar" unless="no.deps"/>
+    <target depends="init, deps-module-jar, deps-ear-jar" name="deps-jar" unless="no.deps"/>
+    <target depends="init,deps-jar" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target name="-copy-webdir">
+        <copy todir="${build.web.dir}">
+            <fileset dir="${web.docbase.dir}" excludes="${build.web.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+        <copy todir="${build.web.dir}/WEB-INF">
+            <fileset dir="${webinf.dir}" excludes="${build.web.excludes}"/>
+        </copy>
+    </target>
+    <target depends="init, deps-jar, -pre-pre-compile, -pre-compile, -copy-manifest, -copy-persistence-xml, -copy-webdir, library-inclusion-in-archive,library-inclusion-in-manifest" if="have.sources" name="-do-compile">
+        <webproject2:javac destdir="${build.classes.dir}" gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.custom.manifest" name="-copy-manifest">
+        <mkdir dir="${build.meta.inf.dir}"/>
+        <copy todir="${build.meta.inf.dir}">
+            <fileset dir="${conf.dir}" includes="MANIFEST.MF"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.web.dir}/WEB-INF/classes/META-INF"/>
+        <copy todir="${build.web.dir}/WEB-INF/classes/META-INF">
+            <fileset dir="${persistence.xml.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <webproject2:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <property name="jspc.schemas" value="/resources/schemas/"/>
+    <property name="jspc.dtds" value="/resources/dtds/"/>
+    <target depends="compile" description="Test compile JSP pages to expose compilation errors." if="do.compile.jsps" name="compile-jsps">
+        <mkdir dir="${build.generated.dir}/src"/>
+        <java classname="org.netbeans.modules.web.project.ant.JspC" failonerror="true" fork="true">
+            <arg value="-uriroot"/>
+            <arg file="${basedir}/${build.web.dir}"/>
+            <arg value="-d"/>
+            <arg file="${basedir}/${build.generated.dir}/src"/>
+            <arg value="-die1"/>
+            <arg value="-schemas ${jspc.schemas}"/>
+            <arg value="-dtds ${jspc.dtds}"/>
+            <arg value="-compilerSourceVM ${javac.source}"/>
+            <arg value="-compilerTargetVM ${javac.target}"/>
+            <arg value="-javaEncoding ${source.encoding}"/>
+            <arg value="-sysClasspath ${libs.jsp-compilation-syscp.classpath}"/>
+            <classpath path="${java.home}/../lib/tools.jar:${libs.jsp-compiler.classpath}:${libs.jsp-compilation.classpath}"/>
+        </java>
+        <mkdir dir="${build.generated.dir}/classes"/>
+        <webproject2:javac classpath="${build.classes.dir}:${libs.jsp-compilation.classpath}:${javac.classpath}:${j2ee.platform.classpath}" destdir="${build.generated.dir}/classes" srcdir="${build.generated.dir}/src"/>
+    </target>
+    <target depends="compile" if="jsp.includes" name="-do-compile-single-jsp">
+        <fail unless="javac.jsp.includes">Must select some files in the IDE or set javac.jsp.includes</fail>
+        <mkdir dir="${build.generated.dir}/src"/>
+        <java classname="org.netbeans.modules.web.project.ant.JspCSingle" failonerror="true" fork="true">
+            <arg value="-uriroot"/>
+            <arg file="${basedir}/${build.web.dir}"/>
+            <arg value="-d"/>
+            <arg file="${basedir}/${build.generated.dir}/src"/>
+            <arg value="-die1"/>
+            <arg value="-schemas ${jspc.schemas}"/>
+            <arg value="-dtds ${jspc.dtds}"/>
+            <arg value="-sysClasspath ${libs.jsp-compilation-syscp.classpath}"/>
+            <arg value="-jspc.files"/>
+            <arg path="${jsp.includes}"/>
+            <arg value="-compilerSourceVM ${javac.source}"/>
+            <arg value="-compilerTargetVM ${javac.target}"/>
+            <arg value="-javaEncoding ${source.encoding}"/>
+            <classpath path="${java.home}/../lib/tools.jar:${libs.jsp-compiler.classpath}:${libs.jsp-compilation.classpath}"/>
+        </java>
+        <mkdir dir="${build.generated.dir}/classes"/>
+        <webproject2:javac classpath="${build.classes.dir}:${libs.jsp-compilation.classpath}:${javac.classpath}:${j2ee.platform.classpath}" destdir="${build.generated.dir}/classes" srcdir="${build.generated.dir}/src">
+            <customize>
+                <patternset includes="${javac.jsp.includes}"/>
+            </customize>
+        </webproject2:javac>
+    </target>
+    <target name="compile-single-jsp">
+        <fail unless="jsp.includes">Must select a file in the IDE or set jsp.includes</fail>
+        <antcall target="-do-compile-single-jsp"/>
+    </target>
+    <!--
+                DIST BUILDING SECTION
+            -->
+    <target name="-pre-dist">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.without.custom.manifest" name="-do-dist-without-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.with.custom.manifest" name="-do-dist-with-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.without.custom.manifest" name="-do-tmp-dist-without-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.with.custom.manifest" name="-do-tmp-dist-with-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist,-do-dist-with-manifest,-do-dist-without-manifest" name="do-dist"/>
+    <target depends="init" if="dist.ear.dir" name="library-inclusion-in-manifest">
+        <mkdir dir="${build.web.dir}/META-INF"/>
+        <manifest file="${build.web.dir}/META-INF/MANIFEST.MF" mode="update"/>
+    </target>
+    <target depends="init" name="library-inclusion-in-archive" unless="dist.ear.dir"/>
+    <target depends="init" if="dist.ear.dir" name="-clean-webinf-lib">
+        <delete dir="${build.web.dir}/WEB-INF/lib"/>
+    </target>
+    <target depends="init,-clean-webinf-lib,compile,compile-jsps,-pre-dist,library-inclusion-in-manifest" if="do.tmp.war.package" name="do-ear-dist">
+        <dirname file="${dist.ear.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.ear.war}" manifest="${build.web.dir}/META-INF/MANIFEST.MF">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target name="-post-dist">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-dist,do-dist,-post-dist" description="Build distribution (WAR)." name="dist"/>
+    <target depends="init,-clean-webinf-lib,-init-cos,compile,-pre-dist,do-ear-dist,-post-dist" description="Build distribution (WAR) to be packaged into an EAR." name="dist-ear"/>
+    <!--
+                EXECUTION SECTION
+            -->
+    <target depends="run-deploy,run-display-browser" description="Deploy to server and show in browser." name="run"/>
+    <target name="-pre-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target name="-post-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target name="-pre-nbmodule-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- This target can be overriden by NetBeans modules. Don't override it directly, use -pre-run-deploy task instead. -->
+    </target>
+    <target name="-post-nbmodule-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- This target can be overriden by NetBeans modules. Don't override it directly, use -post-run-deploy task instead. -->
+    </target>
+    <target name="-run-deploy-am">
+        <!-- Task to deploy to the Access Manager runtime. -->
+    </target>
+    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest,-pre-run-deploy,-pre-nbmodule-run-deploy,-run-deploy-nb,-init-deploy-ant,-deploy-ant,-run-deploy-am,-post-nbmodule-run-deploy,-post-run-deploy,-do-update-breakpoints" name="run-deploy"/>
+    <target if="netbeans.home" name="-run-deploy-nb">
+        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="false" forceRedeploy="${forceRedeploy}"/>
+    </target>
+    <target name="-init-deploy-ant" unless="netbeans.home">
+        <property name="deploy.ant.archive" value="${dist.war}"/>
+        <property name="deploy.ant.docbase.dir" value="${web.docbase.dir}"/>
+        <property name="deploy.ant.resource.dir" value="${resource.dir}"/>
+        <property name="deploy.ant.enabled" value="true"/>
+    </target>
+    <target depends="dist,-run-undeploy-nb,-init-deploy-ant,-undeploy-ant" name="run-undeploy"/>
+    <target if="netbeans.home" name="-run-undeploy-nb">
+        <fail message="Undeploy is not supported from within the IDE"/>
+    </target>
+    <target depends="init,-pre-dist,dist,-post-dist" name="verify">
+        <nbverify file="${dist.war}"/>
+    </target>
+    <target depends="run-deploy,-init-display-browser,-display-browser-nb-old,-display-browser-nb,-display-browser-cl" name="run-display-browser"/>
+    <target if="do.display.browser" name="-init-display-browser">
+        <condition property="do.display.browser.nb.old">
+            <and>
+                <isset property="netbeans.home"/>
+                <not>
+                    <isset property="browser.context"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.display.browser.nb">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="browser.context"/>
+            </and>
+        </condition>
+        <condition property="do.display.browser.cl">
+            <isset property="deploy.ant.enabled"/>
+        </condition>
+    </target>
+    <target if="do.display.browser.nb.old" name="-display-browser-nb-old">
+        <nbbrowse url="${client.url}"/>
+    </target>
+    <target if="do.display.browser.nb" name="-display-browser-nb">
+        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
+    </target>
+    <target if="do.display.browser.cl" name="-get-browser" unless="browser">
+        <condition property="browser" value="rundll32">
+            <os family="windows"/>
+        </condition>
+        <condition else="" property="browser.args" value="url.dll,FileProtocolHandler">
+            <os family="windows"/>
+        </condition>
+        <condition property="browser" value="/usr/bin/open">
+            <os family="mac"/>
+        </condition>
+        <property environment="env"/>
+        <condition property="browser" value="${env.BROWSER}">
+            <isset property="env.BROWSER"/>
+        </condition>
+        <condition property="browser" value="/usr/bin/firefox">
+            <available file="/usr/bin/firefox"/>
+        </condition>
+        <condition property="browser" value="/usr/local/firefox/firefox">
+            <available file="/usr/local/firefox/firefox"/>
+        </condition>
+        <condition property="browser" value="/usr/bin/mozilla">
+            <available file="/usr/bin/mozilla"/>
+        </condition>
+        <condition property="browser" value="/usr/local/mozilla/mozilla">
+            <available file="/usr/local/mozilla/mozilla"/>
+        </condition>
+        <condition property="browser" value="/usr/sfw/lib/firefox/firefox">
+            <available file="/usr/sfw/lib/firefox/firefox"/>
+        </condition>
+        <condition property="browser" value="/opt/csw/bin/firefox">
+            <available file="/opt/csw/bin/firefox"/>
+        </condition>
+        <condition property="browser" value="/usr/sfw/lib/mozilla/mozilla">
+            <available file="/usr/sfw/lib/mozilla/mozilla"/>
+        </condition>
+        <condition property="browser" value="/opt/csw/bin/mozilla">
+            <available file="/opt/csw/bin/mozilla"/>
+        </condition>
+    </target>
+    <target depends="-get-browser" if="do.display.browser.cl" name="-display-browser-cl">
+        <fail unless="browser">
+                    Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable.
+                </fail>
+        <property name="browse.url" value="${deploy.ant.client.url}${client.urlPart}"/>
+        <echo>Launching ${browse.url}</echo>
+        <exec executable="${browser}" spawn="true">
+            <arg line="${browser.args} ${browse.url}"/>
+        </exec>
+    </target>
+    <target depends="init,-init-cos,compile-single" name="run-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <webproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <webproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-do-update-breakpoints">
+        <webproject1:nbjpdaappreloaded/>
+    </target>
+    <!--
+                DEBUGGING SECTION
+            -->
+    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest" description="Debug project in IDE." if="netbeans.home" name="debug">
+        <nbstartserver debugmode="true"/>
+        <antcall target="connect-debugger"/>
+        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="true" forceRedeploy="true"/>
+        <antcall target="debug-display-browser-old"/>
+        <antcall target="debug-display-browser"/>
+        <antcall target="connect-client-debugger"/>
+    </target>
+    <target if="do.debug.server" name="connect-debugger" unless="is.debugged">
+        <condition property="listeningcp" value="sourcepath">
+            <istrue value="${j2ee.compile.on.save}"/>
+        </condition>
+        <nbjpdaconnect address="${jpda.address}" host="${jpda.host}" listeningcp="${listeningcp}" name="${name}" transport="${jpda.transport}">
+            <classpath>
+                <path path="${debug.classpath}:${j2ee.platform.classpath}"/>
+            </classpath>
+            <sourcepath>
+                <path path="${web.docbase.dir}"/>
+            </sourcepath>
+        </nbjpdaconnect>
+    </target>
+    <target if="do.display.browser.debug.old" name="debug-display-browser-old">
+        <nbbrowse url="${client.url}"/>
+    </target>
+    <target if="do.display.browser.debug" name="debug-display-browser">
+        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
+    </target>
+    <target if="do.debug.client" name="connect-client-debugger">
+        <webproject1:nbjsdebugstart webUrl="${client.url}"/>
+    </target>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <webproject1:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init,compile,compile-jsps,-do-compile-single-jsp,debug" if="netbeans.home" name="debug-single"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <webproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <webproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <webproject1:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <webproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+            =================
+            PROFILING SECTION
+            =================
+            -->
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target description="Profile a J2EE project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <condition else="start-profiled-server" property="profiler.startserver.target" value="start-profiled-server-extraargs">
+            <isset property="profiler.info.jvmargs.extra"/>
+        </condition>
+        <antcall target="${profiler.startserver.target}"/>
+        <antcall target="run"/>
+        <antcall target="-profile-start-loadgen"/>
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="start-profiled-server">
+        <nbstartprofiledserver forceRestart="${profiler.j2ee.serverForceRestart}" javaPlatform="${profiler.info.javaPlatform}" startupTimeout="${profiler.j2ee.serverStartupTimeout}">
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg value="${profiler.j2ee.agentID}"/>
+        </nbstartprofiledserver>
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="start-profiled-server-extraargs">
+        <nbstartprofiledserver forceRestart="${profiler.j2ee.serverForceRestart}" javaPlatform="${profiler.info.javaPlatform}" startupTimeout="${profiler.j2ee.serverStartupTimeout}">
+            <jvmarg value="${profiler.info.jvmargs.extra}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg value="${profiler.j2ee.agentID}"/>
+        </nbstartprofiledserver>
+    </target>
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+                <path path="${j2ee.platform.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg line="${profiler.info.jvmargs}"/>
+            <test name="${profile.class}"/>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+                <path path="${j2ee.platform.classpath}"/>
+            </classpath>
+            <syspropertyset>
+                <propertyref prefix="test-sys-prop."/>
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>
+            </syspropertyset>
+            <formatter type="brief" usefile="false"/>
+            <formatter type="xml"/>
+        </junit>
+    </target>
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest" name="-do-profile">
+        <startprofiler/>
+        <nbstartserver profilemode="true"/>
+        <nbdeploy clientUrlPart="${client.urlPart}" forceRedeploy="true" profilemode="true"/>
+        <antcall target="debug-display-browser-old"/>
+        <antcall target="debug-display-browser"/>
+        <antcall target="-profile-start-loadgen"/>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a J2EE project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <antcall target="-do-profile"/>
+    </target>
+    <target depends="-profile-test-single-pre72" name="profile-test-single"/>
+    <target depends="-profile-check" if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target if="profiler.loadgen.path" name="-profile-start-loadgen">
+        <loadgenstart path="${profiler.loadgen.path}"/>
+    </target>
+    <!--
+                JAVADOC SECTION
+            -->
+    <target depends="init" if="have.sources" name="javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}:${j2ee.platform.classpath}"/>
+            </classpath>
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+            </fileset>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,javadoc-build" if="netbeans.home" name="javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,javadoc-build,javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                
+                TEST COMPILATION SECTION
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+        <property name="j2ee.platform.embeddableejb.classpath" value=""/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test" if="have.tests" name="-do-compile-test">
+        <webproject2:javac classpath="${javac.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <webproject2:javac classpath="${javac.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" srcdir="${test.src.dir}"/>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                
+                TEST EXECUTION SECTION
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+        <webproject2:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <webproject2:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <webproject2:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                
+                TEST DEBUGGING SECTION
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <webproject2:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <webproject2:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <webproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <webproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                
+                CLEANUP SECTION
+            -->
+    <target depends="init" name="deps-clean" unless="no.deps"/>
+    <target depends="init" name="do-clean">
+        <condition property="build.dir.to.clean" value="${build.web.dir}">
+            <isset property="dist.ear.dir"/>
+        </condition>
+        <property name="build.dir.to.clean" value="${build.web.dir}"/>
+        <delete includeEmptyDirs="true" quiet="true">
+            <fileset dir="${build.dir.to.clean}/WEB-INF/lib"/>
+        </delete>
+        <delete dir="${build.dir}"/>
+        <available file="${build.dir.to.clean}/WEB-INF/lib" property="status.clean-failed" type="dir"/>
+        <delete dir="${dist.dir}"/>
+    </target>
+    <target depends="do-clean" if="status.clean-failed" name="check-clean">
+        <echo message="Warning: unable to delete some files in ${build.web.dir}/WEB-INF/lib - they are probably locked by the J2EE server. "/>
+        <echo level="info" message="To delete all files undeploy the module from Server Registry in Runtime tab and then use Clean again."/>
+    </target>
+    <target depends="init" if="netbeans.home" name="undeploy-clean">
+        <nbundeploy failOnError="false" startServer="false"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,undeploy-clean,deps-clean,do-clean,check-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target depends="clean" description="Clean build products." name="clean-ear"/>
+</project>
diff --git a/Client2/nbproject/genfiles.properties b/Client2/nbproject/genfiles.properties
new file mode 100644
index 0000000..2ada31e
--- /dev/null
+++ b/Client2/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=de65ed0f
+build.xml.script.CRC32=b4783445
+build.xml.stylesheet.CRC32=651128d4@1.77.1.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=de65ed0f
+nbproject/build-impl.xml.script.CRC32=b339b746
+nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.77.1.1
diff --git a/Client2/nbproject/private/private.properties b/Client2/nbproject/private/private.properties
new file mode 100644
index 0000000..51adf31
--- /dev/null
+++ b/Client2/nbproject/private/private.properties
@@ -0,0 +1,10 @@
+deploy.ant.properties.file=C:\\Users\\YUKI\\AppData\\Roaming\\NetBeans\\8.2\\config\\GlassFishEE6\\Properties\\gfv3340685615.properties
+j2ee.platform.is.jsr109=true
+j2ee.server.domain=C:/Users/YUKI/domain-client-2
+j2ee.server.home=C:/Program Files/glassfish-4.1.1/glassfish
+j2ee.server.instance=[C:\\Program Files\\glassfish-4.1.1\\glassfish;C:\\Users\\YUKI\\domain-client-2]deployer:gfv3ee6wc:localhost:40095
+j2ee.server.middleware=C:/Program Files/glassfish-4.1.1
+javac.debug=true
+javadoc.preview=true
+selected.browser=default
+user.properties.file=C:\\Users\\YUKI\\AppData\\Roaming\\NetBeans\\8.2\\build.properties
diff --git a/Client2/nbproject/project.properties b/Client2/nbproject/project.properties
new file mode 100644
index 0000000..21ca81d
--- /dev/null
+++ b/Client2/nbproject/project.properties
@@ -0,0 +1,88 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=true
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+build.classes.dir=${build.web.dir}/WEB-INF/classes
+build.classes.excludes=**/*.java,**/*.form
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+build.web.dir=${build.dir}/web
+build.web.excludes=${build.classes.excludes}
+client.urlPart=
+compile.jsps=false
+conf.dir=${source.root}/conf
+debug.classpath=${build.classes.dir}:${javac.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+display.browser=true
+# Files to be excluded from distribution war
+dist.archive.excludes=
+dist.dir=dist
+dist.ear.war=${dist.dir}/${war.ear.name}
+dist.javadoc.dir=${dist.dir}/javadoc
+dist.war=${dist.dir}/${war.name}
+endorsed.classpath=\
+    ${libs.javaee-endorsed-api-7.0.classpath}
+excludes=
+includes=**
+j2ee.compile.on.save=true
+j2ee.copy.static.files.on.save=true
+j2ee.deploy.on.save=true
+j2ee.platform=1.7-web
+j2ee.platform.classpath=${j2ee.server.home}/modules/endorsed/javax.annotation-api.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/bean-validator.jar:${j2ee.server.home}/modules/cdi-api.jar:${j2ee.server.home}/modules/javax.batch-api.jar:${j2ee.server.home}/modules/javax.ejb-api.jar:${j2ee.server.home}/modules/javax.el.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent-api.jar:${j2ee.server.home}/modules/javax.enterprise.concurrent.jar:${j2ee.server.home}/modules/javax.enterprise.deploy-api.jar:${j2ee.server.home}/modules/javax.faces.jar:${j2ee.server.home}/modules/javax.inject.jar:${j2ee.server.home}/modules/javax.interceptor-api.jar:${j2ee.server.home}/modules/javax.jms-api.jar:${j2ee.server.home}/modules/javax.json.jar:${j2ee.server.home}/modules/javax.mail.jar:${j2ee.server.home}/modules/javax.management.j2ee-api.jar:${j2ee.server.home}/modules/javax.persistence.jar:${j2ee.server.home}/modules/javax.resource-api.jar:${j2ee.server.home}/modules/javax.security.auth.message-api.jar:${j2ee.server.home}/modules/javax.security.jacc-api.jar:${j2ee.server.home}/modules/javax.servlet-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl-api.jar:${j2ee.server.home}/modules/javax.servlet.jsp.jstl.jar:${j2ee.server.home}/modules/javax.transaction-api.jar:${j2ee.server.home}/modules/javax.websocket-api.jar:${j2ee.server.home}/modules/javax.ws.rs-api.jar:${j2ee.server.home}/modules/javax.xml.registry-api.jar:${j2ee.server.home}/modules/javax.xml.rpc-api.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/weld-osgi-bundle.jar:${j2ee.server.middleware}/mq/lib/jaxm-api.jar
+j2ee.platform.embeddableejb.classpath=${j2ee.server.home}/lib/embedded/glassfish-embedded-static-shell.jar
+j2ee.platform.wscompile.classpath=${j2ee.server.home}/modules/webservices-osgi.jar
+j2ee.platform.wsgen.classpath=${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar
+j2ee.platform.wsimport.classpath=${j2ee.server.home}/modules/webservices-osgi.jar:${j2ee.server.home}/modules/endorsed/webservices-api-osgi.jar:${j2ee.server.home}/modules/jaxb-osgi.jar:${j2ee.server.home}/modules/endorsed/jaxb-api.jar
+j2ee.platform.wsit.classpath=
+j2ee.server.type=gfv3ee6
+jar.compress=false
+javac.classpath=
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.debug=true
+javac.deprecation=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.preview=true
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+lib.dir=${web.docbase.dir}/WEB-INF/lib
+persistence.xml.dir=${conf.dir}
+platform.active=default_platform
+resource.dir=setup
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+# Space-separated list of JVM arguments used when running a class with a main method or a unit test
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value):
+runmain.jvmargs=
+source.encoding=UTF-8
+source.root=src
+src.dir=${source.root}/java
+test.src.dir=test
+war.content.additional=
+war.ear.name=${war.name}
+war.name=Client2.war
+web.docbase.dir=web
+webinf.dir=web/WEB-INF
diff --git a/Client2/nbproject/project.xml b/Client2/nbproject/project.xml
new file mode 100644
index 0000000..3d8231e
--- /dev/null
+++ b/Client2/nbproject/project.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.web.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/web-project/3">
+            <name>Client2</name>
+            <minimum-ant-version>1.6.5</minimum-ant-version>
+            <web-module-libraries/>
+            <web-module-additional-libraries/>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots>
+                <root id="test.src.dir"/>
+            </test-roots>
+        </data>
+    </configuration>
+</project>
diff --git a/Client2/src/conf/MANIFEST.MF b/Client2/src/conf/MANIFEST.MF
new file mode 100644
index 0000000..59499bc
--- /dev/null
+++ b/Client2/src/conf/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
diff --git a/Client2/web/META-INF/context.xml b/Client2/web/META-INF/context.xml
new file mode 100644
index 0000000..7ecfab3
--- /dev/null
+++ b/Client2/web/META-INF/context.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context path="/Client2"/>
diff --git a/Client2/web/catalog.jsp b/Client2/web/catalog.jsp
new file mode 100644
index 0000000..9a806e1
--- /dev/null
+++ b/Client2/web/catalog.jsp
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>TODO supply a title</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        
+        <!--Manifest-->
+        <link rel="manifest" href="manifest.json">
+        
+        <!--AngularJS-->
+        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
+    </head>
+    <body >
+        <%
+            String username = "";
+            if (session.getAttribute("username") == null) {
+                response.sendRedirect("login.jsp");
+            }
+            else {
+                username = (String)session.getAttribute("username");
+            }
+        %>
+        <h1>Client Server</h1>
+        <div id="username" value="<%out.print(username);%>"></div>
+        <!-- Container for the Table of content -->
+        <div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
+          <div class="mdl-card__supporting-text mdl-color-text--grey-600">
+            <h3>Messages</h3>
+            <div id="messages"></div>
+            <h3>Online Users</h3>
+            <div id="onlineUsers"></div>
+            <div ng-app="clientApp" ng-controller="clientController">
+                <ul>
+                <li ng-repeat="x in onlineUsers">
+                    <input type="checkbox" ng-model="x.show">
+                    {{ x.show+ x.username + '('+x.token+')' }}
+                    <div ng-show="x.show">
+                        <form>
+                            <div id="box-{{x.username}}"></div>
+                            <input ng-model="x.message" id="message-{{x.username}}"></input>
+                            <button ng-click="sendChat(x.token, x.message, x.username)">send</button>
+                        </form>
+                    </div>
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+        <a href="logout.jsp" >logout</a></p>
+        
+        <!--Scripts-->
+        <!--Jquery-->
+        <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
+
+        <!-- Firebase -->
+        <!-- ********************************************************
+             * TODO(DEVELOPER): Update Firebase initialization code:
+                1. Go to the Firebase console: https://console.firebase.google.com/
+                2. Choose a Firebase project you've created
+                3. Click "Add Firebase to your web app"
+                4. Replace the following initialization code with the code from the Firebase console:
+        -->
+        <!-- START INITIALIZATION CODE -->
+        <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
+       
+        
+        <script>
+            var app = angular.module("clientApp", []);
+            app.controller("clientController", function($scope, $http) {
+                var cUsername = $('#username').attr('value');
+                console.log('checking online users');                
+                $http.get("http://localhost:8083/chat-server.php?code=checkingOnlineUsers&callback=?&username="+cUsername)
+                    .then(function (response) {
+                        $scope.onlineUsers = response.data;
+                    });
+                
+                $scope.sendChat = function(token, message, username) {
+                    $('#box-'+username).append("You: "+message);
+                    $('#message-'+username).val("");
+                    console.log('sending message...');
+                    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                        code: "sendChat",
+                        to: token,
+                        message: message,
+                        senderUsername: $('#username').attr('value'),
+                      },function(res){
+                          alert('Response: '+res.response);
+                    });
+                };
+                
+                $scope.updateOnlineUsers = function() {
+                    console.log('updating online users');
+                    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                        code: "checkingOnlineUsers",
+                        token: cToken,
+                      },function(res){
+                          console.log("response: "+res.data);
+                          $scope.$apply(function(){
+                            $scope.onlineUsers = res.data;
+                          });
+                    });
+                }
+            });
+        </script>
+        <script type="text/javascript" src="chat.js"></script>
+    </body>
+</html>
diff --git a/Client2/web/chat.js b/Client2/web/chat.js
new file mode 100644
index 0000000..50853aa
--- /dev/null
+++ b/Client2/web/chat.js
@@ -0,0 +1,235 @@
+// Initialize Firebase
+var config = {
+  apiKey: "AIzaSyAdh562gpCPSX-WYPLUmZuFhXZMMJPvD2M",
+  authDomain: "my-app-ac59b.firebaseapp.com",
+  databaseURL: "https://my-app-ac59b.firebaseio.com",
+  storageBucket: "my-app-ac59b.appspot.com",
+  messagingSenderId: "288252171454"
+};
+firebase.initializeApp(config);
+ var cToken = "";
+// [START get_messaging_object]
+// Retrieve Firebase Messaging object.
+const messaging = firebase.messaging();
+// [END get_messaging_object]
+// IDs of divs that display Instance ID token UI or request permission UI.
+const tokenDivId = 'token_div';
+const permissionDivId = 'permission_div';
+// [START refresh_token]
+// Callback fired if Instance ID token is updated.
+messaging.onTokenRefresh(function() {
+  messaging.getToken()
+  .then(function(refreshedToken) {
+    console.log('Token refreshed.');
+    // Indicate that the new Instance ID token has not yet been sent to the
+    // app server.
+    setTokenSentToServer(false);
+    // Send Instance ID token to app server.
+    sendTokenToServer(refreshedToken);
+    // [START_EXCLUDE]
+    // Display new Instance ID token and clear UI of all previous messages.
+    resetUI();
+    // [END_EXCLUDE]
+  })
+  .catch(function(err) {
+    console.log('Unable to retrieve refreshed token ', err);
+    showToken('Unable to retrieve refreshed token ', err);
+  });
+});
+// [END refresh_token]
+// [START receive_message]
+// Handle incoming messages. Called when:
+// - a message is received while the app has focus
+// - the user clicks on an app notification created by a sevice worker
+//   `messaging.setBackgroundMessageHandler` handler.
+messaging.onMessage(function(payload) {
+  console.log("Message received. ", payload);
+  // [START_EXCLUDE]
+  // Update the UI to include the received message.
+  appendMessage(payload);
+  // [END_EXCLUDE]
+});
+// [END receive_message]
+function resetUI() {
+  clearMessages();
+  showToken('loading...');
+  // [START get_token]
+  // Get Instance ID token. Initially this makes a network call, once retrieved
+  // subsequent calls to getToken will return from cache.
+  messaging.getToken()
+  .then(function(currentToken) {
+    if (currentToken) {
+      sendTokenToServer(currentToken);
+      updateUIForPushEnabled(currentToken);
+    } else {
+      // Show permission request.
+      console.log('No Instance ID token available. Request permission to generate one.');
+      // Show permission UI.
+      updateUIForPushPermissionRequired();
+      setTokenSentToServer(false);
+    }
+  })
+  .catch(function(err) {
+    console.log('An error occurred while retrieving token. ', err);
+    showToken('Error retrieving Instance ID token. ', err);
+    setTokenSentToServer(false);
+  });
+}
+// [END get_token]
+function showToken(currentToken) {
+  // Show token in console and UI.
+//  var tokenElement = document.querySelector('#token');
+//  tokenElement.textContent = currentToken;
+}
+// Send the Instance ID token your application server, so that it can:
+// - send messages back to this app
+// - subscribe/unsubscribe the token from topics
+function sendTokenToServer(currentToken) {
+  if (!isTokenSentToServer()) {
+    console.log('Sending token to server...');
+    // TODO(developer): Send the current token to your server.
+    // Send the data using post
+    console.log('sending...');              
+    console.log($('#username').attr('value'));
+    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+        code: "registerClient",
+        token: currentToken,
+        username: $('#username').attr('value'),
+        email: "null",
+      },function(res){
+        alert('Response '+res.response);
+    });
+    cToken = currentToken;
+
+    setTokenSentToServer(true);
+  } else {
+    console.log('Token already sent to server so won\'t send it again ' +
+        'unless it changes');
+  }
+}
+function isTokenSentToServer() {
+  if (window.localStorage.getItem('sentToServer') == 1) {
+        return true;
+  }
+  return false;
+}
+function setTokenSentToServer(sent) {
+  if (sent) {
+    window.localStorage.setItem('sentToServer', 1);
+  } else {
+    window.localStorage.setItem('sentToServer', 0);
+  }
+}
+function showHideDiv(divId, show) {
+  const div = document.querySelector('#' + divId);
+  if (show) {
+    div.style = "display: visible";
+  } else {
+    div.style = "display: none";
+  }
+}
+function requestPermission() {
+  console.log('Requesting permission...');
+  // [START request_permission]
+  messaging.requestPermission()
+  .then(function() {
+    console.log('Notification permission granted.');
+    // TODO(developer): Retrieve an Instance ID token for use with FCM.
+    // [START_EXCLUDE]
+    // In many cases once an app has been granted notification permission, it
+    // should update its UI reflecting this.
+    resetUI();
+    // [END_EXCLUDE]
+  })
+  .catch(function(err) {
+    console.log('Unable to get permission to notify.', err);
+  });
+  // [END request_permission]
+}
+function deleteToken() {
+  // Delete Instance ID token.
+  // [START delete_token]
+  messaging.getToken()
+  .then(function(currentToken) {
+    messaging.deleteToken(currentToken)
+    .then(function() {
+      console.log('Token deleted.');
+      setTokenSentToServer(false);
+      // [START_EXCLUDE]
+      // Once token is deleted update UI.
+//      resetUI();
+      // [END_EXCLUDE]
+        console.log('deleting token from database');
+        $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+            code: "deleteOnlineUser",
+            token: currentToken,
+          },function(res){
+            alert('Response '+res.response);
+        });
+    })
+    .catch(function(err) {
+      console.log('Unable to delete token. ', err);
+    });
+    // [END delete_token]
+  })
+  .catch(function(err) {
+    console.log('Error retrieving Instance ID token. ', err);
+    showToken('Error retrieving Instance ID token. ', err);
+  });
+}
+// Add a message to the messages element.
+function appendMessage(payload) {
+  var username = payload.data.username;
+//  const dataElement = document.createElement('p');
+  const dataElement2 = document.createElement('p');
+//  dataElement.textContent = payload.data.time;
+  dataElement2.textContent = username+": "+payload.data.message;
+//  $("#box-"+payload.data.username).append(dataElement);
+  $("#box-"+payload.data.username).append(dataElement2);
+//  const dataHeaderELement = document.createElement('h5');
+//  const dataElement = document.createElement('pre');
+//  dataElement.style = 'overflow-x:hidden;'
+//  dataHeaderELement.textContent = 'Received message:';
+//  dataElement.textContent = JSON.stringify(payload, null, 2);
+}
+// Clear the messages element of all children.
+function clearMessages() {
+  const messagesElement = document.querySelector('#messages');
+  while (messagesElement.hasChildNodes()) {
+    messagesElement.removeChild(messagesElement.lastChild);
+  }
+}
+function updateUIForPushEnabled(currentToken) {
+//  showHideDiv(tokenDivId, true);
+//  showHideDiv(permissionDivId, false);
+//  showToken(currentToken);
+}
+function updateUIForPushPermissionRequired() {
+//  showHideDiv(tokenDivId, false);
+//  showHideDiv(permissionDivId, true);
+}
+resetUI();
+
+
+function checkOnlineUsers(currentToken) {
+    console.log('checking online users...');               
+    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+        code: "checkingOnlineUsers",
+        token: cToken,
+      },function(res){
+        console.log('hell');
+        displayOnlineUsers(res);
+        alert('Response '+res.response);
+    });
+}
+
+function displayOnlineUsers(payload) {
+    const onlineUsersElement = document.querySelector('#onlineUsers');
+    const dataHeaderELement = document.createElement('h5');
+    const dataElement = document.createElement('pre');
+    dataElement.style = 'overflow-x:hidden;'
+    dataHeaderELement.textContent = 'Received message:';
+    dataElement.textContent = JSON.stringify(payload, null, 2);
+    onlineUsersElement.appendChild(dataHeaderELement);
+    onlineUsersElement.appendChild(dataElement);
+}
\ No newline at end of file
diff --git a/Client2/web/index.html b/Client2/web/index.html
new file mode 100644
index 0000000..1e12903
--- /dev/null
+++ b/Client2/web/index.html
@@ -0,0 +1,344 @@
+<!DOCTYPE html>
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <title>TODO supply a title</title>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        
+        <!--Manifest-->
+        <link rel="manifest" href="manifest.json">
+        
+        <!--AngularJS-->
+        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
+    </head>
+    <body >
+        <h1>Client Server</h1>
+        <!-- Container for the Table of content -->
+        <div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
+          <div class="mdl-card__supporting-text mdl-color-text--grey-600">
+            <!-- div to display the generated Instance ID token -->
+            <div id="token_div" style="display: none;">
+              <h4>Instance ID Token</h4>
+              <p id="token" style="word-break: break-all;"></p>
+              <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
+                      onclick="deleteToken()">Delete Token</button>
+            </div>
+            <!-- div to display the UI to allow the request for permission to
+                 notify the user. This is shown if the app has not yet been
+                 granted permission to notify. -->
+            <div id="permission_div" style="display: none;">
+              <h4>Needs Permission</h4>
+              <p id="token"></p>
+              <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
+                      onclick="requestPermission()">Request Permission</button>
+            </div>
+            <button onclick="checkOnlineUsers()">Check Online Users</button>
+            <!-- div to display messages received by this app. -->
+            <h3>Messages</h3>
+            <div id="messages"></div>
+            <h3>Online Users</h3>
+            <div id="onlineUsers"></div>
+            <div ng-app="clientApp" ng-controller="clientController">
+                <ul>
+                <li ng-repeat="x in onlineUsers">
+                  {{ x.username + '('+x.token+')' }}
+                  
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+        
+        
+        <!--Scripts-->
+        <!--Jquery-->
+        <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
+        
+        <script>
+            var app = angular.module("clientApp", []);
+            app.controller("clientController", function($scope, $http) {
+//                console.log('checking online users');
+//                $scope.onlineUsers = "a";
+//                var y = 's';
+//                $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+//                    code: "checkingOnlineUsers",
+//                    token: cToken,
+//                  },function(res){
+//                      
+//                      console.log("response: "+res.data);
+//                      var x = String(res.data);
+//                      y = x.split(",");
+//                      $scope.$apply(function(){
+//                        $scope.onlineUsers = res.data;
+//                      });
+//                      console.log(y);
+//                      $scope.onlineUsers = y;
+//                });
+//                console.log(y);
+//                $scope.onlineUsers = y;
+                
+                $http.get("http://localhost:8083/chat-server.php?code=checkingOnlineUsers&callback=?")
+                    .then(function (response) {
+                        $scope.onlineUsers = response.data;
+                    });
+                
+                $scope.sendChat = function(token) {
+                    $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                        code: "sendChat",
+                        to: token,
+                      },function(res){
+                          alert('Response: '+res.response);
+                    });
+                };
+            });
+        </script>
+
+        <!-- Firebase -->
+        <!-- ********************************************************
+             * TODO(DEVELOPER): Update Firebase initialization code:
+                1. Go to the Firebase console: https://console.firebase.google.com/
+                2. Choose a Firebase project you've created
+                3. Click "Add Firebase to your web app"
+                4. Replace the following initialization code with the code from the Firebase console:
+        -->
+        <!-- START INITIALIZATION CODE -->
+        <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
+        <script>
+            // Initialize Firebase
+            var config = {
+              apiKey: "AIzaSyAdh562gpCPSX-WYPLUmZuFhXZMMJPvD2M",
+              authDomain: "my-app-ac59b.firebaseapp.com",
+              databaseURL: "https://my-app-ac59b.firebaseio.com",
+              storageBucket: "my-app-ac59b.appspot.com",
+              messagingSenderId: "288252171454"
+            };
+            firebase.initializeApp(config);
+        </script>
+        
+        
+        <!-- END INITIALIZATION CODE -->
+        <!-- ******************************************************** -->
+        <script>
+            var cToken = "";
+            // [START get_messaging_object]
+            // Retrieve Firebase Messaging object.
+            const messaging = firebase.messaging();
+            // [END get_messaging_object]
+            // IDs of divs that display Instance ID token UI or request permission UI.
+            const tokenDivId = 'token_div';
+            const permissionDivId = 'permission_div';
+            // [START refresh_token]
+            // Callback fired if Instance ID token is updated.
+            messaging.onTokenRefresh(function() {
+              messaging.getToken()
+              .then(function(refreshedToken) {
+                console.log('Token refreshed.');
+                // Indicate that the new Instance ID token has not yet been sent to the
+                // app server.
+                setTokenSentToServer(false);
+                // Send Instance ID token to app server.
+                sendTokenToServer(refreshedToken);
+                // [START_EXCLUDE]
+                // Display new Instance ID token and clear UI of all previous messages.
+                resetUI();
+                // [END_EXCLUDE]
+              })
+              .catch(function(err) {
+                console.log('Unable to retrieve refreshed token ', err);
+                showToken('Unable to retrieve refreshed token ', err);
+              });
+            });
+            // [END refresh_token]
+            // [START receive_message]
+            // Handle incoming messages. Called when:
+            // - a message is received while the app has focus
+            // - the user clicks on an app notification created by a sevice worker
+            //   `messaging.setBackgroundMessageHandler` handler.
+            messaging.onMessage(function(payload) {
+              console.log("Message received. ", payload);
+              // [START_EXCLUDE]
+              // Update the UI to include the received message.
+              appendMessage(payload);
+              // [END_EXCLUDE]
+            });
+            // [END receive_message]
+            function resetUI() {
+              clearMessages();
+              showToken('loading...');
+              // [START get_token]
+              // Get Instance ID token. Initially this makes a network call, once retrieved
+              // subsequent calls to getToken will return from cache.
+              messaging.getToken()
+              .then(function(currentToken) {
+                if (currentToken) {
+                  sendTokenToServer(currentToken);
+                  updateUIForPushEnabled(currentToken);
+                } else {
+                  // Show permission request.
+                  console.log('No Instance ID token available. Request permission to generate one.');
+                  // Show permission UI.
+                  updateUIForPushPermissionRequired();
+                  setTokenSentToServer(false);
+                }
+              })
+              .catch(function(err) {
+                console.log('An error occurred while retrieving token. ', err);
+                showToken('Error retrieving Instance ID token. ', err);
+                setTokenSentToServer(false);
+              });
+            }
+            // [END get_token]
+            function showToken(currentToken) {
+              // Show token in console and UI.
+              var tokenElement = document.querySelector('#token');
+              tokenElement.textContent = currentToken;
+            }
+            // Send the Instance ID token your application server, so that it can:
+            // - send messages back to this app
+            // - subscribe/unsubscribe the token from topics
+            function sendTokenToServer(currentToken) {
+              if (!isTokenSentToServer()) {
+                console.log('Sending token to server...');
+                // TODO(developer): Send the current token to your server.
+                // Send the data using post
+                var url = 'http://localhost:8083/chat-server.php';
+                console.log('sending...');               
+                $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                    code: "registerClient",
+                    token: currentToken,
+                    username: "user1",
+                    email: "user1@gmail.com",
+                  },function(res){
+                    alert('Response '+res.response);
+                });
+                cToken = currentToken;
+                
+                setTokenSentToServer(true);
+              } else {
+                console.log('Token already sent to server so won\'t send it again ' +
+                    'unless it changes');
+              }
+            }
+            function isTokenSentToServer() {
+              if (window.localStorage.getItem('sentToServer') == 1) {
+                    return true;
+              }
+              return false;
+            }
+            function setTokenSentToServer(sent) {
+              if (sent) {
+                window.localStorage.setItem('sentToServer', 1);
+              } else {
+                window.localStorage.setItem('sentToServer', 0);
+              }
+            }
+            function showHideDiv(divId, show) {
+              const div = document.querySelector('#' + divId);
+              if (show) {
+                div.style = "display: visible";
+              } else {
+                div.style = "display: none";
+              }
+            }
+            function requestPermission() {
+              console.log('Requesting permission...');
+              // [START request_permission]
+              messaging.requestPermission()
+              .then(function() {
+                console.log('Notification permission granted.');
+                // TODO(developer): Retrieve an Instance ID token for use with FCM.
+                // [START_EXCLUDE]
+                // In many cases once an app has been granted notification permission, it
+                // should update its UI reflecting this.
+                resetUI();
+                // [END_EXCLUDE]
+              })
+              .catch(function(err) {
+                console.log('Unable to get permission to notify.', err);
+              });
+              // [END request_permission]
+            }
+            function deleteToken() {
+              // Delete Instance ID token.
+              // [START delete_token]
+              messaging.getToken()
+              .then(function(currentToken) {
+                messaging.deleteToken(currentToken)
+                .then(function() {
+                  console.log('Token deleted.');
+                  setTokenSentToServer(false);
+                  // [START_EXCLUDE]
+                  // Once token is deleted update UI.
+                  resetUI();
+                  // [END_EXCLUDE]
+                })
+                .catch(function(err) {
+                  console.log('Unable to delete token. ', err);
+                });
+                // [END delete_token]
+              })
+              .catch(function(err) {
+                console.log('Error retrieving Instance ID token. ', err);
+                showToken('Error retrieving Instance ID token. ', err);
+              });
+            }
+            // Add a message to the messages element.
+            function appendMessage(payload) {
+              const messagesElement = document.querySelector('#messages');
+              const dataHeaderELement = document.createElement('h5');
+              const dataElement = document.createElement('pre');
+              dataElement.style = 'overflow-x:hidden;'
+              dataHeaderELement.textContent = 'Received message:';
+              dataElement.textContent = JSON.stringify(payload, null, 2);
+              messagesElement.appendChild(dataHeaderELement);
+              messagesElement.appendChild(dataElement);
+            }
+            // Clear the messages element of all children.
+            function clearMessages() {
+              const messagesElement = document.querySelector('#messages');
+              while (messagesElement.hasChildNodes()) {
+                messagesElement.removeChild(messagesElement.lastChild);
+              }
+            }
+            function updateUIForPushEnabled(currentToken) {
+              showHideDiv(tokenDivId, true);
+              showHideDiv(permissionDivId, false);
+              showToken(currentToken);
+            }
+            function updateUIForPushPermissionRequired() {
+              showHideDiv(tokenDivId, false);
+              showHideDiv(permissionDivId, true);
+            }
+            resetUI();
+        </script>
+        <script>
+            function checkOnlineUsers(currentToken) {
+                console.log('checking online users...');               
+                $.getJSON('http://localhost:8083/chat-server.php?callback=?',{
+                    code: "checkingOnlineUsers",
+                    token: cToken,
+                  },function(res){
+                    console.log('hell');
+                    displayOnlineUsers(res);
+                    alert('Response '+res.response);
+                });
+            }
+            
+            function displayOnlineUsers(payload) {
+                const onlineUsersElement = document.querySelector('#onlineUsers');
+                const dataHeaderELement = document.createElement('h5');
+                const dataElement = document.createElement('pre');
+                dataElement.style = 'overflow-x:hidden;'
+                dataHeaderELement.textContent = 'Received message:';
+                dataElement.textContent = JSON.stringify(payload, null, 2);
+                onlineUsersElement.appendChild(dataHeaderELement);
+                onlineUsersElement.appendChild(dataElement);
+            }
+        </script>
+    </body>
+</html>
diff --git a/Client2/web/login.jsp b/Client2/web/login.jsp
new file mode 100644
index 0000000..3b582c3
--- /dev/null
+++ b/Client2/web/login.jsp
@@ -0,0 +1,31 @@
+<%-- 
+    Document   : login2
+    Created on : Nov 29, 2016, 5:49:15 AM
+    Author     : YUKI
+--%>
+
+<%@page contentType="text/html" pageEncoding="UTF-8"%>
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <title>JSP Page</title>
+    </head>
+    <body>
+        <form method="POST" action="login.jsp" id="loginForm">
+            Email or Username<br><input type="text" name="username" /><br>
+            Password<br><input type="password" name="password"  /><br>
+            <input type="submit" value="LOGIN" name="login" />
+        </form>
+    </body>
+</html>
+<% 
+    if("POST".equalsIgnoreCase(request.getMethod())) {
+        String username = request.getParameter("username");
+        
+        session.setAttribute("username", username);
+//        session.setAttribute("firebaseToken", firebaseToken);
+        response.sendRedirect("catalog.jsp");
+    }
+%>
+        
\ No newline at end of file
diff --git a/Client2/web/logout.jsp b/Client2/web/logout.jsp
new file mode 100644
index 0000000..c9a81d2
--- /dev/null
+++ b/Client2/web/logout.jsp
@@ -0,0 +1,24 @@
+<%-- 
+    Document   : logout
+    Created on : Nov 29, 2016, 6:53:05 AM
+    Author     : YUKI
+--%>
+
+<%@page contentType="text/html" pageEncoding="UTF-8"%>
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <title>JSP Page</title>
+    </head>
+    <body>
+        <h1>Hello World!</h1>
+    </body>
+    <!--Jquery-->
+    <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
+    <script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
+    <script type="text/javascript" src="chat.js"></script>
+    <script>
+        deleteToken();
+    </script>
+</html>
diff --git a/Client2/web/manifest.json b/Client2/web/manifest.json
new file mode 100644
index 0000000..51ef539
--- /dev/null
+++ b/Client2/web/manifest.json
@@ -0,0 +1,5 @@
+{
+  "//": "Some browsers will use this to enable push notifications.",
+  "//": "It is the same for all projects, this is not your project's sender ID",
+  "gcm_sender_id": "103953800507"
+}
\ No newline at end of file
-- 
GitLab