소스 검색

HADOOP-10075. Update jetty dependency to version 9 (rkanter)

Robert Kanter 8 년 전
부모
커밋
5877f20f9c
100개의 변경된 파일5972개의 추가작업 그리고 703개의 파일을 삭제
  1. 10 10
      hadoop-client/pom.xml
  2. 1 1
      hadoop-common-project/hadoop-auth-examples/pom.xml
  3. 12 0
      hadoop-common-project/hadoop-auth-examples/src/main/java/org/apache/hadoop/security/authentication/examples/RequestLoggerFilter.java
  4. 9 4
      hadoop-common-project/hadoop-auth/pom.xml
  5. 18 11
      hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java
  6. 28 6
      hadoop-common-project/hadoop-common/pom.xml
  7. 1 1
      hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/AdminAuthorizedServlet.java
  8. 2 2
      hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpRequestLog.java
  9. 184 121
      hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java
  10. 35 0
      hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/JettyUtils.java
  11. 0 58
      hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SslSelectChannelConnectorSecure.java
  12. 1 1
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/conf/TestConfServlet.java
  13. 2 2
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/FSMainOperationsBaseTest.java
  14. 5 5
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFileSystemTestSetup.java
  15. 5 5
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFsTestSetup.java
  16. 6 5
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestAuthenticationSessionCookie.java
  17. 2 2
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpRequestLog.java
  18. 14 8
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java
  19. 5 2
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestServletFilter.java
  20. 3 2
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/resource/JerseyResource.java
  21. 36 28
      hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/token/delegation/web/TestWebDelegationToken.java
  22. 10 10
      hadoop-common-project/hadoop-kms/pom.xml
  23. 11 10
      hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java
  24. 12 0
      hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSAuthenticationFilter.java
  25. 2 1
      hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
  26. 37 26
      hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
  27. 1 1
      hadoop-common-project/hadoop-nfs/pom.xml
  28. 13 13
      hadoop-hdfs-project/hadoop-hdfs-httpfs/pom.xml
  29. 7 5
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java
  30. 2 1
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/JSONMapProvider.java
  31. 2 1
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/JSONProvider.java
  32. 3 3
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/client/BaseTestHttpFSWith.java
  33. 3 3
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServer.java
  34. 3 3
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServerNoACLs.java
  35. 3 3
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServerNoXAttrs.java
  36. 3 3
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSWithKerberos.java
  37. 4 4
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/test/TestHFSTestCase.java
  38. 4 4
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/test/TestHTestCase.java
  39. 34 22
      hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/test/TestJettyHelper.java
  40. 4 4
      hadoop-hdfs-project/hadoop-hdfs-nfs/pom.xml
  41. 21 4
      hadoop-hdfs-project/hadoop-hdfs/pom.xml
  42. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNode.java
  43. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java
  44. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
  45. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NNStorage.java
  46. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/TransferFsImage.java
  47. 23 16
      hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java
  48. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDecommission.java
  49. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/server/TestJournalNodeMXBean.java
  50. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockStatsMXBean.java
  51. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestDataNodeMXBean.java
  52. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFSNamesystemMBean.java
  53. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java
  54. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestStartupProgressServlet.java
  55. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestTransferFsImage.java
  56. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFSForHA.java
  57. 1 1
      hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/test/MiniDFSClusterManager.java
  58. 21 16
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/JobEndNotifier.java
  59. 33 16
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebServices.java
  60. 21 10
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServices.java
  61. 9 4
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesAttempt.java
  62. 23 11
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesAttempts.java
  63. 9 4
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesJobConf.java
  64. 43 21
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesJobs.java
  65. 41 20
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesTasks.java
  66. 27 13
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsWebServices.java
  67. 17 8
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServices.java
  68. 23 11
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesAttempts.java
  69. 9 4
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesJobConf.java
  70. 45 22
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesJobs.java
  71. 51 25
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesJobsQuery.java
  72. 41 20
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesTasks.java
  73. 7 5
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/NotificationTestCase.java
  74. 1 1
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapreduce/MiniHadoopClusterManager.java
  75. 8 6
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle/src/main/java/org/apache/hadoop/mapred/ShuffleHandler.java
  76. 13 12
      hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle/src/test/java/org/apache/hadoop/mapred/TestShuffleHandler.java
  77. 2 2
      hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
  78. 2 2
      hadoop-mapreduce-project/pom.xml
  79. 4 0
      hadoop-maven-plugins/pom.xml
  80. 125 0
      hadoop-maven-plugins/src/main/java/org/apache/hadoop/maven/plugin/resourcegz/ResourceGzMojo.java
  81. 40 12
      hadoop-project/pom.xml
  82. 1 1
      hadoop-tools/hadoop-azure-datalake/pom.xml
  83. 6 1
      hadoop-tools/hadoop-azure/pom.xml
  84. 1 1
      hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azure/AzureNativeFileSystemStore.java
  85. 3 3
      hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azure/BlockBlobAppendStream.java
  86. 5 5
      hadoop-tools/hadoop-sls/pom.xml
  87. 11 8
      hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/web/SLSWebApp.java
  88. 5 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestAMRMClient.java
  89. 5 5
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java
  90. 14 3
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/pom.xml
  91. 157 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/dt-1.9.4/js/jquery.dataTables.min.js
  92. BIN
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/dt-1.9.4/js/jquery.dataTables.min.js.gz
  93. 1 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-1.8.2.min.js
  94. BIN
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-1.8.2.min.js.gz
  95. 5 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-ui-1.9.1.custom.min.js
  96. BIN
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-ui-1.9.1.custom.min.js.gz
  97. 4544 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jt/jquery.jstree.js
  98. BIN
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jt/jquery.jstree.js.gz
  99. 2 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/MyTestWebService.java
  100. 1 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/pom.xml

+ 10 - 10
hadoop-client/pom.xml

@@ -41,7 +41,7 @@
       <exclusions>
         <exclusion>
           <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
         <exclusion>
           <groupId>commons-logging</groupId>
@@ -49,18 +49,18 @@
         </exclusion>
         <exclusion>
           <groupId>jetty</groupId>
-          <artifactId>org.mortbay.jetty</artifactId>
+          <artifactId>org.eclipse.jetty</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>servlet-api-2.5</artifactId>
         </exclusion>
         <exclusion>
@@ -112,8 +112,8 @@
           <artifactId>avro</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
           <groupId>com.sun.jersey</groupId>
@@ -125,7 +125,7 @@
         </exclusion>
         <exclusion>
           <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
       </exclusions>
     </dependency>
@@ -137,7 +137,7 @@
       <exclusions>
         <exclusion>
           <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
         <exclusion>
           <groupId>org.apache.hadoop</groupId>

+ 1 - 1
hadoop-common-project/hadoop-auth-examples/pom.xml

@@ -34,7 +34,7 @@
   <dependencies>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>

+ 12 - 0
hadoop-common-project/hadoop-auth-examples/src/main/java/org/apache/hadoop/security/authentication/examples/RequestLoggerFilter.java

@@ -139,7 +139,19 @@ public class RequestLoggerFilter implements Filter {
       status = sc;
     }
 
+    /**
+     * Calls setStatus(int sc, String msg) on the wrapped
+     * {@link HttpServletResponseWrapper} object.
+     *
+     * @param sc the status code
+     * @param msg the status message
+     * @deprecated {@link HttpServletResponseWrapper#setStatus(int, String)} is
+     * deprecated. To set a status code use {@link #setStatus(int)}, to send an
+     * error with a description use {@link #sendError(int, String)}
+     */
     @Override
+    @Deprecated
+    @SuppressWarnings("deprecation")
     public void setStatus(int sc, String msg) {
       super.setStatus(sc, msg);
       status = sc;

+ 9 - 4
hadoop-common-project/hadoop-auth/pom.xml

@@ -53,13 +53,18 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
       <scope>test</scope>
     </dependency>
      <dependency>
@@ -74,7 +79,7 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>

+ 18 - 11
hadoop-common-project/hadoop-auth/src/test/java/org/apache/hadoop/security/authentication/client/AuthenticatorTestCase.java

@@ -30,11 +30,14 @@ import org.apache.http.impl.auth.SPNegoScheme;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.util.EntityUtils;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.FilterHolder;
-import org.mortbay.jetty.servlet.ServletHolder;
-
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+
+import javax.servlet.DispatcherType;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -53,6 +56,7 @@ import java.net.HttpURLConnection;
 import java.net.ServerSocket;
 import java.net.URL;
 import java.security.Principal;
+import java.util.EnumSet;
 import java.util.Properties;
 
 import org.junit.Assert;
@@ -63,7 +67,7 @@ public class AuthenticatorTestCase {
   private int port = -1;
   private boolean useTomcat = false;
   private Tomcat tomcat = null;
-  Context context;
+  ServletContextHandler context;
 
   private static Properties authenticatorConfig;
 
@@ -121,16 +125,19 @@ public class AuthenticatorTestCase {
   }
 
   protected void startJetty() throws Exception {
-    server = new Server(0);
-    context = new Context();
+    server = new Server();
+    context = new ServletContextHandler();
     context.setContextPath("/foo");
     server.setHandler(context);
-    context.addFilter(new FilterHolder(TestFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(TestFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(TestServlet.class), "/bar");
     host = "localhost";
     port = getLocalPort();
-    server.getConnectors()[0].setHost(host);
-    server.getConnectors()[0].setPort(port);
+    ServerConnector connector = new ServerConnector(server);
+    connector.setHost(host);
+    connector.setPort(port);
+    server.setConnectors(new Connector[] {connector});
     server.start();
     System.out.println("Running embedded servlet container at: http://" + host + ":" + port);
   }

+ 28 - 6
hadoop-common-project/hadoop-common/pom.xml

@@ -93,24 +93,34 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty-sslengine</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-servlet</artifactId>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-webapp</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-util-ajax</artifactId>
+      <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>javax.servlet.jsp</groupId>
       <artifactId>jsp-api</artifactId>
@@ -412,6 +422,18 @@
               <output>${project.build.directory}/generated-test-sources/java</output>
             </configuration>
           </execution>
+          <execution>
+            <id>resource-gz</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>resource-gz</goal>
+            </goals>
+            <configuration>
+              <inputDirectory>${basedir}/src/main/webapps/static</inputDirectory>
+              <outputDirectory>${basedir}/target/webapps/static</outputDirectory>
+              <extensions>js,css</extensions>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>

+ 1 - 1
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/AdminAuthorizedServlet.java

@@ -23,7 +23,7 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.mortbay.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.DefaultServlet;
 
 /**
  * General servlet which is admin-authorized.

+ 2 - 2
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpRequestLog.java

@@ -25,8 +25,8 @@ import org.apache.commons.logging.LogConfigurationException;
 import org.apache.commons.logging.LogFactory;
 import org.apache.log4j.Appender;
 import org.apache.log4j.Logger;
-import org.mortbay.jetty.NCSARequestLog;
-import org.mortbay.jetty.RequestLog;
+import org.eclipse.jetty.server.NCSARequestLog;
+import org.eclipse.jetty.server.RequestLog;
 
 /**
  * RequestLog object for use with Http

+ 184 - 121
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java

@@ -56,7 +56,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.CommonConfigurationKeys;
 import org.apache.hadoop.security.AuthenticationFilterInitializer;
 import org.apache.hadoop.security.authentication.util.SignerSecretProvider;
-import org.apache.hadoop.security.ssl.SslSelectChannelConnectorSecure;
 import org.apache.hadoop.jmx.JMXJsonServlet;
 import org.apache.hadoop.log.LogLevel;
 import org.apache.hadoop.security.SecurityUtil;
@@ -65,34 +64,39 @@ import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.security.authorize.AccessControlList;
 import org.apache.hadoop.util.ReflectionUtils;
 import org.apache.hadoop.util.Shell;
-import org.mortbay.io.Buffer;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Handler;
-import org.mortbay.jetty.MimeTypes;
-import org.mortbay.jetty.RequestLog;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.SessionManager;
-import org.mortbay.jetty.handler.ContextHandler;
-import org.mortbay.jetty.handler.ContextHandlerCollection;
-import org.mortbay.jetty.handler.HandlerCollection;
-import org.mortbay.jetty.handler.RequestLogHandler;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.security.SslSelectChannelConnector;
-import org.mortbay.jetty.servlet.AbstractSessionManager;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.DefaultServlet;
-import org.mortbay.jetty.servlet.FilterHolder;
-import org.mortbay.jetty.servlet.SessionHandler;
-import org.mortbay.jetty.servlet.FilterMapping;
-import org.mortbay.jetty.servlet.ServletHandler;
-import org.mortbay.jetty.servlet.ServletHolder;
-import org.mortbay.jetty.webapp.WebAppContext;
-import org.mortbay.thread.QueuedThreadPool;
-import org.mortbay.util.MultiException;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.RequestLog;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.server.handler.HandlerCollection;
+import org.eclipse.jetty.server.handler.RequestLogHandler;
+import org.eclipse.jetty.server.session.AbstractSessionManager;
+import org.eclipse.jetty.server.session.SessionHandler;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.ServletMapping;
+import org.eclipse.jetty.util.ArrayUtil;
+import org.eclipse.jetty.util.MultiException;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.sun.jersey.spi.container.servlet.ServletContainer;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 
 /**
  * Create a Jetty embedded server to answer http requests. The primary goal is
@@ -126,11 +130,13 @@ public final class HttpServer2 implements FilterContainer {
 
   protected final Server webServer;
 
-  private final List<Connector> listeners = Lists.newArrayList();
+  private final HandlerCollection handlers;
+
+  private final List<ServerConnector> listeners = Lists.newArrayList();
 
   protected final WebAppContext webAppContext;
   protected final boolean findPort;
-  protected final Map<Context, Boolean> defaultContexts =
+  private final Map<ServletContextHandler, Boolean> defaultContexts =
       new HashMap<>();
   protected final List<String> filterNames = new ArrayList<>();
   static final String STATE_DESCRIPTION_ALIVE = " - alive";
@@ -327,49 +333,59 @@ public final class HttpServer2 implements FilterContainer {
       }
 
       for (URI ep : endpoints) {
-        final Connector listener;
+        final ServerConnector connector;
         String scheme = ep.getScheme();
         if ("http".equals(scheme)) {
-          listener = HttpServer2.createDefaultChannelConnector();
+          connector =
+              HttpServer2.createDefaultChannelConnector(server.webServer);
         } else if ("https".equals(scheme)) {
-          listener = createHttpsChannelConnector();
+          connector = createHttpsChannelConnector(server.webServer);
 
         } else {
           throw new HadoopIllegalArgumentException(
               "unknown scheme for endpoint:" + ep);
         }
-        listener.setHost(ep.getHost());
-        listener.setPort(ep.getPort() == -1 ? 0 : ep.getPort());
-        server.addListener(listener);
+        connector.setHost(ep.getHost());
+        connector.setPort(ep.getPort() == -1 ? 0 : ep.getPort());
+        server.addListener(connector);
       }
       server.loadListeners();
       return server;
     }
 
-    private Connector createHttpsChannelConnector() {
-      SslSelectChannelConnector c = new SslSelectChannelConnectorSecure();
-      configureChannelConnector(c);
-
-      c.setNeedClientAuth(needsClientAuth);
-      c.setKeyPassword(keyPassword);
-
+    private ServerConnector createHttpsChannelConnector(Server server) {
+      ServerConnector conn = new ServerConnector(server);
+      HttpConfiguration httpConfig = new HttpConfiguration();
+      httpConfig.setRequestHeaderSize(JettyUtils.HEADER_SIZE);
+      httpConfig.setResponseHeaderSize(JettyUtils.HEADER_SIZE);
+      httpConfig.setSecureScheme("https");
+      httpConfig.addCustomizer(new SecureRequestCustomizer());
+      ConnectionFactory connFactory = new HttpConnectionFactory(httpConfig);
+      conn.addConnectionFactory(connFactory);
+      configureChannelConnector(conn);
+
+      SslContextFactory sslContextFactory = new SslContextFactory();
+      sslContextFactory.setNeedClientAuth(needsClientAuth);
+      sslContextFactory.setKeyManagerPassword(keyPassword);
       if (keyStore != null) {
-        c.setKeystore(keyStore);
-        c.setKeystoreType(keyStoreType);
-        c.setPassword(keyStorePassword);
+        sslContextFactory.setKeyStorePath(keyStore);
+        sslContextFactory.setKeyStoreType(keyStoreType);
+        sslContextFactory.setKeyStorePassword(keyStorePassword);
       }
-
       if (trustStore != null) {
-        c.setTruststore(trustStore);
-        c.setTruststoreType(trustStoreType);
-        c.setTrustPassword(trustStorePassword);
+        sslContextFactory.setTrustStorePath(trustStore);
+        sslContextFactory.setTrustStoreType(trustStoreType);
+        sslContextFactory.setTrustStorePassword(trustStorePassword);
       }
-
       if(null != excludeCiphers && !excludeCiphers.isEmpty()) {
-        c.setExcludeCipherSuites(excludeCiphers.split(","));
+        sslContextFactory.setExcludeCipherSuites(excludeCiphers.split(","));
         LOG.info("Excluded Cipher List:" + excludeCiphers);
       }
-      return c;
+
+      conn.addFirstConnectionFactory(new SslConnectionFactory(sslContextFactory,
+          HttpVersion.HTTP_1_1.asString()));
+
+      return conn;
     }
   }
 
@@ -377,6 +393,7 @@ public final class HttpServer2 implements FilterContainer {
     final String appDir = getWebAppsPath(b.name);
     this.webServer = new Server();
     this.adminsAcl = b.adminsAcl;
+    this.handlers = new HandlerCollection();
     this.webAppContext = createWebAppContext(b.name, b.conf, adminsAcl, appDir);
     this.xFrameOptionIsEnabled = b.xFrameEnabled;
     this.xFrameOption = b.xFrameOption;
@@ -406,36 +423,33 @@ public final class HttpServer2 implements FilterContainer {
     int maxThreads = conf.getInt(HTTP_MAX_THREADS, -1);
     // If HTTP_MAX_THREADS is not configured, QueueThreadPool() will use the
     // default value (currently 250).
-    QueuedThreadPool threadPool = maxThreads == -1 ? new QueuedThreadPool()
-        : new QueuedThreadPool(maxThreads);
+
+    QueuedThreadPool threadPool = (QueuedThreadPool) webServer.getThreadPool();
     threadPool.setDaemon(true);
-    webServer.setThreadPool(threadPool);
+    if (maxThreads != -1) {
+      threadPool.setMaxThreads(maxThreads);
+    }
 
     SessionManager sm = webAppContext.getSessionHandler().getSessionManager();
     if (sm instanceof AbstractSessionManager) {
       AbstractSessionManager asm = (AbstractSessionManager)sm;
       asm.setHttpOnly(true);
-      asm.setSecureCookies(true);
+      asm.getSessionCookieConfig().setSecure(true);
     }
 
     ContextHandlerCollection contexts = new ContextHandlerCollection();
     RequestLog requestLog = HttpRequestLog.getRequestLog(name);
 
+    handlers.addHandler(contexts);
     if (requestLog != null) {
       RequestLogHandler requestLogHandler = new RequestLogHandler();
       requestLogHandler.setRequestLog(requestLog);
-      HandlerCollection handlers = new HandlerCollection();
-      handlers.setHandlers(new Handler[] {contexts, requestLogHandler});
-      webServer.setHandler(handlers);
-    } else {
-      webServer.setHandler(contexts);
+      handlers.addHandler(requestLogHandler);
     }
-
+    handlers.addHandler(webAppContext);
     final String appDir = getWebAppsPath(name);
-
-    webServer.addHandler(webAppContext);
-
     addDefaultApps(contexts, appDir, conf);
+    webServer.setHandler(handlers);
 
     Map<String, String> xFrameParams = new HashMap<>();
     xFrameParams.put(X_FRAME_ENABLED,
@@ -461,7 +475,7 @@ public final class HttpServer2 implements FilterContainer {
     }
   }
 
-  private void addListener(Connector connector) {
+  private void addListener(ServerConnector connector) {
     listeners.add(connector);
   }
 
@@ -507,16 +521,14 @@ public final class HttpServer2 implements FilterContainer {
     return prop;
   }
 
-  private static void addNoCacheFilter(WebAppContext ctxt) {
+  private static void addNoCacheFilter(ServletContextHandler ctxt) {
     defineFilter(ctxt, NO_CACHE_FILTER, NoCacheFilter.class.getName(),
                  Collections.<String, String> emptyMap(), new String[] { "/*" });
   }
 
-  private static void configureChannelConnector(SelectChannelConnector c) {
-    c.setLowResourceMaxIdleTime(10000);
+  private static void configureChannelConnector(ServerConnector c) {
+    c.setIdleTimeout(10000);
     c.setAcceptQueueSize(128);
-    c.setResolveNames(false);
-    c.setUseDirectBuffers(false);
     if(Shell.WINDOWS) {
       // result of setting the SO_REUSEADDR flag is different on Windows
       // http://msdn.microsoft.com/en-us/library/ms740621(v=vs.85).aspx
@@ -524,14 +536,18 @@ public final class HttpServer2 implements FilterContainer {
       // the same port with indeterminate routing of incoming requests to them
       c.setReuseAddress(false);
     }
-    c.setHeaderBufferSize(1024*64);
   }
 
   @InterfaceAudience.Private
-  public static Connector createDefaultChannelConnector() {
-    SelectChannelConnector ret = new SelectChannelConnector();
-    configureChannelConnector(ret);
-    return ret;
+  public static ServerConnector createDefaultChannelConnector(Server server) {
+    ServerConnector conn = new ServerConnector(server);
+    HttpConfiguration httpConfig = new HttpConfiguration();
+    httpConfig.setRequestHeaderSize(JettyUtils.HEADER_SIZE);
+    httpConfig.setResponseHeaderSize(JettyUtils.HEADER_SIZE);
+    ConnectionFactory connFactory = new HttpConnectionFactory(httpConfig);
+    conn.addConnectionFactory(connFactory);
+    configureChannelConnector(conn);
+    return conn;
   }
 
   /** Get an array of FilterConfiguration specified in the conf */
@@ -567,7 +583,8 @@ public final class HttpServer2 implements FilterContainer {
         CommonConfigurationKeys.HADOOP_HTTP_LOGS_ENABLED,
         CommonConfigurationKeys.HADOOP_HTTP_LOGS_ENABLED_DEFAULT);
     if (logDir != null && logsEnabled) {
-      Context logContext = new Context(parent, "/logs");
+      ServletContextHandler logContext =
+          new ServletContextHandler(parent, "/logs");
       logContext.setResourceBase(logDir);
       logContext.addServlet(AdminAuthorizedServlet.class, "/*");
       if (conf.getBoolean(
@@ -575,8 +592,7 @@ public final class HttpServer2 implements FilterContainer {
           CommonConfigurationKeys.DEFAULT_HADOOP_JETTY_LOGS_SERVE_ALIASES)) {
         @SuppressWarnings("unchecked")
         Map<String, String> params = logContext.getInitParams();
-        params.put(
-            "org.mortbay.jetty.servlet.Default.aliases", "true");
+        params.put("org.eclipse.jetty.servlet.Default.aliases", "true");
       }
       logContext.setDisplayName("logs");
       SessionHandler handler = new SessionHandler();
@@ -584,34 +600,37 @@ public final class HttpServer2 implements FilterContainer {
       if (sm instanceof AbstractSessionManager) {
         AbstractSessionManager asm = (AbstractSessionManager) sm;
         asm.setHttpOnly(true);
-        asm.setSecureCookies(true);
+        asm.getSessionCookieConfig().setSecure(true);
       }
       logContext.setSessionHandler(handler);
       setContextAttributes(logContext, conf);
-      addNoCacheFilter(webAppContext);
+      addNoCacheFilter(logContext);
       defaultContexts.put(logContext, true);
     }
     // set up the context for "/static/*"
-    Context staticContext = new Context(parent, "/static");
+    ServletContextHandler staticContext =
+        new ServletContextHandler(parent, "/static");
     staticContext.setResourceBase(appDir + "/static");
     staticContext.addServlet(DefaultServlet.class, "/*");
     staticContext.setDisplayName("static");
     @SuppressWarnings("unchecked")
     Map<String, String> params = staticContext.getInitParams();
-    params.put("org.mortbay.jetty.servlet.Default.dirAllowed", "false");
+    params.put("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
+    params.put("org.eclipse.jetty.servlet.Default.gzip", "true");
     SessionHandler handler = new SessionHandler();
     SessionManager sm = handler.getSessionManager();
     if (sm instanceof AbstractSessionManager) {
       AbstractSessionManager asm = (AbstractSessionManager) sm;
       asm.setHttpOnly(true);
-      asm.setSecureCookies(true);
+      asm.getSessionCookieConfig().setSecure(true);
     }
     staticContext.setSessionHandler(handler);
     setContextAttributes(staticContext, conf);
     defaultContexts.put(staticContext, true);
   }
 
-  private void setContextAttributes(Context context, Configuration conf) {
+  private void setContextAttributes(ServletContextHandler context,
+                                    Configuration conf) {
     context.getServletContext().setAttribute(CONF_CONTEXT_ATTRIBUTE, conf);
     context.getServletContext().setAttribute(ADMINS_ACL, adminsAcl);
   }
@@ -627,9 +646,9 @@ public final class HttpServer2 implements FilterContainer {
     addServlet("conf", "/conf", ConfServlet.class);
   }
 
-  public void addContext(Context ctxt, boolean isFiltered) {
-    webServer.addHandler(ctxt);
-    addNoCacheFilter(webAppContext);
+  public void addContext(ServletContextHandler ctxt, boolean isFiltered) {
+    handlers.addHandler(ctxt);
+    addNoCacheFilter(ctxt);
     defaultContexts.put(ctxt, isFiltered);
   }
 
@@ -691,7 +710,7 @@ public final class HttpServer2 implements FilterContainer {
    * protect with Kerberos authentication.
    * Note: This method is to be used for adding servlets that facilitate
    * internal communication and not for user facing functionality. For
-   +   * servlets added using this method, filters (except internal Kerberos
+   * servlets added using this method, filters (except internal Kerberos
    * filters) are not enabled.
    *
    * @param name The name of the servlet (can be passed as null)
@@ -705,19 +724,58 @@ public final class HttpServer2 implements FilterContainer {
     if (name != null) {
       holder.setName(name);
     }
+    // Jetty doesn't like the same path spec mapping to different servlets, so
+    // if there's already a mapping for this pathSpec, remove it and assume that
+    // the newest one is the one we want
+    final ServletMapping[] servletMappings =
+        webAppContext.getServletHandler().getServletMappings();
+    for (int i = 0; i < servletMappings.length; i++) {
+      if (servletMappings[i].containsPathSpec(pathSpec)) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Found existing " + servletMappings[i].getServletName() +
+              " servlet at path " + pathSpec + "; will replace mapping" +
+              " with " + holder.getName() + " servlet");
+        }
+        ServletMapping[] newServletMappings =
+            ArrayUtil.removeFromArray(servletMappings, servletMappings[i]);
+        webAppContext.getServletHandler()
+            .setServletMappings(newServletMappings);
+        break;
+      }
+    }
     webAppContext.addServlet(holder, pathSpec);
 
     if(requireAuth && UserGroupInformation.isSecurityEnabled()) {
-       LOG.info("Adding Kerberos (SPNEGO) filter to " + name);
-       ServletHandler handler = webAppContext.getServletHandler();
-       FilterMapping fmap = new FilterMapping();
-       fmap.setPathSpec(pathSpec);
-       fmap.setFilterName(SPNEGO_FILTER);
-       fmap.setDispatches(Handler.ALL);
-       handler.addFilterMapping(fmap);
+      LOG.info("Adding Kerberos (SPNEGO) filter to " + name);
+      ServletHandler handler = webAppContext.getServletHandler();
+      FilterMapping fmap = new FilterMapping();
+      fmap.setPathSpec(pathSpec);
+      fmap.setFilterName(SPNEGO_FILTER);
+      fmap.setDispatches(FilterMapping.ALL);
+      handler.addFilterMapping(fmap);
     }
   }
 
+  /**
+   * Add the given handler to the front of the list of handlers.
+   *
+   * @param handler The handler to add
+   */
+  public void addHandlerAtFront(Handler handler) {
+    Handler[] h = ArrayUtil.prependToArray(
+        handler, this.handlers.getHandlers(), Handler.class);
+    handlers.setHandlers(h);
+  }
+
+  /**
+   * Add the given handler to the end of the list of handlers.
+   *
+   * @param handler The handler to add
+   */
+  public void addHandlerAtEnd(Handler handler) {
+    handlers.addHandler(handler);
+  }
+
   @Override
   public void addFilter(String name, String classname,
       Map<String, String> parameters) {
@@ -727,12 +785,14 @@ public final class HttpServer2 implements FilterContainer {
     FilterMapping fmap = getFilterMapping(name, USER_FACING_URLS);
     defineFilter(webAppContext, filterHolder, fmap);
     LOG.info(
-        "Added filter " + name + " (class=" + classname + ") to context " + webAppContext.getDisplayName());
+        "Added filter " + name + " (class=" + classname + ") to context "
+            + webAppContext.getDisplayName());
     final String[] ALL_URLS = { "/*" };
     fmap = getFilterMapping(name, ALL_URLS);
-    for (Map.Entry<Context, Boolean> e : defaultContexts.entrySet()) {
+    for (Map.Entry<ServletContextHandler, Boolean> e
+        : defaultContexts.entrySet()) {
       if (e.getValue()) {
-        Context ctx = e.getKey();
+        ServletContextHandler ctx = e.getKey();
         defineFilter(ctx, filterHolder, fmap);
         LOG.info("Added filter " + name + " (class=" + classname
             + ") to context " + ctx.getDisplayName());
@@ -748,7 +808,7 @@ public final class HttpServer2 implements FilterContainer {
     FilterHolder filterHolder = getFilterHolder(name, classname, parameters);
     FilterMapping fmap = getFilterMapping(name, ALL_URLS);
     defineFilter(webAppContext, filterHolder, fmap);
-    for (Context ctx : defaultContexts.keySet()) {
+    for (ServletContextHandler ctx : defaultContexts.keySet()) {
       defineFilter(ctx, filterHolder, fmap);
     }
     LOG.info("Added global filter '" + name + "' (class=" + classname + ")");
@@ -757,7 +817,7 @@ public final class HttpServer2 implements FilterContainer {
   /**
    * Define a filter for a context and set up default url mappings.
    */
-  public static void defineFilter(Context ctx, String name,
+  public static void defineFilter(ServletContextHandler ctx, String name,
       String classname, Map<String,String> parameters, String[] urls) {
     FilterHolder filterHolder = getFilterHolder(name, classname, parameters);
     FilterMapping fmap = getFilterMapping(name, urls);
@@ -767,8 +827,8 @@ public final class HttpServer2 implements FilterContainer {
   /**
    * Define a filter for a context and set up default url mappings.
    */
-  private static void defineFilter(Context ctx, FilterHolder holder,
-      FilterMapping fmap) {
+  private static void defineFilter(ServletContextHandler ctx,
+                                   FilterHolder holder, FilterMapping fmap) {
     ServletHandler handler = ctx.getServletHandler();
     handler.addFilter(holder, fmap);
   }
@@ -776,7 +836,7 @@ public final class HttpServer2 implements FilterContainer {
   private static FilterMapping getFilterMapping(String name, String[] urls) {
     FilterMapping fmap = new FilterMapping();
     fmap.setPathSpecs(urls);
-    fmap.setDispatches(Handler.ALL);
+    fmap.setDispatches(FilterMapping.ALL);
     fmap.setFilterName(name);
     return fmap;
   }
@@ -786,7 +846,9 @@ public final class HttpServer2 implements FilterContainer {
     FilterHolder holder = new FilterHolder();
     holder.setName(name);
     holder.setClassName(classname);
-    holder.setInitParameters(parameters);
+    if (parameters != null) {
+      holder.setInitParameters(parameters);
+    }
     return holder;
   }
 
@@ -796,13 +858,13 @@ public final class HttpServer2 implements FilterContainer {
    * @param webAppCtx The WebApplicationContext to add to
    */
   protected void addFilterPathMapping(String pathSpec,
-      Context webAppCtx) {
+      ServletContextHandler webAppCtx) {
     ServletHandler handler = webAppCtx.getServletHandler();
     for(String name : filterNames) {
       FilterMapping fmap = new FilterMapping();
       fmap.setPathSpec(pathSpec);
       fmap.setFilterName(name);
-      fmap.setDispatches(Handler.ALL);
+      fmap.setDispatches(FilterMapping.ALL);
       handler.addFilterMapping(fmap);
     }
   }
@@ -841,23 +903,23 @@ public final class HttpServer2 implements FilterContainer {
    */
   @Deprecated
   public int getPort() {
-    return webServer.getConnectors()[0].getLocalPort();
+    return ((ServerConnector)webServer.getConnectors()[0]).getLocalPort();
   }
 
   /**
    * Get the address that corresponds to a particular connector.
    *
    * @return the corresponding address for the connector, or null if there's no
-   *         such connector or the connector is not bounded.
+   *         such connector or the connector is not bounded or was closed.
    */
   public InetSocketAddress getConnectorAddress(int index) {
     Preconditions.checkArgument(index >= 0);
     if (index > webServer.getConnectors().length)
       return null;
 
-    Connector c = webServer.getConnectors()[index];
-    if (c.getLocalPort() == -1) {
-      // The connector is not bounded
+    ServerConnector c = (ServerConnector)webServer.getConnectors()[index];
+    if (c.getLocalPort() == -1 || c.getLocalPort() == -2) {
+      // The connector is not bounded or was closed
       return null;
     }
 
@@ -907,8 +969,8 @@ public final class HttpServer2 implements FilterContainer {
         throw ex;
       }
       // Make sure there is no handler failures.
-      Handler[] handlers = webServer.getHandlers();
-      for (Handler handler : handlers) {
+      Handler[] hs = webServer.getHandlers();
+      for (Handler handler : hs) {
         if (handler.isFailed()) {
           throw new IOException(
               "Problem in starting http server. Server handlers failed");
@@ -944,9 +1006,10 @@ public final class HttpServer2 implements FilterContainer {
    * @throws Exception
    */
   void openListeners() throws Exception {
-    for (Connector listener : listeners) {
-      if (listener.getLocalPort() != -1) {
-        // This listener is either started externally or has been bound
+    for (ServerConnector listener : listeners) {
+      if (listener.getLocalPort() != -1 && listener.getLocalPort() != -2) {
+        // This listener is either started externally or has been bound or was
+        // closed
         continue;
       }
       int port = listener.getPort();
@@ -978,7 +1041,7 @@ public final class HttpServer2 implements FilterContainer {
    */
   public void stop() throws Exception {
     MultiException exception = null;
-    for (Connector c : listeners) {
+    for (ServerConnector c : listeners) {
       try {
         c.close();
       } catch (Exception e) {
@@ -1042,7 +1105,7 @@ public final class HttpServer2 implements FilterContainer {
         .append(isAlive() ? STATE_DESCRIPTION_ALIVE
                     : STATE_DESCRIPTION_NOT_LIVE)
         .append("), listening at:");
-    for (Connector l : listeners) {
+    for (ServerConnector l : listeners) {
       sb.append(l.getHost()).append(":").append(l.getPort()).append("/,");
     }
     return sb.toString();
@@ -1300,10 +1363,10 @@ public final class HttpServer2 implements FilterContainer {
      */
     private String inferMimeType(ServletRequest request) {
       String path = ((HttpServletRequest)request).getRequestURI();
-      ContextHandler.SContext sContext = (ContextHandler.SContext)config.getServletContext();
-      MimeTypes mimes = sContext.getContextHandler().getMimeTypes();
-      Buffer mimeBuffer = mimes.getMimeByExtension(path);
-      return (mimeBuffer == null) ? null : mimeBuffer.toString();
+      ServletContextHandler.Context sContext =
+          (ServletContextHandler.Context)config.getServletContext();
+      String mime = sContext.getMimeType(path);
+      return (mime == null) ? null : mime;
     }
 
   }

+ 35 - 0
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/JettyUtils.java

@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.http;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Contains utility methods and constants relating to Jetty.
+ */
+@InterfaceAudience.Public
+@InterfaceStability.Evolving
+public final class JettyUtils {
+  public static final String UTF_8 = "charset=utf-8";
+  public static final int HEADER_SIZE = 1024 * 64;
+
+  private JettyUtils() {
+  }
+}

+ 0 - 58
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/SslSelectChannelConnectorSecure.java

@@ -1,58 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hadoop.security.ssl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-import javax.net.ssl.SSLEngine;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.mortbay.jetty.security.SslSelectChannelConnector;
-
-/**
- * This subclass of the Jetty SslSelectChannelConnector exists solely to
- * control the TLS protocol versions allowed.  This is fallout from the
- * POODLE vulnerability (CVE-2014-3566), which requires that SSLv3 be disabled.
- * Only TLS 1.0 and later protocols are allowed.
- */
-@InterfaceAudience.Private
-public class SslSelectChannelConnectorSecure extends SslSelectChannelConnector {
-
-  public SslSelectChannelConnectorSecure() {
-    super();
-  }
-
-  /**
-   * Disable SSLv3 protocol.
-   */
-  @Override
-  protected SSLEngine createSSLEngine() throws IOException {
-    SSLEngine engine = super.createSSLEngine();
-    ArrayList<String> nonSSLProtocols = new ArrayList<String>();
-    for (String p : engine.getEnabledProtocols()) {
-      if (!p.contains("SSLv3")) {
-        nonSSLProtocols.add(p);
-      }
-    }
-    engine.setEnabledProtocols(nonSSLProtocols.toArray(
-        new String[nonSSLProtocols.size()]));
-    return engine;
-  }
-}

+ 1 - 1
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/conf/TestConfServlet.java

@@ -31,7 +31,7 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;

+ 2 - 2
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/FSMainOperationsBaseTest.java

@@ -32,7 +32,7 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 /**
  * <p>
@@ -797,7 +797,7 @@ public abstract class FSMainOperationsBaseTest extends FileSystemTestHelper {
       rename(src, dst, false, false, false, Rename.NONE);
       Assert.fail("Should throw FileNotFoundException");
     } catch (IOException e) {
-      Log.info("XXX", e);
+      Log.getLog().info("XXX", e);
       Assert.assertTrue(unwrapException(e) instanceof FileNotFoundException);
     }
 

+ 5 - 5
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFileSystemTestSetup.java

@@ -27,7 +27,7 @@ import org.apache.hadoop.fs.FsConstants;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.viewfs.ConfigUtil;
 import org.apache.hadoop.util.Shell;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 
 /**
@@ -84,7 +84,7 @@ public class ViewFileSystemTestSetup {
 
     FileSystem fsView = FileSystem.get(FsConstants.VIEWFS_URI, conf);
     fsView.setWorkingDirectory(new Path(wdDir)); // in case testdir relative to wd.
-    Log.info("Working dir is: " + fsView.getWorkingDirectory());
+    Log.getLog().info("Working dir is: " + fsView.getWorkingDirectory());
     return fsView;
   }
 
@@ -118,12 +118,12 @@ public class ViewFileSystemTestSetup {
     } else { // home dir is at root. Just link the home dir itse
       URI linkTarget = fsTarget.makeQualified(new Path(homeDir)).toUri();
       ConfigUtil.addLink(conf, homeDir, linkTarget);
-      Log.info("Added link for home dir " + homeDir + "->" + linkTarget);
+      Log.getLog().info("Added link for home dir " + homeDir + "->" + linkTarget);
     }
     // Now set the root of the home dir for viewfs
     String homeDirRoot = fsTarget.getHomeDirectory().getParent().toUri().getPath();
     ConfigUtil.setHomeDirConf(conf, homeDirRoot);
-    Log.info("Home dir base for viewfs" + homeDirRoot);  
+    Log.getLog().info("Home dir base for viewfs" + homeDirRoot);
   }
   
   /*
@@ -138,7 +138,7 @@ public class ViewFileSystemTestSetup {
     String firstComponent = path.substring(0, indexOfEnd);
     URI linkTarget = fsTarget.makeQualified(new Path(firstComponent)).toUri();
     ConfigUtil.addLink(conf, firstComponent, linkTarget);
-    Log.info("Added link for " + info + " " 
+    Log.getLog().info("Added link for " + info + " "
         + firstComponent + "->" + linkTarget);    
   }
 }

+ 5 - 5
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/ViewFsTestSetup.java

@@ -26,7 +26,7 @@ import org.apache.hadoop.fs.FsConstants;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.viewfs.ConfigUtil;
 import org.apache.hadoop.util.Shell;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 
 /**
@@ -82,7 +82,7 @@ public class ViewFsTestSetup {
     
     FileContext fc = FileContext.getFileContext(FsConstants.VIEWFS_URI, conf);
     fc.setWorkingDirectory(new Path(wdDir)); // in case testdir relative to wd.
-    Log.info("Working dir is: " + fc.getWorkingDirectory());
+    Log.getLog().info("Working dir is: " + fc.getWorkingDirectory());
     //System.out.println("SRCOfTests = "+ getTestRootPath(fc, "test"));
     //System.out.println("TargetOfTests = "+ targetOfTests.toUri());
     return fc;
@@ -107,12 +107,12 @@ public class ViewFsTestSetup {
     } else { // home dir is at root. Just link the home dir itse
       URI linkTarget = fsTarget.makeQualified(new Path(homeDir)).toUri();
       ConfigUtil.addLink(conf, homeDir, linkTarget);
-      Log.info("Added link for home dir " + homeDir + "->" + linkTarget);
+      Log.getLog().info("Added link for home dir " + homeDir + "->" + linkTarget);
     }
     // Now set the root of the home dir for viewfs
     String homeDirRoot = fsTarget.getHomeDirectory().getParent().toUri().getPath();
     ConfigUtil.setHomeDirConf(conf, homeDirRoot);
-    Log.info("Home dir base for viewfs" + homeDirRoot);  
+    Log.getLog().info("Home dir base for viewfs" + homeDirRoot);
   }
   
   /*
@@ -128,7 +128,7 @@ public class ViewFsTestSetup {
     String firstComponent = path.substring(0, indexOfEnd);
     URI linkTarget = fsTarget.makeQualified(new Path(firstComponent)).toUri();
     ConfigUtil.addLink(conf, firstComponent, linkTarget);
-    Log.info("Added link for " + info + " " 
+    Log.getLog().info("Added link for " + info + " "
         + firstComponent + "->" + linkTarget);    
   }
 

+ 6 - 5
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestAuthenticationSessionCookie.java

@@ -22,7 +22,7 @@ import org.apache.hadoop.security.ssl.KeyStoreTestUtil;
 import org.apache.hadoop.test.GenericTestUtils;
 import org.junit.After;
 import org.junit.Test;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 import javax.servlet.*;
 import javax.servlet.http.HttpServletResponse;
@@ -33,6 +33,7 @@ import java.net.HttpURLConnection;
 import java.net.URI;
 import java.net.URL;
 import java.net.HttpCookie;
+import java.util.HashMap;
 import java.util.List;
 
 public class TestAuthenticationSessionCookie {
@@ -71,7 +72,7 @@ public class TestAuthenticationSessionCookie {
     @Override
     public void initFilter(FilterContainer container, Configuration conf) {
       container.addFilter("DummyAuth", DummyAuthenticationFilter.class
-              .getName(), null);
+              .getName(), new HashMap<>());
     }
   }
 
@@ -93,7 +94,7 @@ public class TestAuthenticationSessionCookie {
     @Override
     public void initFilter(FilterContainer container, Configuration conf) {
       container.addFilter("Dummy2Auth", Dummy2AuthenticationFilter.class
-              .getName(), null);
+              .getName(), new HashMap<>());
     }
   }
 
@@ -149,7 +150,7 @@ public class TestAuthenticationSessionCookie {
     String header = conn.getHeaderField("Set-Cookie");
     List<HttpCookie> cookies = HttpCookie.parse(header);
     Assert.assertTrue(!cookies.isEmpty());
-    Log.info(header);
+    Log.getLog().info(header);
     Assert.assertFalse(header.contains("; Expires="));
     Assert.assertTrue("token".equals(cookies.get(0).getValue()));
   }
@@ -171,7 +172,7 @@ public class TestAuthenticationSessionCookie {
     String header = conn.getHeaderField("Set-Cookie");
     List<HttpCookie> cookies = HttpCookie.parse(header);
     Assert.assertTrue(!cookies.isEmpty());
-    Log.info(header);
+    Log.getLog().info(header);
     Assert.assertTrue(header.contains("; Expires="));
     Assert.assertTrue("token".equals(cookies.get(0).getValue()));
   }

+ 2 - 2
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpRequestLog.java

@@ -18,9 +18,9 @@
 package org.apache.hadoop.http;
 
 import org.apache.log4j.Logger;
+import org.eclipse.jetty.server.NCSARequestLog;
+import org.eclipse.jetty.server.RequestLog;
 import org.junit.Test;
-import org.mortbay.jetty.NCSARequestLog;
-import org.mortbay.jetty.RequestLog;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;

+ 14 - 8
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java

@@ -28,6 +28,8 @@ import org.apache.hadoop.security.Groups;
 import org.apache.hadoop.security.ShellBasedUnixGroupsMapping;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.authorize.AccessControlList;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.ajax.JSON;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -36,8 +38,6 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.Mockito;
 import org.mockito.internal.util.reflection.Whitebox;
-import org.mortbay.jetty.Connector;
-import org.mortbay.util.ajax.JSON;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -50,6 +50,7 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.HttpURLConnection;
@@ -81,6 +82,7 @@ public class TestHttpServer extends HttpServerFunctionalTest {
     public void doGet(HttpServletRequest request, 
                       HttpServletResponse response
                       ) throws ServletException, IOException {
+      response.setContentType(MediaType.TEXT_PLAIN + "; " + JettyUtils.UTF_8);
       PrintWriter out = response.getWriter();
       Map<String, String[]> params = request.getParameterMap();
       SortedSet<String> keys = new TreeSet<String>(params.keySet());
@@ -108,6 +110,7 @@ public class TestHttpServer extends HttpServerFunctionalTest {
     public void doGet(HttpServletRequest request, 
                       HttpServletResponse response
                       ) throws ServletException, IOException {
+      response.setContentType(MediaType.TEXT_PLAIN + "; " + JettyUtils.UTF_8);
       PrintWriter out = response.getWriter();
       SortedSet<String> sortedKeys = new TreeSet<String>();
       Enumeration<String> keys = request.getParameterNames();
@@ -130,7 +133,7 @@ public class TestHttpServer extends HttpServerFunctionalTest {
     public void doGet(HttpServletRequest request, 
                       HttpServletResponse response
                       ) throws ServletException, IOException {
-      response.setContentType("text/html");
+      response.setContentType(MediaType.TEXT_HTML + "; " + JettyUtils.UTF_8);
       PrintWriter out = response.getWriter();
       out.print("hello world");
       out.close();
@@ -222,7 +225,8 @@ public class TestHttpServer extends HttpServerFunctionalTest {
     conn = (HttpURLConnection)servletUrl.openConnection();
     conn.connect();
     assertEquals(200, conn.getResponseCode());
-    assertEquals("text/plain; charset=utf-8", conn.getContentType());
+    assertEquals(MediaType.TEXT_PLAIN + ";" + JettyUtils.UTF_8,
+        conn.getContentType());
 
     // We should ignore parameters for mime types - ie a parameter
     // ending in .css should not change mime type
@@ -230,14 +234,16 @@ public class TestHttpServer extends HttpServerFunctionalTest {
     conn = (HttpURLConnection)servletUrl.openConnection();
     conn.connect();
     assertEquals(200, conn.getResponseCode());
-    assertEquals("text/plain; charset=utf-8", conn.getContentType());
+    assertEquals(MediaType.TEXT_PLAIN + ";" + JettyUtils.UTF_8,
+        conn.getContentType());
 
     // Servlets that specify text/html should get that content type
     servletUrl = new URL(baseUrl, "/htmlcontent");
     conn = (HttpURLConnection)servletUrl.openConnection();
     conn.connect();
     assertEquals(200, conn.getResponseCode());
-    assertEquals("text/html; charset=utf-8", conn.getContentType());
+    assertEquals(MediaType.TEXT_HTML + ";" + JettyUtils.UTF_8,
+        conn.getContentType());
   }
 
   @Test
@@ -488,7 +494,7 @@ public class TestHttpServer extends HttpServerFunctionalTest {
 
   @SuppressWarnings("unchecked")
   private static Map<String, Object> parse(String jsonString) {
-    return (Map<String, Object>)JSON.parse(jsonString);
+    return (Map<String, Object>) JSON.parse(jsonString);
   }
 
   @Test public void testJersey() throws Exception {
@@ -592,7 +598,7 @@ public class TestHttpServer extends HttpServerFunctionalTest {
       // not bound, ephemeral should return requested port (0 for ephemeral)
       List<?> listeners = (List<?>) Whitebox.getInternalState(server,
           "listeners");
-      Connector listener = (Connector) listeners.get(0);
+      ServerConnector listener = (ServerConnector)listeners.get(0);
 
       assertEquals(port, listener.getPort());
       // verify hostname is what was given

+ 5 - 2
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestServletFilter.java

@@ -146,9 +146,11 @@ public class TestServletFilter extends HttpServerFunctionalTest {
   }
   
   static public class ErrorFilter extends SimpleFilter {
+    static final String EXCEPTION_MESSAGE =
+        "Throwing the exception from Filter init";
     @Override
     public void init(FilterConfig arg0) throws ServletException {
-      throw new ServletException("Throwing the exception from Filter init");
+      throw new ServletException(EXCEPTION_MESSAGE);
     }
 
     /** Configuration for the filter */
@@ -174,7 +176,8 @@ public class TestServletFilter extends HttpServerFunctionalTest {
       http.start();
       fail("expecting exception");
     } catch (IOException e) {
-      assertTrue( e.getMessage().contains("Problem in starting http server. Server handlers failed"));
+      assertEquals("Problem starting http server", e.getMessage());
+      assertEquals(ErrorFilter.EXCEPTION_MESSAGE, e.getCause().getMessage());
     }
   }
   

+ 3 - 2
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/resource/JerseyResource.java

@@ -32,7 +32,8 @@ import javax.ws.rs.core.Response;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.mortbay.util.ajax.JSON;
+import org.apache.hadoop.http.JettyUtils;
+import org.eclipse.jetty.util.ajax.JSON;
 
 /**
  * A simple Jersey resource class TestHttpServer.
@@ -48,7 +49,7 @@ public class JerseyResource {
 
   @GET
   @Path("{" + PATH + ":.*}")
-  @Produces({MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response get(
       @PathParam(PATH) @DefaultValue("UNKNOWN_" + PATH) final String path,
       @QueryParam(OP) @DefaultValue("UNKNOWN_" + OP) final String op

+ 36 - 28
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/token/delegation/web/TestWebDelegationToken.java

@@ -31,22 +31,22 @@ import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHand
 import org.apache.hadoop.security.authentication.util.KerberosUtil;
 import org.apache.hadoop.security.token.delegation.AbstractDelegationTokenSecretManager;
 import org.codehaus.jackson.map.ObjectMapper;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.mortbay.jetty.AbstractConnector;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.FilterHolder;
-import org.mortbay.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
 
 import javax.security.auth.Subject;
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.login.AppConfigurationEntry;
 import javax.security.auth.login.Configuration;
 import javax.security.auth.login.LoginContext;
+import javax.servlet.DispatcherType;
 import javax.servlet.Filter;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
@@ -66,6 +66,7 @@ import java.net.URL;
 import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -177,7 +178,7 @@ public class TestWebDelegationToken {
   protected Server createJettyServer() {
     try {
       jetty = new Server(0);
-      jetty.getConnectors()[0].setHost("localhost");
+      ((ServerConnector)jetty.getConnectors()[0]).setHost("localhost");
       return jetty;
     } catch (Exception ex) {
       throw new RuntimeException("Could not setup Jetty: " + ex.getMessage(),
@@ -186,7 +187,7 @@ public class TestWebDelegationToken {
   }
 
   protected String getJettyURL() {
-    Connector c = jetty.getConnectors()[0];
+    ServerConnector c = (ServerConnector)jetty.getConnectors()[0];
     return "http://" + c.getHost() + ":" + c.getLocalPort();
   }
 
@@ -217,10 +218,11 @@ public class TestWebDelegationToken {
   @Test
   public void testRawHttpCalls() throws Exception {
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(AFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(AFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(PingServlet.class), "/bar");
     try {
       jetty.start();
@@ -337,10 +339,11 @@ public class TestWebDelegationToken {
   private void testDelegationTokenAuthenticatorCalls(final boolean useQS)
       throws Exception {
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(AFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(AFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(PingServlet.class), "/bar");
 
     try {
@@ -446,10 +449,11 @@ public class TestWebDelegationToken {
     DummyDelegationTokenSecretManager secretMgr
         = new DummyDelegationTokenSecretManager();
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(AFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(AFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(PingServlet.class), "/bar");
     try {
       secretMgr.startThreads();
@@ -525,10 +529,11 @@ public class TestWebDelegationToken {
   private void testDelegationTokenAuthenticatedURLWithNoDT(
       Class<? extends Filter> filterClass)  throws Exception {
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(filterClass), "/*", 0);
+    context.addFilter(new FilterHolder(filterClass), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(UserServlet.class), "/bar");
 
     try {
@@ -594,10 +599,11 @@ public class TestWebDelegationToken {
   public void testFallbackToPseudoDelegationTokenAuthenticator()
       throws Exception {
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(PseudoDTAFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(PseudoDTAFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(UserServlet.class), "/bar");
 
     try {
@@ -745,11 +751,11 @@ public class TestWebDelegationToken {
     Assert.assertTrue(testDir.mkdirs());
     MiniKdc kdc = new MiniKdc(MiniKdc.createConf(), testDir);
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    ((AbstractConnector)jetty.getConnectors()[0]).setResolveNames(true);
-    context.addFilter(new FilterHolder(KDTAFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(KDTAFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(UserServlet.class), "/bar");
     try {
       kdc.start();
@@ -824,10 +830,11 @@ public class TestWebDelegationToken {
   @Test
   public void testProxyUser() throws Exception {
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(PseudoDTAFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(PseudoDTAFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(UserServlet.class), "/bar");
 
     try {
@@ -921,10 +928,11 @@ public class TestWebDelegationToken {
   @Test
   public void testHttpUGI() throws Exception {
     final Server jetty = createJettyServer();
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
-    context.addFilter(new FilterHolder(PseudoDTAFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(PseudoDTAFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(UGIServlet.class), "/bar");
 
     try {
@@ -980,12 +988,12 @@ public class TestWebDelegationToken {
   @Test
   public void testIpaddressCheck() throws Exception {
     final Server jetty = createJettyServer();
-    ((AbstractConnector)jetty.getConnectors()[0]).setResolveNames(true);
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/foo");
     jetty.setHandler(context);
 
-    context.addFilter(new FilterHolder(IpAddressBasedPseudoDTAFilter.class), "/*", 0);
+    context.addFilter(new FilterHolder(IpAddressBasedPseudoDTAFilter.class), "/*",
+        EnumSet.of(DispatcherType.REQUEST));
     context.addServlet(new ServletHolder(UGIServlet.class), "/bar");
 
     try {

+ 10 - 10
hadoop-common-project/hadoop-kms/pom.xml

@@ -80,12 +80,12 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -111,7 +111,7 @@
         </exclusion>
         <exclusion>
           <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
         <exclusion>
           <groupId>javax.servlet</groupId>
@@ -122,19 +122,19 @@
           <artifactId>jsp-api</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>jsp-api-2.1</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>servlet-api-2.5</artifactId>
         </exclusion>
         <exclusion>
@@ -178,7 +178,7 @@
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
       <scope>compile</scope>
     </dependency>

+ 11 - 10
hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMS.java

@@ -24,6 +24,7 @@ import org.apache.hadoop.crypto.key.KeyProvider.KeyVersion;
 import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
 import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion;
 import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.crypto.key.kms.KMSClientProvider;
@@ -101,7 +102,7 @@ public class KMS {
   @POST
   @Path(KMSRESTConstants.KEYS_RESOURCE)
   @Consumes(MediaType.APPLICATION_JSON)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   @SuppressWarnings("unchecked")
   public Response createKey(Map jsonKey) throws Exception {
     try{
@@ -204,7 +205,7 @@ public class KMS {
   @POST
   @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}")
   @Consumes(MediaType.APPLICATION_JSON)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response rolloverKey(@PathParam("name") final String name,
       Map jsonMaterial) throws Exception {
     try {
@@ -254,7 +255,7 @@ public class KMS {
 
   @GET
   @Path(KMSRESTConstants.KEYS_METADATA_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getKeysMetadata(@QueryParam(KMSRESTConstants.KEY)
       List<String> keyNamesList) throws Exception {
     try {
@@ -287,7 +288,7 @@ public class KMS {
 
   @GET
   @Path(KMSRESTConstants.KEYS_NAMES_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getKeyNames() throws Exception {
     try {
       LOG.trace("Entering getKeyNames method.");
@@ -332,7 +333,7 @@ public class KMS {
   @GET
   @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" +
       KMSRESTConstants.METADATA_SUB_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getMetadata(@PathParam("name") final String name)
       throws Exception {
     try {
@@ -366,7 +367,7 @@ public class KMS {
   @GET
   @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" +
       KMSRESTConstants.CURRENT_VERSION_SUB_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getCurrentVersion(@PathParam("name") final String name)
       throws Exception {
     try {
@@ -399,7 +400,7 @@ public class KMS {
 
   @GET
   @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getKeyVersion(
       @PathParam("versionName") final String versionName) throws Exception {
     try {
@@ -436,7 +437,7 @@ public class KMS {
   @GET
   @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" +
       KMSRESTConstants.EEK_SUB_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response generateEncryptedKeys(
           @PathParam("name") final String name,
           @QueryParam(KMSRESTConstants.EEK_OP) String edekOp,
@@ -508,7 +509,7 @@ public class KMS {
   @POST
   @Path(KMSRESTConstants.KEY_VERSION_RESOURCE + "/{versionName:.*}/" +
       KMSRESTConstants.EEK_SUB_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response decryptEncryptedKey(
       @PathParam("versionName") final String versionName,
       @QueryParam(KMSRESTConstants.EEK_OP) String eekOp,
@@ -577,7 +578,7 @@ public class KMS {
   @GET
   @Path(KMSRESTConstants.KEY_RESOURCE + "/{name:.*}/" +
       KMSRESTConstants.VERSIONS_SUB_RESOURCE)
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getKeyVersions(@PathParam("name") final String name)
       throws Exception {
     try {

+ 12 - 0
hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSAuthenticationFilter.java

@@ -114,7 +114,19 @@ public class KMSAuthenticationFilter
       super.sendError(sc);
     }
 
+    /**
+     * Calls setStatus(int sc, String msg) on the wrapped
+     * {@link HttpServletResponseWrapper} object.
+     *
+     * @param sc the status code
+     * @param sm the status message
+     * @deprecated {@link HttpServletResponseWrapper#setStatus(int, String)} is
+     * deprecated. To set a status code use {@link #setStatus(int)}, to send an
+     * error with a description use {@link #sendError(int, String)}
+     */
     @Override
+    @Deprecated
+    @SuppressWarnings("deprecation")
     public void setStatus(int sc, String sm) {
       statusCode = sc;
       msg = sm;

+ 2 - 1
hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java

@@ -18,6 +18,7 @@
 package org.apache.hadoop.crypto.key.kms.server;
 
 import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.http.JettyUtils;
 import org.codehaus.jackson.map.ObjectMapper;
 
 import javax.ws.rs.Produces;
@@ -41,7 +42,7 @@ import java.util.Map;
  * to their JSON representation.
  */
 @Provider
-@Produces(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
 @InterfaceAudience.Private
 public class KMSJSONWriter implements MessageBodyWriter<Object> {
 

+ 37 - 26
hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java

@@ -21,14 +21,19 @@ import com.google.common.base.Preconditions;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.util.ThreadUtil;
-import org.apache.hadoop.security.ssl.SslSelectChannelConnectorSecure;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.security.SslSelectChannelConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -37,11 +42,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
 import java.io.IOException;
-import java.net.InetAddress;
 import java.net.MalformedURLException;
-import java.net.ServerSocket;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.UUID;
 
@@ -51,18 +52,28 @@ public class MiniKMS {
     try {
       boolean ssl = keyStore != null;
       String host = "localhost";
-      Server server = new Server(inPort);
-      if (!ssl) {
-        server.getConnectors()[0].setHost(host);
-      } else {
-        SslSelectChannelConnector c = new SslSelectChannelConnectorSecure();
-        c.setHost(host);
-        c.setNeedClientAuth(false);
-        c.setKeystore(keyStore);
-        c.setKeystoreType("jks");
-        c.setKeyPassword(password);
-        server.setConnectors(new Connector[]{c});
+      Server server = new Server();
+      ServerConnector conn = new ServerConnector(server);
+      HttpConfiguration httpConfig = new HttpConfiguration();
+      httpConfig.setRequestHeaderSize(JettyUtils.HEADER_SIZE);
+      httpConfig.setResponseHeaderSize(JettyUtils.HEADER_SIZE);
+      httpConfig.setSecureScheme("https");
+      httpConfig.addCustomizer(new SecureRequestCustomizer());
+      ConnectionFactory connFactory = new HttpConnectionFactory(httpConfig);
+      conn.addConnectionFactory(connFactory);
+      conn.setHost(host);
+      conn.setPort(inPort);
+      if (ssl) {
+        SslContextFactory sslContextFactory = new SslContextFactory();
+        sslContextFactory.setNeedClientAuth(false);
+        sslContextFactory.setKeyStorePath(keyStore);
+        sslContextFactory.setKeyStoreType("jks");
+        sslContextFactory.setKeyStorePassword(password);
+        conn.addFirstConnectionFactory(
+            new SslConnectionFactory(sslContextFactory,
+            HttpVersion.HTTP_1_1.asString()));
       }
+      server.addConnector(conn);
       return server;
     } catch (Exception ex) {
       throw new RuntimeException("Could not start embedded servlet container, "
@@ -71,13 +82,13 @@ public class MiniKMS {
   }
 
   private static URL getJettyURL(Server server) {
-    boolean ssl = server.getConnectors()[0].getClass()
-        == SslSelectChannelConnectorSecure.class;
+    boolean ssl = server.getConnectors()[0]
+        .getConnectionFactory(SslConnectionFactory.class) != null;
     try {
       String scheme = (ssl) ? "https" : "http";
       return new URL(scheme + "://" +
-          server.getConnectors()[0].getHost() + ":" +
-          server.getConnectors()[0].getLocalPort());
+          ((ServerConnector)server.getConnectors()[0]).getHost() + ":"
+          + ((ServerConnector)server.getConnectors()[0]).getLocalPort());
     } catch (MalformedURLException ex) {
       throw new RuntimeException("It should never happen, " + ex.getMessage(),
           ex);
@@ -217,7 +228,7 @@ public class MiniKMS {
     if (webXmlInJar) {
       context.setClassLoader(cl);
     }
-    jetty.addHandler(context);
+    jetty.setHandler(context);
     jetty.start();
     kmsURL = new URL(getJettyURL(jetty), "kms");
   }

+ 1 - 1
hadoop-common-project/hadoop-nfs/pom.xml

@@ -63,7 +63,7 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>

+ 13 - 13
hadoop-hdfs-project/hadoop-hdfs-httpfs/pom.xml

@@ -75,7 +75,7 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>
@@ -89,8 +89,8 @@
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -108,22 +108,22 @@
         </exclusion>
         <exclusion>
           <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
         <exclusion>
           <groupId>javax.servlet.jsp</groupId>
           <artifactId>jsp-api</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>servlet-api-2.5</artifactId>
         </exclusion>
         <exclusion>
@@ -155,18 +155,18 @@
         </exclusion>
         <exclusion>
           <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
         </exclusion>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
+          <groupId>org.eclipse.jetty</groupId>
           <artifactId>servlet-api-2.5</artifactId>
         </exclusion>
         <exclusion>

+ 7 - 5
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/fs/http/server/HttpFSServer.java

@@ -48,6 +48,7 @@ import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrEncodingPa
 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrNameParam;
 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrSetFlagParam;
 import org.apache.hadoop.fs.http.server.HttpFSParametersProvider.XAttrValueParam;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.lib.service.FileSystemAccess;
 import org.apache.hadoop.lib.service.FileSystemAccessException;
 import org.apache.hadoop.lib.service.Groups;
@@ -168,7 +169,7 @@ public class HttpFSServer {
    * {@link HttpFSExceptionProvider}.
    */
   @GET
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response getRoot(@QueryParam(OperationParam.NAME) OperationParam op,
                           @Context Parameters params,
                           @Context HttpServletRequest request)
@@ -197,7 +198,8 @@ public class HttpFSServer {
    */
   @GET
   @Path("{path:.*}")
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response get(@PathParam("path") String path,
                       @QueryParam(OperationParam.NAME) OperationParam op,
                       @Context Parameters params,
@@ -363,7 +365,7 @@ public class HttpFSServer {
    */
   @DELETE
   @Path("{path:.*}")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response delete(@PathParam("path") String path,
                          @QueryParam(OperationParam.NAME) OperationParam op,
                          @Context Parameters params,
@@ -414,7 +416,7 @@ public class HttpFSServer {
   @POST
   @Path("{path:.*}")
   @Consumes({"*/*"})
-  @Produces({MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response post(InputStream is,
                        @Context UriInfo uriInfo,
                        @PathParam("path") String path,
@@ -509,7 +511,7 @@ public class HttpFSServer {
   @PUT
   @Path("{path:.*}")
   @Consumes({"*/*"})
-  @Produces({MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response put(InputStream is,
                        @Context UriInfo uriInfo,
                        @PathParam("path") String path,

+ 2 - 1
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/JSONMapProvider.java

@@ -19,6 +19,7 @@
 package org.apache.hadoop.lib.wsrs;
 
 import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.http.JettyUtils;
 import org.json.simple.JSONObject;
 
 import javax.ws.rs.Produces;
@@ -37,7 +38,7 @@ import java.nio.charset.StandardCharsets;
 import java.util.Map;
 
 @Provider
-@Produces(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
 @InterfaceAudience.Private
 public class JSONMapProvider implements MessageBodyWriter<Map> {
   private static final String ENTER = System.getProperty("line.separator");

+ 2 - 1
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/main/java/org/apache/hadoop/lib/wsrs/JSONProvider.java

@@ -19,6 +19,7 @@
 package org.apache.hadoop.lib.wsrs;
 
 import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.http.JettyUtils;
 import org.json.simple.JSONStreamAware;
 
 import javax.ws.rs.Produces;
@@ -36,7 +37,7 @@ import java.lang.reflect.Type;
 import java.nio.charset.StandardCharsets;
 
 @Provider
-@Produces(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
 @InterfaceAudience.Private
 public class JSONProvider implements MessageBodyWriter<JSONStreamAware> {
   private static final String ENTER = System.getProperty("line.separator");

+ 3 - 3
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/client/BaseTestHttpFSWith.java

@@ -49,8 +49,8 @@ import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import com.google.common.collect.Lists;
 
@@ -127,7 +127,7 @@ public abstract class BaseTestHttpFSWith extends HFSTestCase {
     URL url = cl.getResource("webapp");
     WebAppContext context = new WebAppContext(url.getPath(), "/webhdfs");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
   }
 

+ 3 - 3
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServer.java

@@ -64,8 +64,8 @@ import org.apache.hadoop.test.TestJettyHelper;
 import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
 import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import com.google.common.collect.Maps;
 import java.util.Properties;
@@ -171,7 +171,7 @@ public class TestHttpFSServer extends HFSTestCase {
     URL url = cl.getResource("webapp");
     WebAppContext context = new WebAppContext(url.getPath(), "/webhdfs");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
     if (addDelegationTokenAuthHandler) {
       HttpFSServerWebApp.get().setAuthority(TestJettyHelper.getAuthority());

+ 3 - 3
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServerNoACLs.java

@@ -31,8 +31,8 @@ import org.apache.hadoop.test.TestJetty;
 import org.apache.hadoop.test.TestJettyHelper;
 import org.junit.Assert;
 import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -151,7 +151,7 @@ public class TestHttpFSServerNoACLs extends HTestCase {
     }
     WebAppContext context = new WebAppContext(url.getPath(), "/webhdfs");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
   }
 

+ 3 - 3
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSServerNoXAttrs.java

@@ -32,8 +32,8 @@ import org.apache.hadoop.test.TestJetty;
 import org.apache.hadoop.test.TestJettyHelper;
 import org.junit.Assert;
 import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -152,7 +152,7 @@ public class TestHttpFSServerNoXAttrs extends HTestCase {
     }
     WebAppContext context = new WebAppContext(url.getPath(), "/webhdfs");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
   }
 

+ 3 - 3
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/fs/http/server/TestHttpFSWithKerberos.java

@@ -41,8 +41,8 @@ import org.json.simple.parser.JSONParser;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.webapp.WebAppContext;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -105,7 +105,7 @@ public class TestHttpFSWithKerberos extends HFSTestCase {
     URL url = cl.getResource("webapp");
     WebAppContext context = new WebAppContext(url.getPath(), "/webhdfs");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
     HttpFSServerWebApp.get().setAuthority(TestJettyHelper.getAuthority());
   }

+ 4 - 4
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/test/TestHFSTestCase.java

@@ -38,9 +38,9 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.util.Time;
+import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
+import org.eclipse.jetty.server.Server;
 
 public class TestHFSTestCase extends HFSTestCase {
 
@@ -165,11 +165,11 @@ public class TestHFSTestCase extends HFSTestCase {
   @Test
   @TestJetty
   public void testJetty() throws Exception {
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/");
     context.addServlet(MyServlet.class, "/bar");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
     URL url = new URL(TestJettyHelper.getJettyURL(), "/bar");
     HttpURLConnection conn = (HttpURLConnection) url.openConnection();

+ 4 - 4
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/test/TestHTestCase.java

@@ -33,9 +33,9 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.hadoop.util.Time;
+import org.eclipse.jetty.servlet.ServletContextHandler;
 import org.junit.Test;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
+import org.eclipse.jetty.server.Server;
 
 public class TestHTestCase extends HTestCase {
 
@@ -132,11 +132,11 @@ public class TestHTestCase extends HTestCase {
   @Test
   @TestJetty
   public void testJetty() throws Exception {
-    Context context = new Context();
+    ServletContextHandler context = new ServletContextHandler();
     context.setContextPath("/");
     context.addServlet(MyServlet.class, "/bar");
     Server server = TestJettyHelper.getJettyServer();
-    server.addHandler(context);
+    server.setHandler(context);
     server.start();
     URL url = new URL(TestJettyHelper.getJettyURL(), "/bar");
     HttpURLConnection conn = (HttpURLConnection) url.openConnection();

+ 34 - 22
hadoop-hdfs-project/hadoop-hdfs-httpfs/src/test/java/org/apache/hadoop/test/TestJettyHelper.java

@@ -24,14 +24,19 @@ import java.net.ServerSocket;
 import java.net.URL;
 import java.net.UnknownHostException;
 
-import org.apache.hadoop.security.ssl.SslSelectChannelConnectorSecure;
-import org.junit.Test;
+import org.apache.hadoop.http.JettyUtils;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.junit.rules.MethodRule;
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.Statement;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.security.SslSelectChannelConnector;
 
 public class TestJettyHelper implements MethodRule {
   private boolean ssl;
@@ -88,20 +93,27 @@ public class TestJettyHelper implements MethodRule {
       ServerSocket ss = new ServerSocket(0, 50, localhost);
       int port = ss.getLocalPort();
       ss.close();
-      Server server = new Server(0);
-      if (!ssl) {
-        server.getConnectors()[0].setHost(host);
-        server.getConnectors()[0].setPort(port);
-      } else {
-        SslSelectChannelConnector c = new SslSelectChannelConnectorSecure();
-        c.setHost(host);
-        c.setPort(port);
-        c.setNeedClientAuth(false);
-        c.setKeystore(keyStore);
-        c.setKeystoreType(keyStoreType);
-        c.setKeyPassword(keyStorePassword);
-        server.setConnectors(new Connector[] {c});
+      Server server = new Server();
+      ServerConnector conn = new ServerConnector(server);
+      HttpConfiguration http_config = new HttpConfiguration();
+      http_config.setRequestHeaderSize(JettyUtils.HEADER_SIZE);
+      http_config.setResponseHeaderSize(JettyUtils.HEADER_SIZE);
+      http_config.setSecureScheme("https");
+      http_config.addCustomizer(new SecureRequestCustomizer());
+      ConnectionFactory connFactory = new HttpConnectionFactory(http_config);
+      conn.addConnectionFactory(connFactory);
+      conn.setHost(host);
+      conn.setPort(port);
+      if (ssl) {
+        SslContextFactory sslContextFactory = new SslContextFactory();
+        sslContextFactory.setNeedClientAuth(false);
+        sslContextFactory.setKeyStorePath(keyStore);
+        sslContextFactory.setKeyStoreType(keyStoreType);
+        sslContextFactory.setKeyStorePassword(keyStorePassword);
+        conn.addFirstConnectionFactory(new SslConnectionFactory(sslContextFactory,
+            HttpVersion.HTTP_1_1.asString()));
       }
+      server.addConnector(conn);
       return server;
     } catch (Exception ex) {
       throw new RuntimeException("Could not start embedded servlet container, " + ex.getMessage(), ex);
@@ -117,8 +129,8 @@ public class TestJettyHelper implements MethodRule {
     Server server = getJettyServer();
     try {
       InetAddress add =
-        InetAddress.getByName(server.getConnectors()[0].getHost());
-      int port = server.getConnectors()[0].getPort();
+        InetAddress.getByName(((ServerConnector)server.getConnectors()[0]).getHost());
+      int port = ((ServerConnector)server.getConnectors()[0]).getPort();
       return new InetSocketAddress(add, port);
     } catch (UnknownHostException ex) {
       throw new RuntimeException(ex);
@@ -157,8 +169,8 @@ public class TestJettyHelper implements MethodRule {
     try {
       String scheme = (helper.ssl) ? "https" : "http";
       return new URL(scheme + "://" +
-          helper.server.getConnectors()[0].getHost() + ":" +
-          helper.server.getConnectors()[0].getPort());
+          ((ServerConnector)helper.server.getConnectors()[0]).getHost() + ":" +
+          ((ServerConnector)helper.server.getConnectors()[0]).getPort());
     } catch (MalformedURLException ex) {
       throw new RuntimeException("It should never happen, " + ex.getMessage(), ex);
     }

+ 4 - 4
hadoop-hdfs-project/hadoop-hdfs-nfs/pom.xml

@@ -85,12 +85,12 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
       <scope>compile</scope>
     </dependency>
@@ -146,7 +146,7 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>

+ 21 - 4
hadoop-hdfs-project/hadoop-hdfs/pom.xml

@@ -75,15 +75,20 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-util-ajax</artifactId>
+      <scope>compile</scope>
+    </dependency>
     <dependency>
       <groupId>com.sun.jersey</groupId>
       <artifactId>jersey-core</artifactId>
@@ -136,7 +141,7 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>compile</scope>
     </dependency>
     <dependency>
@@ -356,6 +361,18 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
               <output>${project.build.directory}/generated-sources/java</output>
             </configuration>
           </execution>
+          <execution>
+            <id>resource-gz</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>resource-gz</goal>
+            </goals>
+            <configuration>
+              <inputDirectory>${basedir}/src/main/webapps/static</inputDirectory>
+              <outputDirectory>${basedir}/target/webapps/static</outputDirectory>
+              <extensions>js,css</extensions>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNode.java

@@ -49,7 +49,7 @@ import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.util.Tool;
 import org.apache.hadoop.util.ToolRunner;
 import org.apache.htrace.core.Tracer;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataNode.java

@@ -212,7 +212,7 @@ import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.util.Time;
 import org.apache.hadoop.util.VersionInfo;
 import org.apache.htrace.core.Tracer;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

@@ -283,7 +283,7 @@ import org.apache.hadoop.util.VersionInfo;
 import org.apache.log4j.Appender;
 import org.apache.log4j.AsyncAppender;
 import org.apache.log4j.Logger;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Charsets;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NNStorage.java

@@ -53,7 +53,7 @@ import org.apache.hadoop.hdfs.util.PersistentLongFile;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.net.DNS;
 import org.apache.hadoop.util.Time;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/TransferFsImage.java

@@ -64,7 +64,7 @@ import org.apache.http.client.utils.URIBuilder;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
-import org.mortbay.jetty.EofException;
+import org.eclipse.jetty.io.EofException;
 
 /**
  * This class provides fetching a specified file from the NameNode.

+ 23 - 16
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java

@@ -84,6 +84,7 @@ import org.apache.hadoop.hdfs.web.ParamFilter;
 import org.apache.hadoop.hdfs.web.WebHdfsConstants;
 import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
 import org.apache.hadoop.hdfs.web.resources.*;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ipc.ExternalCall;
 import org.apache.hadoop.ipc.RetriableException;
@@ -355,7 +356,8 @@ public class NamenodeWebHdfsMethods {
   @PUT
   @Path("/")
   @Consumes({"*/*"})
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response putRoot(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -395,13 +397,13 @@ public class NamenodeWebHdfsMethods {
           final CreateParentParam createParent,
       @QueryParam(TokenArgumentParam.NAME) @DefaultValue(TokenArgumentParam.DEFAULT)
           final TokenArgumentParam delegationTokenArgument,
-      @QueryParam(AclPermissionParam.NAME) @DefaultValue(AclPermissionParam.DEFAULT) 
+      @QueryParam(AclPermissionParam.NAME) @DefaultValue(AclPermissionParam.DEFAULT)
           final AclPermissionParam aclPermission,
-      @QueryParam(XAttrNameParam.NAME) @DefaultValue(XAttrNameParam.DEFAULT) 
+      @QueryParam(XAttrNameParam.NAME) @DefaultValue(XAttrNameParam.DEFAULT)
           final XAttrNameParam xattrName,
-      @QueryParam(XAttrValueParam.NAME) @DefaultValue(XAttrValueParam.DEFAULT) 
+      @QueryParam(XAttrValueParam.NAME) @DefaultValue(XAttrValueParam.DEFAULT)
           final XAttrValueParam xattrValue,
-      @QueryParam(XAttrSetFlagParam.NAME) @DefaultValue(XAttrSetFlagParam.DEFAULT) 
+      @QueryParam(XAttrSetFlagParam.NAME) @DefaultValue(XAttrSetFlagParam.DEFAULT)
           final XAttrSetFlagParam xattrSetFlag,
       @QueryParam(SnapshotNameParam.NAME) @DefaultValue(SnapshotNameParam.DEFAULT)
           final SnapshotNameParam snapshotName,
@@ -426,7 +428,8 @@ public class NamenodeWebHdfsMethods {
   @PUT
   @Path("{" + UriFsPathParam.NAME + ":.*}")
   @Consumes({"*/*"})
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response put(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -532,7 +535,7 @@ public class NamenodeWebHdfsMethods {
       final TokenArgumentParam delegationTokenArgument,
       final AclPermissionParam aclPermission,
       final XAttrNameParam xattrName,
-      final XAttrValueParam xattrValue, 
+      final XAttrValueParam xattrValue,
       final XAttrSetFlagParam xattrSetFlag,
       final SnapshotNameParam snapshotName,
       final OldSnapshotNameParam oldSnapshotName,
@@ -690,7 +693,8 @@ public class NamenodeWebHdfsMethods {
   @POST
   @Path("/")
   @Consumes({"*/*"})
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response postRoot(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -720,7 +724,8 @@ public class NamenodeWebHdfsMethods {
   @POST
   @Path("{" + UriFsPathParam.NAME + ":.*}")
   @Consumes({"*/*"})
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response post(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -799,7 +804,7 @@ public class NamenodeWebHdfsMethods {
             "newLength parameter is Missing");
       }
       // We treat each rest request as a separate client.
-      final boolean b = np.truncate(fullpath, newLength.getValue(), 
+      final boolean b = np.truncate(fullpath, newLength.getValue(),
           "DFSClient_" + DFSUtil.getSecureRandom().nextLong());
       final String js = JsonUtil.toJsonString("boolean", b);
       return Response.ok(js).type(MediaType.APPLICATION_JSON).build();
@@ -812,7 +817,8 @@ public class NamenodeWebHdfsMethods {
   /** Handle HTTP GET request for the root. */
   @GET
   @Path("/")
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response getRoot(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -831,9 +837,9 @@ public class NamenodeWebHdfsMethods {
           final RenewerParam renewer,
       @QueryParam(BufferSizeParam.NAME) @DefaultValue(BufferSizeParam.DEFAULT)
           final BufferSizeParam bufferSize,
-      @QueryParam(XAttrNameParam.NAME) @DefaultValue(XAttrNameParam.DEFAULT) 
+      @QueryParam(XAttrNameParam.NAME) @DefaultValue(XAttrNameParam.DEFAULT)
           final List<XAttrNameParam> xattrNames,
-      @QueryParam(XAttrEncodingParam.NAME) @DefaultValue(XAttrEncodingParam.DEFAULT) 
+      @QueryParam(XAttrEncodingParam.NAME) @DefaultValue(XAttrEncodingParam.DEFAULT)
           final XAttrEncodingParam xattrEncoding,
       @QueryParam(ExcludeDatanodesParam.NAME) @DefaultValue(ExcludeDatanodesParam.DEFAULT)
           final ExcludeDatanodesParam excludeDatanodes,
@@ -856,7 +862,8 @@ public class NamenodeWebHdfsMethods {
   /** Handle HTTP GET request. */
   @GET
   @Path("{" + UriFsPathParam.NAME + ":.*}")
-  @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
+  @Produces({MediaType.APPLICATION_OCTET_STREAM + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8})
   public Response get(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -1131,7 +1138,7 @@ public class NamenodeWebHdfsMethods {
   /** Handle HTTP DELETE request for the root. */
   @DELETE
   @Path("/")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response deleteRoot(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)
@@ -1154,7 +1161,7 @@ public class NamenodeWebHdfsMethods {
   /** Handle HTTP DELETE request. */
   @DELETE
   @Path("{" + UriFsPathParam.NAME + ":.*}")
-  @Produces(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8)
   public Response delete(
       @Context final UserGroupInformation ugi,
       @QueryParam(DelegationParam.NAME) @DefaultValue(DelegationParam.DEFAULT)

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDecommission.java

@@ -64,7 +64,7 @@ import org.apache.log4j.Level;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/server/TestJournalNodeMXBean.java

@@ -35,7 +35,7 @@ import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 /**
  * Test {@link JournalNodeMXBean}

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/blockmanagement/TestBlockStatsMXBean.java

@@ -40,7 +40,7 @@ import org.apache.hadoop.hdfs.server.datanode.DataNodeTestUtils;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 /**
  * Class for testing {@link BlockStatsMXBean} implementation

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/datanode/TestDataNodeMXBean.java

@@ -40,7 +40,7 @@ import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.type.TypeReference;
 import org.junit.Assert;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFSNamesystemMBean.java

@@ -35,7 +35,7 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 /**
  * Class for testing {@link NameNodeMXBean} implementation

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestNameNodeMXBean.java

@@ -53,7 +53,7 @@ import org.apache.hadoop.util.VersionInfo;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.junit.Assert;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import javax.management.MBeanServer;
 import javax.management.ObjectName;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestStartupProgressServlet.java

@@ -36,7 +36,7 @@ import com.google.common.collect.ImmutableMap;
 import org.apache.hadoop.hdfs.server.namenode.startupprogress.StartupProgress;
 import org.junit.Before;
 import org.junit.Test;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 public class TestStartupProgressServlet {
 

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestTransferFsImage.java

@@ -120,7 +120,7 @@ public class TestTransferFsImage {
   /**
    * Test to verify the read timeout
    */
-  @Test(timeout = 5000)
+  @Test(timeout = 10000)
   public void testGetImageTimeout() throws Exception {
     HttpServer2 testServer = HttpServerFunctionalTest.createServer("hdfs");
     try {

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestWebHDFSForHA.java

@@ -56,7 +56,7 @@ import org.apache.hadoop.security.token.Token;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.internal.util.reflection.Whitebox;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.Response;

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/test/MiniDFSClusterManager.java

@@ -38,7 +38,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hdfs.HdfsConfiguration;
 import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.StartupOption;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 /**
  * This class drives the creation of a mini-cluster on the local machine. By

+ 21 - 16
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/JobEndNotifier.java

@@ -30,7 +30,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapred.JobContext;
 import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hadoop.mapreduce.v2.api.records.JobReport;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 /**
  * <p>This class handles job end notification. Submitters of jobs can choose to
@@ -101,11 +101,12 @@ public class JobEndNotifier implements Configurable {
         int port = Integer.parseInt(portConf);
         proxyToUse = new Proxy(proxyType,
           new InetSocketAddress(hostname, port));
-        Log.info("Job end notification using proxy type \"" + proxyType + 
-        "\" hostname \"" + hostname + "\" and port \"" + port + "\"");
+        Log.getLog().info("Job end notification using proxy type \""
+            + proxyType + "\" hostname \"" + hostname + "\" and port \"" + port
+            + "\"");
       } catch(NumberFormatException nfe) {
-        Log.warn("Job end notification couldn't parse configured proxy's port "
-          + portConf + ". Not going to use a proxy");
+        Log.getLog().warn("Job end notification couldn't parse configured"
+            + "proxy's port " + portConf + ". Not going to use a proxy");
       }
     }
 
@@ -121,23 +122,25 @@ public class JobEndNotifier implements Configurable {
   protected boolean notifyURLOnce() {
     boolean success = false;
     try {
-      Log.info("Job end notification trying " + urlToNotify);
+      Log.getLog().info("Job end notification trying " + urlToNotify);
       HttpURLConnection conn =
         (HttpURLConnection) urlToNotify.openConnection(proxyToUse);
       conn.setConnectTimeout(timeout);
       conn.setReadTimeout(timeout);
       conn.setAllowUserInteraction(false);
       if(conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
-        Log.warn("Job end notification to " + urlToNotify +" failed with code: "
-        + conn.getResponseCode() + " and message \"" + conn.getResponseMessage()
-        +"\"");
+        Log.getLog().warn("Job end notification to " + urlToNotify
+            + " failed with code: " + conn.getResponseCode() + " and message \""
+            + conn.getResponseMessage() + "\"");
       }
       else {
         success = true;
-        Log.info("Job end notification to " + urlToNotify + " succeeded");
+        Log.getLog().info("Job end notification to " + urlToNotify
+            + " succeeded");
       }
     } catch(IOException ioe) {
-      Log.warn("Job end notification to " + urlToNotify + " failed", ioe);
+      Log.getLog().warn("Job end notification to " + urlToNotify + " failed",
+          ioe);
     }
     return success;
   }
@@ -152,7 +155,7 @@ public class JobEndNotifier implements Configurable {
     throws InterruptedException {
     // Do we need job-end notification?
     if (userUrl == null) {
-      Log.info("Job end notification URL not set, skipping.");
+      Log.getLog().info("Job end notification URL not set, skipping.");
       return;
     }
 
@@ -168,23 +171,25 @@ public class JobEndNotifier implements Configurable {
     try {
       urlToNotify = new URL(userUrl);
     } catch (MalformedURLException mue) {
-      Log.warn("Job end notification couldn't parse " + userUrl, mue);
+      Log.getLog().warn("Job end notification couldn't parse " + userUrl, mue);
       return;
     }
 
     // Send notification
     boolean success = false;
     while (numTries-- > 0 && !success) {
-      Log.info("Job end notification attempts left " + numTries);
+      Log.getLog().info("Job end notification attempts left " + numTries);
       success = notifyURLOnce();
       if (!success) {
         Thread.sleep(waitInterval);
       }
     }
     if (!success) {
-      Log.warn("Job end notification failed to notify : " + urlToNotify);
+      Log.getLog().warn("Job end notification failed to notify : "
+          + urlToNotify);
     } else {
-      Log.info("Job end notification succeeded for " + jobReport.getJobId());
+      Log.getLog().info("Job end notification succeeded for "
+          + jobReport.getJobId());
     }
   }
 }

+ 33 - 16
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebServices.java

@@ -38,6 +38,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.JobACL;
 import org.apache.hadoop.mapreduce.v2.api.protocolrecords.KillTaskAttemptRequest;
 import org.apache.hadoop.mapreduce.v2.api.protocolrecords.KillTaskAttemptResponse;
@@ -221,14 +222,16 @@ public class AMWebServices {
   }
 
   @GET
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public AppInfo get() {
     return getAppInfo();
   }
 
   @GET
   @Path("/info")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public AppInfo getAppInfo() {
     init();
     return new AppInfo(this.app, this.app.context);
@@ -236,7 +239,8 @@ public class AMWebServices {
   
   @GET
   @Path("/blacklistednodes")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public BlacklistedNodesInfo getBlacklistedNodes() {
     init();
     return new BlacklistedNodesInfo(this.app.context);
@@ -244,7 +248,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobsInfo getJobs(@Context HttpServletRequest hsr) {
     init();
     JobsInfo allJobs = new JobsInfo();
@@ -261,7 +266,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobInfo getJob(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid) {
     init();
@@ -271,7 +277,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/jobattempts")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public AMAttemptsInfo getJobAttempts(@PathParam("jobid") String jid) {
     init();
     Job job = getJobFromJobIdString(jid, appCtx);
@@ -286,7 +293,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/counters")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobCounterInfo getJobCounters(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid) {
     init();
@@ -297,7 +305,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/conf")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public ConfInfo getJobConf(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid) {
 
@@ -316,7 +325,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TasksInfo getJobTasks(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @QueryParam("type") String type) {
 
@@ -343,7 +353,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks/{taskid}")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TaskInfo getJobTask(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid) {
 
@@ -356,7 +367,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks/{taskid}/counters")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobTaskCounterInfo getSingleTaskCounters(
       @Context HttpServletRequest hsr, @PathParam("jobid") String jid,
       @PathParam("taskid") String tid) {
@@ -370,7 +382,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks/{taskid}/attempts")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TaskAttemptsInfo getJobTaskAttempts(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid) {
 
@@ -394,7 +407,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TaskAttemptInfo getJobTaskAttemptId(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid,
       @PathParam("attemptid") String attId) {
@@ -413,7 +427,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}/state")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobTaskAttemptState getJobTaskAttemptState(
       @Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid,
@@ -429,7 +444,8 @@ public class AMWebServices {
 
   @PUT
   @Path("/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}/state")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
   public Response updateJobTaskAttemptState(JobTaskAttemptState targetState,
       @Context HttpServletRequest hsr, @PathParam("jobid") String jid,
@@ -466,7 +482,8 @@ public class AMWebServices {
 
   @GET
   @Path("/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}/counters")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobTaskAttemptCounterInfo getJobTaskAttemptIdCounters(
       @Context HttpServletRequest hsr, @PathParam("jobid") String jid,
       @PathParam("taskid") String tid, @PathParam("attemptid") String attId) {

+ 21 - 10
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServices.java

@@ -31,6 +31,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
 import org.apache.hadoop.mapreduce.v2.app.MockAppContext;
 import org.apache.hadoop.yarn.webapp.GenericExceptionHandler;
@@ -112,7 +113,8 @@ public class TestAMWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyAMInfo(json.getJSONObject("info"), appContext);
@@ -123,7 +125,8 @@ public class TestAMWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("mapreduce/")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyAMInfo(json.getJSONObject("info"), appContext);
@@ -134,7 +137,8 @@ public class TestAMWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("mapreduce/")
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyAMInfo(json.getJSONObject("info"), appContext);
@@ -145,7 +149,8 @@ public class TestAMWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     verifyAMInfoXML(xml, appContext);
   }
@@ -156,7 +161,8 @@ public class TestAMWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("info").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyAMInfo(json.getJSONObject("info"), appContext);
@@ -168,7 +174,8 @@ public class TestAMWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("info/").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyAMInfo(json.getJSONObject("info"), appContext);
@@ -179,7 +186,8 @@ public class TestAMWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("info/").get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyAMInfo(json.getJSONObject("info"), appContext);
@@ -191,7 +199,8 @@ public class TestAMWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("info/").accept(MediaType.APPLICATION_XML)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     verifyAMInfoXML(xml, appContext);
   }
@@ -251,7 +260,8 @@ public class TestAMWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("blacklistednodes").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyBlacklistedNodesInfo(json, appContext);
@@ -263,7 +273,8 @@ public class TestAMWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("blacklistednodes").accept(MediaType.APPLICATION_XML)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     verifyBlacklistedNodesInfoXML(xml, appContext);
   }

+ 9 - 4
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesAttempt.java

@@ -32,6 +32,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptState;
@@ -152,7 +153,8 @@ public class TestAMWebServicesAttempt extends JerseyTestBase {
               .path("attempts").path(attid).path("state")
               .queryParam("user.name", webserviceUserName)
               .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           assertEquals(att.getState().toString(), json.get("state"));
@@ -180,7 +182,8 @@ public class TestAMWebServicesAttempt extends JerseyTestBase {
               .queryParam("user.name", webserviceUserName)
               .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-          assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+              response.getType().toString());
           String xml = response.getEntity(String.class);
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();
@@ -219,7 +222,8 @@ public class TestAMWebServicesAttempt extends JerseyTestBase {
               .accept(MediaType.APPLICATION_JSON)
               .type(MediaType.APPLICATION_JSON)
               .put(ClientResponse.class, "{\"state\":\"KILLED\"}");
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           assertEquals(TaskAttemptState.KILLED.toString(), json.get("state"));
@@ -252,7 +256,8 @@ public class TestAMWebServicesAttempt extends JerseyTestBase {
               .put(ClientResponse.class,
                   "<jobTaskAttemptState><state>KILLED" +
                       "</state></jobTaskAttemptState>");
-          assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+              response.getType().toString());
           String xml = response.getEntity(String.class);
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();

+ 23 - 11
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesAttempts.java

@@ -34,6 +34,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
@@ -127,7 +128,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("attempts")
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         verifyAMTaskAttempts(json, task);
       }
@@ -146,7 +148,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("attempts/")
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         verifyAMTaskAttempts(json, task);
       }
@@ -165,7 +168,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("attempts")
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         verifyAMTaskAttempts(json, task);
       }
@@ -185,7 +189,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
             .path("jobs").path(jobId).path("tasks").path(tid).path("attempts")
             .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-        assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         String xml = response.getEntity(String.class);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
@@ -220,7 +225,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
               .path("jobs").path(jobId).path("tasks").path(tid)
               .path("attempts").path(attid).accept(MediaType.APPLICATION_JSON)
               .get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("taskAttempt");
@@ -249,7 +255,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
               .path("jobs").path(jobId).path("tasks").path(tid)
               .path("attempts").path(attid + "/")
               .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("taskAttempt");
@@ -277,7 +284,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
           ClientResponse response = r.path("ws").path("v1").path("mapreduce")
               .path("jobs").path(jobId).path("tasks").path(tid)
               .path("attempts").path(attid).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("taskAttempt");
@@ -305,7 +313,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
               .path("attempts").path(attid).accept(MediaType.APPLICATION_XML)
               .get(ClientResponse.class);
 
-          assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+              response.getType().toString());
           String xml = response.getEntity(String.class);
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();
@@ -377,7 +386,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
         } catch (UniformInterfaceException ue) {
           ClientResponse response = ue.getResponse();
           assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject msg = response.getEntity(JSONObject.class);
           JSONObject exception = msg.getJSONObject("RemoteException");
           assertEquals("incorrect number of elements", 3, exception.length());
@@ -556,7 +566,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
               .path("jobs").path(jobId).path("tasks").path(tid)
               .path("attempts").path(attid).path("counters")
               .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("jobTaskAttemptCounters");
@@ -584,7 +595,8 @@ public class TestAMWebServicesAttempts extends JerseyTestBase {
               .path("attempts").path(attid).path("counters")
               .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-          assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+              response.getType().toString());
           String xml = response.getEntity(String.class);
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();

+ 9 - 4
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesJobConf.java

@@ -37,6 +37,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.FileUtil;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
@@ -156,7 +157,8 @@ public class TestAMWebServicesJobConf extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("conf")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("conf");
@@ -174,7 +176,8 @@ public class TestAMWebServicesJobConf extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("conf/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("conf");
@@ -191,7 +194,8 @@ public class TestAMWebServicesJobConf extends JerseyTestBase {
 
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("conf").get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("conf");
@@ -209,7 +213,8 @@ public class TestAMWebServicesJobConf extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("conf")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();

+ 43 - 21
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesJobs.java

@@ -34,6 +34,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.JobACL;
 import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
@@ -123,7 +124,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("jobs").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -140,7 +142,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("jobs/").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -156,7 +159,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("jobs").get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -173,7 +177,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("mapreduce")
         .path("jobs").accept(MediaType.APPLICATION_XML)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
     DocumentBuilder db = dbf.newDocumentBuilder();
@@ -198,7 +203,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).accept(MediaType.APPLICATION_JSON)
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("job");
@@ -217,7 +223,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId + "/").accept(MediaType.APPLICATION_JSON)
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("job");
@@ -234,7 +241,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
 
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("job");
@@ -254,7 +262,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -281,7 +290,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -304,7 +314,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -327,7 +338,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String msg = response.getEntity(String.class);
       System.out.println(msg);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
@@ -366,7 +378,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -395,7 +408,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).accept(MediaType.APPLICATION_XML)
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
@@ -629,7 +643,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("counters")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -647,7 +662,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("counters/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -664,7 +680,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
 
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("counters/").get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -682,7 +699,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("counters")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
@@ -781,7 +799,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobAttempts");
@@ -799,7 +818,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobAttempts");
@@ -817,7 +837,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts")
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobAttempts");
@@ -835,7 +856,8 @@ public class TestAMWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();

+ 41 - 20
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/test/java/org/apache/hadoop/mapreduce/v2/app/webapp/TestAMWebServicesTasks.java

@@ -32,6 +32,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.TaskID;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
@@ -122,7 +123,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("tasks")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -141,7 +143,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       String jobId = MRApps.toString(id);
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("tasks").get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -161,7 +164,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("tasks/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -182,7 +186,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("tasks")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
@@ -206,7 +211,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("tasks").queryParam("type", type)
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -226,7 +232,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("mapreduce")
           .path("jobs").path(jobId).path("tasks").queryParam("type", type)
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -253,7 +260,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -282,7 +290,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid)
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("task");
@@ -303,7 +312,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid + "/")
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("task");
@@ -324,7 +334,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("task");
@@ -347,7 +358,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -381,7 +393,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -413,7 +426,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -447,7 +461,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -481,7 +496,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -514,7 +530,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
             .path("jobs").path(jobId).path("tasks").path(tid)
             .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-        assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         String xml = response.getEntity(String.class);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
@@ -627,7 +644,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("counters")
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("jobTaskCounters");
@@ -648,7 +666,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("counters/")
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("jobTaskCounters");
@@ -669,7 +688,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("counters")
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("jobTaskCounters");
@@ -690,7 +710,8 @@ public class TestAMWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("mapreduce")
             .path("jobs").path(jobId).path("tasks").path(tid).path("counters")
             .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         String xml = response.getEntity(String.class);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();

+ 27 - 13
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/webapp/HsWebServices.java

@@ -34,6 +34,7 @@ import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.JobACL;
 import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
 import org.apache.hadoop.mapreduce.v2.api.records.JobState;
@@ -110,14 +111,16 @@ public class HsWebServices {
   }
 
   @GET
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public HistoryInfo get() {
     return getHistoryInfo();
   }
 
   @GET
   @Path("/info")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public HistoryInfo getHistoryInfo() {
     init();
     return new HistoryInfo();
@@ -125,7 +128,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobsInfo getJobs(@QueryParam("user") String userQuery,
       @QueryParam("limit") String count,
       @QueryParam("state") String stateQuery,
@@ -215,7 +219,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobInfo getJob(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid) {
 
@@ -227,7 +232,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/jobattempts")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public AMAttemptsInfo getJobAttempts(@PathParam("jobid") String jid) {
 
     init();
@@ -244,7 +250,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/counters")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobCounterInfo getJobCounters(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid) {
 
@@ -256,7 +263,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/conf")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public ConfInfo getJobConf(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid) {
 
@@ -275,7 +283,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/tasks")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TasksInfo getJobTasks(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @QueryParam("type") String type) {
 
@@ -302,7 +311,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/tasks/{taskid}")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TaskInfo getJobTask(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid) {
 
@@ -316,7 +326,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/tasks/{taskid}/counters")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobTaskCounterInfo getSingleTaskCounters(
       @Context HttpServletRequest hsr, @PathParam("jobid") String jid,
       @PathParam("taskid") String tid) {
@@ -337,7 +348,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/tasks/{taskid}/attempts")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TaskAttemptsInfo getJobTaskAttempts(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid) {
 
@@ -360,7 +372,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public TaskAttemptInfo getJobTaskAttemptId(@Context HttpServletRequest hsr,
       @PathParam("jobid") String jid, @PathParam("taskid") String tid,
       @PathParam("attemptid") String attId) {
@@ -380,7 +393,8 @@ public class HsWebServices {
 
   @GET
   @Path("/mapreduce/jobs/{jobid}/tasks/{taskid}/attempts/{attemptid}/counters")
-  @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+      MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public JobTaskAttemptCounterInfo getJobTaskAttemptIdCounters(
       @Context HttpServletRequest hsr, @PathParam("jobid") String jid,
       @PathParam("taskid") String tid, @PathParam("attemptid") String attId) {

+ 17 - 8
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServices.java

@@ -29,6 +29,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
 import org.apache.hadoop.mapreduce.v2.hs.HistoryContext;
 import org.apache.hadoop.mapreduce.v2.hs.JobHistory;
@@ -116,7 +117,8 @@ public class TestHsWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("history")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyHSInfo(json.getJSONObject("historyInfo"), appContext);
@@ -127,7 +129,8 @@ public class TestHsWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("history/")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyHSInfo(json.getJSONObject("historyInfo"), appContext);
@@ -138,7 +141,8 @@ public class TestHsWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("history/")
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyHSInfo(json.getJSONObject("historyInfo"), appContext);
@@ -149,7 +153,8 @@ public class TestHsWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("history")
         .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     verifyHSInfoXML(xml, appContext);
   }
@@ -160,7 +165,8 @@ public class TestHsWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("info").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyHSInfo(json.getJSONObject("historyInfo"), appContext);
@@ -172,7 +178,8 @@ public class TestHsWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("info/").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyHSInfo(json.getJSONObject("historyInfo"), appContext);
@@ -183,7 +190,8 @@ public class TestHsWebServices extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("info/").get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     verifyHSInfo(json.getJSONObject("historyInfo"), appContext);
@@ -195,7 +203,8 @@ public class TestHsWebServices extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("info/").accept(MediaType.APPLICATION_XML)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     verifyHSInfoXML(xml, appContext);
   }

+ 23 - 11
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesAttempts.java

@@ -35,6 +35,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskAttemptId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskType;
@@ -137,7 +138,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("attempts").accept(MediaType.APPLICATION_JSON)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         verifyHsTaskAttempts(json, task);
       }
@@ -157,7 +159,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("attempts/").accept(MediaType.APPLICATION_JSON)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         verifyHsTaskAttempts(json, task);
       }
@@ -176,7 +179,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("history")
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("attempts").get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         verifyHsTaskAttempts(json, task);
       }
@@ -197,7 +201,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
             .path("attempts").accept(MediaType.APPLICATION_XML)
             .get(ClientResponse.class);
 
-        assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         String xml = response.getEntity(String.class);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
@@ -232,7 +237,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
               .path("mapreduce").path("jobs").path(jobId).path("tasks")
               .path(tid).path("attempts").path(attid)
               .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("taskAttempt");
@@ -261,7 +267,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
               .path("mapreduce").path("jobs").path(jobId).path("tasks")
               .path(tid).path("attempts").path(attid + "/")
               .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("taskAttempt");
@@ -289,7 +296,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
           ClientResponse response = r.path("ws").path("v1").path("history")
               .path("mapreduce").path("jobs").path(jobId).path("tasks")
               .path(tid).path("attempts").path(attid).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("taskAttempt");
@@ -317,7 +325,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
               .path(tid).path("attempts").path(attid)
               .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-          assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+              response.getType().toString());
           String xml = response.getEntity(String.class);
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();
@@ -394,7 +403,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
         } catch (UniformInterfaceException ue) {
           ClientResponse response = ue.getResponse();
           assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject msg = response.getEntity(JSONObject.class);
           JSONObject exception = msg.getJSONObject("RemoteException");
           assertEquals("incorrect number of elements", 3, exception.length());
@@ -573,7 +583,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
               .path("mapreduce").path("jobs").path(jobId).path("tasks")
               .path(tid).path("attempts").path(attid).path("counters")
               .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-          assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_JSON_TYPE + "; "
+                  + JettyUtils.UTF_8, response.getType().toString());
           JSONObject json = response.getEntity(JSONObject.class);
           assertEquals("incorrect number of elements", 1, json.length());
           JSONObject info = json.getJSONObject("jobTaskAttemptCounters");
@@ -601,7 +612,8 @@ public class TestHsWebServicesAttempts extends JerseyTestBase {
               .path(tid).path("attempts").path(attid).path("counters")
               .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-          assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+          assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+              response.getType().toString());
           String xml = response.getEntity(String.class);
           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
           DocumentBuilder db = dbf.newDocumentBuilder();

+ 9 - 4
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesJobConf.java

@@ -39,6 +39,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.FileUtil;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.MRJobConfig;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
@@ -167,7 +168,8 @@ public class TestHsWebServicesJobConf extends JerseyTestBase {
           .path("mapreduce")
           .path("jobs").path(jobId).path("conf")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("conf");
@@ -185,7 +187,8 @@ public class TestHsWebServicesJobConf extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history").path("mapreduce")
           .path("jobs").path(jobId).path("conf/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("conf");
@@ -202,7 +205,8 @@ public class TestHsWebServicesJobConf extends JerseyTestBase {
 
       ClientResponse response = r.path("ws").path("v1").path("history").path("mapreduce")
           .path("jobs").path(jobId).path("conf").get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("conf");
@@ -220,7 +224,8 @@ public class TestHsWebServicesJobConf extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history").path("mapreduce")
           .path("jobs").path(jobId).path("conf")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();

+ 45 - 22
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesJobs.java

@@ -36,6 +36,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.api.records.AMInfo;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
@@ -127,7 +128,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -145,7 +147,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs/").accept(MediaType.APPLICATION_JSON)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -162,7 +165,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     WebResource r = resource();
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -180,7 +184,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").accept(MediaType.APPLICATION_XML)
         .get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     String xml = response.getEntity(String.class);
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
     DocumentBuilder db = dbf.newDocumentBuilder();
@@ -271,7 +276,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId)
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("job");
@@ -290,7 +296,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId + "/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("job");
@@ -308,7 +315,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
 
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("job");
@@ -328,7 +336,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -356,7 +365,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -380,7 +390,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -404,7 +415,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String msg = response.getEntity(String.class);
       System.out.println(msg);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
@@ -443,7 +455,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
     } catch (UniformInterfaceException ue) {
       ClientResponse response = ue.getResponse();
       assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject msg = response.getEntity(JSONObject.class);
       JSONObject exception = msg.getJSONObject("RemoteException");
       assertEquals("incorrect number of elements", 3, exception.length());
@@ -470,7 +483,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId)
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
@@ -493,7 +507,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("counters")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -511,7 +526,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("counters/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -549,7 +565,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("counters/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -569,7 +586,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("counters/")
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobCounters");
@@ -587,7 +605,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("counters")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
@@ -686,7 +705,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobAttempts");
@@ -704,7 +724,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobAttempts");
@@ -722,7 +743,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts")
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject info = json.getJSONObject("jobAttempts");
@@ -740,7 +762,8 @@ public class TestHsWebServicesJobs extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("jobattempts")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();

+ 51 - 25
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesJobsQuery.java

@@ -32,6 +32,7 @@ import java.util.Map;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.JobState;
 import org.apache.hadoop.mapreduce.v2.app.AppContext;
@@ -130,7 +131,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs").queryParam("state", notInUse.toString())
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
 
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     assertEquals("jobs is not empty",
@@ -152,7 +154,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").queryParam("state", queryState)
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -172,7 +175,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
 
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -197,7 +201,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").queryParam("user", "bogus")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     assertEquals("jobs is not empty",
@@ -210,7 +215,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").queryParam("user", "mock")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     System.out.println(json.toString());
 
@@ -230,7 +236,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").queryParam("limit", "2")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -248,7 +255,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
 
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -269,7 +277,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").queryParam("queue", "mockqueue")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -283,7 +292,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
     ClientResponse response = r.path("ws").path("v1").path("history")
         .path("mapreduce").path("jobs").queryParam("queue", "bogus")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     assertEquals("jobs is not empty",
@@ -299,7 +309,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs")
         .queryParam("startedTimeEnd", String.valueOf(now))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -316,7 +327,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs")
         .queryParam("startedTimeBegin", String.valueOf(now))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     assertEquals("jobs is not empty",
@@ -343,7 +355,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("startedTimeBegin", String.valueOf(40000))
         .queryParam("startedTimeEnd", String.valueOf(midStartTime))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -362,7 +375,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("startedTimeEnd", String.valueOf(40000))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -388,7 +402,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs").queryParam("startedTimeBegin", "efsd")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -414,7 +429,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs").queryParam("startedTimeEnd", "efsd")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -440,7 +456,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("startedTimeBegin", String.valueOf(-1000))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -466,7 +483,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("startedTimeEnd", String.valueOf(-1000))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -490,7 +508,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("finishedTimeEnd", String.valueOf(-1000))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -514,7 +533,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("finishedTimeBegin", String.valueOf(-1000))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -541,7 +561,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("finishedTimeEnd", String.valueOf(40000))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -567,7 +588,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs").queryParam("finishedTimeBegin", "efsd")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -593,7 +615,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs").queryParam("finishedTimeEnd", "efsd")
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
     assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject msg = response.getEntity(JSONObject.class);
     JSONObject exception = msg.getJSONObject("RemoteException");
     assertEquals("incorrect number of elements", 3, exception.length());
@@ -620,7 +643,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs")
         .queryParam("finishedTimeBegin", String.valueOf(now))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");
@@ -637,7 +661,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .path("mapreduce").path("jobs")
         .queryParam("finishedTimeEnd", String.valueOf(now))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     assertEquals("jobs is not empty",
@@ -665,7 +690,8 @@ public class TestHsWebServicesJobsQuery extends JerseyTestBase {
         .queryParam("finishedTimeBegin", String.valueOf(40000))
         .queryParam("finishedTimeEnd", String.valueOf(midFinishTime))
         .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-    assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+    assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+        response.getType().toString());
     JSONObject json = response.getEntity(JSONObject.class);
     assertEquals("incorrect number of elements", 1, json.length());
     JSONObject jobs = json.getJSONObject("jobs");

+ 41 - 20
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/test/java/org/apache/hadoop/mapreduce/v2/hs/webapp/TestHsWebServicesTasks.java

@@ -34,6 +34,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.hadoop.mapreduce.TaskID;
 import org.apache.hadoop.mapreduce.v2.api.records.JobId;
 import org.apache.hadoop.mapreduce.v2.api.records.TaskId;
@@ -131,7 +132,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("tasks")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -151,7 +153,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("tasks")
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -171,7 +174,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("tasks/")
           .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -192,7 +196,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       ClientResponse response = r.path("ws").path("v1").path("history")
           .path("mapreduce").path("jobs").path(jobId).path("tasks")
           .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       String xml = response.getEntity(String.class);
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
       DocumentBuilder db = dbf.newDocumentBuilder();
@@ -217,7 +222,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
           .path("mapreduce").path("jobs").path(jobId).path("tasks")
           .queryParam("type", type).accept(MediaType.APPLICATION_JSON)
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -238,7 +244,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
           .path("mapreduce").path("jobs").path(jobId).path("tasks")
           .queryParam("type", type).accept(MediaType.APPLICATION_JSON)
           .get(ClientResponse.class);
-      assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+      assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+          response.getType().toString());
       JSONObject json = response.getEntity(JSONObject.class);
       assertEquals("incorrect number of elements", 1, json.length());
       JSONObject tasks = json.getJSONObject("tasks");
@@ -265,7 +272,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.BAD_REQUEST, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -294,7 +302,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("history")
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("task");
@@ -316,7 +325,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks")
             .path(tid + "/").accept(MediaType.APPLICATION_JSON)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("task");
@@ -337,7 +347,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("history")
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("task");
@@ -360,7 +371,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -394,7 +406,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -426,7 +439,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -460,7 +474,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -494,7 +509,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
       } catch (UniformInterfaceException ue) {
         ClientResponse response = ue.getResponse();
         assertResponseStatusCode(Status.NOT_FOUND, response.getStatusInfo());
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject msg = response.getEntity(JSONObject.class);
         JSONObject exception = msg.getJSONObject("RemoteException");
         assertEquals("incorrect number of elements", 3, exception.length());
@@ -527,7 +543,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
 
-        assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         String xml = response.getEntity(String.class);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
@@ -638,7 +655,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("counters").accept(MediaType.APPLICATION_JSON)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("jobTaskCounters");
@@ -660,7 +678,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("counters/").accept(MediaType.APPLICATION_JSON)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("jobTaskCounters");
@@ -681,7 +700,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
         ClientResponse response = r.path("ws").path("v1").path("history")
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("counters").get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_JSON_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_JSON_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         JSONObject json = response.getEntity(JSONObject.class);
         assertEquals("incorrect number of elements", 1, json.length());
         JSONObject info = json.getJSONObject("jobTaskCounters");
@@ -703,7 +723,8 @@ public class TestHsWebServicesTasks extends JerseyTestBase {
             .path("mapreduce").path("jobs").path(jobId).path("tasks").path(tid)
             .path("counters").accept(MediaType.APPLICATION_XML)
             .get(ClientResponse.class);
-        assertEquals(MediaType.APPLICATION_XML_TYPE, response.getType());
+        assertEquals(MediaType.APPLICATION_XML_TYPE + "; " + JettyUtils.UTF_8,
+            response.getType().toString());
         String xml = response.getEntity(String.class);
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();

+ 7 - 5
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/NotificationTestCase.java

@@ -18,9 +18,10 @@
 
 package org.apache.hadoop.mapred;
 
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.io.Text;
@@ -76,7 +77,8 @@ public abstract class NotificationTestCase extends HadoopTestCase {
     }
     webServer = new Server(0);
 
-    Context context = new Context(webServer, contextPath);
+    ServletContextHandler context =
+        new ServletContextHandler(webServer, contextPath);
 
     // create servlet handler
     context.addServlet(new ServletHolder(new NotificationServlet()),
@@ -84,7 +86,7 @@ public abstract class NotificationTestCase extends HadoopTestCase {
 
     // Start webServer
     webServer.start();
-    port = webServer.getConnectors()[0].getLocalPort();
+    port = ((ServerConnector)webServer.getConnectors()[0]).getLocalPort();
 
   }
 

+ 1 - 1
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapreduce/MiniHadoopClusterManager.java

@@ -45,7 +45,7 @@ import org.apache.hadoop.mapred.MiniMRClientClusterFactory;
 import org.apache.hadoop.mapreduce.v2.jobhistory.JHAdminConfig;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.server.MiniYARNCluster;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 
 /**
  * This class drives the creation of a mini-cluster on the local machine. By

+ 8 - 6
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle/src/main/java/org/apache/hadoop/mapred/ShuffleHandler.java

@@ -127,7 +127,7 @@ import org.jboss.netty.handler.codec.http.QueryStringDecoder;
 import org.jboss.netty.handler.ssl.SslHandler;
 import org.jboss.netty.handler.stream.ChunkedWriteHandler;
 import org.jboss.netty.util.CharsetUtil;
-import org.mortbay.jetty.HttpHeaders;
+import org.eclipse.jetty.http.HttpHeader;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Charsets;
@@ -1137,13 +1137,15 @@ public class ShuffleHandler extends AuxiliaryService {
         if (LOG.isDebugEnabled()) {
           LOG.debug("Setting connection close header...");
         }
-        response.headers().set(HttpHeaders.CONNECTION, CONNECTION_CLOSE);
+        response.headers().set(HttpHeader.CONNECTION.asString(),
+            CONNECTION_CLOSE);
       } else {
-        response.headers().set(HttpHeaders.CONTENT_LENGTH,
+        response.headers().set(HttpHeader.CONTENT_LENGTH.asString(),
           String.valueOf(contentLength));
-        response.headers().set(HttpHeaders.CONNECTION, HttpHeaders.KEEP_ALIVE);
-        response.headers().set(HttpHeaders.KEEP_ALIVE, "timeout="
-            + connectionKeepAliveTimeOut);
+        response.headers().set(HttpHeader.CONNECTION.asString(),
+            HttpHeader.KEEP_ALIVE.asString());
+        response.headers().set(HttpHeader.KEEP_ALIVE.asString(),
+            "timeout=" + connectionKeepAliveTimeOut);
         LOG.info("Content Length in shuffle : " + contentLength);
       }
     }

+ 13 - 12
hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle/src/test/java/org/apache/hadoop/mapred/TestShuffleHandler.java

@@ -92,7 +92,7 @@ import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.mockito.Mockito;
-import org.mortbay.jetty.HttpHeaders;
+import org.eclipse.jetty.http.HttpHeader;
 
 public class TestShuffleHandler {
   static final long MiB = 1024 * 1024; 
@@ -299,7 +299,8 @@ public class TestShuffleHandler {
     conn.connect();
     DataInputStream input = new DataInputStream(conn.getInputStream());
     Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
-    Assert.assertEquals("close", conn.getHeaderField(HttpHeaders.CONNECTION));
+    Assert.assertEquals("close",
+        conn.getHeaderField(HttpHeader.CONNECTION.asString()));
     ShuffleHeader header = new ShuffleHeader();
     header.readFields(input);
     input.close();
@@ -409,15 +410,15 @@ public class TestShuffleHandler {
             + "map=attempt_12345_1_m_1_0");
     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     conn.setRequestProperty(ShuffleHeader.HTTP_HEADER_NAME,
-      ShuffleHeader.DEFAULT_HTTP_HEADER_NAME);
+        ShuffleHeader.DEFAULT_HTTP_HEADER_NAME);
     conn.setRequestProperty(ShuffleHeader.HTTP_HEADER_VERSION,
-      ShuffleHeader.DEFAULT_HTTP_HEADER_VERSION);
+        ShuffleHeader.DEFAULT_HTTP_HEADER_VERSION);
     conn.connect();
     DataInputStream input = new DataInputStream(conn.getInputStream());
-    Assert.assertEquals(HttpHeaders.KEEP_ALIVE,
-      conn.getHeaderField(HttpHeaders.CONNECTION));
+    Assert.assertEquals(HttpHeader.KEEP_ALIVE.asString(),
+        conn.getHeaderField(HttpHeader.CONNECTION.asString()));
     Assert.assertEquals("timeout=1",
-      conn.getHeaderField(HttpHeaders.KEEP_ALIVE));
+        conn.getHeaderField(HttpHeader.KEEP_ALIVE.asString()));
     Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
     ShuffleHeader header = new ShuffleHeader();
     header.readFields(input);
@@ -429,15 +430,15 @@ public class TestShuffleHandler {
             + "map=attempt_12345_1_m_1_0&keepAlive=true");
     conn = (HttpURLConnection) url.openConnection();
     conn.setRequestProperty(ShuffleHeader.HTTP_HEADER_NAME,
-      ShuffleHeader.DEFAULT_HTTP_HEADER_NAME);
+        ShuffleHeader.DEFAULT_HTTP_HEADER_NAME);
     conn.setRequestProperty(ShuffleHeader.HTTP_HEADER_VERSION,
-      ShuffleHeader.DEFAULT_HTTP_HEADER_VERSION);
+        ShuffleHeader.DEFAULT_HTTP_HEADER_VERSION);
     conn.connect();
     input = new DataInputStream(conn.getInputStream());
-    Assert.assertEquals(HttpHeaders.KEEP_ALIVE,
-      conn.getHeaderField(HttpHeaders.CONNECTION));
+    Assert.assertEquals(HttpHeader.KEEP_ALIVE.asString(),
+        conn.getHeaderField(HttpHeader.CONNECTION.asString()));
     Assert.assertEquals("timeout=1",
-      conn.getHeaderField(HttpHeaders.KEEP_ALIVE));
+        conn.getHeaderField(HttpHeader.KEEP_ALIVE.asString()));
     Assert.assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
     header = new ShuffleHeader();
     header.readFields(input);

+ 2 - 2
hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml

@@ -46,8 +46,8 @@
       <artifactId>avro</artifactId>
       <exclusions>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
           <groupId>org.apache.ant</groupId>

+ 2 - 2
hadoop-mapreduce-project/pom.xml

@@ -52,8 +52,8 @@
       <artifactId>avro</artifactId>
       <exclusions>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>jetty</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
         </exclusion>
         <exclusion>
           <groupId>org.apache.ant</groupId>

+ 4 - 0
hadoop-maven-plugins/pom.xml

@@ -55,6 +55,10 @@
       <groupId>org.codehaus.jackson</groupId>
       <artifactId>jackson-mapper-asl</artifactId>
     </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
   </dependencies>
   <build>
     <plugins>

+ 125 - 0
hadoop-maven-plugins/src/main/java/org/apache/hadoop/maven/plugin/resourcegz/ResourceGzMojo.java

@@ -0,0 +1,125 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.maven.plugin.resourcegz;
+
+import com.google.inject.internal.util.Lists;
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * ResourceGzMojo will gzip files.
+ * It is meant to be used for gzipping website resource files (e.g. .js, .css,
+ * etc).  It takes an input directory, output directory, and extensions to
+ * process and will generate the .gz files. Any additional directory structure
+ * beyond the input directory is preserved in the output directory.
+ */
+@Mojo(name="resource-gz")
+public class ResourceGzMojo extends AbstractMojo {
+
+  /**
+   * The input directory.  Will be searched recursively and its directory
+   * structure will be maintaned in the outputDirectory.
+   */
+  @Parameter(property = "inputDirectory", required = true)
+  private String inputDirectory;
+
+  /**
+   * The output directory.
+   */
+  @Parameter(property = "outputDirectory", required = true)
+  private String outputDirectory;
+
+  /**
+   * A comma separated list of extensions to include.
+   */
+  @Parameter(property = "extensions", required = true)
+  private String extensions;
+
+  public void execute() throws MojoExecutionException, MojoFailureException {
+    try {
+      Path inputDir = new File(inputDirectory).toPath();
+      File outputDir = new File(outputDirectory);
+      List<String> exts = Lists.newArrayList(extensions.split(","));
+      exts.replaceAll(String::trim);
+      GZConsumer cons = new GZConsumer(inputDir.toFile(), outputDir);
+      Files.walk(inputDir).filter(path -> {
+        for (String ext : exts) {
+          if (path.getFileName().toString().endsWith("." + ext)) {
+            return true;
+          }
+        }
+        return false;
+      }).forEach(cons);
+      if (cons.getThrowable() != null) {
+        throw new MojoExecutionException(cons.getThrowable().toString(),
+            cons.getThrowable());
+      }
+    } catch (Throwable t) {
+      throw new MojoExecutionException(t.toString(), t);
+    }
+  }
+
+  private class GZConsumer implements Consumer<Path> {
+    private final File inputDir;
+    private final File outputDir;
+    private Throwable throwable;
+
+    public GZConsumer(File inputDir, File outputDir) {
+      this.inputDir = inputDir;
+      this.outputDir = outputDir;
+      this.throwable = null;
+    }
+
+    @Override
+    public void accept(Path path) {
+      if (throwable != null) {
+        return;
+      }
+      try {
+        File outFile = new File(outputDir, path.toFile().getCanonicalPath()
+            .replaceFirst(inputDir.getCanonicalPath(), "") + ".gz");
+        outFile.getParentFile().mkdirs();
+        try (
+            GZIPOutputStream os = new GZIPOutputStream(
+                new FileOutputStream(outFile));
+            BufferedReader is = Files.newBufferedReader(path)
+        ) {
+          getLog().info("Compressing " + path + " to " + outFile);
+          IOUtils.copy(is, os);
+        } catch (Throwable t) {
+          this.throwable = t;
+        }
+      } catch (Throwable t) {
+        this.throwable = t;
+      }
+    }
+
+    public Throwable getThrowable() {
+      return throwable;
+    }
+  }
+}

+ 40 - 12
hadoop-project/pom.xml

@@ -35,7 +35,7 @@
 
     <failIfNoTests>false</failIfNoTests>
     <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
-    <jetty.version>6.1.26</jetty.version>
+    <jetty.version>9.3.11.v20160721</jetty.version>
     <test.exclude>_</test.exclude>
     <test.exclude.pattern>_</test.exclude.pattern>
 
@@ -518,28 +518,38 @@
       </dependency>
       <dependency>
         <groupId>javax.servlet</groupId>
-        <artifactId>servlet-api</artifactId>
-        <version>2.5</version>
+        <artifactId>javax.servlet-api</artifactId>
+        <version>3.1.0</version>
       </dependency>
       <dependency>
-        <groupId>org.mortbay.jetty</groupId>
-        <artifactId>jetty</artifactId>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-server</artifactId>
         <version>${jetty.version}</version>
         <exclusions>
           <exclusion>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>servlet-api</artifactId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>javax.servlet-api</artifactId>
           </exclusion>
         </exclusions>
       </dependency>
       <dependency>
-        <groupId>org.mortbay.jetty</groupId>
+        <groupId>org.eclipse.jetty</groupId>
         <artifactId>jetty-util</artifactId>
         <version>${jetty.version}</version>
       </dependency>
       <dependency>
-        <groupId>org.mortbay.jetty</groupId>
-        <artifactId>jetty-sslengine</artifactId>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-servlet</artifactId>
+        <version>${jetty.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-webapp</artifactId>
+        <version>${jetty.version}</version>
+      </dependency>
+        <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-util-ajax</artifactId>
         <version>${jetty.version}</version>
       </dependency>
       <dependency>
@@ -636,11 +646,23 @@
         <artifactId>jersey-test-framework-core</artifactId>
         <version>${jersey.version}</version>
         <scope>test</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+          </exclusion>
+        </exclusions>
       </dependency>
       <dependency>
         <groupId>com.sun.jersey.jersey-test-framework</groupId>
         <artifactId>jersey-test-framework-grizzly2</artifactId>
         <version>${jersey.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+          </exclusion>
+        </exclusions>
       </dependency>
 
       <dependency>
@@ -668,7 +690,7 @@
       </dependency>
 
       <dependency>
-        <groupId>org.mortbay.jetty</groupId>
+        <groupId>org.eclipse.jetty</groupId>
         <artifactId>jetty-servlet-tester</artifactId>
         <version>${jetty.version}</version>
       </dependency>
@@ -687,7 +709,7 @@
           </exclusion>
           <exclusion>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
           </exclusion>
         </exclusions>
       </dependency>
@@ -847,6 +869,12 @@
         <groupId>org.mock-server</groupId>
         <artifactId>mockserver-netty</artifactId>
         <version>3.9.2</version>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+          </exclusion>
+        </exclusions>
       </dependency>
       <dependency>
         <groupId>org.apache.avro</groupId>

+ 1 - 1
hadoop-tools/hadoop-azure-datalake/pom.xml

@@ -135,7 +135,7 @@
       <artifactId>hadoop-client</artifactId>
       <exclusions>
         <exclusion>
-          <artifactId>servlet-api</artifactId>
+          <artifactId>javax.servlet-api</artifactId>
           <groupId>javax.servlet</groupId>
         </exclusion>
       </exclusions>

+ 6 - 1
hadoop-tools/hadoop-azure/pom.xml

@@ -164,13 +164,18 @@
       <artifactId>azure-storage</artifactId>
       <scope>compile</scope>
     </dependency>
-    
 
     <dependency>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
       <scope>compile</scope>
     </dependency>
+
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-util-ajax</artifactId>
+      <scope>compile</scope>
+    </dependency>
     
     
     <!-- dependencies use for test only -->

+ 1 - 1
hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azure/AzureNativeFileSystemStore.java

@@ -59,7 +59,7 @@ import org.apache.hadoop.fs.azure.metrics.ResponseReceivedMetricUpdater;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.fs.permission.PermissionStatus;
 import org.apache.hadoop.io.IOUtils;
-import org.mortbay.util.ajax.JSON;
+import org.eclipse.jetty.util.ajax.JSON;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 3 - 3
hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azure/BlockBlobAppendStream.java

@@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.hadoop.fs.FSExceptionMessages;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.hadoop.fs.azure.StorageInterface.CloudBlockBlobWrapper;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -760,7 +760,7 @@ public class BlockBlobAppendStream extends OutputStream {
               dataPayload.length, new BlobRequestOptions(), opContext);
           break;
         } catch(Exception ioe) {
-          Log.debug("Encountered exception during uploading block for Blob : {} Exception : {}", key, ioe);
+          Log.getLog().debug("Encountered exception during uploading block for Blob : {} Exception : {}", key, ioe);
           uploadRetryAttempts++;
           lastLocalException = new IOException("Encountered Exception while uploading block", ioe);
           try {
@@ -814,7 +814,7 @@ public class BlockBlobAppendStream extends OutputStream {
           Thread.currentThread().interrupt();
         }
 
-        Log.debug("Attempting to renew append lease on {}", key);
+        Log.getLog().debug("Attempting to renew append lease on {}", key);
 
         try {
           if (!leaseFreed) {

+ 5 - 5
hadoop-tools/hadoop-sls/pom.xml

@@ -55,18 +55,18 @@
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
-      <artifactId>jetty</artifactId>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
       <scope>provided</scope>
       <exclusions>
         <exclusion>
-          <groupId>org.mortbay.jetty</groupId>
-          <artifactId>servlet-api</artifactId>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>javax.servlet-api</artifactId>
         </exclusion>
       </exclusions>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
       <scope>provided</scope>
     </dependency>

+ 11 - 8
hadoop-tools/hadoop-sls/src/main/java/org/apache/hadoop/yarn/sls/web/SLSWebApp.java

@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -38,16 +39,16 @@ import org.apache.hadoop.yarn.sls.SLSRunner;
 import org.apache.hadoop.yarn.sls.scheduler.FairSchedulerMetrics;
 import org.apache.hadoop.yarn.sls.scheduler.SchedulerMetrics;
 import org.apache.hadoop.yarn.sls.scheduler.SchedulerWrapper;
-import org.mortbay.jetty.Handler;
-import org.mortbay.jetty.Request;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.handler.AbstractHandler;
-import org.mortbay.jetty.handler.ResourceHandler;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
 
 import com.codahale.metrics.Counter;
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Histogram;
 import com.codahale.metrics.MetricRegistry;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.handler.ResourceHandler;
 
 @Private
 @Unstable
@@ -121,8 +122,10 @@ public class SLSWebApp extends HttpServlet {
 
     Handler handler = new AbstractHandler() {
       @Override
-      public void handle(String target, HttpServletRequest request,
-                         HttpServletResponse response, int dispatch) {
+      public void handle(String target, Request baseRequest,
+                         HttpServletRequest request,
+                         HttpServletResponse response)
+          throws IOException, ServletException {
         try{
           // timeunit
           int timeunit = 1000;   // second, divide millionsecond / 1000
@@ -144,7 +147,7 @@ public class SLSWebApp extends HttpServlet {
             // js/css request
             if (target.startsWith("/js") || target.startsWith("/css")) {
               response.setCharacterEncoding("utf-8");
-              staticHandler.handle(target, request, response, dispatch);
+              staticHandler.handle(target, baseRequest, request, response);
             } else
               // json request
               if (target.equals("/simulateMetrics")) {

+ 5 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestAMRMClient.java

@@ -99,7 +99,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 import com.google.common.base.Supplier;
 
@@ -654,7 +654,8 @@ public class TestAMRMClient {
       int iterationsLeft = 3;
       while (allocatedContainerCount < 2
           && iterationsLeft-- > 0) {
-        Log.info(" == alloc " + allocatedContainerCount + " it left " + iterationsLeft);
+        Log.getLog().info("Allocated " + allocatedContainerCount + " containers"
+            + " with " + iterationsLeft + " iterations left");
         AllocateResponse allocResponse = amClient.allocate(0.1f);
         assertEquals(0, amClient.ask.size());
         assertEquals(0, amClient.release.size());
@@ -822,7 +823,8 @@ public class TestAMRMClient {
       throws YarnException, IOException {
     int allocatedContainerCount = 0;
     while (iterationsLeft-- > 0) {
-      Log.info(" == alloc " + allocatedContainerCount + " it left " + iterationsLeft);
+      Log.getLog().info("Allocated " + allocatedContainerCount + " containers"
+          + " with " + iterationsLeft + " iterations left");
       AllocateResponse allocResponse = amClient.allocate(0.1f);
       assertEquals(0, amClient.ask.size());
       assertEquals(0, amClient.release.size());

+ 5 - 5
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/cli/TestYarnCLI.java

@@ -84,7 +84,7 @@ import static org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.C
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.mortbay.log.Log;
+import org.eclipse.jetty.util.log.Log;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
@@ -325,11 +325,11 @@ public class TestYarnCLI {
         "http://host:2345", "");
     pw.close();
     String appReportStr = baos.toString("UTF-8");
-    Log.info("ExpectedOutput");
-    Log.info("["+appReportStr+"]");
-    Log.info("OutputFrom command");
+    Log.getLog().info("ExpectedOutput");
+    Log.getLog().info("["+appReportStr+"]");
+    Log.getLog().info("OutputFrom command");
     String actualOutput = sysOutStream.toString("UTF-8");
-    Log.info("["+actualOutput+"]");
+    Log.getLog().info("["+actualOutput+"]");
     Assert.assertEquals(appReportStr, actualOutput);
   }
   

+ 14 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/pom.xml

@@ -68,14 +68,14 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
     </dependency>
     <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.mortbay.jetty</groupId>
+      <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-util</artifactId>
     </dependency>
     <dependency>
@@ -279,7 +279,18 @@
               <output>${project.build.directory}/generated-sources/java</output>
             </configuration>
           </execution>
-
+          <execution>
+            <id>resource-gz</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>resource-gz</goal>
+            </goals>
+            <configuration>
+              <inputDirectory>${basedir}/src/main/resources/webapps/static</inputDirectory>
+              <outputDirectory>${basedir}/target/classes/webapps/static</outputDirectory>
+              <extensions>js,css</extensions>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>

+ 157 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/dt-1.9.4/js/jquery.dataTables.min.js

@@ -0,0 +1,157 @@
+/*
+ * File:        jquery.dataTables.min.js
+ * Version:     1.9.4
+ * Author:      Allan Jardine (www.sprymedia.co.uk)
+ * Info:        www.datatables.net
+ *
+ * Copyright 2008-2012 Allan Jardine, all rights reserved.
+ *
+ * This source file is free software, under either the GPL v2 license or a
+ * BSD style license, available at:
+ *   http://datatables.net/license_gpl2
+ *   http://datatables.net/license_bsd
+ *
+ * This source file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
+ */
+(function(la,s,p){(function(i){if(typeof define==="function"&&define.amd)define(["jquery"],i);else jQuery&&!jQuery.fn.dataTable&&i(jQuery)})(function(i){var l=function(h){function n(a,b){var c=l.defaults.columns,d=a.aoColumns.length;b=i.extend({},l.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:s.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mData:c.mData?c.oDefaults:d});a.aoColumns.push(b);if(a.aoPreSearchCols[d]===
+p||a.aoPreSearchCols[d]===null)a.aoPreSearchCols[d]=i.extend({},l.models.oSearch);else{b=a.aoPreSearchCols[d];if(b.bRegex===p)b.bRegex=true;if(b.bSmart===p)b.bSmart=true;if(b.bCaseInsensitive===p)b.bCaseInsensitive=true}q(a,d,null)}function q(a,b,c){var d=a.aoColumns[b];if(c!==p&&c!==null){if(c.mDataProp&&!c.mData)c.mData=c.mDataProp;if(c.sType!==p){d.sType=c.sType;d._bAutoType=false}i.extend(d,c);r(d,c,"sWidth","sWidthOrig");if(c.iDataSort!==p)d.aDataSort=[c.iDataSort];r(d,c,"aDataSort")}var e=d.mRender?
+ca(d.mRender):null,f=ca(d.mData);d.fnGetData=function(g,j){var k=f(g,j);if(d.mRender&&j&&j!=="")return e(k,j,g);return k};d.fnSetData=Ja(d.mData);if(!a.oFeatures.bSort)d.bSortable=false;if(!d.bSortable||i.inArray("asc",d.asSorting)==-1&&i.inArray("desc",d.asSorting)==-1){d.sSortingClass=a.oClasses.sSortableNone;d.sSortingClassJUI=""}else if(i.inArray("asc",d.asSorting)==-1&&i.inArray("desc",d.asSorting)==-1){d.sSortingClass=a.oClasses.sSortable;d.sSortingClassJUI=a.oClasses.sSortJUI}else if(i.inArray("asc",
+d.asSorting)!=-1&&i.inArray("desc",d.asSorting)==-1){d.sSortingClass=a.oClasses.sSortableAsc;d.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed}else if(i.inArray("asc",d.asSorting)==-1&&i.inArray("desc",d.asSorting)!=-1){d.sSortingClass=a.oClasses.sSortableDesc;d.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed}}function o(a){if(a.oFeatures.bAutoWidth===false)return false;ta(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function v(a,b){a=A(a,"bVisible");
+return typeof a[b]==="number"?a[b]:null}function w(a,b){a=A(a,"bVisible");b=i.inArray(b,a);return b!==-1?b:null}function D(a){return A(a,"bVisible").length}function A(a,b){var c=[];i.map(a.aoColumns,function(d,e){d[b]&&c.push(e)});return c}function G(a){for(var b=l.ext.aTypes,c=b.length,d=0;d<c;d++){var e=b[d](a);if(e!==null)return e}return"string"}function E(a,b){b=b.split(",");for(var c=[],d=0,e=a.aoColumns.length;d<e;d++)for(var f=0;f<e;f++)if(a.aoColumns[d].sName==b[f]){c.push(f);break}return c}
+function Y(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";if(b.length==d)return"";return b.slice(0,-1)}function ma(a,b,c,d){var e,f,g,j,k;if(b)for(e=b.length-1;e>=0;e--){var m=b[e].aTargets;i.isArray(m)||O(a,1,"aTargets must be an array of targets, not a "+typeof m);f=0;for(g=m.length;f<g;f++)if(typeof m[f]==="number"&&m[f]>=0){for(;a.aoColumns.length<=m[f];)n(a);d(m[f],b[e])}else if(typeof m[f]==="number"&&m[f]<0)d(a.aoColumns.length+m[f],b[e]);else if(typeof m[f]===
+"string"){j=0;for(k=a.aoColumns.length;j<k;j++)if(m[f]=="_all"||i(a.aoColumns[j].nTh).hasClass(m[f]))d(j,b[e])}}if(c){e=0;for(a=c.length;e<a;e++)d(e,c[e])}}function R(a,b){var c;c=i.isArray(b)?b.slice():i.extend(true,{},b);b=a.aoData.length;var d=i.extend(true,{},l.models.oRow);d._aData=c;a.aoData.push(d);var e;d=0;for(var f=a.aoColumns.length;d<f;d++){c=a.aoColumns[d];typeof c.fnRender==="function"&&c.bUseRendered&&c.mData!==null?S(a,b,d,da(a,b,d)):S(a,b,d,F(a,b,d));if(c._bAutoType&&c.sType!="string"){e=
+F(a,b,d,"type");if(e!==null&&e!==""){e=G(e);if(c.sType===null)c.sType=e;else if(c.sType!=e&&c.sType!="html")c.sType="string"}}}a.aiDisplayMaster.push(b);a.oFeatures.bDeferRender||ua(a,b);return b}function ea(a){var b,c,d,e,f,g,j;if(a.bDeferLoading||a.sAjaxSource===null)for(b=a.nTBody.firstChild;b;){if(b.nodeName.toUpperCase()=="TR"){c=a.aoData.length;b._DT_RowIndex=c;a.aoData.push(i.extend(true,{},l.models.oRow,{nTr:b}));a.aiDisplayMaster.push(c);f=b.firstChild;for(d=0;f;){g=f.nodeName.toUpperCase();
+if(g=="TD"||g=="TH"){S(a,c,d,i.trim(f.innerHTML));d++}f=f.nextSibling}}b=b.nextSibling}e=fa(a);d=[];b=0;for(c=e.length;b<c;b++)for(f=e[b].firstChild;f;){g=f.nodeName.toUpperCase();if(g=="TD"||g=="TH")d.push(f);f=f.nextSibling}c=0;for(e=a.aoColumns.length;c<e;c++){j=a.aoColumns[c];if(j.sTitle===null)j.sTitle=j.nTh.innerHTML;var k=j._bAutoType,m=typeof j.fnRender==="function",u=j.sClass!==null,x=j.bVisible,y,B;if(k||m||u||!x){g=0;for(b=a.aoData.length;g<b;g++){f=a.aoData[g];y=d[g*e+c];if(k&&j.sType!=
+"string"){B=F(a,g,c,"type");if(B!==""){B=G(B);if(j.sType===null)j.sType=B;else if(j.sType!=B&&j.sType!="html")j.sType="string"}}if(j.mRender)y.innerHTML=F(a,g,c,"display");else if(j.mData!==c)y.innerHTML=F(a,g,c,"display");if(m){B=da(a,g,c);y.innerHTML=B;j.bUseRendered&&S(a,g,c,B)}if(u)y.className+=" "+j.sClass;if(x)f._anHidden[c]=null;else{f._anHidden[c]=y;y.parentNode.removeChild(y)}j.fnCreatedCell&&j.fnCreatedCell.call(a.oInstance,y,F(a,g,c,"display"),f._aData,g,c)}}}if(a.aoRowCreatedCallback.length!==
+0){b=0;for(c=a.aoData.length;b<c;b++){f=a.aoData[b];K(a,"aoRowCreatedCallback",null,[f.nTr,f._aData,b])}}}function V(a,b){return b._DT_RowIndex!==p?b._DT_RowIndex:null}function va(a,b,c){b=W(a,b);var d=0;for(a=a.aoColumns.length;d<a;d++)if(b[d]===c)return d;return-1}function na(a,b,c,d){for(var e=[],f=0,g=d.length;f<g;f++)e.push(F(a,b,d[f],c));return e}function F(a,b,c,d){var e=a.aoColumns[c];if((c=e.fnGetData(a.aoData[b]._aData,d))===p){if(a.iDrawError!=a.iDraw&&e.sDefaultContent===null){O(a,0,"Requested unknown parameter "+
+(typeof e.mData=="function"?"{mData function}":"'"+e.mData+"'")+" from the data source for row "+b);a.iDrawError=a.iDraw}return e.sDefaultContent}if(c===null&&e.sDefaultContent!==null)c=e.sDefaultContent;else if(typeof c==="function")return c();if(d=="display"&&c===null)return"";return c}function S(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d)}function ca(a){if(a===null)return function(){return null};else if(typeof a==="function")return function(c,d,e){return a(c,d,e)};else if(typeof a===
+"string"&&(a.indexOf(".")!==-1||a.indexOf("[")!==-1)){var b=function(c,d,e){var f=e.split("."),g;if(e!==""){var j=0;for(g=f.length;j<g;j++){if(e=f[j].match(ga)){f[j]=f[j].replace(ga,"");if(f[j]!=="")c=c[f[j]];g=[];f.splice(0,j+1);f=f.join(".");j=0;for(var k=c.length;j<k;j++)g.push(b(c[j],d,f));c=e[0].substring(1,e[0].length-1);c=c===""?g:g.join(c);break}if(c===null||c[f[j]]===p)return p;c=c[f[j]]}}return c};return function(c,d){return b(c,d,a)}}else return function(c){return c[a]}}function Ja(a){if(a===
+null)return function(){};else if(typeof a==="function")return function(c,d){a(c,"set",d)};else if(typeof a==="string"&&(a.indexOf(".")!==-1||a.indexOf("[")!==-1)){var b=function(c,d,e){e=e.split(".");var f,g,j=0;for(g=e.length-1;j<g;j++){if(f=e[j].match(ga)){e[j]=e[j].replace(ga,"");c[e[j]]=[];f=e.slice();f.splice(0,j+1);g=f.join(".");for(var k=0,m=d.length;k<m;k++){f={};b(f,d[k],g);c[e[j]].push(f)}return}if(c[e[j]]===null||c[e[j]]===p)c[e[j]]={};c=c[e[j]]}c[e[e.length-1].replace(ga,"")]=d};return function(c,
+d){return b(c,d,a)}}else return function(c,d){c[a]=d}}function oa(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function wa(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);I(a)}function xa(a,b){for(var c=-1,d=0,e=a.length;d<e;d++)if(a[d]==b)c=d;else a[d]>b&&a[d]--;c!=-1&&a.splice(c,1)}function da(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,
+aData:a.aoData[b]._aData,mDataProp:d.mData},F(a,b,c,"display"))}function ua(a,b){var c=a.aoData[b],d;if(c.nTr===null){c.nTr=s.createElement("tr");c.nTr._DT_RowIndex=b;if(c._aData.DT_RowId)c.nTr.id=c._aData.DT_RowId;if(c._aData.DT_RowClass)c.nTr.className=c._aData.DT_RowClass;for(var e=0,f=a.aoColumns.length;e<f;e++){var g=a.aoColumns[e];d=s.createElement(g.sCellType);d.innerHTML=typeof g.fnRender==="function"&&(!g.bUseRendered||g.mData===null)?da(a,b,e):F(a,b,e,"display");if(g.sClass!==null)d.className=
+g.sClass;if(g.bVisible){c.nTr.appendChild(d);c._anHidden[e]=null}else c._anHidden[e]=d;g.fnCreatedCell&&g.fnCreatedCell.call(a.oInstance,d,F(a,b,e,"display"),c._aData,b,e)}K(a,"aoRowCreatedCallback",null,[c.nTr,c._aData,b])}}function Ka(a){var b,c,d;if(i("th, td",a.nTHead).length!==0){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;c.setAttribute("role","columnheader");if(a.aoColumns[b].bSortable){c.setAttribute("tabindex",a.iTabIndex);c.setAttribute("aria-controls",a.sTableId)}a.aoColumns[b].sClass!==
+null&&i(c).addClass(a.aoColumns[b].sClass);if(a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}}else{var e=s.createElement("tr");b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;c.innerHTML=a.aoColumns[b].sTitle;c.setAttribute("tabindex","0");a.aoColumns[b].sClass!==null&&i(c).addClass(a.aoColumns[b].sClass);e.appendChild(c)}i(a.nTHead).html("")[0].appendChild(e);ha(a.aoHeader,a.nTHead)}i(a.nTHead).children("tr").attr("role","row");if(a.bJUI){b=0;for(d=a.aoColumns.length;b<
+d;b++){c=a.aoColumns[b].nTh;e=s.createElement("div");e.className=a.oClasses.sSortJUIWrapper;i(c).contents().appendTo(e);var f=s.createElement("span");f.className=a.oClasses.sSortIcon;e.appendChild(f);c.appendChild(e)}}if(a.oFeatures.bSort)for(b=0;b<a.aoColumns.length;b++)a.aoColumns[b].bSortable!==false?ya(a,a.aoColumns[b].nTh,b):i(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);a.oClasses.sFooterTH!==""&&i(a.nTFoot).children("tr").children("th").addClass(a.oClasses.sFooterTH);if(a.nTFoot!==
+null){c=Z(a,null,a.aoFooter);b=0;for(d=a.aoColumns.length;b<d;b++)if(c[b]){a.aoColumns[b].nTf=c[b];a.aoColumns[b].sClass&&i(c[b]).addClass(a.aoColumns[b].sClass)}}}function ia(a,b,c){var d,e,f,g=[],j=[],k=a.aoColumns.length,m;if(c===p)c=false;d=0;for(e=b.length;d<e;d++){g[d]=b[d].slice();g[d].nTr=b[d].nTr;for(f=k-1;f>=0;f--)!a.aoColumns[f].bVisible&&!c&&g[d].splice(f,1);j.push([])}d=0;for(e=g.length;d<e;d++){if(a=g[d].nTr)for(;f=a.firstChild;)a.removeChild(f);f=0;for(b=g[d].length;f<b;f++){m=k=1;
+if(j[d][f]===p){a.appendChild(g[d][f].cell);for(j[d][f]=1;g[d+k]!==p&&g[d][f].cell==g[d+k][f].cell;){j[d+k][f]=1;k++}for(;g[d][f+m]!==p&&g[d][f].cell==g[d][f+m].cell;){for(c=0;c<k;c++)j[d+c][f+m]=1;m++}g[d][f].cell.rowSpan=k;g[d][f].cell.colSpan=m}}}}function H(a){var b=K(a,"aoPreDrawCallback","preDraw",[a]);if(i.inArray(false,b)!==-1)P(a,false);else{var c,d;b=[];var e=0,f=a.asStripeClasses.length;c=a.aoOpenRows.length;a.bDrawing=true;if(a.iInitDisplayStart!==p&&a.iInitDisplayStart!=-1){a._iDisplayStart=
+a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;I(a)}if(a.bDeferLoading){a.bDeferLoading=false;a.iDraw++}else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!La(a))return}else a.iDraw++;if(a.aiDisplay.length!==0){var g=a._iDisplayStart;d=a._iDisplayEnd;if(a.oFeatures.bServerSide){g=0;d=a.aoData.length}for(g=g;g<d;g++){var j=a.aoData[a.aiDisplay[g]];j.nTr===null&&ua(a,a.aiDisplay[g]);var k=j.nTr;if(f!==0){var m=a.asStripeClasses[e%
+f];if(j._sRowStripe!=m){i(k).removeClass(j._sRowStripe).addClass(m);j._sRowStripe=m}}K(a,"aoRowCallback",null,[k,a.aoData[a.aiDisplay[g]]._aData,e,g]);b.push(k);e++;if(c!==0)for(j=0;j<c;j++)if(k==a.aoOpenRows[j].nParent){b.push(a.aoOpenRows[j].nTr);break}}}else{b[0]=s.createElement("tr");if(a.asStripeClasses[0])b[0].className=a.asStripeClasses[0];c=a.oLanguage;f=c.sZeroRecords;if(a.iDraw==1&&a.sAjaxSource!==null&&!a.oFeatures.bServerSide)f=c.sLoadingRecords;else if(c.sEmptyTable&&a.fnRecordsTotal()===
+0)f=c.sEmptyTable;c=s.createElement("td");c.setAttribute("valign","top");c.colSpan=D(a);c.className=a.oClasses.sRowEmpty;c.innerHTML=za(a,f);b[e].appendChild(c)}K(a,"aoHeaderCallback","header",[i(a.nTHead).children("tr")[0],oa(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);K(a,"aoFooterCallback","footer",[i(a.nTFoot).children("tr")[0],oa(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay]);e=s.createDocumentFragment();c=s.createDocumentFragment();if(a.nTBody){f=a.nTBody.parentNode;c.appendChild(a.nTBody);
+if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered)for(;c=a.nTBody.firstChild;)a.nTBody.removeChild(c);c=0;for(d=b.length;c<d;c++)e.appendChild(b[c]);a.nTBody.appendChild(e);f!==null&&f.appendChild(a.nTBody)}K(a,"aoDrawCallback","draw",[a]);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(a.oFeatures.bServerSide){P(a,false);a._bInitComplete||pa(a)}}}function qa(a){if(a.oFeatures.bSort)$(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)X(a,a.oPreviousSearch);else{I(a);H(a)}}function Ma(a){var b=
+i("<div></div>")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=i('<div id="'+a.sTableId+'_wrapper" class="'+a.oClasses.sWrapper+'" role="grid"></div>')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),e,f,g,j,k,m,u,x=0;x<d.length;x++){f=0;g=d[x];if(g=="<"){j=i("<div></div>")[0];k=d[x+1];if(k=="'"||k=='"'){m="";for(u=2;d[x+u]!=k;){m+=d[x+u];u++}if(m=="H")m=a.oClasses.sJUIHeader;else if(m=="F")m=a.oClasses.sJUIFooter;if(m.indexOf(".")!=-1){k=
+m.split(".");j.id=k[0].substr(1,k[0].length-1);j.className=k[1]}else if(m.charAt(0)=="#")j.id=m.substr(1,m.length-1);else j.className=m;x+=u}c.appendChild(j);c=j}else if(g==">")c=c.parentNode;else if(g=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){e=Na(a);f=1}else if(g=="f"&&a.oFeatures.bFilter){e=Oa(a);f=1}else if(g=="r"&&a.oFeatures.bProcessing){e=Pa(a);f=1}else if(g=="t"){e=Qa(a);f=1}else if(g=="i"&&a.oFeatures.bInfo){e=Ra(a);f=1}else if(g=="p"&&a.oFeatures.bPaginate){e=Sa(a);f=1}else if(l.ext.aoFeatures.length!==
+0){j=l.ext.aoFeatures;u=0;for(k=j.length;u<k;u++)if(g==j[u].cFeature){if(e=j[u].fnInit(a))f=1;break}}if(f==1&&e!==null){if(typeof a.aanFeatures[g]!=="object")a.aanFeatures[g]=[];a.aanFeatures[g].push(e);c.appendChild(e)}}b.parentNode.replaceChild(a.nTableWrapper,b)}function ha(a,b){b=i(b).children("tr");var c,d,e,f,g,j,k,m,u,x,y=function(B,T,M){for(B=B[T];B[M];)M++;return M};a.splice(0,a.length);e=0;for(j=b.length;e<j;e++)a.push([]);e=0;for(j=b.length;e<j;e++){c=b[e];for(d=c.firstChild;d;){if(d.nodeName.toUpperCase()==
+"TD"||d.nodeName.toUpperCase()=="TH"){m=d.getAttribute("colspan")*1;u=d.getAttribute("rowspan")*1;m=!m||m===0||m===1?1:m;u=!u||u===0||u===1?1:u;k=y(a,e,0);x=m===1?true:false;for(g=0;g<m;g++)for(f=0;f<u;f++){a[e+f][k+g]={cell:d,unique:x};a[e+f].nTr=c}}d=d.nextSibling}}}function Z(a,b,c){var d=[];if(!c){c=a.aoHeader;if(b){c=[];ha(c,b)}}b=0;for(var e=c.length;b<e;b++)for(var f=0,g=c[b].length;f<g;f++)if(c[b][f].unique&&(!d[f]||!a.bSortCellsTop))d[f]=c[b][f].cell;return d}function La(a){if(a.bAjaxDataGet){a.iDraw++;
+P(a,true);var b=Ta(a);Aa(a,b);a.fnServerData.call(a.oInstance,a.sAjaxSource,b,function(c){Ua(a,c)},a);return false}else return true}function Ta(a){var b=a.aoColumns.length,c=[],d,e,f,g;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:Y(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength:-1});for(f=0;f<b;f++){d=a.aoColumns[f].mData;c.push({name:"mDataProp_"+
+f,value:typeof d==="function"?"function":d})}if(a.oFeatures.bFilter!==false){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});for(f=0;f<b;f++){c.push({name:"sSearch_"+f,value:a.aoPreSearchCols[f].sSearch});c.push({name:"bRegex_"+f,value:a.aoPreSearchCols[f].bRegex});c.push({name:"bSearchable_"+f,value:a.aoColumns[f].bSearchable})}}if(a.oFeatures.bSort!==false){var j=0;d=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();
+for(f=0;f<d.length;f++){e=a.aoColumns[d[f][0]].aDataSort;for(g=0;g<e.length;g++){c.push({name:"iSortCol_"+j,value:e[g]});c.push({name:"sSortDir_"+j,value:d[f][1]});j++}}c.push({name:"iSortingCols",value:j});for(f=0;f<b;f++)c.push({name:"bSortable_"+f,value:a.aoColumns[f].bSortable})}return c}function Aa(a,b){K(a,"aoServerParams","serverParams",[b])}function Ua(a,b){if(b.sEcho!==p)if(b.sEcho*1<a.iDraw)return;else a.iDraw=b.sEcho*1;if(!a.oScroll.bInfinite||a.oScroll.bInfinite&&(a.bSorted||a.bFiltered))wa(a);
+a._iRecordsTotal=parseInt(b.iTotalRecords,10);a._iRecordsDisplay=parseInt(b.iTotalDisplayRecords,10);var c=Y(a);c=b.sColumns!==p&&c!==""&&b.sColumns!=c;var d;if(c)d=E(a,b.sColumns);b=ca(a.sAjaxDataProp)(b);for(var e=0,f=b.length;e<f;e++)if(c){for(var g=[],j=0,k=a.aoColumns.length;j<k;j++)g.push(b[e][d[j]]);R(a,g)}else R(a,b[e]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=false;H(a);a.bAjaxDataGet=true;P(a,false)}function Oa(a){var b=a.oPreviousSearch,c=a.oLanguage.sSearch;c=c.indexOf("_INPUT_")!==
+-1?c.replace("_INPUT_",'<input type="text" />'):c===""?'<input type="text" />':c+' <input type="text" />';var d=s.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="<label>"+c+"</label>";if(!a.aanFeatures.f)d.id=a.sTableId+"_filter";c=i('input[type="text"]',d);d._DT_Input=c[0];c.val(b.sSearch.replace('"',"&quot;"));c.bind("keyup.DT",function(){for(var e=a.aanFeatures.f,f=this.value===""?"":this.value,g=0,j=e.length;g<j;g++)e[g]!=i(this).parents("div.dataTables_filter")[0]&&i(e[g]._DT_Input).val(f);
+f!=b.sSearch&&X(a,{sSearch:f,bRegex:b.bRegex,bSmart:b.bSmart,bCaseInsensitive:b.bCaseInsensitive})});c.attr("aria-controls",a.sTableId).bind("keypress.DT",function(e){if(e.keyCode==13)return false});return d}function X(a,b,c){var d=a.oPreviousSearch,e=a.aoPreSearchCols,f=function(g){d.sSearch=g.sSearch;d.bRegex=g.bRegex;d.bSmart=g.bSmart;d.bCaseInsensitive=g.bCaseInsensitive};if(a.oFeatures.bServerSide)f(b);else{Va(a,b.sSearch,c,b.bRegex,b.bSmart,b.bCaseInsensitive);f(b);for(b=0;b<a.aoPreSearchCols.length;b++)Wa(a,
+e[b].sSearch,b,e[b].bRegex,e[b].bSmart,e[b].bCaseInsensitive);Xa(a)}a.bFiltered=true;i(a.oInstance).trigger("filter",a);a._iDisplayStart=0;I(a);H(a);Ba(a,0)}function Xa(a){for(var b=l.ext.afnFiltering,c=A(a,"bSearchable"),d=0,e=b.length;d<e;d++)for(var f=0,g=0,j=a.aiDisplay.length;g<j;g++){var k=a.aiDisplay[g-f];if(!b[d](a,na(a,k,"filter",c),k)){a.aiDisplay.splice(g-f,1);f++}}}function Wa(a,b,c,d,e,f){if(b!==""){var g=0;b=Ca(b,d,e,f);for(d=a.aiDisplay.length-1;d>=0;d--){e=Ya(F(a,a.aiDisplay[d],c,
+"filter"),a.aoColumns[c].sType);if(!b.test(e)){a.aiDisplay.splice(d,1);g++}}}}function Va(a,b,c,d,e,f){d=Ca(b,d,e,f);e=a.oPreviousSearch;c||(c=0);if(l.ext.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||e.sSearch.length>b.length||c==1||b.indexOf(e.sSearch)!==0){a.aiDisplay.splice(0,a.aiDisplay.length);Ba(a,1);for(b=0;b<a.aiDisplayMaster.length;b++)d.test(a.asDataSearch[b])&&
+a.aiDisplay.push(a.aiDisplayMaster[b])}else for(b=c=0;b<a.asDataSearch.length;b++)if(!d.test(a.asDataSearch[b])){a.aiDisplay.splice(b-c,1);c++}}function Ba(a,b){if(!a.oFeatures.bServerSide){a.asDataSearch=[];var c=A(a,"bSearchable");b=b===1?a.aiDisplayMaster:a.aiDisplay;for(var d=0,e=b.length;d<e;d++)a.asDataSearch[d]=Da(a,na(a,b[d],"filter",c))}}function Da(a,b){a=b.join("  ");if(a.indexOf("&")!==-1)a=i("<div>").html(a).text();return a.replace(/[\n\r]/g," ")}function Ca(a,b,c,d){if(c){a=b?a.split(" "):
+Ea(a).split(" ");a="^(?=.*?"+a.join(")(?=.*?")+").*$";return new RegExp(a,d?"i":"")}else{a=b?a:Ea(a);return new RegExp(a,d?"i":"")}}function Ya(a,b){if(typeof l.ext.ofnSearch[b]==="function")return l.ext.ofnSearch[b](a);else if(a===null)return"";else if(b=="html")return a.replace(/[\r\n]/g," ").replace(/<.*?>/g,"");else if(typeof a==="string")return a.replace(/[\r\n]/g," ");return a}function Ea(a){return a.replace(new RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^|\\-)","g"),
+"\\$1")}function Ra(a){var b=s.createElement("div");b.className=a.oClasses.sInfo;if(!a.aanFeatures.i){a.aoDrawCallback.push({fn:Za,sName:"information"});b.id=a.sTableId+"_info"}a.nTable.setAttribute("aria-describedby",a.sTableId+"_info");return b}function Za(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a.oLanguage,c=a._iDisplayStart+1,d=a.fnDisplayEnd(),e=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),g;g=f===0?b.sInfoEmpty:b.sInfo;if(f!=e)g+=" "+b.sInfoFiltered;g+=b.sInfoPostFix;g=za(a,
+g);if(b.fnInfoCallback!==null)g=b.fnInfoCallback.call(a.oInstance,a,c,d,e,f,g);a=a.aanFeatures.i;b=0;for(c=a.length;b<c;b++)i(a[b]).html(g)}}function za(a,b){var c=a.fnFormatNumber(a._iDisplayStart+1),d=a.fnDisplayEnd();d=a.fnFormatNumber(d);var e=a.fnRecordsDisplay();e=a.fnFormatNumber(e);var f=a.fnRecordsTotal();f=a.fnFormatNumber(f);if(a.oScroll.bInfinite)c=a.fnFormatNumber(1);return b.replace(/_START_/g,c).replace(/_END_/g,d).replace(/_TOTAL_/g,e).replace(/_MAX_/g,f)}function ra(a){var b,c,d=
+a.iInitDisplayStart;if(a.bInitialised===false)setTimeout(function(){ra(a)},200);else{Ma(a);Ka(a);ia(a,a.aoHeader);a.nTFoot&&ia(a,a.aoFooter);P(a,true);a.oFeatures.bAutoWidth&&ta(a);b=0;for(c=a.aoColumns.length;b<c;b++)if(a.aoColumns[b].sWidth!==null)a.aoColumns[b].nTh.style.width=t(a.aoColumns[b].sWidth);if(a.oFeatures.bSort)$(a);else if(a.oFeatures.bFilter)X(a,a.oPreviousSearch);else{a.aiDisplay=a.aiDisplayMaster.slice();I(a);H(a)}if(a.sAjaxSource!==null&&!a.oFeatures.bServerSide){c=[];Aa(a,c);a.fnServerData.call(a.oInstance,
+a.sAjaxSource,c,function(e){var f=a.sAjaxDataProp!==""?ca(a.sAjaxDataProp)(e):e;for(b=0;b<f.length;b++)R(a,f[b]);a.iInitDisplayStart=d;if(a.oFeatures.bSort)$(a);else{a.aiDisplay=a.aiDisplayMaster.slice();I(a);H(a)}P(a,false);pa(a,e)},a)}else if(!a.oFeatures.bServerSide){P(a,false);pa(a)}}}function pa(a,b){a._bInitComplete=true;K(a,"aoInitComplete","init",[a,b])}function Fa(a){var b=l.defaults.oLanguage;!a.sEmptyTable&&a.sZeroRecords&&b.sEmptyTable==="No data available in table"&&r(a,a,"sZeroRecords",
+"sEmptyTable");!a.sLoadingRecords&&a.sZeroRecords&&b.sLoadingRecords==="Loading..."&&r(a,a,"sZeroRecords","sLoadingRecords")}function Na(a){if(a.oScroll.bInfinite)return null;var b='<select size="1" '+('name="'+a.sTableId+'_length"')+">",c,d,e=a.aLengthMenu;if(e.length==2&&typeof e[0]==="object"&&typeof e[1]==="object"){c=0;for(d=e[0].length;c<d;c++)b+='<option value="'+e[0][c]+'">'+e[1][c]+"</option>"}else{c=0;for(d=e.length;c<d;c++)b+='<option value="'+e[c]+'">'+e[c]+"</option>"}b+="</select>";
+e=s.createElement("div");if(!a.aanFeatures.l)e.id=a.sTableId+"_length";e.className=a.oClasses.sLength;e.innerHTML="<label>"+a.oLanguage.sLengthMenu.replace("_MENU_",b)+"</label>";i('select option[value="'+a._iDisplayLength+'"]',e).attr("selected",true);i("select",e).bind("change.DT",function(){var f=i(this).val(),g=a.aanFeatures.l;c=0;for(d=g.length;c<d;c++)g[c]!=this.parentNode&&i("select",g[c]).val(f);a._iDisplayLength=parseInt(f,10);I(a);if(a.fnDisplayEnd()==a.fnRecordsDisplay()){a._iDisplayStart=
+a.fnDisplayEnd()-a._iDisplayLength;if(a._iDisplayStart<0)a._iDisplayStart=0}if(a._iDisplayLength==-1)a._iDisplayStart=0;H(a)});i("select",e).attr("aria-controls",a.sTableId);return e}function I(a){a._iDisplayEnd=a.oFeatures.bPaginate===false?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Sa(a){if(a.oScroll.bInfinite)return null;var b=s.createElement("div");b.className=a.oClasses.sPaging+
+a.sPaginationType;l.ext.oPagination[a.sPaginationType].fnInit(a,b,function(c){I(c);H(c)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(c){l.ext.oPagination[c.sPaginationType].fnUpdate(c,function(d){I(d);H(d)})},sName:"pagination"});return b}function Ga(a,b){var c=a._iDisplayStart;if(typeof b==="number"){a._iDisplayStart=b*a._iDisplayLength;if(a._iDisplayStart>a.fnRecordsDisplay())a._iDisplayStart=0}else if(b=="first")a._iDisplayStart=0;else if(b=="previous"){a._iDisplayStart=a._iDisplayLength>=
+0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength<a.fnRecordsDisplay())a._iDisplayStart+=a._iDisplayLength}else a._iDisplayStart=0;else if(b=="last")if(a._iDisplayLength>=0){b=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else O(a,0,"Unknown paging action: "+b);i(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}
+function Pa(a){var b=s.createElement("div");if(!a.aanFeatures.r)b.id=a.sTableId+"_processing";b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function P(a,b){if(a.oFeatures.bProcessing)for(var c=a.aanFeatures.r,d=0,e=c.length;d<e;d++)c[d].style.visibility=b?"visible":"hidden";i(a.oInstance).trigger("processing",[a,b])}function Qa(a){if(a.oScroll.sX===""&&a.oScroll.sY==="")return a.nTable;var b=s.createElement("div"),c=s.createElement("div"),
+d=s.createElement("div"),e=s.createElement("div"),f=s.createElement("div"),g=s.createElement("div"),j=a.nTable.cloneNode(false),k=a.nTable.cloneNode(false),m=a.nTable.getElementsByTagName("thead")[0],u=a.nTable.getElementsByTagName("tfoot").length===0?null:a.nTable.getElementsByTagName("tfoot")[0],x=a.oClasses;c.appendChild(d);f.appendChild(g);e.appendChild(a.nTable);b.appendChild(c);b.appendChild(e);d.appendChild(j);j.appendChild(m);if(u!==null){b.appendChild(f);g.appendChild(k);k.appendChild(u)}b.className=
+x.sScrollWrapper;c.className=x.sScrollHead;d.className=x.sScrollHeadInner;e.className=x.sScrollBody;f.className=x.sScrollFoot;g.className=x.sScrollFootInner;if(a.oScroll.bAutoCss){c.style.overflow="hidden";c.style.position="relative";f.style.overflow="hidden";e.style.overflow="auto"}c.style.border="0";c.style.width="100%";f.style.border="0";d.style.width=a.oScroll.sXInner!==""?a.oScroll.sXInner:"100%";j.removeAttribute("id");j.style.marginLeft="0";a.nTable.style.marginLeft="0";if(u!==null){k.removeAttribute("id");
+k.style.marginLeft="0"}d=i(a.nTable).children("caption");if(d.length>0){d=d[0];if(d._captionSide==="top")j.appendChild(d);else d._captionSide==="bottom"&&u&&k.appendChild(d)}if(a.oScroll.sX!==""){c.style.width=t(a.oScroll.sX);e.style.width=t(a.oScroll.sX);if(u!==null)f.style.width=t(a.oScroll.sX);i(e).scroll(function(){c.scrollLeft=this.scrollLeft;if(u!==null)f.scrollLeft=this.scrollLeft})}if(a.oScroll.sY!=="")e.style.height=t(a.oScroll.sY);a.aoDrawCallback.push({fn:$a,sName:"scrolling"});a.oScroll.bInfinite&&
+i(e).scroll(function(){if(!a.bDrawing&&i(this).scrollTop()!==0)if(i(this).scrollTop()+i(this).height()>i(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()<a.fnRecordsDisplay()){Ga(a,"next");I(a);H(a)}});a.nScrollHead=c;a.nScrollFoot=f;return b}function $a(a){var b=a.nScrollHead.getElementsByTagName("div")[0],c=b.getElementsByTagName("table")[0],d=a.nTable.parentNode,e,f,g,j,k,m,u,x,y=[],B=[],T=a.nTFoot!==null?a.nScrollFoot.getElementsByTagName("div")[0]:null,M=a.nTFoot!==null?T.getElementsByTagName("table")[0]:
+null,L=a.oBrowser.bScrollOversize,ja=function(z){u=z.style;u.paddingTop="0";u.paddingBottom="0";u.borderTopWidth="0";u.borderBottomWidth="0";u.height=0};i(a.nTable).children("thead, tfoot").remove();e=i(a.nTHead).clone()[0];a.nTable.insertBefore(e,a.nTable.childNodes[0]);g=a.nTHead.getElementsByTagName("tr");j=e.getElementsByTagName("tr");if(a.nTFoot!==null){k=i(a.nTFoot).clone()[0];a.nTable.insertBefore(k,a.nTable.childNodes[1]);m=a.nTFoot.getElementsByTagName("tr");k=k.getElementsByTagName("tr")}if(a.oScroll.sX===
+""){d.style.width="100%";b.parentNode.style.width="100%"}var U=Z(a,e);e=0;for(f=U.length;e<f;e++){x=v(a,e);U[e].style.width=a.aoColumns[x].sWidth}a.nTFoot!==null&&N(function(z){z.style.width=""},k);if(a.oScroll.bCollapse&&a.oScroll.sY!=="")d.style.height=d.offsetHeight+a.nTHead.offsetHeight+"px";e=i(a.nTable).outerWidth();if(a.oScroll.sX===""){a.nTable.style.width="100%";if(L&&(i("tbody",d).height()>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=t(i(a.nTable).outerWidth()-
+a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!=="")a.nTable.style.width=t(a.oScroll.sXInner);else if(e==i(d).width()&&i(d).height()<i(a.nTable).height()){a.nTable.style.width=t(e-a.oScroll.iBarWidth);if(i(a.nTable).outerWidth()>e-a.oScroll.iBarWidth)a.nTable.style.width=t(e)}else a.nTable.style.width=t(e);e=i(a.nTable).outerWidth();N(ja,j);N(function(z){y.push(t(i(z).width()))},j);N(function(z,Q){z.style.width=y[Q]},g);i(j).height(0);if(a.nTFoot!==null){N(ja,k);N(function(z){B.push(t(i(z).width()))},
+k);N(function(z,Q){z.style.width=B[Q]},m);i(k).height(0)}N(function(z,Q){z.innerHTML="";z.style.width=y[Q]},j);a.nTFoot!==null&&N(function(z,Q){z.innerHTML="";z.style.width=B[Q]},k);if(i(a.nTable).outerWidth()<e){g=d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"?e+a.oScroll.iBarWidth:e;if(L&&(d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=t(g-a.oScroll.iBarWidth);d.style.width=t(g);a.nScrollHead.style.width=t(g);if(a.nTFoot!==null)a.nScrollFoot.style.width=
+t(g);if(a.oScroll.sX==="")O(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width.");else a.oScroll.sXInner!==""&&O(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else{d.style.width=t("100%");a.nScrollHead.style.width=t("100%");if(a.nTFoot!==null)a.nScrollFoot.style.width=t("100%")}if(a.oScroll.sY===
+"")if(L)d.style.height=t(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=t(a.oScroll.sY);L=a.oScroll.sX!==""&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight<d.offsetHeight)d.style.height=t(a.nTable.offsetHeight+L)}L=i(a.nTable).outerWidth();c.style.width=t(L);b.style.width=t(L);c=i(a.nTable).height()>d.clientHeight||i(d).css("overflow-y")=="scroll";b.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px";if(a.nTFoot!==
+null){M.style.width=t(L);T.style.width=t(L);T.style.paddingRight=c?a.oScroll.iBarWidth+"px":"0px"}i(d).scroll();if(a.bSorted||a.bFiltered)d.scrollTop=0}function N(a,b,c){for(var d=0,e=0,f=b.length,g,j;e<f;){g=b[e].firstChild;for(j=c?c[e].firstChild:null;g;){if(g.nodeType===1){c?a(g,j,d):a(g,d);d++}g=g.nextSibling;j=c?j.nextSibling:null}e++}}function ab(a,b){if(!a||a===null||a==="")return 0;if(!b)b=s.body;var c=s.createElement("div");c.style.width=t(a);b.appendChild(c);a=c.offsetWidth;b.removeChild(c);
+return a}function ta(a){var b=0,c,d=0,e=a.aoColumns.length,f,g,j=i("th",a.nTHead),k=a.nTable.getAttribute("width");g=a.nTable.parentNode;for(f=0;f<e;f++)if(a.aoColumns[f].bVisible){d++;if(a.aoColumns[f].sWidth!==null){c=ab(a.aoColumns[f].sWidthOrig,g);if(c!==null)a.aoColumns[f].sWidth=t(c);b++}}if(e==j.length&&b===0&&d==e&&a.oScroll.sX===""&&a.oScroll.sY==="")for(f=0;f<a.aoColumns.length;f++){c=i(j[f]).width();if(c!==null)a.aoColumns[f].sWidth=t(c)}else{b=a.nTable.cloneNode(false);f=a.nTHead.cloneNode(true);
+d=s.createElement("tbody");c=s.createElement("tr");b.removeAttribute("id");b.appendChild(f);if(a.nTFoot!==null){b.appendChild(a.nTFoot.cloneNode(true));N(function(u){u.style.width=""},b.getElementsByTagName("tr"))}b.appendChild(d);d.appendChild(c);d=i("thead th",b);if(d.length===0)d=i("tbody tr:eq(0)>td",b);j=Z(a,f);for(f=d=0;f<e;f++){var m=a.aoColumns[f];if(m.bVisible&&m.sWidthOrig!==null&&m.sWidthOrig!=="")j[f-d].style.width=t(m.sWidthOrig);else if(m.bVisible)j[f-d].style.width="";else d++}for(f=
+0;f<e;f++)if(a.aoColumns[f].bVisible){d=bb(a,f);if(d!==null){d=d.cloneNode(true);if(a.aoColumns[f].sContentPadding!=="")d.innerHTML+=a.aoColumns[f].sContentPadding;c.appendChild(d)}}g.appendChild(b);if(a.oScroll.sX!==""&&a.oScroll.sXInner!=="")b.style.width=t(a.oScroll.sXInner);else if(a.oScroll.sX!==""){b.style.width="";if(i(b).width()<g.offsetWidth)b.style.width=t(g.offsetWidth)}else if(a.oScroll.sY!=="")b.style.width=t(g.offsetWidth);else if(k)b.style.width=t(k);b.style.visibility="hidden";cb(a,
+b);e=i("tbody tr:eq(0)",b).children();if(e.length===0)e=Z(a,i("thead",b)[0]);if(a.oScroll.sX!==""){for(f=d=g=0;f<a.aoColumns.length;f++)if(a.aoColumns[f].bVisible){g+=a.aoColumns[f].sWidthOrig===null?i(e[d]).outerWidth():parseInt(a.aoColumns[f].sWidth.replace("px",""),10)+(i(e[d]).outerWidth()-i(e[d]).width());d++}b.style.width=t(g);a.nTable.style.width=t(g)}for(f=d=0;f<a.aoColumns.length;f++)if(a.aoColumns[f].bVisible){g=i(e[d]).width();if(g!==null&&g>0)a.aoColumns[f].sWidth=t(g);d++}e=i(b).css("width");
+a.nTable.style.width=e.indexOf("%")!==-1?e:t(i(b).outerWidth());b.parentNode.removeChild(b)}if(k)a.nTable.style.width=t(k)}function cb(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){i(b).width();b.style.width=t(i(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!=="")b.style.width=t(i(b).outerWidth())}function bb(a,b){var c=db(a,b);if(c<0)return null;if(a.aoData[c].nTr===null){var d=s.createElement("td");d.innerHTML=F(a,c,b,"");return d}return W(a,c)[b]}function db(a,b){for(var c=-1,d=-1,e=
+0;e<a.aoData.length;e++){var f=F(a,e,b,"display")+"";f=f.replace(/<.*?>/g,"");if(f.length>c){c=f.length;d=e}}return d}function t(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b=a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+"px"}function eb(){var a=s.createElement("p"),b=a.style;b.width="100%";b.height="200px";b.padding="0px";var c=s.createElement("div");b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";
+b.height="150px";b.padding="0px";b.overflow="hidden";c.appendChild(a);s.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";a=a.offsetWidth;if(b==a)a=c.clientWidth;s.body.removeChild(c);return b-a}function $(a,b){var c,d,e,f,g,j,k=[],m=[],u=l.ext.oSort,x=a.aoData,y=a.aoColumns,B=a.oLanguage.oAria;if(!a.oFeatures.bServerSide&&(a.aaSorting.length!==0||a.aaSortingFixed!==null)){k=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c<k.length;c++){d=k[c][0];
+e=w(a,d);f=a.aoColumns[d].sSortDataType;if(l.ext.afnSortData[f]){g=l.ext.afnSortData[f].call(a.oInstance,a,d,e);if(g.length===x.length){e=0;for(f=x.length;e<f;e++)S(a,e,d,g[e])}else O(a,0,"Returned data sort array (col "+d+") is the wrong length")}}c=0;for(d=a.aiDisplayMaster.length;c<d;c++)m[a.aiDisplayMaster[c]]=c;var T=k.length,M;c=0;for(d=x.length;c<d;c++)for(e=0;e<T;e++){M=y[k[e][0]].aDataSort;g=0;for(j=M.length;g<j;g++){f=y[M[g]].sType;f=u[(f?f:"string")+"-pre"];x[c]._aSortData[M[g]]=f?f(F(a,
+c,M[g],"sort")):F(a,c,M[g],"sort")}}a.aiDisplayMaster.sort(function(L,ja){var U,z,Q,aa,ka;for(U=0;U<T;U++){ka=y[k[U][0]].aDataSort;z=0;for(Q=ka.length;z<Q;z++){aa=y[ka[z]].sType;aa=u[(aa?aa:"string")+"-"+k[U][1]](x[L]._aSortData[ka[z]],x[ja]._aSortData[ka[z]]);if(aa!==0)return aa}}return u["numeric-asc"](m[L],m[ja])})}if((b===p||b)&&!a.oFeatures.bDeferRender)ba(a);c=0;for(d=a.aoColumns.length;c<d;c++){e=y[c].sTitle.replace(/<.*?>/g,"");b=y[c].nTh;b.removeAttribute("aria-sort");b.removeAttribute("aria-label");
+if(y[c].bSortable)if(k.length>0&&k[0][0]==c){b.setAttribute("aria-sort",k[0][1]=="asc"?"ascending":"descending");b.setAttribute("aria-label",e+((y[c].asSorting[k[0][2]+1]?y[c].asSorting[k[0][2]+1]:y[c].asSorting[0])=="asc"?B.sSortAscending:B.sSortDescending))}else b.setAttribute("aria-label",e+(y[c].asSorting[0]=="asc"?B.sSortAscending:B.sSortDescending));else b.setAttribute("aria-label",e)}a.bSorted=true;i(a.oInstance).trigger("sort",a);if(a.oFeatures.bFilter)X(a,a.oPreviousSearch,1);else{a.aiDisplay=
+a.aiDisplayMaster.slice();a._iDisplayStart=0;I(a);H(a)}}function ya(a,b,c,d){fb(b,{},function(e){if(a.aoColumns[c].bSortable!==false){var f=function(){var g,j;if(e.shiftKey){for(var k=false,m=0;m<a.aaSorting.length;m++)if(a.aaSorting[m][0]==c){k=true;g=a.aaSorting[m][0];j=a.aaSorting[m][2]+1;if(a.aoColumns[g].asSorting[j]){a.aaSorting[m][1]=a.aoColumns[g].asSorting[j];a.aaSorting[m][2]=j}else a.aaSorting.splice(m,1);break}k===false&&a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}else if(a.aaSorting.length==
+1&&a.aaSorting[0][0]==c){g=a.aaSorting[0][0];j=a.aaSorting[0][2]+1;a.aoColumns[g].asSorting[j]||(j=0);a.aaSorting[0][1]=a.aoColumns[g].asSorting[j];a.aaSorting[0][2]=j}else{a.aaSorting.splice(0,a.aaSorting.length);a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}$(a)};if(a.oFeatures.bProcessing){P(a,true);setTimeout(function(){f();a.oFeatures.bServerSide||P(a,false)},0)}else f();typeof d=="function"&&d(a)}})}function ba(a){var b,c,d,e,f,g=a.aoColumns.length,j=a.oClasses;for(b=0;b<g;b++)a.aoColumns[b].bSortable&&
+i(a.aoColumns[b].nTh).removeClass(j.sSortAsc+" "+j.sSortDesc+" "+a.aoColumns[b].sSortingClass);c=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable){f=a.aoColumns[b].sSortingClass;e=-1;for(d=0;d<c.length;d++)if(c[d][0]==b){f=c[d][1]=="asc"?j.sSortAsc:j.sSortDesc;e=d;break}i(a.aoColumns[b].nTh).addClass(f);if(a.bJUI){f=i("span."+j.sSortIcon,a.aoColumns[b].nTh);f.removeClass(j.sSortJUIAsc+" "+j.sSortJUIDesc+" "+
+j.sSortJUI+" "+j.sSortJUIAscAllowed+" "+j.sSortJUIDescAllowed);f.addClass(e==-1?a.aoColumns[b].sSortingClassJUI:c[e][1]=="asc"?j.sSortJUIAsc:j.sSortJUIDesc)}}else i(a.aoColumns[b].nTh).addClass(a.aoColumns[b].sSortingClass);f=j.sSortColumn;if(a.oFeatures.bSort&&a.oFeatures.bSortClasses){a=W(a);e=[];for(b=0;b<g;b++)e.push("");b=0;for(d=1;b<c.length;b++){j=parseInt(c[b][0],10);e[j]=f+d;d<3&&d++}f=new RegExp(f+"[123]");var k;b=0;for(c=a.length;b<c;b++){j=b%g;d=a[b].className;k=e[j];j=d.replace(f,k);
+if(j!=d)a[b].className=i.trim(j);else if(k.length>0&&d.indexOf(k)==-1)a[b].className=d+" "+k}}}function Ha(a){if(!(!a.oFeatures.bStateSave||a.bDestroying)){var b,c;b=a.oScroll.bInfinite;var d={iCreate:(new Date).getTime(),iStart:b?0:a._iDisplayStart,iEnd:b?a._iDisplayLength:a._iDisplayEnd,iLength:a._iDisplayLength,aaSorting:i.extend(true,[],a.aaSorting),oSearch:i.extend(true,{},a.oPreviousSearch),aoSearchCols:i.extend(true,[],a.aoPreSearchCols),abVisCols:[]};b=0;for(c=a.aoColumns.length;b<c;b++)d.abVisCols.push(a.aoColumns[b].bVisible);
+K(a,"aoStateSaveParams","stateSaveParams",[a,d]);a.fnStateSave.call(a.oInstance,a,d)}}function gb(a,b){if(a.oFeatures.bStateSave){var c=a.fnStateLoad.call(a.oInstance,a);if(c){var d=K(a,"aoStateLoadParams","stateLoadParams",[a,c]);if(i.inArray(false,d)===-1){a.oLoadedState=i.extend(true,{},c);a._iDisplayStart=c.iStart;a.iInitDisplayStart=c.iStart;a._iDisplayEnd=c.iEnd;a._iDisplayLength=c.iLength;a.aaSorting=c.aaSorting.slice();a.saved_aaSorting=c.aaSorting.slice();i.extend(a.oPreviousSearch,c.oSearch);
+i.extend(true,a.aoPreSearchCols,c.aoSearchCols);b.saved_aoColumns=[];for(d=0;d<c.abVisCols.length;d++){b.saved_aoColumns[d]={};b.saved_aoColumns[d].bVisible=c.abVisCols[d]}K(a,"aoStateLoaded","stateLoaded",[a,c])}}}}function lb(a,b,c,d,e){var f=new Date;f.setTime(f.getTime()+c*1E3);c=la.location.pathname.split("/");a=a+"_"+c.pop().replace(/[\/:]/g,"").toLowerCase();var g;if(e!==null){g=typeof i.parseJSON==="function"?i.parseJSON(b):eval("("+b+")");b=e(a,g,f.toGMTString(),c.join("/")+"/")}else b=a+
+"="+encodeURIComponent(b)+"; expires="+f.toGMTString()+"; path="+c.join("/")+"/";a=s.cookie.split(";");e=b.split(";")[0].length;f=[];if(e+s.cookie.length+10>4096){for(var j=0,k=a.length;j<k;j++)if(a[j].indexOf(d)!=-1){var m=a[j].split("=");try{(g=eval("("+decodeURIComponent(m[1])+")"))&&g.iCreate&&f.push({name:m[0],time:g.iCreate})}catch(u){}}for(f.sort(function(x,y){return y.time-x.time});e+s.cookie.length+10>4096;){if(f.length===0)return;d=f.pop();s.cookie=d.name+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+
+c.join("/")+"/"}}s.cookie=b}function mb(a){var b=la.location.pathname.split("/");a=a+"_"+b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=";b=s.cookie.split(";");for(var c=0;c<b.length;c++){for(var d=b[c];d.charAt(0)==" ";)d=d.substring(1,d.length);if(d.indexOf(a)===0)return decodeURIComponent(d.substring(a.length,d.length))}return null}function C(a){for(var b=0;b<l.settings.length;b++)if(l.settings[b].nTable===a)return l.settings[b];return null}function fa(a){var b=[];a=a.aoData;for(var c=0,d=
+a.length;c<d;c++)a[c].nTr!==null&&b.push(a[c].nTr);return b}function W(a,b){var c=[],d,e,f,g,j;e=0;var k=a.aoData.length;if(b!==p){e=b;k=b+1}for(e=e;e<k;e++){j=a.aoData[e];if(j.nTr!==null){b=[];for(d=j.nTr.firstChild;d;){f=d.nodeName.toLowerCase();if(f=="td"||f=="th")b.push(d);d=d.nextSibling}f=d=0;for(g=a.aoColumns.length;f<g;f++)if(a.aoColumns[f].bVisible)c.push(b[f-d]);else{c.push(j._anHidden[f]);d++}}}return c}function O(a,b,c){a=a===null?"DataTables warning: "+c:"DataTables warning (table id = '"+
+a.sTableId+"'): "+c;if(b===0)if(l.ext.sErrMode=="alert")alert(a);else throw new Error(a);else la.console&&console.log&&console.log(a)}function r(a,b,c,d){if(d===p)d=c;if(b[c]!==p)a[d]=b[c]}function hb(a,b){var c;for(var d in b)if(b.hasOwnProperty(d)){c=b[d];if(typeof h[d]==="object"&&c!==null&&i.isArray(c)===false)i.extend(true,a[d],c);else a[d]=c}return a}function fb(a,b,c){i(a).bind("click.DT",b,function(d){a.blur();c(d)}).bind("keypress.DT",b,function(d){d.which===13&&c(d)}).bind("selectstart.DT",
+function(){return false})}function J(a,b,c,d){c&&a[b].push({fn:c,sName:d})}function K(a,b,c,d){b=a[b];for(var e=[],f=b.length-1;f>=0;f--)e.push(b[f].fn.apply(a.oInstance,d));c!==null&&i(a.oInstance).trigger(c,d);return e}function ib(a){var b=i('<div style="position:absolute; top:0; left:0; height:1px; width:1px; overflow:hidden"><div style="position:absolute; top:1px; left:1px; width:100px; overflow:scroll;"><div id="DT_BrowserTest" style="width:100%; height:10px;"></div></div></div>')[0];s.body.appendChild(b);
+a.oBrowser.bScrollOversize=i("#DT_BrowserTest",b)[0].offsetWidth===100?true:false;s.body.removeChild(b)}function jb(a){return function(){var b=[C(this[l.ext.iApiIndex])].concat(Array.prototype.slice.call(arguments));return l.ext.oApi[a].apply(this,b)}}var ga=/\[.*?\]$/,kb=la.JSON?JSON.stringify:function(a){var b=typeof a;if(b!=="object"||a===null){if(b==="string")a='"'+a+'"';return a+""}var c,d,e=[],f=i.isArray(a);for(c in a){d=a[c];b=typeof d;if(b==="string")d='"'+d+'"';else if(b==="object"&&d!==
+null)d=kb(d);e.push((f?"":'"'+c+'":')+d)}return(f?"[":"{")+e+(f?"]":"}")};this.$=function(a,b){var c,d=[],e;c=C(this[l.ext.iApiIndex]);var f=c.aoData,g=c.aiDisplay,j=c.aiDisplayMaster;b||(b={});b=i.extend({},{filter:"none",order:"current",page:"all"},b);if(b.page=="current"){b=c._iDisplayStart;for(c=c.fnDisplayEnd();b<c;b++)(e=f[g[b]].nTr)&&d.push(e)}else if(b.order=="current"&&b.filter=="none"){b=0;for(c=j.length;b<c;b++)(e=f[j[b]].nTr)&&d.push(e)}else if(b.order=="current"&&b.filter=="applied"){b=
+0;for(c=g.length;b<c;b++)(e=f[g[b]].nTr)&&d.push(e)}else if(b.order=="original"&&b.filter=="none"){b=0;for(c=f.length;b<c;b++)(e=f[b].nTr)&&d.push(e)}else if(b.order=="original"&&b.filter=="applied"){b=0;for(c=f.length;b<c;b++){e=f[b].nTr;i.inArray(b,g)!==-1&&e&&d.push(e)}}else O(c,1,"Unknown selection options");f=i(d);d=f.filter(a);a=f.find(a);return i([].concat(i.makeArray(d),i.makeArray(a)))};this._=function(a,b){var c=[],d=this.$(a,b);a=0;for(b=d.length;a<b;a++)c.push(this.fnGetData(d[a]));return c};
+this.fnAddData=function(a,b){if(a.length===0)return[];var c=[],d,e=C(this[l.ext.iApiIndex]);if(typeof a[0]==="object"&&a[0]!==null)for(var f=0;f<a.length;f++){d=R(e,a[f]);if(d==-1)return c;c.push(d)}else{d=R(e,a);if(d==-1)return c;c.push(d)}e.aiDisplay=e.aiDisplayMaster.slice();if(b===p||b)qa(e);return c};this.fnAdjustColumnSizing=function(a){var b=C(this[l.ext.iApiIndex]);o(b);if(a===p||a)this.fnDraw(false);else if(b.oScroll.sX!==""||b.oScroll.sY!=="")this.oApi._fnScrollDraw(b)};this.fnClearTable=
+function(a){var b=C(this[l.ext.iApiIndex]);wa(b);if(a===p||a)H(b)};this.fnClose=function(a){for(var b=C(this[l.ext.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a){(a=b.aoOpenRows[c].nTr.parentNode)&&a.removeChild(b.aoOpenRows[c].nTr);b.aoOpenRows.splice(c,1);return 0}return 1};this.fnDeleteRow=function(a,b,c){var d=C(this[l.ext.iApiIndex]),e,f;a=typeof a==="object"?V(d,a):a;var g=d.aoData.splice(a,1);e=0;for(f=d.aoData.length;e<f;e++)if(d.aoData[e].nTr!==null)d.aoData[e].nTr._DT_RowIndex=
+e;e=i.inArray(a,d.aiDisplay);d.asDataSearch.splice(e,1);xa(d.aiDisplayMaster,a);xa(d.aiDisplay,a);typeof b==="function"&&b.call(this,d,g);if(d._iDisplayStart>=d.fnRecordsDisplay()){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(c===p||c){I(d);H(d)}return g};this.fnDestroy=function(a){var b=C(this[l.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,e,f;a=a===p?false:a;b.bDestroying=true;K(b,"aoDestroyCallback","destroy",[b]);if(!a){e=0;for(f=b.aoColumns.length;e<
+f;e++)b.aoColumns[e].bVisible===false&&this.fnSetColumnVis(e,true)}i(b.nTableWrapper).find("*").andSelf().unbind(".DT");i("tbody>tr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();if(b.nTable!=b.nTHead.parentNode){i(b.nTable).children("thead").remove();b.nTable.appendChild(b.nTHead)}if(b.nTFoot&&b.nTable!=b.nTFoot.parentNode){i(b.nTable).children("tfoot").remove();b.nTable.appendChild(b.nTFoot)}b.nTable.parentNode.removeChild(b.nTable);i(b.nTableWrapper).remove();b.aaSorting=[];b.aaSortingFixed=
+[];ba(b);i(fa(b)).removeClass(b.asStripeClasses.join(" "));i("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc,b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));if(b.bJUI){i("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove();i("th, td",b.nTHead).each(function(){var g=i("div."+b.oClasses.sSortJUIWrapper,this),j=g.contents();i(this).append(j);g.remove()})}if(!a&&b.nTableReinsertBefore)c.insertBefore(b.nTable,b.nTableReinsertBefore);
+else a||c.appendChild(b.nTable);e=0;for(f=b.aoData.length;e<f;e++)b.aoData[e].nTr!==null&&d.appendChild(b.aoData[e].nTr);if(b.oFeatures.bAutoWidth===true)b.nTable.style.width=t(b.sDestroyWidth);if(f=b.asDestroyStripes.length){a=i(d).children("tr");for(e=0;e<f;e++)a.filter(":nth-child("+f+"n + "+e+")").addClass(b.asDestroyStripes[e])}e=0;for(f=l.settings.length;e<f;e++)l.settings[e]==b&&l.settings.splice(e,1);h=b=null};this.fnDraw=function(a){var b=C(this[l.ext.iApiIndex]);if(a===false){I(b);H(b)}else qa(b)};
+this.fnFilter=function(a,b,c,d,e,f){var g=C(this[l.ext.iApiIndex]);if(g.oFeatures.bFilter){if(c===p||c===null)c=false;if(d===p||d===null)d=true;if(e===p||e===null)e=true;if(f===p||f===null)f=true;if(b===p||b===null){X(g,{sSearch:a+"",bRegex:c,bSmart:d,bCaseInsensitive:f},1);if(e&&g.aanFeatures.f){b=g.aanFeatures.f;c=0;for(d=b.length;c<d;c++)try{b[c]._DT_Input!=s.activeElement&&i(b[c]._DT_Input).val(a)}catch(j){i(b[c]._DT_Input).val(a)}}}else{i.extend(g.aoPreSearchCols[b],{sSearch:a+"",bRegex:c,bSmart:d,
+bCaseInsensitive:f});X(g,g.oPreviousSearch,1)}}};this.fnGetData=function(a,b){var c=C(this[l.ext.iApiIndex]);if(a!==p){var d=a;if(typeof a==="object"){var e=a.nodeName.toLowerCase();if(e==="tr")d=V(c,a);else if(e==="td"){d=V(c,a.parentNode);b=va(c,d,a)}}if(b!==p)return F(c,d,b,"");return c.aoData[d]!==p?c.aoData[d]._aData:null}return oa(c)};this.fnGetNodes=function(a){var b=C(this[l.ext.iApiIndex]);if(a!==p)return b.aoData[a]!==p?b.aoData[a].nTr:null;return fa(b)};this.fnGetPosition=function(a){var b=
+C(this[l.ext.iApiIndex]),c=a.nodeName.toUpperCase();if(c=="TR")return V(b,a);else if(c=="TD"||c=="TH"){c=V(b,a.parentNode);a=va(b,c,a);return[c,w(b,a),a]}return null};this.fnIsOpen=function(a){for(var b=C(this[l.ext.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a)return true;return false};this.fnOpen=function(a,b,c){var d=C(this[l.ext.iApiIndex]),e=fa(d);if(i.inArray(a,e)!==-1){this.fnClose(a);e=s.createElement("tr");var f=s.createElement("td");e.appendChild(f);f.className=
+c;f.colSpan=D(d);if(typeof b==="string")f.innerHTML=b;else i(f).html(b);b=i("tr",d.nTBody);i.inArray(a,b)!=-1&&i(e).insertAfter(a);d.aoOpenRows.push({nTr:e,nParent:a});return e}};this.fnPageChange=function(a,b){var c=C(this[l.ext.iApiIndex]);Ga(c,a);I(c);if(b===p||b)H(c)};this.fnSetColumnVis=function(a,b,c){var d=C(this[l.ext.iApiIndex]),e,f,g=d.aoColumns,j=d.aoData,k,m;if(g[a].bVisible!=b){if(b){for(e=f=0;e<a;e++)g[e].bVisible&&f++;m=f>=D(d);if(!m)for(e=a;e<g.length;e++)if(g[e].bVisible){k=e;break}e=
+0;for(f=j.length;e<f;e++)if(j[e].nTr!==null)m?j[e].nTr.appendChild(j[e]._anHidden[a]):j[e].nTr.insertBefore(j[e]._anHidden[a],W(d,e)[k])}else{e=0;for(f=j.length;e<f;e++)if(j[e].nTr!==null){k=W(d,e)[a];j[e]._anHidden[a]=k;k.parentNode.removeChild(k)}}g[a].bVisible=b;ia(d,d.aoHeader);d.nTFoot&&ia(d,d.aoFooter);e=0;for(f=d.aoOpenRows.length;e<f;e++)d.aoOpenRows[e].nTr.colSpan=D(d);if(c===p||c){o(d);H(d)}Ha(d)}};this.fnSettings=function(){return C(this[l.ext.iApiIndex])};this.fnSort=function(a){var b=
+C(this[l.ext.iApiIndex]);b.aaSorting=a;$(b)};this.fnSortListener=function(a,b,c){ya(C(this[l.ext.iApiIndex]),a,b,c)};this.fnUpdate=function(a,b,c,d,e){var f=C(this[l.ext.iApiIndex]);b=typeof b==="object"?V(f,b):b;if(i.isArray(a)&&c===p){f.aoData[b]._aData=a.slice();for(c=0;c<f.aoColumns.length;c++)this.fnUpdate(F(f,b,c),b,c,false,false)}else if(i.isPlainObject(a)&&c===p){f.aoData[b]._aData=i.extend(true,{},a);for(c=0;c<f.aoColumns.length;c++)this.fnUpdate(F(f,b,c),b,c,false,false)}else{S(f,b,c,a);
+a=F(f,b,c,"display");var g=f.aoColumns[c];if(g.fnRender!==null){a=da(f,b,c);g.bUseRendered&&S(f,b,c,a)}if(f.aoData[b].nTr!==null)W(f,b)[c].innerHTML=a}c=i.inArray(b,f.aiDisplay);f.asDataSearch[c]=Da(f,na(f,b,"filter",A(f,"bSearchable")));if(e===p||e)o(f);if(d===p||d)qa(f);return 0};this.fnVersionCheck=l.ext.fnVersionCheck;this.oApi={_fnExternApiFunc:jb,_fnInitialise:ra,_fnInitComplete:pa,_fnLanguageCompat:Fa,_fnAddColumn:n,_fnColumnOptions:q,_fnAddData:R,_fnCreateTr:ua,_fnGatherData:ea,_fnBuildHead:Ka,
+_fnDrawHead:ia,_fnDraw:H,_fnReDraw:qa,_fnAjaxUpdate:La,_fnAjaxParameters:Ta,_fnAjaxUpdateDraw:Ua,_fnServerParams:Aa,_fnAddOptionsHtml:Ma,_fnFeatureHtmlTable:Qa,_fnScrollDraw:$a,_fnAdjustColumnSizing:o,_fnFeatureHtmlFilter:Oa,_fnFilterComplete:X,_fnFilterCustom:Xa,_fnFilterColumn:Wa,_fnFilter:Va,_fnBuildSearchArray:Ba,_fnBuildSearchRow:Da,_fnFilterCreateSearch:Ca,_fnDataToSearch:Ya,_fnSort:$,_fnSortAttachListener:ya,_fnSortingClasses:ba,_fnFeatureHtmlPaginate:Sa,_fnPageChange:Ga,_fnFeatureHtmlInfo:Ra,
+_fnUpdateInfo:Za,_fnFeatureHtmlLength:Na,_fnFeatureHtmlProcessing:Pa,_fnProcessingDisplay:P,_fnVisibleToColumnIndex:v,_fnColumnIndexToVisible:w,_fnNodeToDataIndex:V,_fnVisbleColumns:D,_fnCalculateEnd:I,_fnConvertToWidth:ab,_fnCalculateColumnWidths:ta,_fnScrollingWidthAdjust:cb,_fnGetWidestNode:bb,_fnGetMaxLenString:db,_fnStringToCss:t,_fnDetectType:G,_fnSettingsFromNode:C,_fnGetDataMaster:oa,_fnGetTrNodes:fa,_fnGetTdNodes:W,_fnEscapeRegex:Ea,_fnDeleteIndex:xa,_fnReOrderIndex:E,_fnColumnOrdering:Y,
+_fnLog:O,_fnClearTable:wa,_fnSaveState:Ha,_fnLoadState:gb,_fnCreateCookie:lb,_fnReadCookie:mb,_fnDetectHeader:ha,_fnGetUniqueThs:Z,_fnScrollBarWidth:eb,_fnApplyToChildren:N,_fnMap:r,_fnGetRowData:na,_fnGetCellData:F,_fnSetCellData:S,_fnGetObjectDataFn:ca,_fnSetObjectDataFn:Ja,_fnApplyColumnDefs:ma,_fnBindAction:fb,_fnExtend:hb,_fnCallbackReg:J,_fnCallbackFire:K,_fnJsonString:kb,_fnRender:da,_fnNodeToColumnIndex:va,_fnInfoMacros:za,_fnBrowserDetect:ib,_fnGetColumns:A};i.extend(l.ext.oApi,this.oApi);
+for(var Ia in l.ext.oApi)if(Ia)this[Ia]=jb(Ia);var sa=this;this.each(function(){var a=0,b,c,d;c=this.getAttribute("id");var e=false,f=false;if(this.nodeName.toLowerCase()!="table")O(null,0,"Attempted to initialise DataTables on a node which is not a table: "+this.nodeName);else{a=0;for(b=l.settings.length;a<b;a++){if(l.settings[a].nTable==this)if(h===p||h.bRetrieve)return l.settings[a].oInstance;else if(h.bDestroy){l.settings[a].oInstance.fnDestroy();break}else{O(l.settings[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, pass no arguments or see the docs for bRetrieve and bDestroy");
+return}if(l.settings[a].sTableId==this.id){l.settings.splice(a,1);break}}if(c===null||c==="")this.id=c="DataTables_Table_"+l.ext._oExternConfig.iNextUnique++;var g=i.extend(true,{},l.models.oSettings,{nTable:this,oApi:sa.oApi,oInit:h,sDestroyWidth:i(this).width(),sInstance:c,sTableId:c});l.settings.push(g);g.oInstance=sa.length===1?sa:i(this).dataTable();h||(h={});h.oLanguage&&Fa(h.oLanguage);h=hb(i.extend(true,{},l.defaults),h);r(g.oFeatures,h,"bPaginate");r(g.oFeatures,h,"bLengthChange");r(g.oFeatures,
+h,"bFilter");r(g.oFeatures,h,"bSort");r(g.oFeatures,h,"bInfo");r(g.oFeatures,h,"bProcessing");r(g.oFeatures,h,"bAutoWidth");r(g.oFeatures,h,"bSortClasses");r(g.oFeatures,h,"bServerSide");r(g.oFeatures,h,"bDeferRender");r(g.oScroll,h,"sScrollX","sX");r(g.oScroll,h,"sScrollXInner","sXInner");r(g.oScroll,h,"sScrollY","sY");r(g.oScroll,h,"bScrollCollapse","bCollapse");r(g.oScroll,h,"bScrollInfinite","bInfinite");r(g.oScroll,h,"iScrollLoadGap","iLoadGap");r(g.oScroll,h,"bScrollAutoCss","bAutoCss");r(g,
+h,"asStripeClasses");r(g,h,"asStripClasses","asStripeClasses");r(g,h,"fnServerData");r(g,h,"fnFormatNumber");r(g,h,"sServerMethod");r(g,h,"aaSorting");r(g,h,"aaSortingFixed");r(g,h,"aLengthMenu");r(g,h,"sPaginationType");r(g,h,"sAjaxSource");r(g,h,"sAjaxDataProp");r(g,h,"iCookieDuration");r(g,h,"sCookiePrefix");r(g,h,"sDom");r(g,h,"bSortCellsTop");r(g,h,"iTabIndex");r(g,h,"oSearch","oPreviousSearch");r(g,h,"aoSearchCols","aoPreSearchCols");r(g,h,"iDisplayLength","_iDisplayLength");r(g,h,"bJQueryUI",
+"bJUI");r(g,h,"fnCookieCallback");r(g,h,"fnStateLoad");r(g,h,"fnStateSave");r(g.oLanguage,h,"fnInfoCallback");J(g,"aoDrawCallback",h.fnDrawCallback,"user");J(g,"aoServerParams",h.fnServerParams,"user");J(g,"aoStateSaveParams",h.fnStateSaveParams,"user");J(g,"aoStateLoadParams",h.fnStateLoadParams,"user");J(g,"aoStateLoaded",h.fnStateLoaded,"user");J(g,"aoRowCallback",h.fnRowCallback,"user");J(g,"aoRowCreatedCallback",h.fnCreatedRow,"user");J(g,"aoHeaderCallback",h.fnHeaderCallback,"user");J(g,"aoFooterCallback",
+h.fnFooterCallback,"user");J(g,"aoInitComplete",h.fnInitComplete,"user");J(g,"aoPreDrawCallback",h.fnPreDrawCallback,"user");if(g.oFeatures.bServerSide&&g.oFeatures.bSort&&g.oFeatures.bSortClasses)J(g,"aoDrawCallback",ba,"server_side_sort_classes");else g.oFeatures.bDeferRender&&J(g,"aoDrawCallback",ba,"defer_sort_classes");if(h.bJQueryUI){i.extend(g.oClasses,l.ext.oJUIClasses);if(h.sDom===l.defaults.sDom&&l.defaults.sDom==="lfrtip")g.sDom='<"H"lfr>t<"F"ip>'}else i.extend(g.oClasses,l.ext.oStdClasses);
+i(this).addClass(g.oClasses.sTable);if(g.oScroll.sX!==""||g.oScroll.sY!=="")g.oScroll.iBarWidth=eb();if(g.iInitDisplayStart===p){g.iInitDisplayStart=h.iDisplayStart;g._iDisplayStart=h.iDisplayStart}if(h.bStateSave){g.oFeatures.bStateSave=true;gb(g,h);J(g,"aoDrawCallback",Ha,"state_save")}if(h.iDeferLoading!==null){g.bDeferLoading=true;a=i.isArray(h.iDeferLoading);g._iRecordsDisplay=a?h.iDeferLoading[0]:h.iDeferLoading;g._iRecordsTotal=a?h.iDeferLoading[1]:h.iDeferLoading}if(h.aaData!==null)f=true;
+if(h.oLanguage.sUrl!==""){g.oLanguage.sUrl=h.oLanguage.sUrl;i.getJSON(g.oLanguage.sUrl,null,function(k){Fa(k);i.extend(true,g.oLanguage,h.oLanguage,k);ra(g)});e=true}else i.extend(true,g.oLanguage,h.oLanguage);if(h.asStripeClasses===null)g.asStripeClasses=[g.oClasses.sStripeOdd,g.oClasses.sStripeEven];b=g.asStripeClasses.length;g.asDestroyStripes=[];if(b){c=false;d=i(this).children("tbody").children("tr:lt("+b+")");for(a=0;a<b;a++)if(d.hasClass(g.asStripeClasses[a])){c=true;g.asDestroyStripes.push(g.asStripeClasses[a])}c&&
+d.removeClass(g.asStripeClasses.join(" "))}c=[];a=this.getElementsByTagName("thead");if(a.length!==0){ha(g.aoHeader,a[0]);c=Z(g)}if(h.aoColumns===null){d=[];a=0;for(b=c.length;a<b;a++)d.push(null)}else d=h.aoColumns;a=0;for(b=d.length;a<b;a++){if(h.saved_aoColumns!==p&&h.saved_aoColumns.length==b){if(d[a]===null)d[a]={};d[a].bVisible=h.saved_aoColumns[a].bVisible}n(g,c?c[a]:null)}ma(g,h.aoColumnDefs,d,function(k,m){q(g,k,m)});a=0;for(b=g.aaSorting.length;a<b;a++){if(g.aaSorting[a][0]>=g.aoColumns.length)g.aaSorting[a][0]=
+0;var j=g.aoColumns[g.aaSorting[a][0]];if(g.aaSorting[a][2]===p)g.aaSorting[a][2]=0;if(h.aaSorting===p&&g.saved_aaSorting===p)g.aaSorting[a][1]=j.asSorting[0];c=0;for(d=j.asSorting.length;c<d;c++)if(g.aaSorting[a][1]==j.asSorting[c]){g.aaSorting[a][2]=c;break}}ba(g);ib(g);a=i(this).children("caption").each(function(){this._captionSide=i(this).css("caption-side")});b=i(this).children("thead");if(b.length===0){b=[s.createElement("thead")];this.appendChild(b[0])}g.nTHead=b[0];b=i(this).children("tbody");
+if(b.length===0){b=[s.createElement("tbody")];this.appendChild(b[0])}g.nTBody=b[0];g.nTBody.setAttribute("role","alert");g.nTBody.setAttribute("aria-live","polite");g.nTBody.setAttribute("aria-relevant","all");b=i(this).children("tfoot");if(b.length===0&&a.length>0&&(g.oScroll.sX!==""||g.oScroll.sY!=="")){b=[s.createElement("tfoot")];this.appendChild(b[0])}if(b.length>0){g.nTFoot=b[0];ha(g.aoFooter,g.nTFoot)}if(f)for(a=0;a<h.aaData.length;a++)R(g,h.aaData[a]);else ea(g);g.aiDisplay=g.aiDisplayMaster.slice();
+g.bInitialised=true;e===false&&ra(g)}});sa=null;return this};l.fnVersionCheck=function(h){var n=function(A,G){for(;A.length<G;)A+="0";return A},q=l.ext.sVersion.split(".");h=h.split(".");for(var o="",v="",w=0,D=h.length;w<D;w++){o+=n(q[w],3);v+=n(h[w],3)}return parseInt(o,10)>=parseInt(v,10)};l.fnIsDataTable=function(h){for(var n=l.settings,q=0;q<n.length;q++)if(n[q].nTable===h||n[q].nScrollHead===h||n[q].nScrollFoot===h)return true;return false};l.fnTables=function(h){var n=[];jQuery.each(l.settings,
+function(q,o){if(!h||h===true&&i(o.nTable).is(":visible"))n.push(o.nTable)});return n};l.version="1.9.4";l.settings=[];l.models={};l.models.ext={afnFiltering:[],afnSortData:[],aoFeatures:[],aTypes:[],fnVersionCheck:l.fnVersionCheck,iApiIndex:0,ofnSearch:{},oApi:{},oStdClasses:{},oJUIClasses:{},oPagination:{},oSort:{},sVersion:l.version,sErrMode:"alert",_oExternConfig:{iNextUnique:0}};l.models.oSearch={bCaseInsensitive:true,sSearch:"",bRegex:false,bSmart:true};l.models.oRow={nTr:null,_aData:[],_aSortData:[],
+_anHidden:[],_sRowStripe:""};l.models.oColumn={aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bUseRendered:null,bVisible:null,_bAutoType:true,fnCreatedCell:null,fnGetData:null,fnRender:null,fnSetData:null,mData:null,mRender:null,nTh:null,nTf:null,sClass:null,sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};l.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:null,
+aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:null,bAutoWidth:true,bDeferRender:false,bDestroy:false,bFilter:true,bInfo:true,bJQueryUI:false,bLengthChange:true,bPaginate:true,bProcessing:false,bRetrieve:false,bScrollAutoCss:true,bScrollCollapse:false,bScrollInfinite:false,bServerSide:false,bSort:true,bSortCellsTop:false,bSortClasses:true,bStateSave:false,fnCookieCallback:null,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(h){if(h<
+1E3)return h;var n=h+"";h=n.split("");var q="";n=n.length;for(var o=0;o<n;o++){if(o%3===0&&o!==0)q=this.oLanguage.sInfoThousands+q;q=h[n-o-1]+q}return q},fnHeaderCallback:null,fnInfoCallback:null,fnInitComplete:null,fnPreDrawCallback:null,fnRowCallback:null,fnServerData:function(h,n,q,o){o.jqXHR=i.ajax({url:h,data:n,success:function(v){v.sError&&o.oApi._fnLog(o,0,v.sError);i(o.oInstance).trigger("xhr",[o,v]);q(v)},dataType:"json",cache:false,type:o.sServerMethod,error:function(v,w){w=="parsererror"&&
+o.oApi._fnLog(o,0,"DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})},fnServerParams:null,fnStateLoad:function(h){h=this.oApi._fnReadCookie(h.sCookiePrefix+h.sInstance);var n;try{n=typeof i.parseJSON==="function"?i.parseJSON(h):eval("("+h+")")}catch(q){n=null}return n},fnStateLoadParams:null,fnStateLoaded:null,fnStateSave:function(h,n){this.oApi._fnCreateCookie(h.sCookiePrefix+h.sInstance,this.oApi._fnJsonString(n),h.iCookieDuration,h.sCookiePrefix,
+h.fnCookieCallback)},fnStateSaveParams:null,iCookieDuration:7200,iDeferLoading:null,iDisplayLength:10,iDisplayStart:0,iScrollLoadGap:100,iTabIndex:0,oLanguage:{oAria:{sSortAscending:": activate to sort column ascending",sSortDescending:": activate to sort column descending"},oPaginate:{sFirst:"First",sLast:"Last",sNext:"Next",sPrevious:"Previous"},sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",
+sInfoPostFix:"",sInfoThousands:",",sLengthMenu:"Show _MENU_ entries",sLoadingRecords:"Loading...",sProcessing:"Processing...",sSearch:"Search:",sUrl:"",sZeroRecords:"No matching records found"},oSearch:i.extend({},l.models.oSearch),sAjaxDataProp:"aaData",sAjaxSource:null,sCookiePrefix:"SpryMedia_DataTables_",sDom:"lfrtip",sPaginationType:"two_button",sScrollX:"",sScrollXInner:"",sScrollY:"",sServerMethod:"GET"};l.defaults.columns={aDataSort:null,asSorting:["asc","desc"],bSearchable:true,bSortable:true,
+bUseRendered:true,bVisible:true,fnCreatedCell:null,fnRender:null,iDataSort:-1,mData:null,mRender:null,sCellType:"td",sClass:"",sContentPadding:"",sDefaultContent:null,sName:"",sSortDataType:"std",sTitle:null,sType:null,sWidth:null};l.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender:null,bFilter:null,bInfo:null,bLengthChange:null,bPaginate:null,bProcessing:null,bServerSide:null,bSort:null,bSortClasses:null,bStateSave:null},oScroll:{bAutoCss:null,bCollapse:null,bInfinite:null,iBarWidth:0,iLoadGap:null,
+sX:null,sXInner:null,sY:null},oLanguage:{fnInfoCallback:null},oBrowser:{bScrollOversize:false},aanFeatures:[],aoData:[],aiDisplay:[],aiDisplayMaster:[],aoColumns:[],aoHeader:[],aoFooter:[],asDataSearch:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:null,asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],
+aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:false,bInitialised:false,aoOpenRows:[],sDom:null,sPaginationType:"two_button",iCookieDuration:0,sCookiePrefix:"",fnCookieCallback:null,aoStateSave:[],aoStateLoad:[],oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:true,jqXHR:null,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:false,iDrawError:-1,_iDisplayLength:10,
+_iDisplayStart:0,_iDisplayEnd:10,_iRecordsTotal:0,_iRecordsDisplay:0,bJUI:null,oClasses:{},bFiltered:false,bSorted:false,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length},fnRecordsDisplay:function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length},fnDisplayEnd:function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||
+this._iDisplayLength==-1?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null};l.ext=i.extend(true,{},l.models.ext);i.extend(l.ext.oStdClasses,{sTable:"dataTable",sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",
+sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",sPageButtonStaticDisabled:"paginate_button paginate_button_disabled",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",
+sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",
+sFooterTH:"",sJUIHeader:"",sJUIFooter:""});i.extend(l.ext.oJUIClasses,l.ext.oStdClasses,{sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",
+sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl",sPageLast:"last ui-corner-tr ui-corner-br",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default",
+sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollFoot:"dataTables_scrollFoot ui-state-default",
+sFooterTH:"ui-state-default",sJUIHeader:"fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix",sJUIFooter:"fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix"});i.extend(l.ext.oPagination,{two_button:{fnInit:function(h,n,q){var o=h.oLanguage.oPaginate,v=function(D){h.oApi._fnPageChange(h,D.data.action)&&q(h)};o=!h.bJUI?'<a class="'+h.oClasses.sPagePrevDisabled+'" tabindex="'+h.iTabIndex+'" role="button">'+o.sPrevious+'</a><a class="'+
+h.oClasses.sPageNextDisabled+'" tabindex="'+h.iTabIndex+'" role="button">'+o.sNext+"</a>":'<a class="'+h.oClasses.sPagePrevDisabled+'" tabindex="'+h.iTabIndex+'" role="button"><span class="'+h.oClasses.sPageJUIPrev+'"></span></a><a class="'+h.oClasses.sPageNextDisabled+'" tabindex="'+h.iTabIndex+'" role="button"><span class="'+h.oClasses.sPageJUINext+'"></span></a>';i(n).append(o);var w=i("a",n);o=w[0];w=w[1];h.oApi._fnBindAction(o,{action:"previous"},v);h.oApi._fnBindAction(w,{action:"next"},v);
+if(!h.aanFeatures.p){n.id=h.sTableId+"_paginate";o.id=h.sTableId+"_previous";w.id=h.sTableId+"_next";o.setAttribute("aria-controls",h.sTableId);w.setAttribute("aria-controls",h.sTableId)}},fnUpdate:function(h){if(h.aanFeatures.p)for(var n=h.oClasses,q=h.aanFeatures.p,o,v=0,w=q.length;v<w;v++)if(o=q[v].firstChild){o.className=h._iDisplayStart===0?n.sPagePrevDisabled:n.sPagePrevEnabled;o=o.nextSibling;o.className=h.fnDisplayEnd()==h.fnRecordsDisplay()?n.sPageNextDisabled:n.sPageNextEnabled}}},iFullNumbersShowPages:5,
+full_numbers:{fnInit:function(h,n,q){var o=h.oLanguage.oPaginate,v=h.oClasses,w=function(G){h.oApi._fnPageChange(h,G.data.action)&&q(h)};i(n).append('<a  tabindex="'+h.iTabIndex+'" class="'+v.sPageButton+" "+v.sPageFirst+'">'+o.sFirst+'</a><a  tabindex="'+h.iTabIndex+'" class="'+v.sPageButton+" "+v.sPagePrevious+'">'+o.sPrevious+'</a><span></span><a tabindex="'+h.iTabIndex+'" class="'+v.sPageButton+" "+v.sPageNext+'">'+o.sNext+'</a><a tabindex="'+h.iTabIndex+'" class="'+v.sPageButton+" "+v.sPageLast+
+'">'+o.sLast+"</a>");var D=i("a",n);o=D[0];v=D[1];var A=D[2];D=D[3];h.oApi._fnBindAction(o,{action:"first"},w);h.oApi._fnBindAction(v,{action:"previous"},w);h.oApi._fnBindAction(A,{action:"next"},w);h.oApi._fnBindAction(D,{action:"last"},w);if(!h.aanFeatures.p){n.id=h.sTableId+"_paginate";o.id=h.sTableId+"_first";v.id=h.sTableId+"_previous";A.id=h.sTableId+"_next";D.id=h.sTableId+"_last"}},fnUpdate:function(h,n){if(h.aanFeatures.p){var q=l.ext.oPagination.iFullNumbersShowPages,o=Math.floor(q/2),v=
+Math.ceil(h.fnRecordsDisplay()/h._iDisplayLength),w=Math.ceil(h._iDisplayStart/h._iDisplayLength)+1,D="",A,G=h.oClasses,E,Y=h.aanFeatures.p,ma=function(R){h.oApi._fnBindAction(this,{page:R+A-1},function(ea){h.oApi._fnPageChange(h,ea.data.page);n(h);ea.preventDefault()})};if(h._iDisplayLength===-1)w=o=A=1;else if(v<q){A=1;o=v}else if(w<=o){A=1;o=q}else if(w>=v-o){A=v-q+1;o=v}else{A=w-Math.ceil(q/2)+1;o=A+q-1}for(q=A;q<=o;q++)D+=w!==q?'<a tabindex="'+h.iTabIndex+'" class="'+G.sPageButton+'">'+h.fnFormatNumber(q)+
+"</a>":'<a tabindex="'+h.iTabIndex+'" class="'+G.sPageButtonActive+'">'+h.fnFormatNumber(q)+"</a>";q=0;for(o=Y.length;q<o;q++){E=Y[q];if(E.hasChildNodes()){i("span:eq(0)",E).html(D).children("a").each(ma);E=E.getElementsByTagName("a");E=[E[0],E[1],E[E.length-2],E[E.length-1]];i(E).removeClass(G.sPageButton+" "+G.sPageButtonActive+" "+G.sPageButtonStaticDisabled);i([E[0],E[1]]).addClass(w==1?G.sPageButtonStaticDisabled:G.sPageButton);i([E[2],E[3]]).addClass(v===0||w===v||h._iDisplayLength===-1?G.sPageButtonStaticDisabled:
+G.sPageButton)}}}}}});i.extend(l.ext.oSort,{"string-pre":function(h){if(typeof h!="string")h=h!==null&&h.toString?h.toString():"";return h.toLowerCase()},"string-asc":function(h,n){return h<n?-1:h>n?1:0},"string-desc":function(h,n){return h<n?1:h>n?-1:0},"html-pre":function(h){return h.replace(/<.*?>/g,"").toLowerCase()},"html-asc":function(h,n){return h<n?-1:h>n?1:0},"html-desc":function(h,n){return h<n?1:h>n?-1:0},"date-pre":function(h){h=Date.parse(h);if(isNaN(h)||h==="")h=Date.parse("01/01/1970 00:00:00");
+return h},"date-asc":function(h,n){return h-n},"date-desc":function(h,n){return n-h},"numeric-pre":function(h){return h=="-"||h===""?0:h*1},"numeric-asc":function(h,n){return h-n},"numeric-desc":function(h,n){return n-h}});i.extend(l.ext.aTypes,[function(h){if(typeof h==="number")return"numeric";else if(typeof h!=="string")return null;var n,q=false;n=h.charAt(0);if("0123456789-".indexOf(n)==-1)return null;for(var o=1;o<h.length;o++){n=h.charAt(o);if("0123456789.".indexOf(n)==-1)return null;if(n==
+"."){if(q)return null;q=true}}return"numeric"},function(h){var n=Date.parse(h);if(n!==null&&!isNaN(n)||typeof h==="string"&&h.length===0)return"date";return null},function(h){if(typeof h==="string"&&h.indexOf("<")!=-1&&h.indexOf(">")!=-1)return"html";return null}]);i.fn.DataTable=l;i.fn.dataTable=l;i.fn.dataTableSettings=l.settings;i.fn.dataTableExt=l.ext})})(window,document);

BIN
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/dt-1.9.4/js/jquery.dataTables.min.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-1.8.2.min.js


BIN
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-1.8.2.min.js.gz


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 5 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-ui-1.9.1.custom.min.js


BIN
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jquery/jquery-ui-1.9.1.custom.min.js.gz


+ 4544 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jt/jquery.jstree.js

@@ -0,0 +1,4544 @@
+/*
+ * jsTree 1.0-rc3
+ * http://jstree.com/
+ *
+ * Copyright (c) 2010 Ivan Bozhanov (vakata.com)
+ *
+ * Licensed same as jquery - under the terms of either the MIT License or the GPL Version 2 License
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * $Date$
+ * $Revision$
+ */
+
+/*jslint browser: true, onevar: true, undef: true, bitwise: true, strict: true */
+/*global window : false, clearInterval: false, clearTimeout: false, document: false, setInterval: false, setTimeout: false, jQuery: false, navigator: false, XSLTProcessor: false, DOMParser: false, XMLSerializer: false*/
+
+"use strict";
+
+// top wrapper to prevent multiple inclusion (is this OK?)
+(function () { if(jQuery && jQuery.jstree) { return; }
+  var is_ie6 = false, is_ie7 = false, is_ff2 = false;
+
+/*
+ * jsTree core
+ */
+(function ($) {
+  // Common functions not related to jsTree
+  // decided to move them to a `vakata` "namespace"
+  $.vakata = {};
+  // CSS related functions
+  $.vakata.css = {
+    get_css : function(rule_name, delete_flag, sheet) {
+      rule_name = rule_name.toLowerCase();
+      var css_rules = sheet.cssRules || sheet.rules,
+        j = 0;
+      do {
+        if(css_rules.length && j > css_rules.length + 5) { return false; }
+        if(css_rules[j].selectorText && css_rules[j].selectorText.toLowerCase() == rule_name) {
+          if(delete_flag === true) {
+            if(sheet.removeRule) { sheet.removeRule(j); }
+            if(sheet.deleteRule) { sheet.deleteRule(j); }
+            return true;
+          }
+          else { return css_rules[j]; }
+        }
+      }
+      while (css_rules[++j]);
+      return false;
+    },
+    add_css : function(rule_name, sheet) {
+      if($.jstree.css.get_css(rule_name, false, sheet)) { return false; }
+      if(sheet.insertRule) { sheet.insertRule(rule_name + ' { }', 0); } else { sheet.addRule(rule_name, null, 0); }
+      return $.vakata.css.get_css(rule_name);
+    },
+    remove_css : function(rule_name, sheet) {
+      return $.vakata.css.get_css(rule_name, true, sheet);
+    },
+    add_sheet : function(opts) {
+      var tmp = false, is_new = true;
+      if(opts.str) {
+        if(opts.title) { tmp = $("style[id='" + opts.title + "-stylesheet']")[0]; }
+        if(tmp) { is_new = false; }
+        else {
+          tmp = document.createElement("style");
+          tmp.setAttribute('type',"text/css");
+          if(opts.title) { tmp.setAttribute("id", opts.title + "-stylesheet"); }
+        }
+        if(tmp.styleSheet) {
+          if(is_new) {
+            document.getElementsByTagName("head")[0].appendChild(tmp);
+            tmp.styleSheet.cssText = opts.str;
+          }
+          else {
+            tmp.styleSheet.cssText = tmp.styleSheet.cssText + " " + opts.str;
+          }
+        }
+        else {
+          tmp.appendChild(document.createTextNode(opts.str));
+          document.getElementsByTagName("head")[0].appendChild(tmp);
+        }
+        return tmp.sheet || tmp.styleSheet;
+      }
+      if(opts.url) {
+        if(document.createStyleSheet) {
+          try { tmp = document.createStyleSheet(opts.url); } catch (e) { }
+        }
+        else {
+          tmp      = document.createElement('link');
+          tmp.rel    = 'stylesheet';
+          tmp.type  = 'text/css';
+          tmp.media  = "all";
+          tmp.href  = opts.url;
+          document.getElementsByTagName("head")[0].appendChild(tmp);
+          return tmp.styleSheet;
+        }
+      }
+    }
+  };
+
+  // private variables
+  var instances = [],      // instance array (used by $.jstree.reference/create/focused)
+    focused_instance = -1,  // the index in the instance array of the currently focused instance
+    plugins = {},      // list of included plugins
+    prepared_move = {};    // for the move_node function
+
+  // jQuery plugin wrapper (thanks to jquery UI widget function)
+  $.fn.jstree = function (settings) {
+    var isMethodCall = (typeof settings == 'string'), // is this a method call like $().jstree("open_node")
+      args = Array.prototype.slice.call(arguments, 1),
+      returnValue = this;
+
+    // if a method call execute the method on all selected instances
+    if(isMethodCall) {
+      if(settings.substring(0, 1) == '_') { return returnValue; }
+      this.each(function() {
+        var instance = instances[$.data(this, "jstree-instance-id")],
+          methodValue = (instance && $.isFunction(instance[settings])) ? instance[settings].apply(instance, args) : instance;
+          if(typeof methodValue !== "undefined" && (settings.indexOf("is_") === 0 || (methodValue !== true && methodValue !== false))) { returnValue = methodValue; return false; }
+      });
+    }
+    else {
+      this.each(function() {
+        // extend settings and allow for multiple hashes and $.data
+        var instance_id = $.data(this, "jstree-instance-id"),
+          a = [],
+          b = settings ? $.extend({}, true, settings) : {},
+          c = $(this),
+          s = false,
+          t = [];
+        a = a.concat(args);
+        if(c.data("jstree")) { a.push(c.data("jstree")); }
+        b = a.length ? $.extend.apply(null, [true, b].concat(a)) : b;
+
+        // if an instance already exists, destroy it first
+        if(typeof instance_id !== "undefined" && instances[instance_id]) { instances[instance_id].destroy(); }
+        // push a new empty object to the instances array
+        instance_id = parseInt(instances.push({}),10) - 1;
+        // store the jstree instance id to the container element
+        $.data(this, "jstree-instance-id", instance_id);
+        // clean up all plugins
+        b.plugins = $.isArray(b.plugins) ? b.plugins : $.jstree.defaults.plugins.slice();
+        b.plugins.unshift("core");
+        // only unique plugins
+        b.plugins = b.plugins.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",");
+
+        // extend defaults with passed data
+        s = $.extend(true, {}, $.jstree.defaults, b);
+        s.plugins = b.plugins;
+        $.each(plugins, function (i, val) {
+          if($.inArray(i, s.plugins) === -1) { s[i] = null; delete s[i]; }
+          else { t.push(i); }
+        });
+        s.plugins = t;
+
+        // push the new object to the instances array (at the same time set the default classes to the container) and init
+        instances[instance_id] = new $.jstree._instance(instance_id, $(this).addClass("jstree jstree-" + instance_id), s);
+        // init all activated plugins for this instance
+        $.each(instances[instance_id]._get_settings().plugins, function (i, val) { instances[instance_id].data[val] = {}; });
+        $.each(instances[instance_id]._get_settings().plugins, function (i, val) { if(plugins[val]) { plugins[val].__init.apply(instances[instance_id]); } });
+        // initialize the instance
+        setTimeout(function() { instances[instance_id].init(); }, 0);
+      });
+    }
+    // return the jquery selection (or if it was a method call that returned a value - the returned value)
+    return returnValue;
+  };
+  // object to store exposed functions and objects
+  $.jstree = {
+    defaults : {
+      plugins : []
+    },
+    _focused : function () { return instances[focused_instance] || null; },
+    _reference : function (needle) {
+      // get by instance id
+      if(instances[needle]) { return instances[needle]; }
+      // get by DOM (if still no luck - return null
+      var o = $(needle);
+      if(!o.length && typeof needle === "string") { o = $("#" + needle); }
+      if(!o.length) { return null; }
+      return instances[o.closest(".jstree").data("jstree-instance-id")] || null;
+    },
+    _instance : function (index, container, settings) {
+      // for plugins to store data in
+      this.data = { core : {} };
+      this.get_settings  = function () { return $.extend(true, {}, settings); };
+      this._get_settings  = function () { return settings; };
+      this.get_index    = function () { return index; };
+      this.get_container  = function () { return container; };
+      this.get_container_ul = function () { return container.children("ul:eq(0)"); };
+      this._set_settings  = function (s) {
+        settings = $.extend(true, {}, settings, s);
+      };
+    },
+    _fn : { },
+    plugin : function (pname, pdata) {
+      pdata = $.extend({}, {
+        __init    : $.noop,
+        __destroy  : $.noop,
+        _fn      : {},
+        defaults  : false
+      }, pdata);
+      plugins[pname] = pdata;
+
+      $.jstree.defaults[pname] = pdata.defaults;
+      $.each(pdata._fn, function (i, val) {
+        val.plugin    = pname;
+        val.old      = $.jstree._fn[i];
+        $.jstree._fn[i] = function () {
+          var rslt,
+            func = val,
+            args = Array.prototype.slice.call(arguments),
+            evnt = new $.Event("before.jstree"),
+            rlbk = false;
+
+          if(this.data.core.locked === true && i !== "unlock" && i !== "is_locked") { return; }
+
+          // Check if function belongs to the included plugins of this instance
+          do {
+            if(func && func.plugin && $.inArray(func.plugin, this._get_settings().plugins) !== -1) { break; }
+            func = func.old;
+          } while(func);
+          if(!func) { return; }
+
+          // context and function to trigger events, then finally call the function
+          if(i.indexOf("_") === 0) {
+            rslt = func.apply(this, args);
+          }
+          else {
+            rslt = this.get_container().triggerHandler(evnt, { "func" : i, "inst" : this, "args" : args, "plugin" : func.plugin });
+            if(rslt === false) { return; }
+            if(typeof rslt !== "undefined") { args = rslt; }
+
+            rslt = func.apply(
+              $.extend({}, this, {
+                __callback : function (data) {
+                  this.get_container().triggerHandler( i + '.jstree', { "inst" : this, "args" : args, "rslt" : data, "rlbk" : rlbk });
+                },
+                __rollback : function () {
+                  rlbk = this.get_rollback();
+                  return rlbk;
+                },
+                __call_old : function (replace_arguments) {
+                  return func.old.apply(this, (replace_arguments ? Array.prototype.slice.call(arguments, 1) : args ) );
+                }
+              }), args);
+          }
+
+          // return the result
+          return rslt;
+        };
+        $.jstree._fn[i].old = val.old;
+        $.jstree._fn[i].plugin = pname;
+      });
+    },
+    rollback : function (rb) {
+      if(rb) {
+        if(!$.isArray(rb)) { rb = [ rb ]; }
+        $.each(rb, function (i, val) {
+          instances[val.i].set_rollback(val.h, val.d);
+        });
+      }
+    }
+  };
+  // set the prototype for all instances
+  $.jstree._fn = $.jstree._instance.prototype = {};
+
+  // load the css when DOM is ready
+  $(function() {
+    // code is copied from jQuery ($.browser is deprecated + there is a bug in IE)
+    var u = navigator.userAgent.toLowerCase(),
+      v = (u.match( /.+?(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
+      css_string = '' +
+        '.jstree ul, .jstree li { display:block; margin:0 0 0 0; padding:0 0 0 0; list-style-type:none; } ' +
+        '.jstree li { display:block; min-height:18px; line-height:18px; white-space:nowrap; margin-left:18px; min-width:18px; } ' +
+        '.jstree-rtl li { margin-left:0; margin-right:18px; } ' +
+        '.jstree > ul > li { margin-left:0px; } ' +
+        '.jstree-rtl > ul > li { margin-right:0px; } ' +
+        '.jstree ins { display:inline-block; text-decoration:none; width:18px; height:18px; margin:0 0 0 0; padding:0; } ' +
+        '.jstree a { display:inline-block; line-height:16px; height:16px; color:black; white-space:nowrap; text-decoration:none; padding:1px 2px; margin:0; } ' +
+        '.jstree a:focus { outline: none; } ' +
+        '.jstree a > ins { height:16px; width:16px; } ' +
+        '.jstree a > .jstree-icon { margin-right:3px; } ' +
+        '.jstree-rtl a > .jstree-icon { margin-left:3px; margin-right:0; } ' +
+        'li.jstree-open > ul { display:block; } ' +
+        'li.jstree-closed > ul { display:none; } ';
+    // Correct IE 6 (does not support the > CSS selector)
+    if(/msie/.test(u) && parseInt(v, 10) == 6) {
+      is_ie6 = true;
+
+      // fix image flicker and lack of caching
+      try {
+        document.execCommand("BackgroundImageCache", false, true);
+      } catch (err) { }
+
+      css_string += '' +
+        '.jstree li { height:18px; margin-left:0; margin-right:0; } ' +
+        '.jstree li li { margin-left:18px; } ' +
+        '.jstree-rtl li li { margin-left:0px; margin-right:18px; } ' +
+        'li.jstree-open ul { display:block; } ' +
+        'li.jstree-closed ul { display:none !important; } ' +
+        '.jstree li a { display:inline; border-width:0 !important; padding:0px 2px !important; } ' +
+        '.jstree li a ins { height:16px; width:16px; margin-right:3px; } ' +
+        '.jstree-rtl li a ins { margin-right:0px; margin-left:3px; } ';
+    }
+    // Correct IE 7 (shifts anchor nodes onhover)
+    if(/msie/.test(u) && parseInt(v, 10) == 7) {
+      is_ie7 = true;
+      css_string += '.jstree li a { border-width:0 !important; padding:0px 2px !important; } ';
+    }
+    // correct ff2 lack of display:inline-block
+    if(!/compatible/.test(u) && /mozilla/.test(u) && parseFloat(v, 10) < 1.9) {
+      is_ff2 = true;
+      css_string += '' +
+        '.jstree ins { display:-moz-inline-box; } ' +
+        '.jstree li { line-height:12px; } ' + // WHY??
+        '.jstree a { display:-moz-inline-box; } ' +
+        '.jstree .jstree-no-icons .jstree-checkbox { display:-moz-inline-stack !important; } ';
+        /* this shouldn't be here as it is theme specific */
+    }
+    // the default stylesheet
+    $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
+  });
+
+  // core functions (open, close, create, update, delete)
+  $.jstree.plugin("core", {
+    __init : function () {
+      this.data.core.locked = false;
+      this.data.core.to_open = this.get_settings().core.initially_open;
+      this.data.core.to_load = this.get_settings().core.initially_load;
+    },
+    defaults : {
+      html_titles  : false,
+      animation  : 500,
+      initially_open : [],
+      initially_load : [],
+      open_parents : true,
+      notify_plugins : true,
+      rtl      : false,
+      load_open  : false,
+      strings    : {
+        loading    : "Loading ...",
+        new_node  : "New node",
+        multiple_selection : "Multiple selection"
+      }
+    },
+    _fn : {
+      init  : function () {
+        this.set_focus();
+        if(this._get_settings().core.rtl) {
+          this.get_container().addClass("jstree-rtl").css("direction", "rtl");
+        }
+        this.get_container().html("<ul><li class='jstree-last jstree-leaf'><ins>&#160;</ins><a class='jstree-loading' href='#'><ins class='jstree-icon'>&#160;</ins>" + this._get_string("loading") + "</a></li></ul>");
+        this.data.core.li_height = this.get_container_ul().find("li.jstree-closed, li.jstree-leaf").eq(0).height() || 18;
+
+        this.get_container()
+          .delegate("li > ins", "click.jstree", $.proxy(function (event) {
+              var trgt = $(event.target);
+              if(trgt.is("ins") && event.pageY - trgt.offset().top < this.data.core.li_height) { this.toggle_node(trgt); }
+            }, this))
+          .bind("mousedown.jstree", $.proxy(function () {
+              this.set_focus(); // This used to be setTimeout(set_focus,0) - why?
+            }, this))
+          .bind("dblclick.jstree", function (event) {
+            var sel;
+            if(document.selection && document.selection.empty) { document.selection.empty(); }
+            else {
+              if(window.getSelection) {
+                sel = window.getSelection();
+                try {
+                  sel.removeAllRanges();
+                  sel.collapse();
+                } catch (err) { }
+              }
+            }
+          });
+        if(this._get_settings().core.notify_plugins) {
+          this.get_container()
+            .bind("load_node.jstree", $.proxy(function (e, data) {
+                var o = this._get_node(data.rslt.obj),
+                  t = this;
+                if(o === -1) { o = this.get_container_ul(); }
+                if(!o.length) { return; }
+                o.find("li").each(function () {
+                  var th = $(this);
+                  if(th.data("jstree")) {
+                    $.each(th.data("jstree"), function (plugin, values) {
+                      if(t.data[plugin] && $.isFunction(t["_" + plugin + "_notify"])) {
+                        t["_" + plugin + "_notify"].call(t, th, values);
+                      }
+                    });
+                  }
+                });
+              }, this));
+        }
+        if(this._get_settings().core.load_open) {
+          this.get_container()
+            .bind("load_node.jstree", $.proxy(function (e, data) {
+                var o = this._get_node(data.rslt.obj),
+                  t = this;
+                if(o === -1) { o = this.get_container_ul(); }
+                if(!o.length) { return; }
+                o.find("li.jstree-open:not(:has(ul))").each(function () {
+                  t.load_node(this, $.noop, $.noop);
+                });
+              }, this));
+        }
+        this.__callback();
+        this.load_node(-1, function () { this.loaded(); this.reload_nodes(); });
+      },
+      destroy  : function () {
+        var i,
+          n = this.get_index(),
+          s = this._get_settings(),
+          _this = this;
+
+        $.each(s.plugins, function (i, val) {
+          try { plugins[val].__destroy.apply(_this); } catch(err) { }
+        });
+        this.__callback();
+        // set focus to another instance if this one is focused
+        if(this.is_focused()) {
+          for(i in instances) {
+            if(instances.hasOwnProperty(i) && i != n) {
+              instances[i].set_focus();
+              break;
+            }
+          }
+        }
+        // if no other instance found
+        if(n === focused_instance) { focused_instance = -1; }
+        // remove all traces of jstree in the DOM (only the ones set using jstree*) and cleans all events
+        this.get_container()
+          .unbind(".jstree")
+          .undelegate(".jstree")
+          .removeData("jstree-instance-id")
+          .find("[class^='jstree']")
+            .andSelf()
+            .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); });
+        $(document)
+          .unbind(".jstree-" + n)
+          .undelegate(".jstree-" + n);
+        // remove the actual data
+        instances[n] = null;
+        delete instances[n];
+      },
+
+      _core_notify : function (n, data) {
+        if(data.opened) {
+          this.open_node(n, false, true);
+        }
+      },
+
+      lock : function () {
+        this.data.core.locked = true;
+        this.get_container().children("ul").addClass("jstree-locked").css("opacity","0.7");
+        this.__callback({});
+      },
+      unlock : function () {
+        this.data.core.locked = false;
+        this.get_container().children("ul").removeClass("jstree-locked").css("opacity","1");
+        this.__callback({});
+      },
+      is_locked : function () { return this.data.core.locked; },
+      save_opened : function () {
+        var _this = this;
+        this.data.core.to_open = [];
+        this.get_container_ul().find("li.jstree-open").each(function () {
+          if(this.id) { _this.data.core.to_open.push("#" + this.id.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:")); }
+        });
+        this.__callback(_this.data.core.to_open);
+      },
+      save_loaded : function () { },
+      reload_nodes : function (is_callback) {
+        var _this = this,
+          done = true,
+          current = [],
+          remaining = [];
+        if(!is_callback) {
+          this.data.core.reopen = false;
+          this.data.core.refreshing = true;
+          this.data.core.to_open = $.map($.makeArray(this.data.core.to_open), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
+          this.data.core.to_load = $.map($.makeArray(this.data.core.to_load), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
+          if(this.data.core.to_open.length) {
+            this.data.core.to_load = this.data.core.to_load.concat(this.data.core.to_open);
+          }
+        }
+        if(this.data.core.to_load.length) {
+          $.each(this.data.core.to_load, function (i, val) {
+            if(val == "#") { return true; }
+            if($(val).length) { current.push(val); }
+            else { remaining.push(val); }
+          });
+          if(current.length) {
+            this.data.core.to_load = remaining;
+            $.each(current, function (i, val) {
+              if(!_this._is_loaded(val)) {
+                _this.load_node(val, function () { _this.reload_nodes(true); }, function () { _this.reload_nodes(true); });
+                done = false;
+              }
+            });
+          }
+        }
+        if(this.data.core.to_open.length) {
+          $.each(this.data.core.to_open, function (i, val) {
+            _this.open_node(val, false, true);
+          });
+        }
+        if(done) {
+          // TODO: find a more elegant approach to syncronizing returning requests
+          if(this.data.core.reopen) { clearTimeout(this.data.core.reopen); }
+          this.data.core.reopen = setTimeout(function () { _this.__callback({}, _this); }, 50);
+          this.data.core.refreshing = false;
+          this.reopen();
+        }
+      },
+      reopen : function () {
+        var _this = this;
+        if(this.data.core.to_open.length) {
+          $.each(this.data.core.to_open, function (i, val) {
+            _this.open_node(val, false, true);
+          });
+        }
+        this.__callback({});
+      },
+      refresh : function (obj) {
+        var _this = this;
+        this.save_opened();
+        if(!obj) { obj = -1; }
+        obj = this._get_node(obj);
+        if(!obj) { obj = -1; }
+        if(obj !== -1) { obj.children("UL").remove(); }
+        else { this.get_container_ul().empty(); }
+        this.load_node(obj, function () { _this.__callback({ "obj" : obj}); _this.reload_nodes(); });
+      },
+      // Dummy function to fire after the first load (so that there is a jstree.loaded event)
+      loaded  : function () {
+        this.__callback();
+      },
+      // deal with focus
+      set_focus  : function () {
+        if(this.is_focused()) { return; }
+        var f = $.jstree._focused();
+        if(f) { f.unset_focus(); }
+
+        this.get_container().addClass("jstree-focused");
+        focused_instance = this.get_index();
+        this.__callback();
+      },
+      is_focused  : function () {
+        return focused_instance == this.get_index();
+      },
+      unset_focus  : function () {
+        if(this.is_focused()) {
+          this.get_container().removeClass("jstree-focused");
+          focused_instance = -1;
+        }
+        this.__callback();
+      },
+
+      // traverse
+      _get_node    : function (obj) {
+        var $obj = $(obj, this.get_container());
+        if($obj.is(".jstree") || obj == -1) { return -1; }
+        $obj = $obj.closest("li", this.get_container());
+        return $obj.length ? $obj : false;
+      },
+      _get_next    : function (obj, strict) {
+        obj = this._get_node(obj);
+        if(obj === -1) { return this.get_container().find("> ul > li:first-child"); }
+        if(!obj.length) { return false; }
+        if(strict) { return (obj.nextAll("li").size() > 0) ? obj.nextAll("li:eq(0)") : false; }
+
+        if(obj.hasClass("jstree-open")) { return obj.find("li:eq(0)"); }
+        else if(obj.nextAll("li").size() > 0) { return obj.nextAll("li:eq(0)"); }
+        else { return obj.parentsUntil(".jstree","li").next("li").eq(0); }
+      },
+      _get_prev    : function (obj, strict) {
+        obj = this._get_node(obj);
+        if(obj === -1) { return this.get_container().find("> ul > li:last-child"); }
+        if(!obj.length) { return false; }
+        if(strict) { return (obj.prevAll("li").length > 0) ? obj.prevAll("li:eq(0)") : false; }
+
+        if(obj.prev("li").length) {
+          obj = obj.prev("li").eq(0);
+          while(obj.hasClass("jstree-open")) { obj = obj.children("ul:eq(0)").children("li:last"); }
+          return obj;
+        }
+        else { var o = obj.parentsUntil(".jstree","li:eq(0)"); return o.length ? o : false; }
+      },
+      _get_parent    : function (obj) {
+        obj = this._get_node(obj);
+        if(obj == -1 || !obj.length) { return false; }
+        var o = obj.parentsUntil(".jstree", "li:eq(0)");
+        return o.length ? o : -1;
+      },
+      _get_children  : function (obj) {
+        obj = this._get_node(obj);
+        if(obj === -1) { return this.get_container().children("ul:eq(0)").children("li"); }
+        if(!obj.length) { return false; }
+        return obj.children("ul:eq(0)").children("li");
+      },
+      get_path    : function (obj, id_mode) {
+        var p = [],
+          _this = this;
+        obj = this._get_node(obj);
+        if(obj === -1 || !obj || !obj.length) { return false; }
+        obj.parentsUntil(".jstree", "li").each(function () {
+          p.push( id_mode ? this.id : _this.get_text(this) );
+        });
+        p.reverse();
+        p.push( id_mode ? obj.attr("id") : this.get_text(obj) );
+        return p;
+      },
+
+      // string functions
+      _get_string : function (key) {
+        return this._get_settings().core.strings[key] || key;
+      },
+
+      is_open    : function (obj) { obj = this._get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-open"); },
+      is_closed  : function (obj) { obj = this._get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-closed"); },
+      is_leaf    : function (obj) { obj = this._get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-leaf"); },
+      correct_state  : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj || obj === -1) { return false; }
+        obj.removeClass("jstree-closed jstree-open").addClass("jstree-leaf").children("ul").remove();
+        this.__callback({ "obj" : obj });
+      },
+      // open/close
+      open_node  : function (obj, callback, skip_animation) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        if(!obj.hasClass("jstree-closed")) { if(callback) { callback.call(); } return false; }
+        var s = skip_animation || is_ie6 ? 0 : this._get_settings().core.animation,
+          t = this;
+        if(!this._is_loaded(obj)) {
+          obj.children("a").addClass("jstree-loading");
+          this.load_node(obj, function () { t.open_node(obj, callback, skip_animation); }, callback);
+        }
+        else {
+          if(this._get_settings().core.open_parents) {
+            obj.parentsUntil(".jstree",".jstree-closed").each(function () {
+              t.open_node(this, false, true);
+            });
+          }
+          if(s) { obj.children("ul").css("display","none"); }
+          obj.removeClass("jstree-closed").addClass("jstree-open").children("a").removeClass("jstree-loading");
+          if(s) { obj.children("ul").stop(true, true).slideDown(s, function () { this.style.display = ""; t.after_open(obj); }); }
+          else { t.after_open(obj); }
+          this.__callback({ "obj" : obj });
+          if(callback) { callback.call(); }
+        }
+      },
+      after_open  : function (obj) { this.__callback({ "obj" : obj }); },
+      close_node  : function (obj, skip_animation) {
+        obj = this._get_node(obj);
+        var s = skip_animation || is_ie6 ? 0 : this._get_settings().core.animation,
+          t = this;
+        if(!obj.length || !obj.hasClass("jstree-open")) { return false; }
+        if(s) { obj.children("ul").attr("style","display:block !important"); }
+        obj.removeClass("jstree-open").addClass("jstree-closed");
+        if(s) { obj.children("ul").stop(true, true).slideUp(s, function () { this.style.display = ""; t.after_close(obj); }); }
+        else { t.after_close(obj); }
+        this.__callback({ "obj" : obj });
+      },
+      after_close  : function (obj) { this.__callback({ "obj" : obj }); },
+      toggle_node  : function (obj) {
+        obj = this._get_node(obj);
+        if(obj.hasClass("jstree-closed")) { return this.open_node(obj); }
+        if(obj.hasClass("jstree-open")) { return this.close_node(obj); }
+      },
+      open_all  : function (obj, do_animation, original_obj) {
+        obj = obj ? this._get_node(obj) : -1;
+        if(!obj || obj === -1) { obj = this.get_container_ul(); }
+        if(original_obj) {
+          obj = obj.find("li.jstree-closed");
+        }
+        else {
+          original_obj = obj;
+          if(obj.is(".jstree-closed")) { obj = obj.find("li.jstree-closed").andSelf(); }
+          else { obj = obj.find("li.jstree-closed"); }
+        }
+        var _this = this;
+        obj.each(function () {
+          var __this = this;
+          if(!_this._is_loaded(this)) { _this.open_node(this, function() { _this.open_all(__this, do_animation, original_obj); }, !do_animation); }
+          else { _this.open_node(this, false, !do_animation); }
+        });
+        // so that callback is fired AFTER all nodes are open
+        if(original_obj.find('li.jstree-closed').length === 0) { this.__callback({ "obj" : original_obj }); }
+      },
+      close_all  : function (obj, do_animation) {
+        var _this = this;
+        obj = obj ? this._get_node(obj) : this.get_container();
+        if(!obj || obj === -1) { obj = this.get_container_ul(); }
+        obj.find("li.jstree-open").andSelf().each(function () { _this.close_node(this, !do_animation); });
+        this.__callback({ "obj" : obj });
+      },
+      clean_node  : function (obj) {
+        obj = obj && obj != -1 ? $(obj) : this.get_container_ul();
+        obj = obj.is("li") ? obj.find("li").andSelf() : obj.find("li");
+        obj.removeClass("jstree-last")
+          .filter("li:last-child").addClass("jstree-last").end()
+          .filter(":has(li)")
+            .not(".jstree-open").removeClass("jstree-leaf").addClass("jstree-closed");
+        obj.not(".jstree-open, .jstree-closed").addClass("jstree-leaf").children("ul").remove();
+        this.__callback({ "obj" : obj });
+      },
+      // rollback
+      get_rollback : function () {
+        this.__callback();
+        return { i : this.get_index(), h : this.get_container().children("ul").clone(true), d : this.data };
+      },
+      set_rollback : function (html, data) {
+        this.get_container().empty().append(html);
+        this.data = data;
+        this.__callback();
+      },
+      // Dummy functions to be overwritten by any datastore plugin included
+      load_node  : function (obj, s_call, e_call) { this.__callback({ "obj" : obj }); },
+      _is_loaded  : function (obj) { return true; },
+
+      // Basic operations: create
+      create_node  : function (obj, position, js, callback, is_loaded) {
+        obj = this._get_node(obj);
+        position = typeof position === "undefined" ? "last" : position;
+        var d = $("<li />"),
+          s = this._get_settings().core,
+          tmp;
+
+        if(obj !== -1 && !obj.length) { return false; }
+        if(!is_loaded && !this._is_loaded(obj)) { this.load_node(obj, function () { this.create_node(obj, position, js, callback, true); }); return false; }
+
+        this.__rollback();
+
+        if(typeof js === "string") { js = { "data" : js }; }
+        if(!js) { js = {}; }
+        if(js.attr) { d.attr(js.attr); }
+        if(js.metadata) { d.data(js.metadata); }
+        if(js.state) { d.addClass("jstree-" + js.state); }
+        if(!js.data) { js.data = this._get_string("new_node"); }
+        if(!$.isArray(js.data)) { tmp = js.data; js.data = []; js.data.push(tmp); }
+        $.each(js.data, function (i, m) {
+          tmp = $("<a />");
+          if($.isFunction(m)) { m = m.call(this, js); }
+          if(typeof m == "string") { tmp.attr('href','#')[ s.html_titles ? "html" : "text" ](m); }
+          else {
+            if(!m.attr) { m.attr = {}; }
+            if(!m.attr.href) { m.attr.href = '#'; }
+            tmp.attr(m.attr)[ s.html_titles ? "html" : "text" ](m.title);
+            if(m.language) { tmp.addClass(m.language); }
+          }
+          tmp.prepend("<ins class='jstree-icon'>&#160;</ins>");
+          if(m.icon) {
+            if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); }
+            else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); }
+          }
+          d.append(tmp);
+        });
+        d.prepend("<ins class='jstree-icon'>&#160;</ins>");
+        if(obj === -1) {
+          obj = this.get_container();
+          if(position === "before") { position = "first"; }
+          if(position === "after") { position = "last"; }
+        }
+        switch(position) {
+          case "before": obj.before(d); tmp = this._get_parent(obj); break;
+          case "after" : obj.after(d);  tmp = this._get_parent(obj); break;
+          case "inside":
+          case "first" :
+            if(!obj.children("ul").length) { obj.append("<ul />"); }
+            obj.children("ul").prepend(d);
+            tmp = obj;
+            break;
+          case "last":
+            if(!obj.children("ul").length) { obj.append("<ul />"); }
+            obj.children("ul").append(d);
+            tmp = obj;
+            break;
+          default:
+            if(!obj.children("ul").length) { obj.append("<ul />"); }
+            if(!position) { position = 0; }
+            tmp = obj.children("ul").children("li").eq(position);
+            if(tmp.length) { tmp.before(d); }
+            else { obj.children("ul").append(d); }
+            tmp = obj;
+            break;
+        }
+        if(tmp === -1 || tmp.get(0) === this.get_container().get(0)) { tmp = -1; }
+        this.clean_node(tmp);
+        this.__callback({ "obj" : d, "parent" : tmp });
+        if(callback) { callback.call(this, d); }
+        return d;
+      },
+      // Basic operations: rename (deal with text)
+      get_text  : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        var s = this._get_settings().core.html_titles;
+        obj = obj.children("a:eq(0)");
+        if(s) {
+          obj = obj.clone();
+          obj.children("INS").remove();
+          return obj.html();
+        }
+        else {
+          obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
+          return obj.nodeValue;
+        }
+      },
+      set_text  : function (obj, val) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        obj = obj.children("a:eq(0)");
+        if(this._get_settings().core.html_titles) {
+          var tmp = obj.children("INS").clone();
+          obj.html(val).prepend(tmp);
+          this.__callback({ "obj" : obj, "name" : val });
+          return true;
+        }
+        else {
+          obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
+          this.__callback({ "obj" : obj, "name" : val });
+          return (obj.nodeValue = val);
+        }
+      },
+      rename_node : function (obj, val) {
+        obj = this._get_node(obj);
+        this.__rollback();
+        if(obj && obj.length && this.set_text.apply(this, Array.prototype.slice.call(arguments))) { this.__callback({ "obj" : obj, "name" : val }); }
+      },
+      // Basic operations: deleting nodes
+      delete_node : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        this.__rollback();
+        var p = this._get_parent(obj), prev = $([]), t = this;
+        obj.each(function () {
+          prev = prev.add(t._get_prev(this));
+        });
+        obj = obj.detach();
+        if(p !== -1 && p.find("> ul > li").length === 0) {
+          p.removeClass("jstree-open jstree-closed").addClass("jstree-leaf");
+        }
+        this.clean_node(p);
+        this.__callback({ "obj" : obj, "prev" : prev, "parent" : p });
+        return obj;
+      },
+      prepare_move : function (o, r, pos, cb, is_cb) {
+        var p = {};
+
+        p.ot = $.jstree._reference(o) || this;
+        p.o = p.ot._get_node(o);
+        p.r = r === - 1 ? -1 : this._get_node(r);
+        p.p = (typeof pos === "undefined" || pos === false) ? "last" : pos; // TODO: move to a setting
+        if(!is_cb && prepared_move.o && prepared_move.o[0] === p.o[0] && prepared_move.r[0] === p.r[0] && prepared_move.p === p.p) {
+          this.__callback(prepared_move);
+          if(cb) { cb.call(this, prepared_move); }
+          return;
+        }
+        p.ot = $.jstree._reference(p.o) || this;
+        p.rt = $.jstree._reference(p.r) || this; // r === -1 ? p.ot : $.jstree._reference(p.r) || this
+        if(p.r === -1 || !p.r) {
+          p.cr = -1;
+          switch(p.p) {
+            case "first":
+            case "before":
+            case "inside":
+              p.cp = 0;
+              break;
+            case "after":
+            case "last":
+              p.cp = p.rt.get_container().find(" > ul > li").length;
+              break;
+            default:
+              p.cp = p.p;
+              break;
+          }
+        }
+        else {
+          if(!/^(before|after)$/.test(p.p) && !this._is_loaded(p.r)) {
+            return this.load_node(p.r, function () { this.prepare_move(o, r, pos, cb, true); });
+          }
+          switch(p.p) {
+            case "before":
+              p.cp = p.r.index();
+              p.cr = p.rt._get_parent(p.r);
+              break;
+            case "after":
+              p.cp = p.r.index() + 1;
+              p.cr = p.rt._get_parent(p.r);
+              break;
+            case "inside":
+            case "first":
+              p.cp = 0;
+              p.cr = p.r;
+              break;
+            case "last":
+              p.cp = p.r.find(" > ul > li").length;
+              p.cr = p.r;
+              break;
+            default:
+              p.cp = p.p;
+              p.cr = p.r;
+              break;
+          }
+        }
+        p.np = p.cr == -1 ? p.rt.get_container() : p.cr;
+        p.op = p.ot._get_parent(p.o);
+        p.cop = p.o.index();
+        if(p.op === -1) { p.op = p.ot ? p.ot.get_container() : this.get_container(); }
+        if(!/^(before|after)$/.test(p.p) && p.op && p.np && p.op[0] === p.np[0] && p.o.index() < p.cp) { p.cp++; }
+        //if(p.p === "before" && p.op && p.np && p.op[0] === p.np[0] && p.o.index() < p.cp) { p.cp--; }
+        p.or = p.np.find(" > ul > li:nth-child(" + (p.cp + 1) + ")");
+        prepared_move = p;
+        this.__callback(prepared_move);
+        if(cb) { cb.call(this, prepared_move); }
+      },
+      check_move : function () {
+        var obj = prepared_move, ret = true, r = obj.r === -1 ? this.get_container() : obj.r;
+        if(!obj || !obj.o || obj.or[0] === obj.o[0]) { return false; }
+        if(obj.op && obj.np && obj.op[0] === obj.np[0] && obj.cp - 1 === obj.o.index()) { return false; }
+        obj.o.each(function () {
+          if(r.parentsUntil(".jstree", "li").andSelf().index(this) !== -1) { ret = false; return false; }
+        });
+        return ret;
+      },
+      move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) {
+        if(!is_prepared) {
+          return this.prepare_move(obj, ref, position, function (p) {
+            this.move_node(p, false, false, is_copy, true, skip_check);
+          });
+        }
+        if(is_copy) {
+          prepared_move.cy = true;
+        }
+        if(!skip_check && !this.check_move()) { return false; }
+
+        this.__rollback();
+        var o = false;
+        if(is_copy) {
+          o = obj.o.clone(true);
+          o.find("*[id]").andSelf().each(function () {
+            if(this.id) { this.id = "copy_" + this.id; }
+          });
+        }
+        else { o = obj.o; }
+
+        if(obj.or.length) { obj.or.before(o); }
+        else {
+          if(!obj.np.children("ul").length) { $("<ul />").appendTo(obj.np); }
+          obj.np.children("ul:eq(0)").append(o);
+        }
+
+        try {
+          obj.ot.clean_node(obj.op);
+          obj.rt.clean_node(obj.np);
+          if(!obj.op.find("> ul > li").length) {
+            obj.op.removeClass("jstree-open jstree-closed").addClass("jstree-leaf").children("ul").remove();
+          }
+        } catch (e) { }
+
+        if(is_copy) {
+          prepared_move.cy = true;
+          prepared_move.oc = o;
+        }
+        this.__callback(prepared_move);
+        return prepared_move;
+      },
+      _get_move : function () { return prepared_move; }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree ui plugin
+ * This plugins handles selecting/deselecting/hovering/dehovering nodes
+ */
+(function ($) {
+  var scrollbar_width, e1, e2;
+  $(function() {
+    if (/msie/.test(navigator.userAgent.toLowerCase())) {
+      e1 = $('<textarea cols="10" rows="2"></textarea>').css({ position: 'absolute', top: -1000, left: 0 }).appendTo('body');
+      e2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>').css({ position: 'absolute', top: -1000, left: 0 }).appendTo('body');
+      scrollbar_width = e1.width() - e2.width();
+      e1.add(e2).remove();
+    }
+    else {
+      e1 = $('<div />').css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: 0 })
+          .prependTo('body').append('<div />').find('div').css({ width: '100%', height: 200 });
+      scrollbar_width = 100 - e1.width();
+      e1.parent().remove();
+    }
+  });
+  $.jstree.plugin("ui", {
+    __init : function () {
+      this.data.ui.selected = $();
+      this.data.ui.last_selected = false;
+      this.data.ui.hovered = null;
+      this.data.ui.to_select = this.get_settings().ui.initially_select;
+
+      this.get_container()
+        .delegate("a", "click.jstree", $.proxy(function (event) {
+            event.preventDefault();
+            event.currentTarget.blur();
+            if(!$(event.currentTarget).hasClass("jstree-loading")) {
+              this.select_node(event.currentTarget, true, event);
+            }
+          }, this))
+        .delegate("a", "mouseenter.jstree", $.proxy(function (event) {
+            if(!$(event.currentTarget).hasClass("jstree-loading")) {
+              this.hover_node(event.target);
+            }
+          }, this))
+        .delegate("a", "mouseleave.jstree", $.proxy(function (event) {
+            if(!$(event.currentTarget).hasClass("jstree-loading")) {
+              this.dehover_node(event.target);
+            }
+          }, this))
+        .bind("reopen.jstree", $.proxy(function () {
+            this.reselect();
+          }, this))
+        .bind("get_rollback.jstree", $.proxy(function () {
+            this.dehover_node();
+            this.save_selected();
+          }, this))
+        .bind("set_rollback.jstree", $.proxy(function () {
+            this.reselect();
+          }, this))
+        .bind("close_node.jstree", $.proxy(function (event, data) {
+            var s = this._get_settings().ui,
+              obj = this._get_node(data.rslt.obj),
+              clk = (obj && obj.length) ? obj.children("ul").find("a.jstree-clicked") : $(),
+              _this = this;
+            if(s.selected_parent_close === false || !clk.length) { return; }
+            clk.each(function () {
+              _this.deselect_node(this);
+              if(s.selected_parent_close === "select_parent") { _this.select_node(obj); }
+            });
+          }, this))
+        .bind("delete_node.jstree", $.proxy(function (event, data) {
+            var s = this._get_settings().ui.select_prev_on_delete,
+              obj = this._get_node(data.rslt.obj),
+              clk = (obj && obj.length) ? obj.find("a.jstree-clicked") : [],
+              _this = this;
+            clk.each(function () { _this.deselect_node(this); });
+            if(s && clk.length) {
+              data.rslt.prev.each(function () {
+                if(this.parentNode) { _this.select_node(this); return false; /* if return false is removed all prev nodes will be selected */}
+              });
+            }
+          }, this))
+        .bind("move_node.jstree", $.proxy(function (event, data) {
+            if(data.rslt.cy) {
+              data.rslt.oc.find("a.jstree-clicked").removeClass("jstree-clicked");
+            }
+          }, this));
+    },
+    defaults : {
+      select_limit : -1, // 0, 1, 2 ... or -1 for unlimited
+      select_multiple_modifier : "ctrl", // on, or ctrl, shift, alt
+      select_range_modifier : "shift",
+      selected_parent_close : "select_parent", // false, "deselect", "select_parent"
+      selected_parent_open : true,
+      select_prev_on_delete : true,
+      disable_selecting_children : false,
+      initially_select : []
+    },
+    _fn : {
+      _get_node : function (obj, allow_multiple) {
+        if(typeof obj === "undefined" || obj === null) { return allow_multiple ? this.data.ui.selected : this.data.ui.last_selected; }
+        var $obj = $(obj, this.get_container());
+        if($obj.is(".jstree") || obj == -1) { return -1; }
+        $obj = $obj.closest("li", this.get_container());
+        return $obj.length ? $obj : false;
+      },
+      _ui_notify : function (n, data) {
+        if(data.selected) {
+          this.select_node(n, false);
+        }
+      },
+      save_selected : function () {
+        var _this = this;
+        this.data.ui.to_select = [];
+        this.data.ui.selected.each(function () { if(this.id) { _this.data.ui.to_select.push("#" + this.id.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:")); } });
+        this.__callback(this.data.ui.to_select);
+      },
+      reselect : function () {
+        var _this = this,
+          s = this.data.ui.to_select;
+        s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
+        // this.deselect_all(); WHY deselect, breaks plugin state notifier?
+        $.each(s, function (i, val) { if(val && val !== "#") { _this.select_node(val); } });
+        this.data.ui.selected = this.data.ui.selected.filter(function () { return this.parentNode; });
+        this.__callback();
+      },
+      refresh : function (obj) {
+        this.save_selected();
+        return this.__call_old();
+      },
+      hover_node : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        //if(this.data.ui.hovered && obj.get(0) === this.data.ui.hovered.get(0)) { return; }
+        if(!obj.hasClass("jstree-hovered")) { this.dehover_node(); }
+        this.data.ui.hovered = obj.children("a").addClass("jstree-hovered").parent();
+        this._fix_scroll(obj);
+        this.__callback({ "obj" : obj });
+      },
+      dehover_node : function () {
+        var obj = this.data.ui.hovered, p;
+        if(!obj || !obj.length) { return false; }
+        p = obj.children("a").removeClass("jstree-hovered").parent();
+        if(this.data.ui.hovered[0] === p[0]) { this.data.ui.hovered = null; }
+        this.__callback({ "obj" : obj });
+      },
+      select_node : function (obj, check, e) {
+        obj = this._get_node(obj);
+        if(obj == -1 || !obj || !obj.length) { return false; }
+        var s = this._get_settings().ui,
+          is_multiple = (s.select_multiple_modifier == "on" || (s.select_multiple_modifier !== false && e && e[s.select_multiple_modifier + "Key"])),
+          is_range = (s.select_range_modifier !== false && e && e[s.select_range_modifier + "Key"] && this.data.ui.last_selected && this.data.ui.last_selected[0] !== obj[0] && this.data.ui.last_selected.parent()[0] === obj.parent()[0]),
+          is_selected = this.is_selected(obj),
+          proceed = true,
+          t = this;
+        if(check) {
+          if(s.disable_selecting_children && is_multiple &&
+            (
+              (obj.parentsUntil(".jstree","li").children("a.jstree-clicked").length) ||
+              (obj.children("ul").find("a.jstree-clicked:eq(0)").length)
+            )
+          ) {
+            return false;
+          }
+          proceed = false;
+          switch(!0) {
+            case (is_range):
+              this.data.ui.last_selected.addClass("jstree-last-selected");
+              obj = obj[ obj.index() < this.data.ui.last_selected.index() ? "nextUntil" : "prevUntil" ](".jstree-last-selected").andSelf();
+              if(s.select_limit == -1 || obj.length < s.select_limit) {
+                this.data.ui.last_selected.removeClass("jstree-last-selected");
+                this.data.ui.selected.each(function () {
+                  if(this !== t.data.ui.last_selected[0]) { t.deselect_node(this); }
+                });
+                is_selected = false;
+                proceed = true;
+              }
+              else {
+                proceed = false;
+              }
+              break;
+            case (is_selected && !is_multiple):
+              this.deselect_all();
+              is_selected = false;
+              proceed = true;
+              break;
+            case (!is_selected && !is_multiple):
+              if(s.select_limit == -1 || s.select_limit > 0) {
+                this.deselect_all();
+                proceed = true;
+              }
+              break;
+            case (is_selected && is_multiple):
+              this.deselect_node(obj);
+              break;
+            case (!is_selected && is_multiple):
+              if(s.select_limit == -1 || this.data.ui.selected.length + 1 <= s.select_limit) {
+                proceed = true;
+              }
+              break;
+          }
+        }
+        if(proceed && !is_selected) {
+          if(!is_range) { this.data.ui.last_selected = obj; }
+          obj.children("a").addClass("jstree-clicked");
+          if(s.selected_parent_open) {
+            obj.parents(".jstree-closed").each(function () { t.open_node(this, false, true); });
+          }
+          this.data.ui.selected = this.data.ui.selected.add(obj);
+          this._fix_scroll(obj.eq(0));
+          this.__callback({ "obj" : obj, "e" : e });
+        }
+      },
+      _fix_scroll : function (obj) {
+        var c = this.get_container()[0], t;
+        if(c.scrollHeight > c.offsetHeight) {
+          obj = this._get_node(obj);
+          if(!obj || obj === -1 || !obj.length || !obj.is(":visible")) { return; }
+          t = obj.offset().top - this.get_container().offset().top;
+          if(t < 0) {
+            c.scrollTop = c.scrollTop + t - 1;
+          }
+          if(t + this.data.core.li_height + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0) > c.offsetHeight) {
+            c.scrollTop = c.scrollTop + (t - c.offsetHeight + this.data.core.li_height + 1 + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0));
+          }
+        }
+      },
+      deselect_node : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        if(this.is_selected(obj)) {
+          obj.children("a").removeClass("jstree-clicked");
+          this.data.ui.selected = this.data.ui.selected.not(obj);
+          if(this.data.ui.last_selected.get(0) === obj.get(0)) { this.data.ui.last_selected = this.data.ui.selected.eq(0); }
+          this.__callback({ "obj" : obj });
+        }
+      },
+      toggle_select : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return false; }
+        if(this.is_selected(obj)) { this.deselect_node(obj); }
+        else { this.select_node(obj); }
+      },
+      is_selected : function (obj) { return this.data.ui.selected.index(this._get_node(obj)) >= 0; },
+      get_selected : function (context) {
+        return context ? $(context).find("a.jstree-clicked").parent() : this.data.ui.selected;
+      },
+      deselect_all : function (context) {
+        var ret = context ? $(context).find("a.jstree-clicked").parent() : this.get_container().find("a.jstree-clicked").parent();
+        ret.children("a.jstree-clicked").removeClass("jstree-clicked");
+        this.data.ui.selected = $([]);
+        this.data.ui.last_selected = false;
+        this.__callback({ "obj" : ret });
+      }
+    }
+  });
+  // include the selection plugin by default
+  $.jstree.defaults.plugins.push("ui");
+})(jQuery);
+//*/
+
+/*
+ * jsTree CRRM plugin
+ * Handles creating/renaming/removing/moving nodes by user interaction.
+ */
+(function ($) {
+  $.jstree.plugin("crrm", {
+    __init : function () {
+      this.get_container()
+        .bind("move_node.jstree", $.proxy(function (e, data) {
+          if(this._get_settings().crrm.move.open_onmove) {
+            var t = this;
+            data.rslt.np.parentsUntil(".jstree").andSelf().filter(".jstree-closed").each(function () {
+              t.open_node(this, false, true);
+            });
+          }
+        }, this));
+    },
+    defaults : {
+      input_width_limit : 200,
+      move : {
+        always_copy      : false, // false, true or "multitree"
+        open_onmove      : true,
+        default_position  : "last",
+        check_move      : function (m) { return true; }
+      }
+    },
+    _fn : {
+      _show_input : function (obj, callback) {
+        obj = this._get_node(obj);
+        var rtl = this._get_settings().core.rtl,
+          w = this._get_settings().crrm.input_width_limit,
+          w1 = obj.children("ins").width(),
+          w2 = obj.find("> a:visible > ins").width() * obj.find("> a:visible > ins").length,
+          t = this.get_text(obj),
+          h1 = $("<div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"),
+          h2 = obj.css("position","relative").append(
+          $("<input />", {
+            "value" : t,
+            "class" : "jstree-rename-input",
+            // "size" : t.length,
+            "css" : {
+              "padding" : "0",
+              "border" : "1px solid silver",
+              "position" : "absolute",
+              "left"  : (rtl ? "auto" : (w1 + w2 + 4) + "px"),
+              "right" : (rtl ? (w1 + w2 + 4) + "px" : "auto"),
+              "top" : "0px",
+              "height" : (this.data.core.li_height - 2) + "px",
+              "lineHeight" : (this.data.core.li_height - 2) + "px",
+              "width" : "150px" // will be set a bit further down
+            },
+            "blur" : $.proxy(function () {
+              var i = obj.children(".jstree-rename-input"),
+                v = i.val();
+              if(v === "") { v = t; }
+              h1.remove();
+              i.remove(); // rollback purposes
+              this.set_text(obj,t); // rollback purposes
+              this.rename_node(obj, v);
+              callback.call(this, obj, v, t);
+              obj.css("position","");
+            }, this),
+            "keyup" : function (event) {
+              var key = event.keyCode || event.which;
+              if(key == 27) { this.value = t; this.blur(); return; }
+              else if(key == 13) { this.blur(); return; }
+              else {
+                h2.width(Math.min(h1.text("pW" + this.value).width(),w));
+              }
+            },
+            "keypress" : function(event) {
+              var key = event.keyCode || event.which;
+              if(key == 13) { return false; }
+            }
+          })
+        ).children(".jstree-rename-input");
+        this.set_text(obj, "");
+        h1.css({
+            fontFamily    : h2.css('fontFamily')    || '',
+            fontSize    : h2.css('fontSize')    || '',
+            fontWeight    : h2.css('fontWeight')    || '',
+            fontStyle    : h2.css('fontStyle')    || '',
+            fontStretch    : h2.css('fontStretch')    || '',
+            fontVariant    : h2.css('fontVariant')    || '',
+            letterSpacing  : h2.css('letterSpacing')  || '',
+            wordSpacing    : h2.css('wordSpacing')    || ''
+        });
+        h2.width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
+      },
+      rename : function (obj) {
+        obj = this._get_node(obj);
+        this.__rollback();
+        var f = this.__callback;
+        this._show_input(obj, function (obj, new_name, old_name) {
+          f.call(this, { "obj" : obj, "new_name" : new_name, "old_name" : old_name });
+        });
+      },
+      create : function (obj, position, js, callback, skip_rename) {
+        var t, _this = this;
+        obj = this._get_node(obj);
+        if(!obj) { obj = -1; }
+        this.__rollback();
+        t = this.create_node(obj, position, js, function (t) {
+          var p = this._get_parent(t),
+            pos = $(t).index();
+          if(callback) { callback.call(this, t); }
+          if(p.length && p.hasClass("jstree-closed")) { this.open_node(p, false, true); }
+          if(!skip_rename) {
+            this._show_input(t, function (obj, new_name, old_name) {
+              _this.__callback({ "obj" : obj, "name" : new_name, "parent" : p, "position" : pos });
+            });
+          }
+          else { _this.__callback({ "obj" : t, "name" : this.get_text(t), "parent" : p, "position" : pos }); }
+        });
+        return t;
+      },
+      remove : function (obj) {
+        obj = this._get_node(obj, true);
+        var p = this._get_parent(obj), prev = this._get_prev(obj);
+        this.__rollback();
+        obj = this.delete_node(obj);
+        if(obj !== false) { this.__callback({ "obj" : obj, "prev" : prev, "parent" : p }); }
+      },
+      check_move : function () {
+        if(!this.__call_old()) { return false; }
+        var s = this._get_settings().crrm.move;
+        if(!s.check_move.call(this, this._get_move())) { return false; }
+        return true;
+      },
+      move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) {
+        var s = this._get_settings().crrm.move;
+        if(!is_prepared) {
+          if(typeof position === "undefined") { position = s.default_position; }
+          if(position === "inside" && !s.default_position.match(/^(before|after)$/)) { position = s.default_position; }
+          return this.__call_old(true, obj, ref, position, is_copy, false, skip_check);
+        }
+        // if the move is already prepared
+        if(s.always_copy === true || (s.always_copy === "multitree" && obj.rt.get_index() !== obj.ot.get_index() )) {
+          is_copy = true;
+        }
+        this.__call_old(true, obj, ref, position, is_copy, true, skip_check);
+      },
+
+      cut : function (obj) {
+        obj = this._get_node(obj, true);
+        if(!obj || !obj.length) { return false; }
+        this.data.crrm.cp_nodes = false;
+        this.data.crrm.ct_nodes = obj;
+        this.__callback({ "obj" : obj });
+      },
+      copy : function (obj) {
+        obj = this._get_node(obj, true);
+        if(!obj || !obj.length) { return false; }
+        this.data.crrm.ct_nodes = false;
+        this.data.crrm.cp_nodes = obj;
+        this.__callback({ "obj" : obj });
+      },
+      paste : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj || !obj.length) { return false; }
+        var nodes = this.data.crrm.ct_nodes ? this.data.crrm.ct_nodes : this.data.crrm.cp_nodes;
+        if(!this.data.crrm.ct_nodes && !this.data.crrm.cp_nodes) { return false; }
+        if(this.data.crrm.ct_nodes) { this.move_node(this.data.crrm.ct_nodes, obj); this.data.crrm.ct_nodes = false; }
+        if(this.data.crrm.cp_nodes) { this.move_node(this.data.crrm.cp_nodes, obj, false, true); }
+        this.__callback({ "obj" : obj, "nodes" : nodes });
+      }
+    }
+  });
+  // include the crr plugin by default
+  // $.jstree.defaults.plugins.push("crrm");
+})(jQuery);
+//*/
+
+/*
+ * jsTree themes plugin
+ * Handles loading and setting themes, as well as detecting path to themes, etc.
+ */
+(function ($) {
+  var themes_loaded = [];
+  // this variable stores the path to the themes folder - if left as false - it will be autodetected
+  $.jstree._themes = false;
+  $.jstree.plugin("themes", {
+    __init : function () {
+      this.get_container()
+        .bind("init.jstree", $.proxy(function () {
+            var s = this._get_settings().themes;
+            this.data.themes.dots = s.dots;
+            this.data.themes.icons = s.icons;
+            this.set_theme(s.theme, s.url);
+          }, this))
+        .bind("loaded.jstree", $.proxy(function () {
+            // bound here too, as simple HTML tree's won't honor dots & icons otherwise
+            if(!this.data.themes.dots) { this.hide_dots(); }
+            else { this.show_dots(); }
+            if(!this.data.themes.icons) { this.hide_icons(); }
+            else { this.show_icons(); }
+          }, this));
+    },
+    defaults : {
+      theme : "default",
+      url : false,
+      dots : true,
+      icons : true
+    },
+    _fn : {
+      set_theme : function (theme_name, theme_url) {
+        if(!theme_name) { return false; }
+        if(!theme_url) { theme_url = $.jstree._themes + theme_name + '/style.css'; }
+        if($.inArray(theme_url, themes_loaded) == -1) {
+          $.vakata.css.add_sheet({ "url" : theme_url });
+          themes_loaded.push(theme_url);
+        }
+        if(this.data.themes.theme != theme_name) {
+          this.get_container().removeClass('jstree-' + this.data.themes.theme);
+          this.data.themes.theme = theme_name;
+        }
+        this.get_container().addClass('jstree-' + theme_name);
+        if(!this.data.themes.dots) { this.hide_dots(); }
+        else { this.show_dots(); }
+        if(!this.data.themes.icons) { this.hide_icons(); }
+        else { this.show_icons(); }
+        this.__callback();
+      },
+      get_theme  : function () { return this.data.themes.theme; },
+
+      show_dots  : function () { this.data.themes.dots = true; this.get_container().children("ul").removeClass("jstree-no-dots"); },
+      hide_dots  : function () { this.data.themes.dots = false; this.get_container().children("ul").addClass("jstree-no-dots"); },
+      toggle_dots  : function () { if(this.data.themes.dots) { this.hide_dots(); } else { this.show_dots(); } },
+
+      show_icons  : function () { this.data.themes.icons = true; this.get_container().children("ul").removeClass("jstree-no-icons"); },
+      hide_icons  : function () { this.data.themes.icons = false; this.get_container().children("ul").addClass("jstree-no-icons"); },
+      toggle_icons: function () { if(this.data.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }
+    }
+  });
+  // autodetect themes path
+  $(function () {
+    if($.jstree._themes === false) {
+      $("script").each(function () {
+        if(this.src.toString().match(/jquery\.jstree[^\/]*?\.js(\?.*)?$/)) {
+          $.jstree._themes = this.src.toString().replace(/jquery\.jstree[^\/]*?\.js(\?.*)?$/, "") + 'themes/';
+          return false;
+        }
+      });
+    }
+    if($.jstree._themes === false) { $.jstree._themes = "themes/"; }
+  });
+  // include the themes plugin by default
+  $.jstree.defaults.plugins.push("themes");
+})(jQuery);
+//*/
+
+/*
+ * jsTree hotkeys plugin
+ * Enables keyboard navigation for all tree instances
+ * Depends on the jstree ui & jquery hotkeys plugins
+ */
+(function ($) {
+  var bound = [];
+  function exec(i, event) {
+    var f = $.jstree._focused(), tmp;
+    if(f && f.data && f.data.hotkeys && f.data.hotkeys.enabled) {
+      tmp = f._get_settings().hotkeys[i];
+      if(tmp) { return tmp.call(f, event); }
+    }
+  }
+  $.jstree.plugin("hotkeys", {
+    __init : function () {
+      if(typeof $.hotkeys === "undefined") { throw "jsTree hotkeys: jQuery hotkeys plugin not included."; }
+      if(!this.data.ui) { throw "jsTree hotkeys: jsTree UI plugin not included."; }
+      $.each(this._get_settings().hotkeys, function (i, v) {
+        if(v !== false && $.inArray(i, bound) == -1) {
+          $(document).bind("keydown", i, function (event) { return exec(i, event); });
+          bound.push(i);
+        }
+      });
+      this.get_container()
+        .bind("lock.jstree", $.proxy(function () {
+            if(this.data.hotkeys.enabled) { this.data.hotkeys.enabled = false; this.data.hotkeys.revert = true; }
+          }, this))
+        .bind("unlock.jstree", $.proxy(function () {
+            if(this.data.hotkeys.revert) { this.data.hotkeys.enabled = true; }
+          }, this));
+      this.enable_hotkeys();
+    },
+    defaults : {
+      "up" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+        this.hover_node(this._get_prev(o));
+        return false;
+      },
+      "ctrl+up" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+        this.hover_node(this._get_prev(o));
+        return false;
+      },
+      "shift+up" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+        this.hover_node(this._get_prev(o));
+        return false;
+      },
+      "down" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+        this.hover_node(this._get_next(o));
+        return false;
+      },
+      "ctrl+down" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+        this.hover_node(this._get_next(o));
+        return false;
+      },
+      "shift+down" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+        this.hover_node(this._get_next(o));
+        return false;
+      },
+      "left" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected;
+        if(o) {
+          if(o.hasClass("jstree-open")) { this.close_node(o); }
+          else { this.hover_node(this._get_prev(o)); }
+        }
+        return false;
+      },
+      "ctrl+left" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected;
+        if(o) {
+          if(o.hasClass("jstree-open")) { this.close_node(o); }
+          else { this.hover_node(this._get_prev(o)); }
+        }
+        return false;
+      },
+      "shift+left" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected;
+        if(o) {
+          if(o.hasClass("jstree-open")) { this.close_node(o); }
+          else { this.hover_node(this._get_prev(o)); }
+        }
+        return false;
+      },
+      "right" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected;
+        if(o && o.length) {
+          if(o.hasClass("jstree-closed")) { this.open_node(o); }
+          else { this.hover_node(this._get_next(o)); }
+        }
+        return false;
+      },
+      "ctrl+right" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected;
+        if(o && o.length) {
+          if(o.hasClass("jstree-closed")) { this.open_node(o); }
+          else { this.hover_node(this._get_next(o)); }
+        }
+        return false;
+      },
+      "shift+right" : function () {
+        var o = this.data.ui.hovered || this.data.ui.last_selected;
+        if(o && o.length) {
+          if(o.hasClass("jstree-closed")) { this.open_node(o); }
+          else { this.hover_node(this._get_next(o)); }
+        }
+        return false;
+      },
+      "space" : function () {
+        if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").click(); }
+        return false;
+      },
+      "ctrl+space" : function (event) {
+        event.type = "click";
+        if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); }
+        return false;
+      },
+      "shift+space" : function (event) {
+        event.type = "click";
+        if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); }
+        return false;
+      },
+      "f2" : function () { this.rename(this.data.ui.hovered || this.data.ui.last_selected); },
+      "del" : function () { this.remove(this.data.ui.hovered || this._get_node(null)); }
+    },
+    _fn : {
+      enable_hotkeys : function () {
+        this.data.hotkeys.enabled = true;
+      },
+      disable_hotkeys : function () {
+        this.data.hotkeys.enabled = false;
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree JSON plugin
+ * The JSON data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions.
+ */
+(function ($) {
+  $.jstree.plugin("json_data", {
+    __init : function() {
+      var s = this._get_settings().json_data;
+      if(s.progressive_unload) {
+        this.get_container().bind("after_close.jstree", function (e, data) {
+          data.rslt.obj.children("ul").remove();
+        });
+      }
+    },
+    defaults : {
+      // `data` can be a function:
+      //  * accepts two arguments - node being loaded and a callback to pass the result to
+      //  * will be executed in the current tree's scope & ajax won't be supported
+      data : false,
+      ajax : false,
+      correct_state : true,
+      progressive_render : false,
+      progressive_unload : false
+    },
+    _fn : {
+      load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_json(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
+      _is_loaded : function (obj) {
+        var s = this._get_settings().json_data;
+        obj = this._get_node(obj);
+        return obj == -1 || !obj || (!s.ajax && !s.progressive_render && !$.isFunction(s.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").length > 0;
+      },
+      refresh : function (obj) {
+        obj = this._get_node(obj);
+        var s = this._get_settings().json_data;
+        if(obj && obj !== -1 && s.progressive_unload && ($.isFunction(s.data) || !!s.ajax)) {
+          obj.removeData("jstree-children");
+        }
+        return this.__call_old();
+      },
+      load_node_json : function (obj, s_call, e_call) {
+        var s = this.get_settings().json_data, d,
+          error_func = function () {},
+          success_func = function () {};
+        obj = this._get_node(obj);
+
+        if(obj && obj !== -1 && (s.progressive_render || s.progressive_unload) && !obj.is(".jstree-open, .jstree-leaf") && obj.children("ul").children("li").length === 0 && obj.data("jstree-children")) {
+          d = this._parse_json(obj.data("jstree-children"), obj);
+          if(d) {
+            obj.append(d);
+            if(!s.progressive_unload) { obj.removeData("jstree-children"); }
+          }
+          this.clean_node(obj);
+          if(s_call) { s_call.call(this); }
+          return;
+        }
+
+        if(obj && obj !== -1) {
+          if(obj.data("jstree-is-loading")) { return; }
+          else { obj.data("jstree-is-loading",true); }
+        }
+        switch(!0) {
+          case (!s.data && !s.ajax): throw "Neither data nor ajax settings supplied.";
+          // function option added here for easier model integration (also supporting async - see callback)
+          case ($.isFunction(s.data)):
+            s.data.call(this, obj, $.proxy(function (d) {
+              d = this._parse_json(d, obj);
+              if(!d) {
+                if(obj === -1 || !obj) {
+                  if(s.correct_state) { this.get_container().children("ul").empty(); }
+                }
+                else {
+                  obj.children("a.jstree-loading").removeClass("jstree-loading");
+                  obj.removeData("jstree-is-loading");
+                  if(s.correct_state) { this.correct_state(obj); }
+                }
+                if(e_call) { e_call.call(this); }
+              }
+              else {
+                if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); }
+                else { obj.append(d).children("a.jstree-loading").removeClass("jstree-loading"); obj.removeData("jstree-is-loading"); }
+                this.clean_node(obj);
+                if(s_call) { s_call.call(this); }
+              }
+            }, this));
+            break;
+          case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)):
+            if(!obj || obj == -1) {
+              d = this._parse_json(s.data, obj);
+              if(d) {
+                this.get_container().children("ul").empty().append(d.children());
+                this.clean_node();
+              }
+              else {
+                if(s.correct_state) { this.get_container().children("ul").empty(); }
+              }
+            }
+            if(s_call) { s_call.call(this); }
+            break;
+          case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
+            error_func = function (x, t, e) {
+              var ef = this.get_settings().json_data.ajax.error;
+              if(ef) { ef.call(this, x, t, e); }
+              if(obj != -1 && obj.length) {
+                obj.children("a.jstree-loading").removeClass("jstree-loading");
+                obj.removeData("jstree-is-loading");
+                if(t === "success" && s.correct_state) { this.correct_state(obj); }
+              }
+              else {
+                if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); }
+              }
+              if(e_call) { e_call.call(this); }
+            };
+            success_func = function (d, t, x) {
+              var sf = this.get_settings().json_data.ajax.success;
+              if(sf) { d = sf.call(this,d,t,x) || d; }
+              if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "") || (!$.isArray(d) && !$.isPlainObject(d))) {
+                return error_func.call(this, x, t, "");
+              }
+              d = this._parse_json(d, obj);
+              if(d) {
+                if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); }
+                else { obj.append(d).children("a.jstree-loading").removeClass("jstree-loading"); obj.removeData("jstree-is-loading"); }
+                this.clean_node(obj);
+                if(s_call) { s_call.call(this); }
+              }
+              else {
+                if(obj === -1 || !obj) {
+                  if(s.correct_state) {
+                    this.get_container().children("ul").empty();
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+                else {
+                  obj.children("a.jstree-loading").removeClass("jstree-loading");
+                  obj.removeData("jstree-is-loading");
+                  if(s.correct_state) {
+                    this.correct_state(obj);
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+              }
+            };
+            s.ajax.context = this;
+            s.ajax.error = error_func;
+            s.ajax.success = success_func;
+            if(!s.ajax.dataType) { s.ajax.dataType = "json"; }
+            if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); }
+            if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); }
+            $.ajax(s.ajax);
+            break;
+        }
+      },
+      _parse_json : function (js, obj, is_callback) {
+        var d = false,
+          p = this._get_settings(),
+          s = p.json_data,
+          t = p.core.html_titles,
+          tmp, i, j, ul1, ul2;
+
+        if(!js) { return d; }
+        if(s.progressive_unload && obj && obj !== -1) {
+          obj.data("jstree-children", d);
+        }
+        if($.isArray(js)) {
+          d = $();
+          if(!js.length) { return false; }
+          for(i = 0, j = js.length; i < j; i++) {
+            tmp = this._parse_json(js[i], obj, true);
+            if(tmp.length) { d = d.add(tmp); }
+          }
+        }
+        else {
+          if(typeof js == "string") { js = { data : js }; }
+          if(!js.data && js.data !== "") { return d; }
+          d = $("<li />");
+          if(js.attr) { d.attr(js.attr); }
+          if(js.metadata) { d.data(js.metadata); }
+          if(js.state) { d.addClass("jstree-" + js.state); }
+          if(!$.isArray(js.data)) { tmp = js.data; js.data = []; js.data.push(tmp); }
+          $.each(js.data, function (i, m) {
+            tmp = $("<a />");
+            if($.isFunction(m)) { m = m.call(this, js); }
+            if(typeof m == "string") { tmp.attr('href','#')[ t ? "html" : "text" ](m); }
+            else {
+              if(!m.attr) { m.attr = {}; }
+              if(!m.attr.href) { m.attr.href = '#'; }
+              tmp.attr(m.attr)[ t ? "html" : "text" ](m.title);
+              if(m.language) { tmp.addClass(m.language); }
+            }
+            tmp.prepend("<ins class='jstree-icon'>&#160;</ins>");
+            if(!m.icon && js.icon) { m.icon = js.icon; }
+            if(m.icon) {
+              if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); }
+              else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); }
+            }
+            d.append(tmp);
+          });
+          d.prepend("<ins class='jstree-icon'>&#160;</ins>");
+          if(js.children) {
+            if(s.progressive_render && js.state !== "open") {
+              d.addClass("jstree-closed").data("jstree-children", js.children);
+            }
+            else {
+              if(s.progressive_unload) { d.data("jstree-children", js.children); }
+              if($.isArray(js.children) && js.children.length) {
+                tmp = this._parse_json(js.children, obj, true);
+                if(tmp.length) {
+                  ul2 = $("<ul />");
+                  ul2.append(tmp);
+                  d.append(ul2);
+                }
+              }
+            }
+          }
+        }
+        if(!is_callback) {
+          ul1 = $("<ul />");
+          ul1.append(d);
+          d = ul1;
+        }
+        return d;
+      },
+      get_json : function (obj, li_attr, a_attr, is_callback) {
+        var result = [],
+          s = this._get_settings(),
+          _this = this,
+          tmp1, tmp2, li, a, t, lang;
+        obj = this._get_node(obj);
+        if(!obj || obj === -1) { obj = this.get_container().find("> ul > li"); }
+        li_attr = $.isArray(li_attr) ? li_attr : [ "id", "class" ];
+        if(!is_callback && this.data.types) { li_attr.push(s.types.type_attr); }
+        a_attr = $.isArray(a_attr) ? a_attr : [ ];
+
+        obj.each(function () {
+          li = $(this);
+          tmp1 = { data : [] };
+          if(li_attr.length) { tmp1.attr = { }; }
+          $.each(li_attr, function (i, v) {
+            tmp2 = li.attr(v);
+            if(tmp2 && tmp2.length && tmp2.replace(/jstree[^ ]*/ig,'').length) {
+              tmp1.attr[v] = (" " + tmp2).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
+            }
+          });
+          if(li.hasClass("jstree-open")) { tmp1.state = "open"; }
+          if(li.hasClass("jstree-closed")) { tmp1.state = "closed"; }
+          if(li.data()) { tmp1.metadata = li.data(); }
+          a = li.children("a");
+          a.each(function () {
+            t = $(this);
+            if(
+              a_attr.length ||
+              $.inArray("languages", s.plugins) !== -1 ||
+              t.children("ins").get(0).style.backgroundImage.length ||
+              (t.children("ins").get(0).className && t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').length)
+            ) {
+              lang = false;
+              if($.inArray("languages", s.plugins) !== -1 && $.isArray(s.languages) && s.languages.length) {
+                $.each(s.languages, function (l, lv) {
+                  if(t.hasClass(lv)) {
+                    lang = lv;
+                    return false;
+                  }
+                });
+              }
+              tmp2 = { attr : { }, title : _this.get_text(t, lang) };
+              $.each(a_attr, function (k, z) {
+                tmp2.attr[z] = (" " + (t.attr(z) || "")).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
+              });
+              if($.inArray("languages", s.plugins) !== -1 && $.isArray(s.languages) && s.languages.length) {
+                $.each(s.languages, function (k, z) {
+                  if(t.hasClass(z)) { tmp2.language = z; return true; }
+                });
+              }
+              if(t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"").length) {
+                tmp2.icon = t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
+              }
+              if(t.children("ins").get(0).style.backgroundImage.length) {
+                tmp2.icon = t.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")","");
+              }
+            }
+            else {
+              tmp2 = _this.get_text(t);
+            }
+            if(a.length > 1) { tmp1.data.push(tmp2); }
+            else { tmp1.data = tmp2; }
+          });
+          li = li.find("> ul > li");
+          if(li.length) { tmp1.children = _this.get_json(li, li_attr, a_attr, true); }
+          result.push(tmp1);
+        });
+        return result;
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree languages plugin
+ * Adds support for multiple language versions in one tree
+ * This basically allows for many titles coexisting in one node, but only one of them being visible at any given time
+ * This is useful for maintaining the same structure in many languages (hence the name of the plugin)
+ */
+(function ($) {
+  $.jstree.plugin("languages", {
+    __init : function () { this._load_css();  },
+    defaults : [],
+    _fn : {
+      set_lang : function (i) {
+        var langs = this._get_settings().languages,
+          st = false,
+          selector = ".jstree-" + this.get_index() + ' a';
+        if(!$.isArray(langs) || langs.length === 0) { return false; }
+        if($.inArray(i,langs) == -1) {
+          if(!!langs[i]) { i = langs[i]; }
+          else { return false; }
+        }
+        if(i == this.data.languages.current_language) { return true; }
+        st = $.vakata.css.get_css(selector + "." + this.data.languages.current_language, false, this.data.languages.language_css);
+        if(st !== false) { st.style.display = "none"; }
+        st = $.vakata.css.get_css(selector + "." + i, false, this.data.languages.language_css);
+        if(st !== false) { st.style.display = ""; }
+        this.data.languages.current_language = i;
+        this.__callback(i);
+        return true;
+      },
+      get_lang : function () {
+        return this.data.languages.current_language;
+      },
+      _get_string : function (key, lang) {
+        var langs = this._get_settings().languages,
+          s = this._get_settings().core.strings;
+        if($.isArray(langs) && langs.length) {
+          lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language;
+        }
+        if(s[lang] && s[lang][key]) { return s[lang][key]; }
+        if(s[key]) { return s[key]; }
+        return key;
+      },
+      get_text : function (obj, lang) {
+        obj = this._get_node(obj) || this.data.ui.last_selected;
+        if(!obj.size()) { return false; }
+        var langs = this._get_settings().languages,
+          s = this._get_settings().core.html_titles;
+        if($.isArray(langs) && langs.length) {
+          lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language;
+          obj = obj.children("a." + lang);
+        }
+        else { obj = obj.children("a:eq(0)"); }
+        if(s) {
+          obj = obj.clone();
+          obj.children("INS").remove();
+          return obj.html();
+        }
+        else {
+          obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
+          return obj.nodeValue;
+        }
+      },
+      set_text : function (obj, val, lang) {
+        obj = this._get_node(obj) || this.data.ui.last_selected;
+        if(!obj.size()) { return false; }
+        var langs = this._get_settings().languages,
+          s = this._get_settings().core.html_titles,
+          tmp;
+        if($.isArray(langs) && langs.length) {
+          lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language;
+          obj = obj.children("a." + lang);
+        }
+        else { obj = obj.children("a:eq(0)"); }
+        if(s) {
+          tmp = obj.children("INS").clone();
+          obj.html(val).prepend(tmp);
+          this.__callback({ "obj" : obj, "name" : val, "lang" : lang });
+          return true;
+        }
+        else {
+          obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
+          this.__callback({ "obj" : obj, "name" : val, "lang" : lang });
+          return (obj.nodeValue = val);
+        }
+      },
+      _load_css : function () {
+        var langs = this._get_settings().languages,
+          str = "/* languages css */",
+          selector = ".jstree-" + this.get_index() + ' a',
+          ln;
+        if($.isArray(langs) && langs.length) {
+          this.data.languages.current_language = langs[0];
+          for(ln = 0; ln < langs.length; ln++) {
+            str += selector + "." + langs[ln] + " {";
+            if(langs[ln] != this.data.languages.current_language) { str += " display:none; "; }
+            str += " } ";
+          }
+          this.data.languages.language_css = $.vakata.css.add_sheet({ 'str' : str, 'title' : "jstree-languages" });
+        }
+      },
+      create_node : function (obj, position, js, callback) {
+        var t = this.__call_old(true, obj, position, js, function (t) {
+          var langs = this._get_settings().languages,
+            a = t.children("a"),
+            ln;
+          if($.isArray(langs) && langs.length) {
+            for(ln = 0; ln < langs.length; ln++) {
+              if(!a.is("." + langs[ln])) {
+                t.append(a.eq(0).clone().removeClass(langs.join(" ")).addClass(langs[ln]));
+              }
+            }
+            a.not("." + langs.join(", .")).remove();
+          }
+          if(callback) { callback.call(this, t); }
+        });
+        return t;
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree cookies plugin
+ * Stores the currently opened/selected nodes in a cookie and then restores them
+ * Depends on the jquery.cookie plugin
+ */
+(function ($) {
+  $.jstree.plugin("cookies", {
+    __init : function () {
+      if(typeof $.cookie === "undefined") { throw "jsTree cookie: jQuery cookie plugin not included."; }
+
+      var s = this._get_settings().cookies,
+        tmp;
+      if(!!s.save_loaded) {
+        tmp = $.cookie(s.save_loaded);
+        if(tmp && tmp.length) { this.data.core.to_load = tmp.split(","); }
+      }
+      if(!!s.save_opened) {
+        tmp = $.cookie(s.save_opened);
+        if(tmp && tmp.length) { this.data.core.to_open = tmp.split(","); }
+      }
+      if(!!s.save_selected) {
+        tmp = $.cookie(s.save_selected);
+        if(tmp && tmp.length && this.data.ui) { this.data.ui.to_select = tmp.split(","); }
+      }
+      this.get_container()
+        .one( ( this.data.ui ? "reselect" : "reopen" ) + ".jstree", $.proxy(function () {
+          this.get_container()
+            .bind("open_node.jstree close_node.jstree select_node.jstree deselect_node.jstree", $.proxy(function (e) {
+                if(this._get_settings().cookies.auto_save) { this.save_cookie((e.handleObj.namespace + e.handleObj.type).replace("jstree","")); }
+              }, this));
+        }, this));
+    },
+    defaults : {
+      save_loaded    : "jstree_load",
+      save_opened    : "jstree_open",
+      save_selected  : "jstree_select",
+      auto_save    : true,
+      cookie_options  : {}
+    },
+    _fn : {
+      save_cookie : function (c) {
+        if(this.data.core.refreshing) { return; }
+        var s = this._get_settings().cookies;
+        if(!c) { // if called manually and not by event
+          if(s.save_loaded) {
+            this.save_loaded();
+            $.cookie(s.save_loaded, this.data.core.to_load.join(","), s.cookie_options);
+          }
+          if(s.save_opened) {
+            this.save_opened();
+            $.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options);
+          }
+          if(s.save_selected && this.data.ui) {
+            this.save_selected();
+            $.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options);
+          }
+          return;
+        }
+        switch(c) {
+          case "open_node":
+          case "close_node":
+            if(!!s.save_opened) {
+              this.save_opened();
+              $.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options);
+            }
+            if(!!s.save_loaded) {
+              this.save_loaded();
+              $.cookie(s.save_loaded, this.data.core.to_load.join(","), s.cookie_options);
+            }
+            break;
+          case "select_node":
+          case "deselect_node":
+            if(!!s.save_selected && this.data.ui) {
+              this.save_selected();
+              $.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options);
+            }
+            break;
+        }
+      }
+    }
+  });
+  // include cookies by default
+  // $.jstree.defaults.plugins.push("cookies");
+})(jQuery);
+//*/
+
+/*
+ * jsTree sort plugin
+ * Sorts items alphabetically (or using any other function)
+ */
+(function ($) {
+  $.jstree.plugin("sort", {
+    __init : function () {
+      this.get_container()
+        .bind("load_node.jstree", $.proxy(function (e, data) {
+            var obj = this._get_node(data.rslt.obj);
+            obj = obj === -1 ? this.get_container().children("ul") : obj.children("ul");
+            this.sort(obj);
+          }, this))
+        .bind("rename_node.jstree create_node.jstree create.jstree", $.proxy(function (e, data) {
+            this.sort(data.rslt.obj.parent());
+          }, this))
+        .bind("move_node.jstree", $.proxy(function (e, data) {
+            var m = data.rslt.np == -1 ? this.get_container() : data.rslt.np;
+            this.sort(m.children("ul"));
+          }, this));
+    },
+    defaults : function (a, b) { return this.get_text(a) > this.get_text(b) ? 1 : -1; },
+    _fn : {
+      sort : function (obj) {
+        var s = this._get_settings().sort,
+          t = this;
+        obj.append($.makeArray(obj.children("li")).sort($.proxy(s, t)));
+        obj.find("> li > ul").each(function() { t.sort($(this)); });
+        this.clean_node(obj);
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree DND plugin
+ * Drag and drop plugin for moving/copying nodes
+ */
+(function ($) {
+  var o = false,
+    r = false,
+    m = false,
+    ml = false,
+    sli = false,
+    sti = false,
+    dir1 = false,
+    dir2 = false,
+    last_pos = false;
+  $.vakata.dnd = {
+    is_down : false,
+    is_drag : false,
+    helper : false,
+    scroll_spd : 10,
+    init_x : 0,
+    init_y : 0,
+    threshold : 5,
+    helper_left : 5,
+    helper_top : 10,
+    user_data : {},
+
+    drag_start : function (e, data, html) {
+      if($.vakata.dnd.is_drag) { $.vakata.drag_stop({}); }
+      try {
+        e.currentTarget.unselectable = "on";
+        e.currentTarget.onselectstart = function() { return false; };
+        if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
+      } catch(err) { }
+      $.vakata.dnd.init_x = e.pageX;
+      $.vakata.dnd.init_y = e.pageY;
+      $.vakata.dnd.user_data = data;
+      $.vakata.dnd.is_down = true;
+      $.vakata.dnd.helper = $("<div id='vakata-dragged' />").html(html); //.fadeTo(10,0.25);
+      $(document).bind("mousemove", $.vakata.dnd.drag);
+      $(document).bind("mouseup", $.vakata.dnd.drag_stop);
+      return false;
+    },
+    drag : function (e) {
+      if(!$.vakata.dnd.is_down) { return; }
+      if(!$.vakata.dnd.is_drag) {
+        if(Math.abs(e.pageX - $.vakata.dnd.init_x) > 5 || Math.abs(e.pageY - $.vakata.dnd.init_y) > 5) {
+          $.vakata.dnd.helper.appendTo("body");
+          $.vakata.dnd.is_drag = true;
+          $(document).triggerHandler("drag_start.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
+        }
+        else { return; }
+      }
+
+      // maybe use a scrolling parent element instead of document?
+      if(e.type === "mousemove") { // thought of adding scroll in order to move the helper, but mouse poisition is n/a
+        var d = $(document), t = d.scrollTop(), l = d.scrollLeft();
+        if(e.pageY - t < 20) {
+          if(sti && dir1 === "down") { clearInterval(sti); sti = false; }
+          if(!sti) { dir1 = "up"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() - $.vakata.dnd.scroll_spd); }, 150); }
+        }
+        else {
+          if(sti && dir1 === "up") { clearInterval(sti); sti = false; }
+        }
+        if($(window).height() - (e.pageY - t) < 20) {
+          if(sti && dir1 === "up") { clearInterval(sti); sti = false; }
+          if(!sti) { dir1 = "down"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() + $.vakata.dnd.scroll_spd); }, 150); }
+        }
+        else {
+          if(sti && dir1 === "down") { clearInterval(sti); sti = false; }
+        }
+
+        if(e.pageX - l < 20) {
+          if(sli && dir2 === "right") { clearInterval(sli); sli = false; }
+          if(!sli) { dir2 = "left"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() - $.vakata.dnd.scroll_spd); }, 150); }
+        }
+        else {
+          if(sli && dir2 === "left") { clearInterval(sli); sli = false; }
+        }
+        if($(window).width() - (e.pageX - l) < 20) {
+          if(sli && dir2 === "left") { clearInterval(sli); sli = false; }
+          if(!sli) { dir2 = "right"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() + $.vakata.dnd.scroll_spd); }, 150); }
+        }
+        else {
+          if(sli && dir2 === "right") { clearInterval(sli); sli = false; }
+        }
+      }
+
+      $.vakata.dnd.helper.css({ left : (e.pageX + $.vakata.dnd.helper_left) + "px", top : (e.pageY + $.vakata.dnd.helper_top) + "px" });
+      $(document).triggerHandler("drag.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
+    },
+    drag_stop : function (e) {
+      if(sli) { clearInterval(sli); }
+      if(sti) { clearInterval(sti); }
+      $(document).unbind("mousemove", $.vakata.dnd.drag);
+      $(document).unbind("mouseup", $.vakata.dnd.drag_stop);
+      $(document).triggerHandler("drag_stop.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
+      $.vakata.dnd.helper.remove();
+      $.vakata.dnd.init_x = 0;
+      $.vakata.dnd.init_y = 0;
+      $.vakata.dnd.user_data = {};
+      $.vakata.dnd.is_down = false;
+      $.vakata.dnd.is_drag = false;
+    }
+  };
+  $(function() {
+    var css_string = '#vakata-dragged { display:block; margin:0 0 0 0; padding:4px 4px 4px 24px; position:absolute; top:-2000px; line-height:16px; z-index:10000; } ';
+    $.vakata.css.add_sheet({ str : css_string, title : "vakata" });
+  });
+
+  $.jstree.plugin("dnd", {
+    __init : function () {
+      this.data.dnd = {
+        active : false,
+        after : false,
+        inside : false,
+        before : false,
+        off : false,
+        prepared : false,
+        w : 0,
+        to1 : false,
+        to2 : false,
+        cof : false,
+        cw : false,
+        ch : false,
+        i1 : false,
+        i2 : false,
+        mto : false
+      };
+      this.get_container()
+        .bind("mouseenter.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              if(this.data.themes) {
+                m.attr("class", "jstree-" + this.data.themes.theme);
+                if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
+                $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
+              }
+              //if($(e.currentTarget).find("> ul > li").length === 0) {
+              if(e.currentTarget === e.target && $.vakata.dnd.user_data.obj && $($.vakata.dnd.user_data.obj).length && $($.vakata.dnd.user_data.obj).parents(".jstree:eq(0)")[0] !== e.target) { // node should not be from the same tree
+                var tr = $.jstree._reference(e.target), dc;
+                if(tr.data.dnd.foreign) {
+                  dc = tr._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : tr.get_container(), is_root : true });
+                  if(dc === true || dc.inside === true || dc.before === true || dc.after === true) {
+                    $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
+                  }
+                }
+                else {
+                  tr.prepare_move(o, tr.get_container(), "last");
+                  if(tr.check_move()) {
+                    $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
+                  }
+                }
+              }
+            }
+          }, this))
+        .bind("mouseup.jstree", $.proxy(function (e) {
+            //if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && $(e.currentTarget).find("> ul > li").length === 0) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && e.currentTarget === e.target && $.vakata.dnd.user_data.obj && $($.vakata.dnd.user_data.obj).length && $($.vakata.dnd.user_data.obj).parents(".jstree:eq(0)")[0] !== e.target) { // node should not be from the same tree
+              var tr = $.jstree._reference(e.currentTarget), dc;
+              if(tr.data.dnd.foreign) {
+                dc = tr._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : tr.get_container(), is_root : true });
+                if(dc === true || dc.inside === true || dc.before === true || dc.after === true) {
+                  tr._get_settings().dnd.drag_finish.call(this, { "o" : o, "r" : tr.get_container(), is_root : true });
+                }
+              }
+              else {
+                tr.move_node(o, tr.get_container(), "last", e[tr._get_settings().dnd.copy_modifier + "Key"]);
+              }
+            }
+          }, this))
+        .bind("mouseleave.jstree", $.proxy(function (e) {
+            if(e.relatedTarget && e.relatedTarget.id && e.relatedTarget.id === "jstree-marker-line") {
+              return false;
+            }
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
+              if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
+              if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
+              if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
+              if($.vakata.dnd.helper.children("ins").hasClass("jstree-ok")) {
+                $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
+              }
+            }
+          }, this))
+        .bind("mousemove.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              var cnt = this.get_container()[0];
+
+              // Horizontal scroll
+              if(e.pageX + 24 > this.data.dnd.cof.left + this.data.dnd.cw) {
+                if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
+                this.data.dnd.i1 = setInterval($.proxy(function () { this.scrollLeft += $.vakata.dnd.scroll_spd; }, cnt), 100);
+              }
+              else if(e.pageX - 24 < this.data.dnd.cof.left) {
+                if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
+                this.data.dnd.i1 = setInterval($.proxy(function () { this.scrollLeft -= $.vakata.dnd.scroll_spd; }, cnt), 100);
+              }
+              else {
+                if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
+              }
+
+              // Vertical scroll
+              if(e.pageY + 24 > this.data.dnd.cof.top + this.data.dnd.ch) {
+                if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
+                this.data.dnd.i2 = setInterval($.proxy(function () { this.scrollTop += $.vakata.dnd.scroll_spd; }, cnt), 100);
+              }
+              else if(e.pageY - 24 < this.data.dnd.cof.top) {
+                if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
+                this.data.dnd.i2 = setInterval($.proxy(function () { this.scrollTop -= $.vakata.dnd.scroll_spd; }, cnt), 100);
+              }
+              else {
+                if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
+              }
+
+            }
+          }, this))
+        .bind("scroll.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && m && ml) {
+              m.hide();
+              ml.hide();
+            }
+          }, this))
+        .delegate("a", "mousedown.jstree", $.proxy(function (e) {
+            if(e.which === 1) {
+              this.start_drag(e.currentTarget, e);
+              return false;
+            }
+          }, this))
+        .delegate("a", "mouseenter.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              this.dnd_enter(e.currentTarget);
+            }
+          }, this))
+        .delegate("a", "mousemove.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              if(!r || !r.length || r.children("a")[0] !== e.currentTarget) {
+                this.dnd_enter(e.currentTarget);
+              }
+              if(typeof this.data.dnd.off.top === "undefined") { this.data.dnd.off = $(e.target).offset(); }
+              this.data.dnd.w = (e.pageY - (this.data.dnd.off.top || 0)) % this.data.core.li_height;
+              if(this.data.dnd.w < 0) { this.data.dnd.w += this.data.core.li_height; }
+              this.dnd_show();
+            }
+          }, this))
+        .delegate("a", "mouseleave.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              if(e.relatedTarget && e.relatedTarget.id && e.relatedTarget.id === "jstree-marker-line") {
+                return false;
+              }
+                if(m) { m.hide(); }
+                if(ml) { ml.hide(); }
+              /*
+              var ec = $(e.currentTarget).closest("li"),
+                er = $(e.relatedTarget).closest("li");
+              if(er[0] !== ec.prev()[0] && er[0] !== ec.next()[0]) {
+                if(m) { m.hide(); }
+                if(ml) { ml.hide(); }
+              }
+              */
+              this.data.dnd.mto = setTimeout(
+                (function (t) { return function () { t.dnd_leave(e); }; })(this),
+              0);
+            }
+          }, this))
+        .delegate("a", "mouseup.jstree", $.proxy(function (e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
+              this.dnd_finish(e);
+            }
+          }, this));
+
+      $(document)
+        .bind("drag_stop.vakata", $.proxy(function () {
+            if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
+            if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
+            if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
+            if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
+            this.data.dnd.after    = false;
+            this.data.dnd.before  = false;
+            this.data.dnd.inside  = false;
+            this.data.dnd.off    = false;
+            this.data.dnd.prepared  = false;
+            this.data.dnd.w      = false;
+            this.data.dnd.to1    = false;
+            this.data.dnd.to2    = false;
+            this.data.dnd.i1    = false;
+            this.data.dnd.i2    = false;
+            this.data.dnd.active  = false;
+            this.data.dnd.foreign  = false;
+            if(m) { m.css({ "top" : "-2000px" }); }
+            if(ml) { ml.css({ "top" : "-2000px" }); }
+          }, this))
+        .bind("drag_start.vakata", $.proxy(function (e, data) {
+            if(data.data.jstree) {
+              var et = $(data.event.target);
+              if(et.closest(".jstree").hasClass("jstree-" + this.get_index())) {
+                this.dnd_enter(et);
+              }
+            }
+          }, this));
+        /*
+        .bind("keydown.jstree-" + this.get_index() + " keyup.jstree-" + this.get_index(), $.proxy(function(e) {
+            if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && !this.data.dnd.foreign) {
+              var h = $.vakata.dnd.helper.children("ins");
+              if(e[this._get_settings().dnd.copy_modifier + "Key"] && h.hasClass("jstree-ok")) {
+                h.parent().html(h.parent().html().replace(/ \(Copy\)$/, "") + " (Copy)");
+              }
+              else {
+                h.parent().html(h.parent().html().replace(/ \(Copy\)$/, ""));
+              }
+            }
+          }, this)); */
+
+
+
+      var s = this._get_settings().dnd;
+      if(s.drag_target) {
+        $(document)
+          .delegate(s.drag_target, "mousedown.jstree-" + this.get_index(), $.proxy(function (e) {
+            o = e.target;
+            $.vakata.dnd.drag_start(e, { jstree : true, obj : e.target }, "<ins class='jstree-icon'></ins>" + $(e.target).text() );
+            if(this.data.themes) {
+              if(m) { m.attr("class", "jstree-" + this.data.themes.theme); }
+              if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
+              $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
+            }
+            $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
+            var cnt = this.get_container();
+            this.data.dnd.cof = cnt.offset();
+            this.data.dnd.cw = parseInt(cnt.width(),10);
+            this.data.dnd.ch = parseInt(cnt.height(),10);
+            this.data.dnd.foreign = true;
+            e.preventDefault();
+          }, this));
+      }
+      if(s.drop_target) {
+        $(document)
+          .delegate(s.drop_target, "mouseenter.jstree-" + this.get_index(), $.proxy(function (e) {
+              if(this.data.dnd.active && this._get_settings().dnd.drop_check.call(this, { "o" : o, "r" : $(e.target), "e" : e })) {
+                $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
+              }
+            }, this))
+          .delegate(s.drop_target, "mouseleave.jstree-" + this.get_index(), $.proxy(function (e) {
+              if(this.data.dnd.active) {
+                $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
+              }
+            }, this))
+          .delegate(s.drop_target, "mouseup.jstree-" + this.get_index(), $.proxy(function (e) {
+              if(this.data.dnd.active && $.vakata.dnd.helper.children("ins").hasClass("jstree-ok")) {
+                this._get_settings().dnd.drop_finish.call(this, { "o" : o, "r" : $(e.target), "e" : e });
+              }
+            }, this));
+      }
+    },
+    defaults : {
+      copy_modifier  : "ctrl",
+      check_timeout  : 100,
+      open_timeout  : 500,
+      drop_target    : ".jstree-drop",
+      drop_check    : function (data) { return true; },
+      drop_finish    : $.noop,
+      drag_target    : ".jstree-draggable",
+      drag_finish    : $.noop,
+      drag_check    : function (data) { return { after : false, before : false, inside : true }; }
+    },
+    _fn : {
+      dnd_prepare : function () {
+        if(!r || !r.length) { return; }
+        this.data.dnd.off = r.offset();
+        if(this._get_settings().core.rtl) {
+          this.data.dnd.off.right = this.data.dnd.off.left + r.width();
+        }
+        if(this.data.dnd.foreign) {
+          var a = this._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : r });
+          this.data.dnd.after = a.after;
+          this.data.dnd.before = a.before;
+          this.data.dnd.inside = a.inside;
+          this.data.dnd.prepared = true;
+          return this.dnd_show();
+        }
+        this.prepare_move(o, r, "before");
+        this.data.dnd.before = this.check_move();
+        this.prepare_move(o, r, "after");
+        this.data.dnd.after = this.check_move();
+        if(this._is_loaded(r)) {
+          this.prepare_move(o, r, "inside");
+          this.data.dnd.inside = this.check_move();
+        }
+        else {
+          this.data.dnd.inside = false;
+        }
+        this.data.dnd.prepared = true;
+        return this.dnd_show();
+      },
+      dnd_show : function () {
+        if(!this.data.dnd.prepared) { return; }
+        var o = ["before","inside","after"],
+          r = false,
+          rtl = this._get_settings().core.rtl,
+          pos;
+        if(this.data.dnd.w < this.data.core.li_height/3) { o = ["before","inside","after"]; }
+        else if(this.data.dnd.w <= this.data.core.li_height*2/3) {
+          o = this.data.dnd.w < this.data.core.li_height/2 ? ["inside","before","after"] : ["inside","after","before"];
+        }
+        else { o = ["after","inside","before"]; }
+        $.each(o, $.proxy(function (i, val) {
+          if(this.data.dnd[val]) {
+            $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
+            r = val;
+            return false;
+          }
+        }, this));
+        if(r === false) { $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); }
+
+        pos = rtl ? (this.data.dnd.off.right - 18) : (this.data.dnd.off.left + 10);
+        switch(r) {
+          case "before":
+            m.css({ "left" : pos + "px", "top" : (this.data.dnd.off.top - 6) + "px" }).show();
+            if(ml) { ml.css({ "left" : (pos + 8) + "px", "top" : (this.data.dnd.off.top - 1) + "px" }).show(); }
+            break;
+          case "after":
+            m.css({ "left" : pos + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height - 6) + "px" }).show();
+            if(ml) { ml.css({ "left" : (pos + 8) + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height - 1) + "px" }).show(); }
+            break;
+          case "inside":
+            m.css({ "left" : pos + ( rtl ? -4 : 4) + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height/2 - 5) + "px" }).show();
+            if(ml) { ml.hide(); }
+            break;
+          default:
+            m.hide();
+            if(ml) { ml.hide(); }
+            break;
+        }
+        last_pos = r;
+        return r;
+      },
+      dnd_open : function () {
+        this.data.dnd.to2 = false;
+        this.open_node(r, $.proxy(this.dnd_prepare,this), true);
+      },
+      dnd_finish : function (e) {
+        if(this.data.dnd.foreign) {
+          if(this.data.dnd.after || this.data.dnd.before || this.data.dnd.inside) {
+            this._get_settings().dnd.drag_finish.call(this, { "o" : o, "r" : r, "p" : last_pos });
+          }
+        }
+        else {
+          this.dnd_prepare();
+          this.move_node(o, r, last_pos, e[this._get_settings().dnd.copy_modifier + "Key"]);
+        }
+        o = false;
+        r = false;
+        m.hide();
+        if(ml) { ml.hide(); }
+      },
+      dnd_enter : function (obj) {
+        if(this.data.dnd.mto) {
+          clearTimeout(this.data.dnd.mto);
+          this.data.dnd.mto = false;
+        }
+        var s = this._get_settings().dnd;
+        this.data.dnd.prepared = false;
+        r = this._get_node(obj);
+        if(s.check_timeout) {
+          // do the calculations after a minimal timeout (users tend to drag quickly to the desired location)
+          if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
+          this.data.dnd.to1 = setTimeout($.proxy(this.dnd_prepare, this), s.check_timeout);
+        }
+        else {
+          this.dnd_prepare();
+        }
+        if(s.open_timeout) {
+          if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
+          if(r && r.length && r.hasClass("jstree-closed")) {
+            // if the node is closed - open it, then recalculate
+            this.data.dnd.to2 = setTimeout($.proxy(this.dnd_open, this), s.open_timeout);
+          }
+        }
+        else {
+          if(r && r.length && r.hasClass("jstree-closed")) {
+            this.dnd_open();
+          }
+        }
+      },
+      dnd_leave : function (e) {
+        this.data.dnd.after    = false;
+        this.data.dnd.before  = false;
+        this.data.dnd.inside  = false;
+        $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
+        m.hide();
+        if(ml) { ml.hide(); }
+        if(r && r[0] === e.target.parentNode) {
+          if(this.data.dnd.to1) {
+            clearTimeout(this.data.dnd.to1);
+            this.data.dnd.to1 = false;
+          }
+          if(this.data.dnd.to2) {
+            clearTimeout(this.data.dnd.to2);
+            this.data.dnd.to2 = false;
+          }
+        }
+      },
+      start_drag : function (obj, e) {
+        o = this._get_node(obj);
+        if(this.data.ui && this.is_selected(o)) { o = this._get_node(null, true); }
+        var dt = o.length > 1 ? this._get_string("multiple_selection") : this.get_text(o),
+          cnt = this.get_container();
+        if(!this._get_settings().core.html_titles) { dt = dt.replace(/</ig,"&lt;").replace(/>/ig,"&gt;"); }
+        $.vakata.dnd.drag_start(e, { jstree : true, obj : o }, "<ins class='jstree-icon'></ins>" + dt );
+        if(this.data.themes) {
+          if(m) { m.attr("class", "jstree-" + this.data.themes.theme); }
+          if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
+          $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
+        }
+        this.data.dnd.cof = cnt.offset();
+        this.data.dnd.cw = parseInt(cnt.width(),10);
+        this.data.dnd.ch = parseInt(cnt.height(),10);
+        this.data.dnd.active = true;
+      }
+    }
+  });
+  $(function() {
+    var css_string = '' +
+      '#vakata-dragged ins { display:block; text-decoration:none; width:16px; height:16px; margin:0 0 0 0; padding:0; position:absolute; top:4px; left:4px; ' +
+      ' -moz-border-radius:4px; border-radius:4px; -webkit-border-radius:4px; ' +
+      '} ' +
+      '#vakata-dragged .jstree-ok { background:green; } ' +
+      '#vakata-dragged .jstree-invalid { background:red; } ' +
+      '#jstree-marker { padding:0; margin:0; font-size:12px; overflow:hidden; height:12px; width:8px; position:absolute; top:-30px; z-index:10001; background-repeat:no-repeat; display:none; background-color:transparent; text-shadow:1px 1px 1px white; color:black; line-height:10px; } ' +
+      '#jstree-marker-line { padding:0; margin:0; line-height:0%; font-size:1px; overflow:hidden; height:1px; width:100px; position:absolute; top:-30px; z-index:10000; background-repeat:no-repeat; display:none; background-color:#456c43; ' +
+      ' cursor:pointer; border:1px solid #eeeeee; border-left:0; -moz-box-shadow: 0px 0px 2px #666; -webkit-box-shadow: 0px 0px 2px #666; box-shadow: 0px 0px 2px #666; ' +
+      ' -moz-border-radius:1px; border-radius:1px; -webkit-border-radius:1px; ' +
+      '}' +
+      '';
+    $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
+    m = $("<div />").attr({ id : "jstree-marker" }).hide().html("&raquo;")
+      .bind("mouseleave mouseenter", function (e) {
+        m.hide();
+        ml.hide();
+        e.preventDefault();
+        e.stopImmediatePropagation();
+        return false;
+      })
+      .appendTo("body");
+    ml = $("<div />").attr({ id : "jstree-marker-line" }).hide()
+      .bind("mouseup", function (e) {
+        if(r && r.length) {
+          r.children("a").trigger(e);
+          e.preventDefault();
+          e.stopImmediatePropagation();
+          return false;
+        }
+      })
+      .bind("mouseleave", function (e) {
+        var rt = $(e.relatedTarget);
+        if(rt.is(".jstree") || rt.closest(".jstree").length === 0) {
+          if(r && r.length) {
+            r.children("a").trigger(e);
+            m.hide();
+            ml.hide();
+            e.preventDefault();
+            e.stopImmediatePropagation();
+            return false;
+          }
+        }
+      })
+      .appendTo("body");
+    $(document).bind("drag_start.vakata", function (e, data) {
+      if(data.data.jstree) { m.show(); if(ml) { ml.show(); } }
+    });
+    $(document).bind("drag_stop.vakata", function (e, data) {
+      if(data.data.jstree) { m.hide(); if(ml) { ml.hide(); } }
+    });
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree checkbox plugin
+ * Inserts checkboxes in front of every node
+ * Depends on the ui plugin
+ * DOES NOT WORK NICELY WITH MULTITREE DRAG'N'DROP
+ */
+(function ($) {
+  $.jstree.plugin("checkbox", {
+    __init : function () {
+      this.data.checkbox.noui = this._get_settings().checkbox.override_ui;
+      if(this.data.ui && this.data.checkbox.noui) {
+        this.select_node = this.deselect_node = this.deselect_all = $.noop;
+        this.get_selected = this.get_checked;
+      }
+
+      this.get_container()
+        .bind("open_node.jstree create_node.jstree clean_node.jstree refresh.jstree", $.proxy(function (e, data) {
+            this._prepare_checkboxes(data.rslt.obj);
+          }, this))
+        .bind("loaded.jstree", $.proxy(function (e) {
+            this._prepare_checkboxes();
+          }, this))
+        .delegate( (this.data.ui && this.data.checkbox.noui ? "a" : "ins.jstree-checkbox") , "click.jstree", $.proxy(function (e) {
+            e.preventDefault();
+            if(this._get_node(e.target).hasClass("jstree-checked")) { this.uncheck_node(e.target); }
+            else { this.check_node(e.target); }
+            if(this.data.ui && this.data.checkbox.noui) {
+              this.save_selected();
+              if(this.data.cookies) { this.save_cookie("select_node"); }
+            }
+            else {
+              e.stopImmediatePropagation();
+              return false;
+            }
+          }, this));
+    },
+    defaults : {
+      override_ui : false,
+      two_state : false,
+      real_checkboxes : false,
+      checked_parent_open : true,
+      real_checkboxes_names : function (n) { return [ ("check_" + (n[0].id || Math.ceil(Math.random() * 10000))) , 1]; }
+    },
+    __destroy : function () {
+      this.get_container()
+        .find("input.jstree-real-checkbox").removeClass("jstree-real-checkbox").end()
+        .find("ins.jstree-checkbox").remove();
+    },
+    _fn : {
+      _checkbox_notify : function (n, data) {
+        if(data.checked) {
+          this.check_node(n, false);
+        }
+      },
+      _prepare_checkboxes : function (obj) {
+        obj = !obj || obj == -1 ? this.get_container().find("> ul > li") : this._get_node(obj);
+        if(obj === false) { return; } // added for removing root nodes
+        var c, _this = this, t, ts = this._get_settings().checkbox.two_state, rc = this._get_settings().checkbox.real_checkboxes, rcn = this._get_settings().checkbox.real_checkboxes_names;
+        obj.each(function () {
+          t = $(this);
+          c = t.is("li") && (t.hasClass("jstree-checked") || (rc && t.children(":checked").length)) ? "jstree-checked" : "jstree-unchecked";
+          t.find("li").andSelf().each(function () {
+            var $t = $(this), nm;
+            $t.children("a" + (_this.data.languages ? "" : ":eq(0)") ).not(":has(.jstree-checkbox)").prepend("<ins class='jstree-checkbox'>&#160;</ins>").parent().not(".jstree-checked, .jstree-unchecked").addClass( ts ? "jstree-unchecked" : c );
+            if(rc) {
+              if(!$t.children(":checkbox").length) {
+                nm = rcn.call(_this, $t);
+                $t.prepend("<input type='checkbox' class='jstree-real-checkbox' id='" + nm[0] + "' name='" + nm[0] + "' value='" + nm[1] + "' />");
+              }
+              else {
+                $t.children(":checkbox").addClass("jstree-real-checkbox");
+              }
+              if(c === "jstree-checked") {
+                $t.children(":checkbox").attr("checked","checked");
+              }
+            }
+            if(c === "jstree-checked" && !ts) {
+              $t.find("li").addClass("jstree-checked");
+            }
+          });
+        });
+        if(!ts) {
+          if(obj.length === 1 && obj.is("li")) { this._repair_state(obj); }
+          if(obj.is("li")) { obj.each(function () { _this._repair_state(this); }); }
+          else { obj.find("> ul > li").each(function () { _this._repair_state(this); }); }
+          obj.find(".jstree-checked").parent().parent().each(function () { _this._repair_state(this); });
+        }
+      },
+      change_state : function (obj, state) {
+        obj = this._get_node(obj);
+        var coll = false, rc = this._get_settings().checkbox.real_checkboxes;
+        if(!obj || obj === -1) { return false; }
+        state = (state === false || state === true) ? state : obj.hasClass("jstree-checked");
+        if(this._get_settings().checkbox.two_state) {
+          if(state) {
+            obj.removeClass("jstree-checked").addClass("jstree-unchecked");
+            if(rc) { obj.children(":checkbox").removeAttr("checked"); }
+          }
+          else {
+            obj.removeClass("jstree-unchecked").addClass("jstree-checked");
+            if(rc) { obj.children(":checkbox").attr("checked","checked"); }
+          }
+        }
+        else {
+          if(state) {
+            coll = obj.find("li").andSelf();
+            if(!coll.filter(".jstree-checked, .jstree-undetermined").length) { return false; }
+            coll.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked");
+            if(rc) { coll.children(":checkbox").removeAttr("checked"); }
+          }
+          else {
+            coll = obj.find("li").andSelf();
+            if(!coll.filter(".jstree-unchecked, .jstree-undetermined").length) { return false; }
+            coll.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked");
+            if(rc) { coll.children(":checkbox").attr("checked","checked"); }
+            if(this.data.ui) { this.data.ui.last_selected = obj; }
+            this.data.checkbox.last_selected = obj;
+          }
+          obj.parentsUntil(".jstree", "li").each(function () {
+            var $this = $(this);
+            if(state) {
+              if($this.children("ul").children("li.jstree-checked, li.jstree-undetermined").length) {
+                $this.parentsUntil(".jstree", "li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
+                if(rc) { $this.parentsUntil(".jstree", "li").andSelf().children(":checkbox").removeAttr("checked"); }
+                return false;
+              }
+              else {
+                $this.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked");
+                if(rc) { $this.children(":checkbox").removeAttr("checked"); }
+              }
+            }
+            else {
+              if($this.children("ul").children("li.jstree-unchecked, li.jstree-undetermined").length) {
+                $this.parentsUntil(".jstree", "li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
+                if(rc) { $this.parentsUntil(".jstree", "li").andSelf().children(":checkbox").removeAttr("checked"); }
+                return false;
+              }
+              else {
+                $this.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked");
+                if(rc) { $this.children(":checkbox").attr("checked","checked"); }
+              }
+            }
+          });
+        }
+        if(this.data.ui && this.data.checkbox.noui) { this.data.ui.selected = this.get_checked(); }
+        this.__callback(obj);
+        return true;
+      },
+      check_node : function (obj) {
+        if(this.change_state(obj, false)) {
+          obj = this._get_node(obj);
+          if(this._get_settings().checkbox.checked_parent_open) {
+            var t = this;
+            obj.parents(".jstree-closed").each(function () { t.open_node(this, false, true); });
+          }
+          this.__callback({ "obj" : obj });
+        }
+      },
+      uncheck_node : function (obj) {
+        if(this.change_state(obj, true)) { this.__callback({ "obj" : this._get_node(obj) }); }
+      },
+      check_all : function () {
+        var _this = this,
+          coll = this._get_settings().checkbox.two_state ? this.get_container_ul().find("li") : this.get_container_ul().children("li");
+        coll.each(function () {
+          _this.change_state(this, false);
+        });
+        this.__callback();
+      },
+      uncheck_all : function () {
+        var _this = this,
+          coll = this._get_settings().checkbox.two_state ? this.get_container_ul().find("li") : this.get_container_ul().children("li");
+        coll.each(function () {
+          _this.change_state(this, true);
+        });
+        this.__callback();
+      },
+
+      is_checked : function(obj) {
+        obj = this._get_node(obj);
+        return obj.length ? obj.is(".jstree-checked") : false;
+      },
+      get_checked : function (obj, get_all) {
+        obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj);
+        return get_all || this._get_settings().checkbox.two_state ? obj.find(".jstree-checked") : obj.find("> ul > .jstree-checked, .jstree-undetermined > ul > .jstree-checked");
+      },
+      get_unchecked : function (obj, get_all) {
+        obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj);
+        return get_all || this._get_settings().checkbox.two_state ? obj.find(".jstree-unchecked") : obj.find("> ul > .jstree-unchecked, .jstree-undetermined > ul > .jstree-unchecked");
+      },
+
+      show_checkboxes : function () { this.get_container().children("ul").removeClass("jstree-no-checkboxes"); },
+      hide_checkboxes : function () { this.get_container().children("ul").addClass("jstree-no-checkboxes"); },
+
+      _repair_state : function (obj) {
+        obj = this._get_node(obj);
+        if(!obj.length) { return; }
+        var rc = this._get_settings().checkbox.real_checkboxes,
+          a = obj.find("> ul > .jstree-checked").length,
+          b = obj.find("> ul > .jstree-undetermined").length,
+          c = obj.find("> ul > li").length;
+        if(c === 0) { if(obj.hasClass("jstree-undetermined")) { this.change_state(obj, false); } }
+        else if(a === 0 && b === 0) { this.change_state(obj, true); }
+        else if(a === c) { this.change_state(obj, false); }
+        else {
+          obj.parentsUntil(".jstree","li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
+          if(rc) { obj.parentsUntil(".jstree", "li").andSelf().children(":checkbox").removeAttr("checked"); }
+        }
+      },
+      reselect : function () {
+        if(this.data.ui && this.data.checkbox.noui) {
+          var _this = this,
+            s = this.data.ui.to_select;
+          s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
+          this.deselect_all();
+          $.each(s, function (i, val) { _this.check_node(val); });
+          this.__callback();
+        }
+        else {
+          this.__call_old();
+        }
+      },
+      save_loaded : function () {
+        var _this = this;
+        this.data.core.to_load = [];
+        this.get_container_ul().find("li.jstree-closed.jstree-undetermined").each(function () {
+          if(this.id) { _this.data.core.to_load.push("#" + this.id); }
+        });
+      }
+    }
+  });
+  $(function() {
+    var css_string = '.jstree .jstree-real-checkbox { display:none; } ';
+    $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree XML plugin
+ * The XML data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions.
+ */
+(function ($) {
+  $.vakata.xslt = function (xml, xsl, callback) {
+    var rs = "", xm, xs, processor, support;
+    // TODO: IE9 no XSLTProcessor, no document.recalc
+    if(document.recalc) {
+      xm = document.createElement('xml');
+      xs = document.createElement('xml');
+      xm.innerHTML = xml;
+      xs.innerHTML = xsl;
+      $("body").append(xm).append(xs);
+      setTimeout( (function (xm, xs, callback) {
+        return function () {
+          callback.call(null, xm.transformNode(xs.XMLDocument));
+          setTimeout( (function (xm, xs) { return function () { $(xm).remove(); $(xs).remove(); }; })(xm, xs), 200);
+        };
+      })(xm, xs, callback), 100);
+      return true;
+    }
+    if(typeof window.DOMParser !== "undefined" && typeof window.XMLHttpRequest !== "undefined" && typeof window.XSLTProcessor === "undefined") {
+      xml = new DOMParser().parseFromString(xml, "text/xml");
+      xsl = new DOMParser().parseFromString(xsl, "text/xml");
+      // alert(xml.transformNode());
+      // callback.call(null, new XMLSerializer().serializeToString(rs));
+
+    }
+    if(typeof window.DOMParser !== "undefined" && typeof window.XMLHttpRequest !== "undefined" && typeof window.XSLTProcessor !== "undefined") {
+      processor = new XSLTProcessor();
+      support = $.isFunction(processor.transformDocument) ? (typeof window.XMLSerializer !== "undefined") : true;
+      if(!support) { return false; }
+      xml = new DOMParser().parseFromString(xml, "text/xml");
+      xsl = new DOMParser().parseFromString(xsl, "text/xml");
+      if($.isFunction(processor.transformDocument)) {
+        rs = document.implementation.createDocument("", "", null);
+        processor.transformDocument(xml, xsl, rs, null);
+        callback.call(null, new XMLSerializer().serializeToString(rs));
+        return true;
+      }
+      else {
+        processor.importStylesheet(xsl);
+        rs = processor.transformToFragment(xml, document);
+        callback.call(null, $("<div />").append(rs).html());
+        return true;
+      }
+    }
+    return false;
+  };
+  var xsl = {
+    'nest' : '<' + '?xml version="1.0" encoding="utf-8" ?>' +
+      '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' +
+      '<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/html" />' +
+      '<xsl:template match="/">' +
+      '  <xsl:call-template name="nodes">' +
+      '    <xsl:with-param name="node" select="/root" />' +
+      '  </xsl:call-template>' +
+      '</xsl:template>' +
+      '<xsl:template name="nodes">' +
+      '  <xsl:param name="node" />' +
+      '  <ul>' +
+      '  <xsl:for-each select="$node/item">' +
+      '    <xsl:variable name="children" select="count(./item) &gt; 0" />' +
+      '    <li>' +
+      '      <xsl:attribute name="class">' +
+      '        <xsl:if test="position() = last()">jstree-last </xsl:if>' +
+      '        <xsl:choose>' +
+      '          <xsl:when test="@state = \'open\'">jstree-open </xsl:when>' +
+      '          <xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' +
+      '          <xsl:otherwise>jstree-leaf </xsl:otherwise>' +
+      '        </xsl:choose>' +
+      '        <xsl:value-of select="@class" />' +
+      '      </xsl:attribute>' +
+      '      <xsl:for-each select="@*">' +
+      '        <xsl:if test="name() != \'class\' and name() != \'state\' and name() != \'hasChildren\'">' +
+      '          <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+      '        </xsl:if>' +
+      '      </xsl:for-each>' +
+      '  <ins class="jstree-icon"><xsl:text>&#xa0;</xsl:text></ins>' +
+      '      <xsl:for-each select="content/name">' +
+      '        <a>' +
+      '        <xsl:attribute name="href">' +
+      '          <xsl:choose>' +
+      '          <xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' +
+      '          <xsl:otherwise>#</xsl:otherwise>' +
+      '          </xsl:choose>' +
+      '        </xsl:attribute>' +
+      '        <xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' +
+      '        <xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' +
+      '        <xsl:for-each select="@*">' +
+      '          <xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' +
+      '            <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+      '          </xsl:if>' +
+      '        </xsl:for-each>' +
+      '          <ins>' +
+      '            <xsl:attribute name="class">jstree-icon ' +
+      '              <xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' +
+      '            </xsl:attribute>' +
+      '            <xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' +
+      '            <xsl:text>&#xa0;</xsl:text>' +
+      '          </ins>' +
+      '          <xsl:copy-of select="./child::node()" />' +
+      '        </a>' +
+      '      </xsl:for-each>' +
+      '      <xsl:if test="$children or @hasChildren"><xsl:call-template name="nodes"><xsl:with-param name="node" select="current()" /></xsl:call-template></xsl:if>' +
+      '    </li>' +
+      '  </xsl:for-each>' +
+      '  </ul>' +
+      '</xsl:template>' +
+      '</xsl:stylesheet>',
+
+    'flat' : '<' + '?xml version="1.0" encoding="utf-8" ?>' +
+      '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >' +
+      '<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" standalone="no" indent="no" media-type="text/xml" />' +
+      '<xsl:template match="/">' +
+      '  <ul>' +
+      '  <xsl:for-each select="//item[not(@parent_id) or @parent_id=0 or not(@parent_id = //item/@id)]">' + /* the last `or` may be removed */
+      '    <xsl:call-template name="nodes">' +
+      '      <xsl:with-param name="node" select="." />' +
+      '      <xsl:with-param name="is_last" select="number(position() = last())" />' +
+      '    </xsl:call-template>' +
+      '  </xsl:for-each>' +
+      '  </ul>' +
+      '</xsl:template>' +
+      '<xsl:template name="nodes">' +
+      '  <xsl:param name="node" />' +
+      '  <xsl:param name="is_last" />' +
+      '  <xsl:variable name="children" select="count(//item[@parent_id=$node/attribute::id]) &gt; 0" />' +
+      '  <li>' +
+      '  <xsl:attribute name="class">' +
+      '    <xsl:if test="$is_last = true()">jstree-last </xsl:if>' +
+      '    <xsl:choose>' +
+      '      <xsl:when test="@state = \'open\'">jstree-open </xsl:when>' +
+      '      <xsl:when test="$children or @hasChildren or @state = \'closed\'">jstree-closed </xsl:when>' +
+      '      <xsl:otherwise>jstree-leaf </xsl:otherwise>' +
+      '    </xsl:choose>' +
+      '    <xsl:value-of select="@class" />' +
+      '  </xsl:attribute>' +
+      '  <xsl:for-each select="@*">' +
+      '    <xsl:if test="name() != \'parent_id\' and name() != \'hasChildren\' and name() != \'class\' and name() != \'state\'">' +
+      '    <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+      '    </xsl:if>' +
+      '  </xsl:for-each>' +
+      '  <ins class="jstree-icon"><xsl:text>&#xa0;</xsl:text></ins>' +
+      '  <xsl:for-each select="content/name">' +
+      '    <a>' +
+      '    <xsl:attribute name="href">' +
+      '      <xsl:choose>' +
+      '      <xsl:when test="@href"><xsl:value-of select="@href" /></xsl:when>' +
+      '      <xsl:otherwise>#</xsl:otherwise>' +
+      '      </xsl:choose>' +
+      '    </xsl:attribute>' +
+      '    <xsl:attribute name="class"><xsl:value-of select="@lang" /> <xsl:value-of select="@class" /></xsl:attribute>' +
+      '    <xsl:attribute name="style"><xsl:value-of select="@style" /></xsl:attribute>' +
+      '    <xsl:for-each select="@*">' +
+      '      <xsl:if test="name() != \'style\' and name() != \'class\' and name() != \'href\'">' +
+      '        <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute>' +
+      '      </xsl:if>' +
+      '    </xsl:for-each>' +
+      '      <ins>' +
+      '        <xsl:attribute name="class">jstree-icon ' +
+      '          <xsl:if test="string-length(attribute::icon) > 0 and not(contains(@icon,\'/\'))"><xsl:value-of select="@icon" /></xsl:if>' +
+      '        </xsl:attribute>' +
+      '        <xsl:if test="string-length(attribute::icon) > 0 and contains(@icon,\'/\')"><xsl:attribute name="style">background:url(<xsl:value-of select="@icon" />) center center no-repeat;</xsl:attribute></xsl:if>' +
+      '        <xsl:text>&#xa0;</xsl:text>' +
+      '      </ins>' +
+      '      <xsl:copy-of select="./child::node()" />' +
+      '    </a>' +
+      '  </xsl:for-each>' +
+      '  <xsl:if test="$children">' +
+      '    <ul>' +
+      '    <xsl:for-each select="//item[@parent_id=$node/attribute::id]">' +
+      '      <xsl:call-template name="nodes">' +
+      '        <xsl:with-param name="node" select="." />' +
+      '        <xsl:with-param name="is_last" select="number(position() = last())" />' +
+      '      </xsl:call-template>' +
+      '    </xsl:for-each>' +
+      '    </ul>' +
+      '  </xsl:if>' +
+      '  </li>' +
+      '</xsl:template>' +
+      '</xsl:stylesheet>'
+  },
+  escape_xml = function(string) {
+    return string
+      .toString()
+      .replace(/&/g, '&amp;')
+      .replace(/</g, '&lt;')
+      .replace(/>/g, '&gt;')
+      .replace(/"/g, '&quot;')
+      .replace(/'/g, '&apos;');
+  };
+  $.jstree.plugin("xml_data", {
+    defaults : {
+      data : false,
+      ajax : false,
+      xsl : "flat",
+      clean_node : false,
+      correct_state : true,
+      get_skip_empty : false,
+      get_include_preamble : true
+    },
+    _fn : {
+      load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_xml(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
+      _is_loaded : function (obj) {
+        var s = this._get_settings().xml_data;
+        obj = this._get_node(obj);
+        return obj == -1 || !obj || (!s.ajax && !$.isFunction(s.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0;
+      },
+      load_node_xml : function (obj, s_call, e_call) {
+        var s = this.get_settings().xml_data,
+          error_func = function () {},
+          success_func = function () {};
+
+        obj = this._get_node(obj);
+        if(obj && obj !== -1) {
+          if(obj.data("jstree-is-loading")) { return; }
+          else { obj.data("jstree-is-loading",true); }
+        }
+        switch(!0) {
+          case (!s.data && !s.ajax): throw "Neither data nor ajax settings supplied.";
+          case ($.isFunction(s.data)):
+            s.data.call(this, obj, $.proxy(function (d) {
+              this.parse_xml(d, $.proxy(function (d) {
+                if(d) {
+                  d = d.replace(/ ?xmlns="[^"]*"/ig, "");
+                  if(d.length > 10) {
+                    d = $(d);
+                    if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); }
+                    else { obj.children("a.jstree-loading").removeClass("jstree-loading"); obj.append(d); obj.removeData("jstree-is-loading"); }
+                    if(s.clean_node) { this.clean_node(obj); }
+                    if(s_call) { s_call.call(this); }
+                  }
+                  else {
+                    if(obj && obj !== -1) {
+                      obj.children("a.jstree-loading").removeClass("jstree-loading");
+                      obj.removeData("jstree-is-loading");
+                      if(s.correct_state) {
+                        this.correct_state(obj);
+                        if(s_call) { s_call.call(this); }
+                      }
+                    }
+                    else {
+                      if(s.correct_state) {
+                        this.get_container().children("ul").empty();
+                        if(s_call) { s_call.call(this); }
+                      }
+                    }
+                  }
+                }
+              }, this));
+            }, this));
+            break;
+          case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)):
+            if(!obj || obj == -1) {
+              this.parse_xml(s.data, $.proxy(function (d) {
+                if(d) {
+                  d = d.replace(/ ?xmlns="[^"]*"/ig, "");
+                  if(d.length > 10) {
+                    d = $(d);
+                    this.get_container().children("ul").empty().append(d.children());
+                    if(s.clean_node) { this.clean_node(obj); }
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+                else {
+                  if(s.correct_state) {
+                    this.get_container().children("ul").empty();
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+              }, this));
+            }
+            break;
+          case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
+            error_func = function (x, t, e) {
+              var ef = this.get_settings().xml_data.ajax.error;
+              if(ef) { ef.call(this, x, t, e); }
+              if(obj !== -1 && obj.length) {
+                obj.children("a.jstree-loading").removeClass("jstree-loading");
+                obj.removeData("jstree-is-loading");
+                if(t === "success" && s.correct_state) { this.correct_state(obj); }
+              }
+              else {
+                if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); }
+              }
+              if(e_call) { e_call.call(this); }
+            };
+            success_func = function (d, t, x) {
+              d = x.responseText;
+              var sf = this.get_settings().xml_data.ajax.success;
+              if(sf) { d = sf.call(this,d,t,x) || d; }
+              if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "")) {
+                return error_func.call(this, x, t, "");
+              }
+              this.parse_xml(d, $.proxy(function (d) {
+                if(d) {
+                  d = d.replace(/ ?xmlns="[^"]*"/ig, "");
+                  if(d.length > 10) {
+                    d = $(d);
+                    if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); }
+                    else { obj.children("a.jstree-loading").removeClass("jstree-loading"); obj.append(d); obj.removeData("jstree-is-loading"); }
+                    if(s.clean_node) { this.clean_node(obj); }
+                    if(s_call) { s_call.call(this); }
+                  }
+                  else {
+                    if(obj && obj !== -1) {
+                      obj.children("a.jstree-loading").removeClass("jstree-loading");
+                      obj.removeData("jstree-is-loading");
+                      if(s.correct_state) {
+                        this.correct_state(obj);
+                        if(s_call) { s_call.call(this); }
+                      }
+                    }
+                    else {
+                      if(s.correct_state) {
+                        this.get_container().children("ul").empty();
+                        if(s_call) { s_call.call(this); }
+                      }
+                    }
+                  }
+                }
+              }, this));
+            };
+            s.ajax.context = this;
+            s.ajax.error = error_func;
+            s.ajax.success = success_func;
+            if(!s.ajax.dataType) { s.ajax.dataType = "xml"; }
+            if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); }
+            if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); }
+            $.ajax(s.ajax);
+            break;
+        }
+      },
+      parse_xml : function (xml, callback) {
+        var s = this._get_settings().xml_data;
+        $.vakata.xslt(xml, xsl[s.xsl], callback);
+      },
+      get_xml : function (tp, obj, li_attr, a_attr, is_callback) {
+        var result = "",
+          s = this._get_settings(),
+          _this = this,
+          tmp1, tmp2, li, a, lang;
+        if(!tp) { tp = "flat"; }
+        if(!is_callback) { is_callback = 0; }
+        obj = this._get_node(obj);
+        if(!obj || obj === -1) { obj = this.get_container().find("> ul > li"); }
+        li_attr = $.isArray(li_attr) ? li_attr : [ "id", "class" ];
+        if(!is_callback && this.data.types && $.inArray(s.types.type_attr, li_attr) === -1) { li_attr.push(s.types.type_attr); }
+
+        a_attr = $.isArray(a_attr) ? a_attr : [ ];
+
+        if(!is_callback) {
+          if(s.xml_data.get_include_preamble) {
+            result += '<' + '?xml version="1.0" encoding="UTF-8"?' + '>';
+          }
+          result += "<root>";
+        }
+        obj.each(function () {
+          result += "<item";
+          li = $(this);
+          $.each(li_attr, function (i, v) {
+            var t = li.attr(v);
+            if(!s.xml_data.get_skip_empty || typeof t !== "undefined") {
+              result += " " + v + "=\"" + escape_xml((" " + (t || "")).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"")) + "\"";
+            }
+          });
+          if(li.hasClass("jstree-open")) { result += " state=\"open\""; }
+          if(li.hasClass("jstree-closed")) { result += " state=\"closed\""; }
+          if(tp === "flat") { result += " parent_id=\"" + escape_xml(is_callback) + "\""; }
+          result += ">";
+          result += "<content>";
+          a = li.children("a");
+          a.each(function () {
+            tmp1 = $(this);
+            lang = false;
+            result += "<name";
+            if($.inArray("languages", s.plugins) !== -1) {
+              $.each(s.languages, function (k, z) {
+                if(tmp1.hasClass(z)) { result += " lang=\"" + escape_xml(z) + "\""; lang = z; return false; }
+              });
+            }
+            if(a_attr.length) {
+              $.each(a_attr, function (k, z) {
+                var t = tmp1.attr(z);
+                if(!s.xml_data.get_skip_empty || typeof t !== "undefined") {
+                  result += " " + z + "=\"" + escape_xml((" " + t || "").replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"")) + "\"";
+                }
+              });
+            }
+            if(tmp1.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"").length) {
+              result += ' icon="' + escape_xml(tmp1.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"")) + '"';
+            }
+            if(tmp1.children("ins").get(0).style.backgroundImage.length) {
+              result += ' icon="' + escape_xml(tmp1.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")","").replace(/'/ig,"").replace(/"/ig,"")) + '"';
+            }
+            result += ">";
+            result += "<![CDATA[" + _this.get_text(tmp1, lang) + "]]>";
+            result += "</name>";
+          });
+          result += "</content>";
+          tmp2 = li[0].id || true;
+          li = li.find("> ul > li");
+          if(li.length) { tmp2 = _this.get_xml(tp, li, li_attr, a_attr, tmp2); }
+          else { tmp2 = ""; }
+          if(tp == "nest") { result += tmp2; }
+          result += "</item>";
+          if(tp == "flat") { result += tmp2; }
+        });
+        if(!is_callback) { result += "</root>"; }
+        return result;
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree search plugin
+ * Enables both sync and async search on the tree
+ * DOES NOT WORK WITH JSON PROGRESSIVE RENDER
+ */
+(function ($) {
+  $.expr[':'].jstree_contains = function(a,i,m){
+    return (a.textContent || a.innerText || "").toLowerCase().indexOf(m[3].toLowerCase())>=0;
+  };
+  $.expr[':'].jstree_title_contains = function(a,i,m) {
+    return (a.getAttribute("title") || "").toLowerCase().indexOf(m[3].toLowerCase())>=0;
+  };
+  $.jstree.plugin("search", {
+    __init : function () {
+      this.data.search.str = "";
+      this.data.search.result = $();
+      if(this._get_settings().search.show_only_matches) {
+        this.get_container()
+          .bind("search.jstree", function (e, data) {
+            $(this).children("ul").find("li").hide().removeClass("jstree-last");
+            data.rslt.nodes.parentsUntil(".jstree").andSelf().show()
+              .filter("ul").each(function () { $(this).children("li:visible").eq(-1).addClass("jstree-last"); });
+          })
+          .bind("clear_search.jstree", function () {
+            $(this).children("ul").find("li").css("display","").end().end().jstree("clean_node", -1);
+          });
+      }
+    },
+    defaults : {
+      ajax : false,
+      search_method : "jstree_contains", // for case insensitive - jstree_contains
+      show_only_matches : false
+    },
+    _fn : {
+      search : function (str, skip_async) {
+        if($.trim(str) === "") { this.clear_search(); return; }
+        var s = this.get_settings().search,
+          t = this,
+          error_func = function () { },
+          success_func = function () { };
+        this.data.search.str = str;
+
+        if(!skip_async && s.ajax !== false && this.get_container_ul().find("li.jstree-closed:not(:has(ul)):eq(0)").length > 0) {
+          this.search.supress_callback = true;
+          error_func = function () { };
+          success_func = function (d, t, x) {
+            var sf = this.get_settings().search.ajax.success;
+            if(sf) { d = sf.call(this,d,t,x) || d; }
+            this.data.search.to_open = d;
+            this._search_open();
+          };
+          s.ajax.context = this;
+          s.ajax.error = error_func;
+          s.ajax.success = success_func;
+          if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, str); }
+          if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, str); }
+          if(!s.ajax.data) { s.ajax.data = { "search_string" : str }; }
+          if(!s.ajax.dataType || /^json/.exec(s.ajax.dataType)) { s.ajax.dataType = "json"; }
+          $.ajax(s.ajax);
+          return;
+        }
+        if(this.data.search.result.length) { this.clear_search(); }
+        this.data.search.result = this.get_container().find("a" + (this.data.languages ? "." + this.get_lang() : "" ) + ":" + (s.search_method) + "(" + this.data.search.str + ")");
+        this.data.search.result.addClass("jstree-search").parent().parents(".jstree-closed").each(function () {
+          t.open_node(this, false, true);
+        });
+        this.__callback({ nodes : this.data.search.result, str : str });
+      },
+      clear_search : function (str) {
+        this.data.search.result.removeClass("jstree-search");
+        this.__callback(this.data.search.result);
+        this.data.search.result = $();
+      },
+      _search_open : function (is_callback) {
+        var _this = this,
+          done = true,
+          current = [],
+          remaining = [];
+        if(this.data.search.to_open.length) {
+          $.each(this.data.search.to_open, function (i, val) {
+            if(val == "#") { return true; }
+            if($(val).length && $(val).is(".jstree-closed")) { current.push(val); }
+            else { remaining.push(val); }
+          });
+          if(current.length) {
+            this.data.search.to_open = remaining;
+            $.each(current, function (i, val) {
+              _this.open_node(val, function () { _this._search_open(true); });
+            });
+            done = false;
+          }
+        }
+        if(done) { this.search(this.data.search.str, true); }
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree contextmenu plugin
+ */
+(function ($) {
+  $.vakata.context = {
+    hide_on_mouseleave : false,
+
+    cnt    : $("<div id='vakata-contextmenu' />"),
+    vis    : false,
+    tgt    : false,
+    par    : false,
+    func  : false,
+    data  : false,
+    rtl    : false,
+    show  : function (s, t, x, y, d, p, rtl) {
+      $.vakata.context.rtl = !!rtl;
+      var html = $.vakata.context.parse(s), h, w;
+      if(!html) { return; }
+      $.vakata.context.vis = true;
+      $.vakata.context.tgt = t;
+      $.vakata.context.par = p || t || null;
+      $.vakata.context.data = d || null;
+      $.vakata.context.cnt
+        .html(html)
+        .css({ "visibility" : "hidden", "display" : "block", "left" : 0, "top" : 0 });
+
+      if($.vakata.context.hide_on_mouseleave) {
+        $.vakata.context.cnt
+          .one("mouseleave", function(e) { $.vakata.context.hide(); });
+      }
+
+      h = $.vakata.context.cnt.height();
+      w = $.vakata.context.cnt.width();
+      if(x + w > $(document).width()) {
+        x = $(document).width() - (w + 5);
+        $.vakata.context.cnt.find("li > ul").addClass("right");
+      }
+      if(y + h > $(document).height()) {
+        y = y - (h + t[0].offsetHeight);
+        $.vakata.context.cnt.find("li > ul").addClass("bottom");
+      }
+
+      $.vakata.context.cnt
+        .css({ "left" : x, "top" : y })
+        .find("li:has(ul)")
+          .bind("mouseenter", function (e) {
+            var w = $(document).width(),
+              h = $(document).height(),
+              ul = $(this).children("ul").show();
+            if(w !== $(document).width()) { ul.toggleClass("right"); }
+            if(h !== $(document).height()) { ul.toggleClass("bottom"); }
+          })
+          .bind("mouseleave", function (e) {
+            $(this).children("ul").hide();
+          })
+          .end()
+        .css({ "visibility" : "visible" })
+        .show();
+      $(document).triggerHandler("context_show.vakata");
+    },
+    hide  : function () {
+      $.vakata.context.vis = false;
+      $.vakata.context.cnt.attr("class","").css({ "visibility" : "hidden" });
+      $(document).triggerHandler("context_hide.vakata");
+    },
+    parse  : function (s, is_callback) {
+      if(!s) { return false; }
+      var str = "",
+        tmp = false,
+        was_sep = true;
+      if(!is_callback) { $.vakata.context.func = {}; }
+      str += "<ul>";
+      $.each(s, function (i, val) {
+        if(!val) { return true; }
+        $.vakata.context.func[i] = val.action;
+        if(!was_sep && val.separator_before) {
+          str += "<li class='vakata-separator vakata-separator-before'></li>";
+        }
+        was_sep = false;
+        str += "<li class='" + (val._class || "") + (val._disabled ? " jstree-contextmenu-disabled " : "") + "'><ins ";
+        if(val.icon && val.icon.indexOf("/") === -1) { str += " class='" + val.icon + "' "; }
+        if(val.icon && val.icon.indexOf("/") !== -1) { str += " style='background:url(" + val.icon + ") center center no-repeat;' "; }
+        str += ">&#160;</ins><a href='#' rel='" + i + "'>";
+        if(val.submenu) {
+          str += "<span style='float:" + ($.vakata.context.rtl ? "left" : "right") + ";'>&raquo;</span>";
+        }
+        str += val.label + "</a>";
+        if(val.submenu) {
+          tmp = $.vakata.context.parse(val.submenu, true);
+          if(tmp) { str += tmp; }
+        }
+        str += "</li>";
+        if(val.separator_after) {
+          str += "<li class='vakata-separator vakata-separator-after'></li>";
+          was_sep = true;
+        }
+      });
+      str = str.replace(/<li class\='vakata-separator vakata-separator-after'\><\/li\>$/,"");
+      str += "</ul>";
+      $(document).triggerHandler("context_parse.vakata");
+      return str.length > 10 ? str : false;
+    },
+    exec  : function (i) {
+      if($.isFunction($.vakata.context.func[i])) {
+        // if is string - eval and call it!
+        $.vakata.context.func[i].call($.vakata.context.data, $.vakata.context.par);
+        return true;
+      }
+      else { return false; }
+    }
+  };
+  $(function () {
+    var css_string = '' +
+      '#vakata-contextmenu { display:block; visibility:hidden; left:0; top:-200px; position:absolute; margin:0; padding:0; min-width:180px; background:#ebebeb; border:1px solid silver; z-index:10000; *width:180px; } ' +
+      '#vakata-contextmenu ul { min-width:180px; *width:180px; } ' +
+      '#vakata-contextmenu ul, #vakata-contextmenu li { margin:0; padding:0; list-style-type:none; display:block; } ' +
+      '#vakata-contextmenu li { line-height:20px; min-height:20px; position:relative; padding:0px; } ' +
+      '#vakata-contextmenu li a { padding:1px 6px; line-height:17px; display:block; text-decoration:none; margin:1px 1px 0 1px; } ' +
+      '#vakata-contextmenu li ins { float:left; width:16px; height:16px; text-decoration:none; margin-right:2px; } ' +
+      '#vakata-contextmenu li a:hover, #vakata-contextmenu li.vakata-hover > a { background:gray; color:white; } ' +
+      '#vakata-contextmenu li ul { display:none; position:absolute; top:-2px; left:100%; background:#ebebeb; border:1px solid gray; } ' +
+      '#vakata-contextmenu .right { right:100%; left:auto; } ' +
+      '#vakata-contextmenu .bottom { bottom:-1px; top:auto; } ' +
+      '#vakata-contextmenu li.vakata-separator { min-height:0; height:1px; line-height:1px; font-size:1px; overflow:hidden; margin:0 2px; background:silver; /* border-top:1px solid #fefefe; */ padding:0; } ';
+    $.vakata.css.add_sheet({ str : css_string, title : "vakata" });
+    $.vakata.context.cnt
+      .delegate("a","click", function (e) { e.preventDefault(); })
+      .delegate("a","mouseup", function (e) {
+        if(!$(this).parent().hasClass("jstree-contextmenu-disabled") && $.vakata.context.exec($(this).attr("rel"))) {
+          $.vakata.context.hide();
+        }
+        else { $(this).blur(); }
+      })
+      .delegate("a","mouseover", function () {
+        $.vakata.context.cnt.find(".vakata-hover").removeClass("vakata-hover");
+      })
+      .appendTo("body");
+    $(document).bind("mousedown", function (e) { if($.vakata.context.vis && !$.contains($.vakata.context.cnt[0], e.target)) { $.vakata.context.hide(); } });
+    if(typeof $.hotkeys !== "undefined") {
+      $(document)
+        .bind("keydown", "up", function (e) {
+          if($.vakata.context.vis) {
+            var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").prevAll("li:not(.vakata-separator)").first();
+            if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").last(); }
+            o.addClass("vakata-hover");
+            e.stopImmediatePropagation();
+            e.preventDefault();
+          }
+        })
+        .bind("keydown", "down", function (e) {
+          if($.vakata.context.vis) {
+            var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").nextAll("li:not(.vakata-separator)").first();
+            if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").first(); }
+            o.addClass("vakata-hover");
+            e.stopImmediatePropagation();
+            e.preventDefault();
+          }
+        })
+        .bind("keydown", "right", function (e) {
+          if($.vakata.context.vis) {
+            $.vakata.context.cnt.find(".vakata-hover").children("ul").show().children("li:not(.vakata-separator)").removeClass("vakata-hover").first().addClass("vakata-hover");
+            e.stopImmediatePropagation();
+            e.preventDefault();
+          }
+        })
+        .bind("keydown", "left", function (e) {
+          if($.vakata.context.vis) {
+            $.vakata.context.cnt.find(".vakata-hover").children("ul").hide().children(".vakata-separator").removeClass("vakata-hover");
+            e.stopImmediatePropagation();
+            e.preventDefault();
+          }
+        })
+        .bind("keydown", "esc", function (e) {
+          $.vakata.context.hide();
+          e.preventDefault();
+        })
+        .bind("keydown", "space", function (e) {
+          $.vakata.context.cnt.find(".vakata-hover").last().children("a").click();
+          e.preventDefault();
+        });
+    }
+  });
+
+  $.jstree.plugin("contextmenu", {
+    __init : function () {
+      this.get_container()
+        .delegate("a", "contextmenu.jstree", $.proxy(function (e) {
+            e.preventDefault();
+            if(!$(e.currentTarget).hasClass("jstree-loading")) {
+              this.show_contextmenu(e.currentTarget, e.pageX, e.pageY);
+            }
+          }, this))
+        .delegate("a", "click.jstree", $.proxy(function (e) {
+            if(this.data.contextmenu) {
+              $.vakata.context.hide();
+            }
+          }, this))
+        .bind("destroy.jstree", $.proxy(function () {
+            // TODO: move this to descruct method
+            if(this.data.contextmenu) {
+              $.vakata.context.hide();
+            }
+          }, this));
+      $(document).bind("context_hide.vakata", $.proxy(function () { this.data.contextmenu = false; }, this));
+    },
+    defaults : {
+      select_node : false, // requires UI plugin
+      show_at_node : true,
+      items : { // Could be a function that should return an object like this one
+        "create" : {
+          "separator_before"  : false,
+          "separator_after"  : true,
+          "label"        : "Create",
+          "action"      : function (obj) { this.create(obj); }
+        },
+        "rename" : {
+          "separator_before"  : false,
+          "separator_after"  : false,
+          "label"        : "Rename",
+          "action"      : function (obj) { this.rename(obj); }
+        },
+        "remove" : {
+          "separator_before"  : false,
+          "icon"        : false,
+          "separator_after"  : false,
+          "label"        : "Delete",
+          "action"      : function (obj) { if(this.is_selected(obj)) { this.remove(); } else { this.remove(obj); } }
+        },
+        "ccp" : {
+          "separator_before"  : true,
+          "icon"        : false,
+          "separator_after"  : false,
+          "label"        : "Edit",
+          "action"      : false,
+          "submenu" : {
+            "cut" : {
+              "separator_before"  : false,
+              "separator_after"  : false,
+              "label"        : "Cut",
+              "action"      : function (obj) { this.cut(obj); }
+            },
+            "copy" : {
+              "separator_before"  : false,
+              "icon"        : false,
+              "separator_after"  : false,
+              "label"        : "Copy",
+              "action"      : function (obj) { this.copy(obj); }
+            },
+            "paste" : {
+              "separator_before"  : false,
+              "icon"        : false,
+              "separator_after"  : false,
+              "label"        : "Paste",
+              "action"      : function (obj) { this.paste(obj); }
+            }
+          }
+        }
+      }
+    },
+    _fn : {
+      show_contextmenu : function (obj, x, y) {
+        obj = this._get_node(obj);
+        var s = this.get_settings().contextmenu,
+          a = obj.children("a:visible:eq(0)"),
+          o = false,
+          i = false;
+        if(s.select_node && this.data.ui && !this.is_selected(obj)) {
+          this.deselect_all();
+          this.select_node(obj, true);
+        }
+        if(s.show_at_node || typeof x === "undefined" || typeof y === "undefined") {
+          o = a.offset();
+          x = o.left;
+          y = o.top + this.data.core.li_height;
+        }
+        i = obj.data("jstree") && obj.data("jstree").contextmenu ? obj.data("jstree").contextmenu : s.items;
+        if($.isFunction(i)) { i = i.call(this, obj); }
+        this.data.contextmenu = true;
+        $.vakata.context.show(i, a, x, y, this, obj, this._get_settings().core.rtl);
+        if(this.data.themes) { $.vakata.context.cnt.attr("class", "jstree-" + this.data.themes.theme + "-context"); }
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree types plugin
+ * Adds support types of nodes
+ * You can set an attribute on each li node, that represents its type.
+ * According to the type setting the node may get custom icon/validation rules
+ */
+(function ($) {
+  $.jstree.plugin("types", {
+    __init : function () {
+      var s = this._get_settings().types;
+      this.data.types.attach_to = [];
+      this.get_container()
+        .bind("init.jstree", $.proxy(function () {
+            var types = s.types,
+              attr  = s.type_attr,
+              icons_css = "",
+              _this = this;
+
+            $.each(types, function (i, tp) {
+              $.each(tp, function (k, v) {
+                if(!/^(max_depth|max_children|icon|valid_children)$/.test(k)) { _this.data.types.attach_to.push(k); }
+              });
+              if(!tp.icon) { return true; }
+              if( tp.icon.image || tp.icon.position) {
+                if(i == "default")  { icons_css += '.jstree-' + _this.get_index() + ' a > .jstree-icon { '; }
+                else        { icons_css += '.jstree-' + _this.get_index() + ' li[' + attr + '="' + i + '"] > a > .jstree-icon { '; }
+                if(tp.icon.image)  { icons_css += ' background-image:url(' + tp.icon.image + '); '; }
+                if(tp.icon.position){ icons_css += ' background-position:' + tp.icon.position + '; '; }
+                else        { icons_css += ' background-position:0 0; '; }
+                icons_css += '} ';
+              }
+            });
+            if(icons_css !== "") { $.vakata.css.add_sheet({ 'str' : icons_css, title : "jstree-types" }); }
+          }, this))
+        .bind("before.jstree", $.proxy(function (e, data) {
+            var s, t,
+              o = this._get_settings().types.use_data ? this._get_node(data.args[0]) : false,
+              d = o && o !== -1 && o.length ? o.data("jstree") : false;
+            if(d && d.types && d.types[data.func] === false) { e.stopImmediatePropagation(); return false; }
+            if($.inArray(data.func, this.data.types.attach_to) !== -1) {
+              if(!data.args[0] || (!data.args[0].tagName && !data.args[0].jquery)) { return; }
+              s = this._get_settings().types.types;
+              t = this._get_type(data.args[0]);
+              if(
+                (
+                  (s[t] && typeof s[t][data.func] !== "undefined") ||
+                  (s["default"] && typeof s["default"][data.func] !== "undefined")
+                ) && this._check(data.func, data.args[0]) === false
+              ) {
+                e.stopImmediatePropagation();
+                return false;
+              }
+            }
+          }, this));
+      if(is_ie6) {
+        this.get_container()
+          .bind("load_node.jstree set_type.jstree", $.proxy(function (e, data) {
+              var r = data && data.rslt && data.rslt.obj && data.rslt.obj !== -1 ? this._get_node(data.rslt.obj).parent() : this.get_container_ul(),
+                c = false,
+                s = this._get_settings().types;
+              $.each(s.types, function (i, tp) {
+                if(tp.icon && (tp.icon.image || tp.icon.position)) {
+                  c = i === "default" ? r.find("li > a > .jstree-icon") : r.find("li[" + s.type_attr + "='" + i + "'] > a > .jstree-icon");
+                  if(tp.icon.image) { c.css("backgroundImage","url(" + tp.icon.image + ")"); }
+                  c.css("backgroundPosition", tp.icon.position || "0 0");
+                }
+              });
+            }, this));
+      }
+    },
+    defaults : {
+      // defines maximum number of root nodes (-1 means unlimited, -2 means disable max_children checking)
+      max_children    : -1,
+      // defines the maximum depth of the tree (-1 means unlimited, -2 means disable max_depth checking)
+      max_depth      : -1,
+      // defines valid node types for the root nodes
+      valid_children    : "all",
+
+      // whether to use $.data
+      use_data : false,
+      // where is the type stores (the rel attribute of the LI element)
+      type_attr : "rel",
+      // a list of types
+      types : {
+        // the default type
+        "default" : {
+          "max_children"  : -1,
+          "max_depth"    : -1,
+          "valid_children": "all"
+
+          // Bound functions - you can bind any other function here (using boolean or function)
+          //"select_node"  : true
+        }
+      }
+    },
+    _fn : {
+      _types_notify : function (n, data) {
+        if(data.type && this._get_settings().types.use_data) {
+          this.set_type(data.type, n);
+        }
+      },
+      _get_type : function (obj) {
+        obj = this._get_node(obj);
+        return (!obj || !obj.length) ? false : obj.attr(this._get_settings().types.type_attr) || "default";
+      },
+      set_type : function (str, obj) {
+        obj = this._get_node(obj);
+        var ret = (!obj.length || !str) ? false : obj.attr(this._get_settings().types.type_attr, str);
+        if(ret) { this.__callback({ obj : obj, type : str}); }
+        return ret;
+      },
+      _check : function (rule, obj, opts) {
+        obj = this._get_node(obj);
+        var v = false, t = this._get_type(obj), d = 0, _this = this, s = this._get_settings().types, data = false;
+        if(obj === -1) {
+          if(!!s[rule]) { v = s[rule]; }
+          else { return; }
+        }
+        else {
+          if(t === false) { return; }
+          data = s.use_data ? obj.data("jstree") : false;
+          if(data && data.types && typeof data.types[rule] !== "undefined") { v = data.types[rule]; }
+          else if(!!s.types[t] && typeof s.types[t][rule] !== "undefined") { v = s.types[t][rule]; }
+          else if(!!s.types["default"] && typeof s.types["default"][rule] !== "undefined") { v = s.types["default"][rule]; }
+        }
+        if($.isFunction(v)) { v = v.call(this, obj); }
+        if(rule === "max_depth" && obj !== -1 && opts !== false && s.max_depth !== -2 && v !== 0) {
+          // also include the node itself - otherwise if root node it is not checked
+          obj.children("a:eq(0)").parentsUntil(".jstree","li").each(function (i) {
+            // check if current depth already exceeds global tree depth
+            if(s.max_depth !== -1 && s.max_depth - (i + 1) <= 0) { v = 0; return false; }
+            d = (i === 0) ? v : _this._check(rule, this, false);
+            // check if current node max depth is already matched or exceeded
+            if(d !== -1 && d - (i + 1) <= 0) { v = 0; return false; }
+            // otherwise - set the max depth to the current value minus current depth
+            if(d >= 0 && (d - (i + 1) < v || v < 0) ) { v = d - (i + 1); }
+            // if the global tree depth exists and it minus the nodes calculated so far is less than `v` or `v` is unlimited
+            if(s.max_depth >= 0 && (s.max_depth - (i + 1) < v || v < 0) ) { v = s.max_depth - (i + 1); }
+          });
+        }
+        return v;
+      },
+      check_move : function () {
+        if(!this.__call_old()) { return false; }
+        var m  = this._get_move(),
+          s  = m.rt._get_settings().types,
+          mc = m.rt._check("max_children", m.cr),
+          md = m.rt._check("max_depth", m.cr),
+          vc = m.rt._check("valid_children", m.cr),
+          ch = 0, d = 1, t;
+
+        if(vc === "none") { return false; }
+        if($.isArray(vc) && m.ot && m.ot._get_type) {
+          m.o.each(function () {
+            if($.inArray(m.ot._get_type(this), vc) === -1) { d = false; return false; }
+          });
+          if(d === false) { return false; }
+        }
+        if(s.max_children !== -2 && mc !== -1) {
+          ch = m.cr === -1 ? this.get_container().find("> ul > li").not(m.o).length : m.cr.find("> ul > li").not(m.o).length;
+          if(ch + m.o.length > mc) { return false; }
+        }
+        if(s.max_depth !== -2 && md !== -1) {
+          d = 0;
+          if(md === 0) { return false; }
+          if(typeof m.o.d === "undefined") {
+            // TODO: deal with progressive rendering and async when checking max_depth (how to know the depth of the moved node)
+            t = m.o;
+            while(t.length > 0) {
+              t = t.find("> ul > li");
+              d ++;
+            }
+            m.o.d = d;
+          }
+          if(md - m.o.d < 0) { return false; }
+        }
+        return true;
+      },
+      create_node : function (obj, position, js, callback, is_loaded, skip_check) {
+        if(!skip_check && (is_loaded || this._is_loaded(obj))) {
+          var p  = (typeof position == "string" && position.match(/^before|after$/i) && obj !== -1) ? this._get_parent(obj) : this._get_node(obj),
+            s  = this._get_settings().types,
+            mc = this._check("max_children", p),
+            md = this._check("max_depth", p),
+            vc = this._check("valid_children", p),
+            ch;
+          if(typeof js === "string") { js = { data : js }; }
+          if(!js) { js = {}; }
+          if(vc === "none") { return false; }
+          if($.isArray(vc)) {
+            if(!js.attr || !js.attr[s.type_attr]) {
+              if(!js.attr) { js.attr = {}; }
+              js.attr[s.type_attr] = vc[0];
+            }
+            else {
+              if($.inArray(js.attr[s.type_attr], vc) === -1) { return false; }
+            }
+          }
+          if(s.max_children !== -2 && mc !== -1) {
+            ch = p === -1 ? this.get_container().find("> ul > li").length : p.find("> ul > li").length;
+            if(ch + 1 > mc) { return false; }
+          }
+          if(s.max_depth !== -2 && md !== -1 && (md - 1) < 0) { return false; }
+        }
+        return this.__call_old(true, obj, position, js, callback, is_loaded, skip_check);
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree HTML plugin
+ * The HTML data store. Datastores are build by replacing the `load_node` and `_is_loaded` functions.
+ */
+(function ($) {
+  $.jstree.plugin("html_data", {
+    __init : function () {
+      // this used to use html() and clean the whitespace, but this way any attached data was lost
+      this.data.html_data.original_container_html = this.get_container().find(" > ul > li").clone(true);
+      // remove white space from LI node - otherwise nodes appear a bit to the right
+      this.data.html_data.original_container_html.find("li").andSelf().contents().filter(function() { return this.nodeType == 3; }).remove();
+    },
+    defaults : {
+      data : false,
+      ajax : false,
+      correct_state : true
+    },
+    _fn : {
+      load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_html(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
+      _is_loaded : function (obj) {
+        obj = this._get_node(obj);
+        return obj == -1 || !obj || (!this._get_settings().html_data.ajax && !$.isFunction(this._get_settings().html_data.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0;
+      },
+      load_node_html : function (obj, s_call, e_call) {
+        var d,
+          s = this.get_settings().html_data,
+          error_func = function () {},
+          success_func = function () {};
+        obj = this._get_node(obj);
+        if(obj && obj !== -1) {
+          if(obj.data("jstree-is-loading")) { return; }
+          else { obj.data("jstree-is-loading",true); }
+        }
+        switch(!0) {
+          case ($.isFunction(s.data)):
+            s.data.call(this, obj, $.proxy(function (d) {
+              if(d && d !== "" && d.toString && d.toString().replace(/^[\s\n]+$/,"") !== "") {
+                d = $(d);
+                if(!d.is("ul")) { d = $("<ul />").append(d); }
+                if(obj == -1 || !obj) { this.get_container().children("ul").empty().append(d.children()).find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'>&#160;</ins>").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); }
+                else { obj.children("a.jstree-loading").removeClass("jstree-loading"); obj.append(d).children("ul").find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'>&#160;</ins>").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); obj.removeData("jstree-is-loading"); }
+                this.clean_node(obj);
+                if(s_call) { s_call.call(this); }
+              }
+              else {
+                if(obj && obj !== -1) {
+                  obj.children("a.jstree-loading").removeClass("jstree-loading");
+                  obj.removeData("jstree-is-loading");
+                  if(s.correct_state) {
+                    this.correct_state(obj);
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+                else {
+                  if(s.correct_state) {
+                    this.get_container().children("ul").empty();
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+              }
+            }, this));
+            break;
+          case (!s.data && !s.ajax):
+            if(!obj || obj == -1) {
+              this.get_container()
+                .children("ul").empty()
+                .append(this.data.html_data.original_container_html)
+                .find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'>&#160;</ins>").end()
+                .filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon");
+              this.clean_node();
+            }
+            if(s_call) { s_call.call(this); }
+            break;
+          case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)):
+            if(!obj || obj == -1) {
+              d = $(s.data);
+              if(!d.is("ul")) { d = $("<ul />").append(d); }
+              this.get_container()
+                .children("ul").empty().append(d.children())
+                .find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'>&#160;</ins>").end()
+                .filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon");
+              this.clean_node();
+            }
+            if(s_call) { s_call.call(this); }
+            break;
+          case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
+            obj = this._get_node(obj);
+            error_func = function (x, t, e) {
+              var ef = this.get_settings().html_data.ajax.error;
+              if(ef) { ef.call(this, x, t, e); }
+              if(obj != -1 && obj.length) {
+                obj.children("a.jstree-loading").removeClass("jstree-loading");
+                obj.removeData("jstree-is-loading");
+                if(t === "success" && s.correct_state) { this.correct_state(obj); }
+              }
+              else {
+                if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); }
+              }
+              if(e_call) { e_call.call(this); }
+            };
+            success_func = function (d, t, x) {
+              var sf = this.get_settings().html_data.ajax.success;
+              if(sf) { d = sf.call(this,d,t,x) || d; }
+              if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "")) {
+                return error_func.call(this, x, t, "");
+              }
+              if(d) {
+                d = $(d);
+                if(!d.is("ul")) { d = $("<ul />").append(d); }
+                if(obj == -1 || !obj) { this.get_container().children("ul").empty().append(d.children()).find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'>&#160;</ins>").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); }
+                else { obj.children("a.jstree-loading").removeClass("jstree-loading"); obj.append(d).children("ul").find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend("<ins class='jstree-icon'>&#160;</ins>").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); obj.removeData("jstree-is-loading"); }
+                this.clean_node(obj);
+                if(s_call) { s_call.call(this); }
+              }
+              else {
+                if(obj && obj !== -1) {
+                  obj.children("a.jstree-loading").removeClass("jstree-loading");
+                  obj.removeData("jstree-is-loading");
+                  if(s.correct_state) {
+                    this.correct_state(obj);
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+                else {
+                  if(s.correct_state) {
+                    this.get_container().children("ul").empty();
+                    if(s_call) { s_call.call(this); }
+                  }
+                }
+              }
+            };
+            s.ajax.context = this;
+            s.ajax.error = error_func;
+            s.ajax.success = success_func;
+            if(!s.ajax.dataType) { s.ajax.dataType = "html"; }
+            if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); }
+            if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); }
+            $.ajax(s.ajax);
+            break;
+        }
+      }
+    }
+  });
+  // include the HTML data plugin by default
+  $.jstree.defaults.plugins.push("html_data");
+})(jQuery);
+//*/
+
+/*
+ * jsTree themeroller plugin
+ * Adds support for jQuery UI themes. Include this at the end of your plugins list, also make sure "themes" is not included.
+ */
+(function ($) {
+  $.jstree.plugin("themeroller", {
+    __init : function () {
+      var s = this._get_settings().themeroller;
+      this.get_container()
+        .addClass("ui-widget-content")
+        .addClass("jstree-themeroller")
+        .delegate("a","mouseenter.jstree", function (e) {
+          if(!$(e.currentTarget).hasClass("jstree-loading")) {
+            $(this).addClass(s.item_h);
+          }
+        })
+        .delegate("a","mouseleave.jstree", function () {
+          $(this).removeClass(s.item_h);
+        })
+        .bind("init.jstree", $.proxy(function (e, data) {
+            data.inst.get_container().find("> ul > li > .jstree-loading > ins").addClass("ui-icon-refresh");
+            this._themeroller(data.inst.get_container().find("> ul > li"));
+          }, this))
+        .bind("open_node.jstree create_node.jstree", $.proxy(function (e, data) {
+            this._themeroller(data.rslt.obj);
+          }, this))
+        .bind("loaded.jstree refresh.jstree", $.proxy(function (e) {
+            this._themeroller();
+          }, this))
+        .bind("close_node.jstree", $.proxy(function (e, data) {
+            this._themeroller(data.rslt.obj);
+          }, this))
+        .bind("delete_node.jstree", $.proxy(function (e, data) {
+            this._themeroller(data.rslt.parent);
+          }, this))
+        .bind("correct_state.jstree", $.proxy(function (e, data) {
+            data.rslt.obj
+              .children("ins.jstree-icon").removeClass(s.opened + " " + s.closed + " ui-icon").end()
+              .find("> a > ins.ui-icon")
+                .filter(function() {
+                  return this.className.toString()
+                    .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
+                    .indexOf("ui-icon-") === -1;
+                }).removeClass(s.item_open + " " + s.item_clsd).addClass(s.item_leaf || "jstree-no-icon");
+          }, this))
+        .bind("select_node.jstree", $.proxy(function (e, data) {
+            data.rslt.obj.children("a").addClass(s.item_a);
+          }, this))
+        .bind("deselect_node.jstree deselect_all.jstree", $.proxy(function (e, data) {
+            this.get_container()
+              .find("a." + s.item_a).removeClass(s.item_a).end()
+              .find("a.jstree-clicked").addClass(s.item_a);
+          }, this))
+        .bind("dehover_node.jstree", $.proxy(function (e, data) {
+            data.rslt.obj.children("a").removeClass(s.item_h);
+          }, this))
+        .bind("hover_node.jstree", $.proxy(function (e, data) {
+            this.get_container()
+              .find("a." + s.item_h).not(data.rslt.obj).removeClass(s.item_h);
+            data.rslt.obj.children("a").addClass(s.item_h);
+          }, this))
+        .bind("move_node.jstree", $.proxy(function (e, data) {
+            this._themeroller(data.rslt.o);
+            this._themeroller(data.rslt.op);
+          }, this));
+    },
+    __destroy : function () {
+      var s = this._get_settings().themeroller,
+        c = [ "ui-icon" ];
+      $.each(s, function (i, v) {
+        v = v.split(" ");
+        if(v.length) { c = c.concat(v); }
+      });
+      this.get_container()
+        .removeClass("ui-widget-content")
+        .find("." + c.join(", .")).removeClass(c.join(" "));
+    },
+    _fn : {
+      _themeroller : function (obj) {
+        var s = this._get_settings().themeroller;
+        obj = !obj || obj == -1 ? this.get_container_ul() : this._get_node(obj).parent();
+        obj
+          .find("li.jstree-closed")
+            .children("ins.jstree-icon").removeClass(s.opened).addClass("ui-icon " + s.closed).end()
+            .children("a").addClass(s.item)
+              .children("ins.jstree-icon").addClass("ui-icon")
+                .filter(function() {
+                  return this.className.toString()
+                    .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
+                    .indexOf("ui-icon-") === -1;
+                }).removeClass(s.item_leaf + " " + s.item_open).addClass(s.item_clsd || "jstree-no-icon")
+                .end()
+              .end()
+            .end()
+          .end()
+          .find("li.jstree-open")
+            .children("ins.jstree-icon").removeClass(s.closed).addClass("ui-icon " + s.opened).end()
+            .children("a").addClass(s.item)
+              .children("ins.jstree-icon").addClass("ui-icon")
+                .filter(function() {
+                  return this.className.toString()
+                    .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
+                    .indexOf("ui-icon-") === -1;
+                }).removeClass(s.item_leaf + " " + s.item_clsd).addClass(s.item_open || "jstree-no-icon")
+                .end()
+              .end()
+            .end()
+          .end()
+          .find("li.jstree-leaf")
+            .children("ins.jstree-icon").removeClass(s.closed + " ui-icon " + s.opened).end()
+            .children("a").addClass(s.item)
+              .children("ins.jstree-icon").addClass("ui-icon")
+                .filter(function() {
+                  return this.className.toString()
+                    .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
+                    .indexOf("ui-icon-") === -1;
+                }).removeClass(s.item_clsd + " " + s.item_open).addClass(s.item_leaf || "jstree-no-icon");
+      }
+    },
+    defaults : {
+      "opened"  : "ui-icon-triangle-1-se",
+      "closed"  : "ui-icon-triangle-1-e",
+      "item"    : "ui-state-default",
+      "item_h"  : "ui-state-hover",
+      "item_a"  : "ui-state-active",
+      "item_open"  : "ui-icon-folder-open",
+      "item_clsd"  : "ui-icon-folder-collapsed",
+      "item_leaf"  : "ui-icon-document"
+    }
+  });
+  $(function() {
+    var css_string = '' +
+      '.jstree-themeroller .ui-icon { overflow:visible; } ' +
+      '.jstree-themeroller a { padding:0 2px; } ' +
+      '.jstree-themeroller .jstree-no-icon { display:none; }';
+    $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree unique plugin
+ * Forces different names amongst siblings (still a bit experimental)
+ * NOTE: does not check language versions (it will not be possible to have nodes with the same title, even in different languages)
+ */
+(function ($) {
+  $.jstree.plugin("unique", {
+    __init : function () {
+      this.get_container()
+        .bind("before.jstree", $.proxy(function (e, data) {
+            var nms = [], res = true, p, t;
+            if(data.func == "move_node") {
+              // obj, ref, position, is_copy, is_prepared, skip_check
+              if(data.args[4] === true) {
+                if(data.args[0].o && data.args[0].o.length) {
+                  data.args[0].o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); });
+                  res = this._check_unique(nms, data.args[0].np.find("> ul > li").not(data.args[0].o), "move_node");
+                }
+              }
+            }
+            if(data.func == "create_node") {
+              // obj, position, js, callback, is_loaded
+              if(data.args[4] || this._is_loaded(data.args[0])) {
+                p = this._get_node(data.args[0]);
+                if(data.args[1] && (data.args[1] === "before" || data.args[1] === "after")) {
+                  p = this._get_parent(data.args[0]);
+                  if(!p || p === -1) { p = this.get_container(); }
+                }
+                if(typeof data.args[2] === "string") { nms.push(data.args[2]); }
+                else if(!data.args[2] || !data.args[2].data) { nms.push(this._get_string("new_node")); }
+                else { nms.push(data.args[2].data); }
+                res = this._check_unique(nms, p.find("> ul > li"), "create_node");
+              }
+            }
+            if(data.func == "rename_node") {
+              // obj, val
+              nms.push(data.args[1]);
+              t = this._get_node(data.args[0]);
+              p = this._get_parent(t);
+              if(!p || p === -1) { p = this.get_container(); }
+              res = this._check_unique(nms, p.find("> ul > li").not(t), "rename_node");
+            }
+            if(!res) {
+              e.stopPropagation();
+              return false;
+            }
+          }, this));
+    },
+    defaults : {
+      error_callback : $.noop
+    },
+    _fn : {
+      _check_unique : function (nms, p, func) {
+        var cnms = [];
+        p.children("a").each(function () { cnms.push($(this).text().replace(/^\s+/g,"")); });
+        if(!cnms.length || !nms.length) { return true; }
+        cnms = cnms.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",");
+        if((cnms.length + nms.length) != cnms.concat(nms).sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",").length) {
+          this._get_settings().unique.error_callback.call(null, nms, p, func);
+          return false;
+        }
+        return true;
+      },
+      check_move : function () {
+        if(!this.__call_old()) { return false; }
+        var p = this._get_move(), nms = [];
+        if(p.o && p.o.length) {
+          p.o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); });
+          return this._check_unique(nms, p.np.find("> ul > li").not(p.o), "check_move");
+        }
+        return true;
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+/*
+ * jsTree wholerow plugin
+ * Makes select and hover work on the entire width of the node
+ * MAY BE HEAVY IN LARGE DOM
+ */
+(function ($) {
+  $.jstree.plugin("wholerow", {
+    __init : function () {
+      if(!this.data.ui) { throw "jsTree wholerow: jsTree UI plugin not included."; }
+      this.data.wholerow.html = false;
+      this.data.wholerow.to = false;
+      this.get_container()
+        .bind("init.jstree", $.proxy(function (e, data) {
+            this._get_settings().core.animation = 0;
+          }, this))
+        .bind("open_node.jstree create_node.jstree clean_node.jstree loaded.jstree", $.proxy(function (e, data) {
+            this._prepare_wholerow_span( data && data.rslt && data.rslt.obj ? data.rslt.obj : -1 );
+          }, this))
+        .bind("search.jstree clear_search.jstree reopen.jstree after_open.jstree after_close.jstree create_node.jstree delete_node.jstree clean_node.jstree", $.proxy(function (e, data) {
+            if(this.data.to) { clearTimeout(this.data.to); }
+            this.data.to = setTimeout( (function (t, o) { return function() { t._prepare_wholerow_ul(o); }; })(this,  data && data.rslt && data.rslt.obj ? data.rslt.obj : -1), 0);
+          }, this))
+        .bind("deselect_all.jstree", $.proxy(function (e, data) {
+            this.get_container().find(" > .jstree-wholerow .jstree-clicked").removeClass("jstree-clicked " + (this.data.themeroller ? this._get_settings().themeroller.item_a : "" ));
+          }, this))
+        .bind("select_node.jstree deselect_node.jstree ", $.proxy(function (e, data) {
+            data.rslt.obj.each(function () {
+              var ref = data.inst.get_container().find(" > .jstree-wholerow li:visible:eq(" + ( parseInt((($(this).offset().top - data.inst.get_container().offset().top + data.inst.get_container()[0].scrollTop) / data.inst.data.core.li_height),10)) + ")");
+              // ref.children("a")[e.type === "select_node" ? "addClass" : "removeClass"]("jstree-clicked");
+              ref.children("a").attr("class",data.rslt.obj.children("a").attr("class"));
+            });
+          }, this))
+        .bind("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
+            this.get_container().find(" > .jstree-wholerow .jstree-hovered").removeClass("jstree-hovered " + (this.data.themeroller ? this._get_settings().themeroller.item_h : "" ));
+            if(e.type === "hover_node") {
+              var ref = this.get_container().find(" > .jstree-wholerow li:visible:eq(" + ( parseInt(((data.rslt.obj.offset().top - this.get_container().offset().top + this.get_container()[0].scrollTop) / this.data.core.li_height),10)) + ")");
+              // ref.children("a").addClass("jstree-hovered");
+              ref.children("a").attr("class",data.rslt.obj.children(".jstree-hovered").attr("class"));
+            }
+          }, this))
+        .delegate(".jstree-wholerow-span, ins.jstree-icon, li", "click.jstree", function (e) {
+            var n = $(e.currentTarget);
+            if(e.target.tagName === "A" || (e.target.tagName === "INS" && n.closest("li").is(".jstree-open, .jstree-closed"))) { return; }
+            n.closest("li").children("a:visible:eq(0)").click();
+            e.stopImmediatePropagation();
+          })
+        .delegate("li", "mouseover.jstree", $.proxy(function (e) {
+            e.stopImmediatePropagation();
+            if($(e.currentTarget).children(".jstree-hovered, .jstree-clicked").length) { return false; }
+            this.hover_node(e.currentTarget);
+            return false;
+          }, this))
+        .delegate("li", "mouseleave.jstree", $.proxy(function (e) {
+            if($(e.currentTarget).children("a").hasClass("jstree-hovered").length) { return; }
+            this.dehover_node(e.currentTarget);
+          }, this));
+      if(is_ie7 || is_ie6) {
+        $.vakata.css.add_sheet({ str : ".jstree-" + this.get_index() + " { position:relative; } ", title : "jstree" });
+      }
+    },
+    defaults : {
+    },
+    __destroy : function () {
+      this.get_container().children(".jstree-wholerow").remove();
+      this.get_container().find(".jstree-wholerow-span").remove();
+    },
+    _fn : {
+      _prepare_wholerow_span : function (obj) {
+        obj = !obj || obj == -1 ? this.get_container().find("> ul > li") : this._get_node(obj);
+        if(obj === false) { return; } // added for removing root nodes
+        obj.each(function () {
+          $(this).find("li").andSelf().each(function () {
+            var $t = $(this);
+            if($t.children(".jstree-wholerow-span").length) { return true; }
+            $t.prepend("<span class='jstree-wholerow-span' style='width:" + ($t.parentsUntil(".jstree","li").length * 18) + "px;'>&#160;</span>");
+          });
+        });
+      },
+      _prepare_wholerow_ul : function () {
+        var o = this.get_container().children("ul").eq(0), h = o.html();
+        o.addClass("jstree-wholerow-real");
+        if(this.data.wholerow.last_html !== h) {
+          this.data.wholerow.last_html = h;
+          this.get_container().children(".jstree-wholerow").remove();
+          this.get_container().append(
+            o.clone().removeClass("jstree-wholerow-real")
+              .wrapAll("<div class='jstree-wholerow' />").parent()
+              .width(o.parent()[0].scrollWidth)
+              .css("top", (o.height() + ( is_ie7 ? 5 : 0)) * -1 )
+              .find("li[id]").each(function () { this.removeAttribute("id"); }).end()
+          );
+        }
+      }
+    }
+  });
+  $(function() {
+    var css_string = '' +
+      '.jstree .jstree-wholerow-real { position:relative; z-index:1; } ' +
+      '.jstree .jstree-wholerow-real li { cursor:pointer; } ' +
+      '.jstree .jstree-wholerow-real a { border-left-color:transparent !important; border-right-color:transparent !important; } ' +
+      '.jstree .jstree-wholerow { position:relative; z-index:0; height:0; } ' +
+      '.jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { width:100%; } ' +
+      '.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li, .jstree .jstree-wholerow a { margin:0 !important; padding:0 !important; } ' +
+      '.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { background:transparent !important; }' +
+      '.jstree .jstree-wholerow ins, .jstree .jstree-wholerow span, .jstree .jstree-wholerow input { display:none !important; }' +
+      '.jstree .jstree-wholerow a, .jstree .jstree-wholerow a:hover { text-indent:-9999px; !important; width:100%; padding:0 !important; border-right-width:0px !important; border-left-width:0px !important; } ' +
+      '.jstree .jstree-wholerow-span { position:absolute; left:0; margin:0px; padding:0; height:18px; border-width:0; padding:0; z-index:0; }';
+    if(is_ff2) {
+      css_string += '' +
+        '.jstree .jstree-wholerow a { display:block; height:18px; margin:0; padding:0; border:0; } ' +
+        '.jstree .jstree-wholerow-real a { border-color:transparent !important; } ';
+    }
+    if(is_ie7 || is_ie6) {
+      css_string += '' +
+        '.jstree .jstree-wholerow, .jstree .jstree-wholerow li, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow a { margin:0; padding:0; line-height:18px; } ' +
+        '.jstree .jstree-wholerow a { display:block; height:18px; line-height:18px; overflow:hidden; } ';
+    }
+    $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
+  });
+})(jQuery);
+//*/
+
+/*
+* jsTree model plugin
+* This plugin gets jstree to use a class model to retrieve data, creating great dynamism
+*/
+(function ($) {
+  var nodeInterface = ["getChildren","getChildrenCount","getAttr","getName","getProps"],
+    validateInterface = function(obj, inter) {
+      var valid = true;
+      obj = obj || {};
+      inter = [].concat(inter);
+      $.each(inter, function (i, v) {
+        if(!$.isFunction(obj[v])) { valid = false; return false; }
+      });
+      return valid;
+    };
+  $.jstree.plugin("model", {
+    __init : function () {
+      if(!this.data.json_data) { throw "jsTree model: jsTree json_data plugin not included."; }
+      this._get_settings().json_data.data = function (n, b) {
+        var obj = (n == -1) ? this._get_settings().model.object : n.data("jstree_model");
+        if(!validateInterface(obj, nodeInterface)) { return b.call(null, false); }
+        if(this._get_settings().model.async) {
+          obj.getChildren($.proxy(function (data) {
+            this.model_done(data, b);
+          }, this));
+        }
+        else {
+          this.model_done(obj.getChildren(), b);
+        }
+      };
+    },
+    defaults : {
+      object : false,
+      id_prefix : false,
+      async : false
+    },
+    _fn : {
+      model_done : function (data, callback) {
+        var ret = [],
+          s = this._get_settings(),
+          _this = this;
+
+        if(!$.isArray(data)) { data = [data]; }
+        $.each(data, function (i, nd) {
+          var r = nd.getProps() || {};
+          r.attr = nd.getAttr() || {};
+          if(nd.getChildrenCount()) { r.state = "closed"; }
+          r.data = nd.getName();
+          if(!$.isArray(r.data)) { r.data = [r.data]; }
+          if(_this.data.types && $.isFunction(nd.getType)) {
+            r.attr[s.types.type_attr] = nd.getType();
+          }
+          if(r.attr.id && s.model.id_prefix) { r.attr.id = s.model.id_prefix + r.attr.id; }
+          if(!r.metadata) { r.metadata = { }; }
+          r.metadata.jstree_model = nd;
+          ret.push(r);
+        });
+        callback.call(null, ret);
+      }
+    }
+  });
+})(jQuery);
+//*/
+
+})();

BIN
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/jt/jquery.jstree.js.gz


+ 2 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/webapp/MyTestWebService.java

@@ -27,12 +27,13 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import com.google.inject.Singleton;
+import org.apache.hadoop.http.JettyUtils;
 
 @Singleton
 @Path("/ws/v1/test")
 public class MyTestWebService {
   @GET
-  @Produces({ MediaType.APPLICATION_XML })
+  @Produces({ MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
   public MyInfo get() {
     return new MyInfo();
   }

+ 1 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-applicationhistoryservice/pom.xml

@@ -38,7 +38,7 @@
   <dependencies>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
     </dependency>
     <!-- 'mvn dependency:analyze' fails to detect use of this dependency -->
     <dependency>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.