You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/06/18 19:19:38 UTC

[tomcat-native] 02/02: Import latest Java code from 9.0.x/master

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

markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat-native.git

commit 1145ea9043809b5fc3c90025def3d13de91a1059
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Jun 18 20:16:39 2019 +0100

    Import latest Java code from 9.0.x/master
---
 java/org/apache/tomcat/jni/Address.java            | 115 ++++
 java/org/apache/tomcat/jni/BIOCallback.java        |  54 ++
 java/org/apache/tomcat/jni/Buffer.java             |  91 +++
 .../org/apache/tomcat/jni/CertificateVerifier.java |  34 +
 java/org/apache/tomcat/jni/Directory.java          | 102 +++
 java/org/apache/tomcat/jni/Error.java              |  96 +++
 java/org/apache/tomcat/jni/File.java               | 746 +++++++++++++++++++++
 java/org/apache/tomcat/jni/FileInfo.java           |  65 ++
 java/org/apache/tomcat/jni/Global.java             | 100 +++
 java/org/apache/tomcat/jni/Library.java            | 294 ++++++++
 .../apache/tomcat/jni/LibraryNotFoundError.java    |  40 ++
 java/org/apache/tomcat/jni/Local.java              |  78 +++
 java/org/apache/tomcat/jni/Lock.java               | 131 ++++
 java/org/apache/tomcat/jni/Mmap.java               |  75 +++
 java/org/apache/tomcat/jni/Multicast.java          |  81 +++
 java/org/apache/tomcat/jni/OS.java                 | 137 ++++
 java/org/apache/tomcat/jni/PasswordCallback.java   |  32 +
 java/org/apache/tomcat/jni/Poll.java               | 188 ++++++
 java/org/apache/tomcat/jni/Pool.java               | 163 +++++
 java/org/apache/tomcat/jni/PoolCallback.java       |  31 +
 java/org/apache/tomcat/jni/Proc.java               | 213 ++++++
 java/org/apache/tomcat/jni/ProcErrorCallback.java  |  36 +
 java/org/apache/tomcat/jni/Procattr.java           | 182 +++++
 java/org/apache/tomcat/jni/Registry.java           | 243 +++++++
 java/org/apache/tomcat/jni/SSL.java                | 725 ++++++++++++++++++++
 java/org/apache/tomcat/jni/SSLConf.java            | 113 ++++
 java/org/apache/tomcat/jni/SSLContext.java         | 584 ++++++++++++++++
 java/org/apache/tomcat/jni/SSLSocket.java          | 131 ++++
 java/org/apache/tomcat/jni/Shm.java                | 127 ++++
 java/org/apache/tomcat/jni/Sockaddr.java           |  40 ++
 java/org/apache/tomcat/jni/Socket.java             | 629 +++++++++++++++++
 java/org/apache/tomcat/jni/Status.java             | 263 ++++++++
 java/org/apache/tomcat/jni/Stdlib.java             |  94 +++
 java/org/apache/tomcat/jni/Thread.java             |  31 +
 java/org/apache/tomcat/jni/Time.java               |  80 +++
 java/org/apache/tomcat/jni/User.java               | 133 ++++
 36 files changed, 6277 insertions(+)

diff --git a/java/org/apache/tomcat/jni/Address.java b/java/org/apache/tomcat/jni/Address.java
new file mode 100644
index 0000000..6bf9ec8
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Address.java
@@ -0,0 +1,115 @@
+/*
+ *  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.tomcat.jni;
+
+/** Address
+ *
+ * @author Mladen Turk
+ */
+public class Address {
+
+    public static final String APR_ANYADDR = "0.0.0.0";
+    /**
+     * Fill the Sockaddr class from apr_sockaddr_t
+     * @param info Sockaddr class to fill
+     * @param sa Structure pointer
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean fill(Sockaddr info, long sa);
+
+    /**
+     * Create the Sockaddr object from apr_sockaddr_t
+     * @param sa Structure pointer
+     * @return the socket address
+     */
+    public static native Sockaddr getInfo(long sa);
+
+    /**
+     * Create apr_sockaddr_t from hostname, address family, and port.
+     * @param hostname The hostname or numeric address string to resolve/parse, or
+     *               NULL to build an address that corresponds to 0.0.0.0 or ::
+     * @param family The address family to use, or APR_UNSPEC if the system should
+     *               decide.
+     * @param port The port number.
+     * @param flags Special processing flags:
+     * <PRE>
+     *       APR_IPV4_ADDR_OK          first query for IPv4 addresses; only look
+     *                                 for IPv6 addresses if the first query failed;
+     *                                 only valid if family is APR_UNSPEC and hostname
+     *                                 isn't NULL; mutually exclusive with
+     *                                 APR_IPV6_ADDR_OK
+     *       APR_IPV6_ADDR_OK          first query for IPv6 addresses; only look
+     *                                 for IPv4 addresses if the first query failed;
+     *                                 only valid if family is APR_UNSPEC and hostname
+     *                                 isn't NULL and APR_HAVE_IPV6; mutually exclusive
+     *                                 with APR_IPV4_ADDR_OK
+     * </PRE>
+     * @param p The pool for the apr_sockaddr_t and associated storage.
+     * @return The new apr_sockaddr_t.
+     * @throws Exception Operation failed
+     */
+    public static native long info(String hostname, int family,
+                                   int port, int flags, long p)
+        throws Exception;
+    /**
+     * Look up the host name from an apr_sockaddr_t.
+     * @param sa The apr_sockaddr_t.
+     * @param flags Special processing flags.
+     * @return The hostname.
+     */
+    public static native String getnameinfo(long sa, int flags);
+
+    /**
+     * Return the IP address (in numeric address string format) in
+     * an APR socket address.  APR will allocate storage for the IP address
+     * string from the pool of the apr_sockaddr_t.
+     * @param sa The socket address to reference.
+     * @return The IP address.
+     */
+    public static native String getip(long sa);
+
+    /**
+     * Given an apr_sockaddr_t and a service name, set the port for the service
+     * @param sockaddr The apr_sockaddr_t that will have its port set
+     * @param servname The name of the service you wish to use
+     * @return APR status code.
+     */
+    public static native int getservbyname(long sockaddr, String servname);
+
+    /**
+     * Return an apr_sockaddr_t from an apr_socket_t
+     * @param which Which interface do we want the apr_sockaddr_t for?
+     * @param sock The socket to use
+     * @return The returned apr_sockaddr_t.
+     * @throws Exception An error occurred
+     */
+    public static native long get(int which, long sock)
+        throws Exception;
+
+    /**
+     * See if the IP addresses in two APR socket addresses are
+     * equivalent.  Appropriate logic is present for comparing
+     * IPv4-mapped IPv6 addresses with IPv4 addresses.
+     *
+     * @param a One of the APR socket addresses.
+     * @param b The other APR socket address.
+     * @return <code>true</code> if the addresses are equal
+     */
+    public static native boolean equal(long a, long b);
+
+}
diff --git a/java/org/apache/tomcat/jni/BIOCallback.java b/java/org/apache/tomcat/jni/BIOCallback.java
new file mode 100644
index 0000000..ee13c70
--- /dev/null
+++ b/java/org/apache/tomcat/jni/BIOCallback.java
@@ -0,0 +1,54 @@
+/*
+ *  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.tomcat.jni;
+
+/** Open SSL BIO Callback Interface
+ *
+ * @author Mladen Turk
+ */
+public interface BIOCallback {
+
+    /**
+     * Write data
+     * @param buf containing the bytes to write.
+     * @return Number of characters written.
+     */
+    public int write(byte [] buf);
+
+    /**
+     * Read data
+     * @param buf buffer to store the read bytes.
+     * @return number of bytes read.
+     */
+    public int read(byte [] buf);
+
+    /**
+     * Puts string
+     * @param data String to write
+     * @return Number of characters written
+     */
+    public int puts(String data);
+
+    /**
+     * Read string up to the len or CLRLF
+     * @param len Maximum number of characters to read
+     * @return String with up to len bytes read
+     */
+    public String gets(int len);
+
+}
diff --git a/java/org/apache/tomcat/jni/Buffer.java b/java/org/apache/tomcat/jni/Buffer.java
new file mode 100644
index 0000000..b79214e
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Buffer.java
@@ -0,0 +1,91 @@
+/*
+ *  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.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+/** Buffer
+ *
+ * @author Mladen Turk
+ */
+public class Buffer {
+
+    /**
+     * Allocate a new ByteBuffer from memory
+     * @param size The amount of memory to allocate
+     * @return The ByteBuffer with allocated memory
+     */
+    public static native ByteBuffer malloc(int size);
+
+    /**
+     * Allocate a new ByteBuffer from memory and set all of the memory to 0
+     * @param num Number of elements.
+     * @param size Length in bytes of each element.
+     * @return The ByteBuffer with allocated memory
+     */
+    public static native ByteBuffer calloc(int num, int size);
+
+    /**
+     * Allocate a new ByteBuffer from a pool
+     * @param p The pool to allocate from
+     * @param size The amount of memory to allocate
+     * @return The ByteBuffer with allocated memory
+     */
+    public static native ByteBuffer palloc(long p, int size);
+
+    /**
+     * Allocate a new ByteBuffer from a pool and set all of the memory to 0
+     * @param p The pool to allocate from
+     * @param size The amount of memory to allocate
+     * @return The ByteBuffer with allocated memory
+     */
+    public static native ByteBuffer pcalloc(long p, int size);
+
+    /**
+     * Allocate a new ByteBuffer from already allocated memory.
+     * <br>Allocated memory must be provided from call to the
+     * Stdlib.alloc or Stdlib.calloc methods.
+     * @param mem The memory to use
+     * @param size The amount of memory to use
+     * @return The ByteBuffer with attached memory
+     */
+    public static native ByteBuffer create(long mem, int size);
+
+    /**
+     * Deallocates or frees a memory block used by ByteBuffer
+     * <br><b>Warning :</b> Call this method only on ByteBuffers
+     * that were created by calling Buffer.alloc or Buffer.calloc.
+     * @param buf Previously allocated ByteBuffer to be freed.
+     */
+    public static native void free(ByteBuffer buf);
+
+    /**
+     * Returns the memory address of the ByteBuffer.
+     * @param buf Previously allocated ByteBuffer.
+     * @return the memory address
+     */
+    public static native long address(ByteBuffer buf);
+
+    /**
+     * Returns the allocated memory size of the ByteBuffer.
+     * @param buf Previously allocated ByteBuffer.
+     * @return the size
+     */
+    public static native long size(ByteBuffer buf);
+
+}
diff --git a/java/org/apache/tomcat/jni/CertificateVerifier.java b/java/org/apache/tomcat/jni/CertificateVerifier.java
new file mode 100644
index 0000000..b9b0d48
--- /dev/null
+++ b/java/org/apache/tomcat/jni/CertificateVerifier.java
@@ -0,0 +1,34 @@
+/*
+ * 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.tomcat.jni;
+
+/**
+ * Is called during handshake and hooked into openssl via {@code SSL_CTX_set_cert_verify_callback}.
+ */
+public interface CertificateVerifier {
+
+    /**
+     * Returns {@code true} if the passed in certificate chain could be verified and so the handshake
+     * should be successful, {@code false} otherwise.
+     *
+     * @param ssl               the SSL instance
+     * @param x509              the {@code X509} certificate chain
+     * @param authAlgorithm     the auth algorithm
+     * @return verified         {@code true} if verified successful, {@code false} otherwise
+     */
+    boolean verify(long ssl, byte[][] x509, String authAlgorithm);
+}
diff --git a/java/org/apache/tomcat/jni/Directory.java b/java/org/apache/tomcat/jni/Directory.java
new file mode 100644
index 0000000..8a94972
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Directory.java
@@ -0,0 +1,102 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.jni;
+
+/** Directory
+ *
+ * @author Mladen Turk
+ */
+public class Directory {
+
+    /**
+     * Create a new directory on the file system.
+     * @param path the path for the directory to be created. (use / on all systems)
+     * @param perm Permissions for the new directory.
+     * @param pool the pool to use.
+     * @return the operation result
+     */
+    public static native int make(String path, int perm, long pool);
+
+    /**
+     * Creates a new directory on the file system, but behaves like
+     * 'mkdir -p'. Creates intermediate directories as required. No error
+     * will be reported if PATH already exists.
+     * @param path the path for the directory to be created. (use / on all systems)
+     * @param perm Permissions for the new directory.
+     * @param pool the pool to use.
+     * @return the operation result
+     */
+    public static native int makeRecursive(String path, int perm, long pool);
+
+    /**
+     * Remove directory from the file system.
+     * @param path the path for the directory to be removed. (use / on all systems)
+     * @param pool the pool to use.
+     * @return the operation result
+     */
+    public static native int remove(String path, long pool);
+
+    /**
+     * Find an existing directory suitable as a temporary storage location.
+     * @param pool The pool to use for any necessary allocations.
+     * @return The temp directory.
+     *
+     * This function uses an algorithm to search for a directory that an
+     * an application can use for temporary storage.  Once such a
+     * directory is found, that location is cached by the library.  Thus,
+     * callers only pay the cost of this algorithm once if that one time
+     * is successful.
+     */
+    public static native String tempGet(long pool);
+
+    /**
+     * Open the specified directory.
+     * @param dirname The full path to the directory (use / on all systems)
+     * @param pool The pool to use.
+     * @return The opened directory descriptor.
+     * @throws Error An error occurred
+     */
+    public static native long open(String dirname, long pool)
+        throws Error;
+
+    /**
+     * close the specified directory.
+     * @param thedir the directory descriptor to close.
+     * @return the operation result
+     */
+    public static native int close(long thedir);
+
+    /**
+     * Rewind the directory to the first entry.
+     * @param thedir the directory descriptor to rewind.
+     * @return the operation result
+     */
+    public static native int rewind(long thedir);
+
+
+    /**
+     * Read the next entry from the specified directory.
+     * @param finfo the file info structure and filled in by apr_dir_read
+     * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values
+     * @param thedir the directory descriptor returned from apr_dir_open
+     * No ordering is guaranteed for the entries read.
+     * @return the operation result
+     */
+    public static native int read(FileInfo finfo, int wanted, long thedir);
+
+}
diff --git a/java/org/apache/tomcat/jni/Error.java b/java/org/apache/tomcat/jni/Error.java
new file mode 100644
index 0000000..d543258
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Error.java
@@ -0,0 +1,96 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.jni;
+
+/** Error
+ *
+ * @author Mladen Turk
+ */
+public class Error extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * APR error type.
+     */
+    private final int error;
+
+    /**
+     * A description of the problem.
+     */
+    private final String description;
+
+    /**
+     * Construct an APRException.
+     *
+     * @param error one of the value in Error
+     * @param description error message
+     */
+    private Error(int error, String description)
+    {
+        super(error + ": " + description);
+        this.error = error;
+        this.description = description;
+    }
+
+    /**
+     * Get the APR error code of the exception.
+     *
+     * @return error of the Exception
+     */
+    public int getError()
+    {
+        return error;
+    }
+
+    /**
+     * Get the APR description of the exception.
+     *
+     * @return description of the Exception
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+    /**
+     * Get the last platform error.
+     * @return apr_status_t the last platform error, folded into apr_status_t, on most platforms
+     * This retrieves errno, or calls a GetLastError() style function, and
+     *      folds it with APR_FROM_OS_ERROR.  Some platforms (such as OS2) have no
+     *      such mechanism, so this call may be unsupported.  Do NOT use this
+     *      call for socket errors from socket, send, recv etc!
+     */
+    public static native int osError();
+
+    /**
+     * Get the last platform socket error.
+     * @return the last socket error, folded into apr_status_t, on all platforms
+     * This retrieves errno or calls a GetLastSocketError() style function,
+     *      and folds it with APR_FROM_OS_ERROR.
+     */
+    public static native int netosError();
+
+    /**
+     * Return a human readable string describing the specified error.
+     * @param statcode The error code the get a string for.
+     * @return The error string.
+    */
+    public static native String strerror(int statcode);
+
+}
diff --git a/java/org/apache/tomcat/jni/File.java b/java/org/apache/tomcat/jni/File.java
new file mode 100644
index 0000000..4ae5523
--- /dev/null
+++ b/java/org/apache/tomcat/jni/File.java
@@ -0,0 +1,746 @@
+/*
+ *  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.tomcat.jni;
+/* Import needed classes */
+import java.nio.ByteBuffer;
+
+/** File
+ *
+ * @author Mladen Turk
+ */
+public class File {
+
+    /** Open the file for reading */
+    public static final int APR_FOPEN_READ       = 0x00001;
+    /** Open the file for writing */
+    public static final int APR_FOPEN_WRITE      = 0x00002;
+    /** Create the file if not there */
+    public static final int APR_FOPEN_CREATE     = 0x00004;
+    /** Append to the end of the file */
+    public static final int APR_FOPEN_APPEND     = 0x00008;
+    /** Open the file and truncate to 0 length */
+    public static final int APR_FOPEN_TRUNCATE   = 0x00010;
+    /** Open the file in binary mode */
+    public static final int APR_FOPEN_BINARY     = 0x00020;
+    /** Open should fail if APR_CREATE and file exists. */
+    public static final int APR_FOPEN_EXCL       = 0x00040;
+    /** Open the file for buffered I/O */
+    public static final int APR_FOPEN_BUFFERED   = 0x00080;
+    /** Delete the file after close */
+    public static final int APR_FOPEN_DELONCLOSE = 0x00100;
+    /** Platform dependent tag to open the file for
+     * use across multiple threads
+     */
+    public static final int APR_FOPEN_XTHREAD     = 0x00200;
+    /** Platform dependent support for higher level locked read/write
+     * access to support writes across process/machines
+     */
+    public static final int APR_FOPEN_SHARELOCK   = 0x00400;
+    /** Do not register a cleanup when the file is opened */
+    public static final int APR_FOPEN_NOCLEANUP   = 0x00800;
+    /** Advisory flag that this file should support
+     * apr_socket_sendfile operation
+     */
+    public static final int APR_FOPEN_SENDFILE_ENABLED = 0x01000;
+    /** Platform dependent flag to enable large file support;
+     * <br><b>Warning :</b> The APR_LARGEFILE flag only has effect on some platforms
+     * where sizeof(apr_off_t) == 4.  Where implemented, it allows opening
+     * and writing to a file which exceeds the size which can be
+     * represented by apr_off_t (2 gigabytes).  When a file's size does
+     * exceed 2Gb, apr_file_info_get() will fail with an error on the
+     * descriptor, likewise apr_stat()/apr_lstat() will fail on the
+     * filename.  apr_dir_read() will fail with APR_INCOMPLETE on a
+     * directory entry for a large file depending on the particular
+     * APR_FINFO_* flags.  Generally, it is not recommended to use this
+     * flag.
+     */
+    public static final int APR_FOPEN_LARGEFILE      = 0x04000;
+
+    /** Set the file position */
+    public static final int APR_SET = 0;
+    /** Current */
+    public static final int APR_CUR = 1;
+    /** Go to end of file */
+    public static final int APR_END = 2;
+
+    /* flags for apr_file_attrs_set */
+
+    /** File is read-only */
+    public static final int APR_FILE_ATTR_READONLY   = 0x01;
+    /** File is executable */
+    public static final int APR_FILE_ATTR_EXECUTABLE = 0x02;
+    /** File is hidden */
+    public static final int APR_FILE_ATTR_HIDDEN     = 0x04;
+
+
+    /* File lock types/flags */
+
+    /** Shared lock. More than one process or thread can hold a shared lock
+     * at any given time. Essentially, this is a "read lock", preventing
+     * writers from establishing an exclusive lock.
+     */
+    public static final int APR_FLOCK_SHARED    = 1;
+
+    /** Exclusive lock. Only one process may hold an exclusive lock at any
+     * given time. This is analogous to a "write lock".
+     */
+    public static final int APR_FLOCK_EXCLUSIVE = 2;
+    /** mask to extract lock type */
+    public static final int APR_FLOCK_TYPEMASK  = 0x000F;
+    /** do not block while acquiring the file lock */
+    public static final int APR_FLOCK_NONBLOCK  = 0x0010;
+
+    /* apr_filetype_e values for the filetype member of the
+     * apr_file_info_t structure
+     * <br><b>Warning :</b>: Not all of the filetypes below can be determined.
+     * For example, a given platform might not correctly report
+     * a socket descriptor as APR_SOCK if that type isn't
+     * well-identified on that platform.  In such cases where
+     * a filetype exists but cannot be described by the recognized
+     * flags below, the filetype will be APR_UNKFILE.  If the
+     * filetype member is not determined, the type will be APR_NOFILE.
+     */
+
+    /** no file type determined */
+    public static final int APR_NOFILE  = 0;
+    /** a regular file */
+    public static final int APR_REG     = 1;
+    /** a directory */
+    public static final int APR_DIR     = 2;
+    /** a character device */
+    public static final int APR_CHR     = 3;
+    /** a block device */
+    public static final int APR_BLK     = 4;
+    /** a FIFO / pipe */
+    public static final int APR_PIPE    = 5;
+    /** a symbolic link */
+    public static final int APR_LNK     = 6;
+    /** a [unix domain] socket */
+    public static final int APR_SOCK    = 7;
+    /** a file of some other unknown type */
+    public static final int APR_UNKFILE = 127;
+
+
+    /*
+     * apr_file_permissions File Permissions flags
+     */
+
+    public static final int APR_FPROT_USETID     = 0x8000; /** Set user id */
+    public static final int APR_FPROT_UREAD      = 0x0400; /** Read by user */
+    public static final int APR_FPROT_UWRITE     = 0x0200; /** Write by user */
+    public static final int APR_FPROT_UEXECUTE   = 0x0100; /** Execute by user */
+
+    public static final int APR_FPROT_GSETID     = 0x4000; /** Set group id */
+    public static final int APR_FPROT_GREAD      = 0x0040; /** Read by group */
+    public static final int APR_FPROT_GWRITE     = 0x0020; /** Write by group */
+    public static final int APR_FPROT_GEXECUTE   = 0x0010; /** Execute by group */
+
+    public static final int APR_FPROT_WSTICKY    = 0x2000; /** Sticky bit */
+    public static final int APR_FPROT_WREAD      = 0x0004; /** Read by others */
+    public static final int APR_FPROT_WWRITE     = 0x0002; /** Write by others */
+    public static final int APR_FPROT_WEXECUTE   = 0x0001; /** Execute by others */
+    public static final int APR_FPROT_OS_DEFAULT = 0x0FFF; /** use OS's default permissions */
+
+
+    public static final int APR_FINFO_LINK   = 0x00000001; /** Stat the link not the file itself if it is a link */
+    public static final int APR_FINFO_MTIME  = 0x00000010; /** Modification Time */
+    public static final int APR_FINFO_CTIME  = 0x00000020; /** Creation or inode-changed time */
+    public static final int APR_FINFO_ATIME  = 0x00000040; /** Access Time */
+    public static final int APR_FINFO_SIZE   = 0x00000100; /** Size of the file */
+    public static final int APR_FINFO_CSIZE  = 0x00000200; /** Storage size consumed by the file */
+    public static final int APR_FINFO_DEV    = 0x00001000; /** Device */
+    public static final int APR_FINFO_INODE  = 0x00002000; /** Inode */
+    public static final int APR_FINFO_NLINK  = 0x00004000; /** Number of links */
+    public static final int APR_FINFO_TYPE   = 0x00008000; /** Type */
+    public static final int APR_FINFO_USER   = 0x00010000; /** User */
+    public static final int APR_FINFO_GROUP  = 0x00020000; /** Group */
+    public static final int APR_FINFO_UPROT  = 0x00100000; /** User protection bits */
+    public static final int APR_FINFO_GPROT  = 0x00200000; /** Group protection bits */
+    public static final int APR_FINFO_WPROT  = 0x00400000; /** World protection bits */
+    public static final int APR_FINFO_ICASE  = 0x01000000; /** if dev is case insensitive */
+    public static final int APR_FINFO_NAME   = 0x02000000; /** -&gt;name in proper case */
+
+    public static final int APR_FINFO_MIN    = 0x00008170; /** type, mtime, ctime, atime, size */
+    public static final int APR_FINFO_IDENT  = 0x00003000; /** dev and inode */
+    public static final int APR_FINFO_OWNER  = 0x00030000; /** user and group */
+    public static final int APR_FINFO_PROT   = 0x00700000; /**  all protections */
+    public static final int APR_FINFO_NORM   = 0x0073b170; /**  an atomic unix apr_stat() */
+    public static final int APR_FINFO_DIRENT = 0x02000000; /**  an atomic unix apr_dir_read() */
+
+
+
+    /**
+     * Open the specified file.
+     * @param fname The full path to the file (using / on all systems)
+     * @param flag Or'ed value of:
+     * <PRE>
+     * APR_FOPEN_READ              open for reading
+     * APR_FOPEN_WRITE             open for writing
+     * APR_FOPEN_CREATE            create the file if not there
+     * APR_FOPEN_APPEND            file ptr is set to end prior to all writes
+     * APR_FOPEN_TRUNCATE          set length to zero if file exists
+     * APR_FOPEN_BINARY            not a text file (This flag is ignored on
+     *                             UNIX because it has no meaning)
+     * APR_FOPEN_BUFFERED          buffer the data.  Default is non-buffered
+     * APR_FOPEN_EXCL              return error if APR_CREATE and file exists
+     * APR_FOPEN_DELONCLOSE        delete the file after closing.
+     * APR_FOPEN_XTHREAD           Platform dependent tag to open the file
+     *                             for use across multiple threads
+     * APR_FOPEN_SHARELOCK         Platform dependent support for higher
+     *                             level locked read/write access to support
+     *                             writes across process/machines
+     * APR_FOPEN_NOCLEANUP         Do not register a cleanup with the pool
+     *                             passed in on the <EM>pool</EM> argument (see below).
+     *                             The apr_os_file_t handle in apr_file_t will not
+     *                             be closed when the pool is destroyed.
+     * APR_FOPEN_SENDFILE_ENABLED  Open with appropriate platform semantics
+     *                             for sendfile operations.  Advisory only,
+     *                             apr_socket_sendfile does not check this flag.
+     * </PRE>
+     * @param perm Access permissions for file.
+     * @param pool The pool to use.
+     * If perm is APR_OS_DEFAULT and the file is being created,
+     * appropriate default permissions will be used.
+     * @return The opened file descriptor.
+     * @throws Error An error occurred
+     */
+    public static native long open(String fname, int flag, int perm, long pool)
+        throws Error;
+
+    /**
+     * Close the specified file.
+     * @param file The file descriptor to close.
+     * @return the operation status
+     */
+    public static native int close(long file);
+
+    /**
+     * Flush the file's buffer.
+     * @param thefile The file descriptor to flush
+     * @return the operation status
+     */
+    public static native int flush(long thefile);
+
+    /**
+     * Open a temporary file
+     * @param templ The template to use when creating a temp file.
+     * @param flags The flags to open the file with. If this is zero,
+     *              the file is opened with
+     *              APR_CREATE | APR_READ | APR_WRITE | APR_EXCL | APR_DELONCLOSE
+     * @param pool The pool to allocate the file out of.
+     * @return The apr file to use as a temporary file.
+     *
+     * This function  generates  a unique temporary file name from template.
+     * The last six characters of template must be XXXXXX and these are replaced
+     * with a string that makes the filename unique. Since it will  be  modified,
+     * template must not be a string constant, but should be declared as a character
+     * array.
+     * @throws Error An error occurred
+     */
+    public static native long mktemp(String templ, int flags, long pool)
+        throws Error;
+
+    /**
+     * Delete the specified file.
+     * @param path The full path to the file (using / on all systems)
+     * @param pool The pool to use.
+     * If the file is open, it won't be removed until all
+     * instances are closed.
+     * @return the operation status
+     */
+    public static native int remove(String path, long pool);
+
+    /**
+     * Rename the specified file.
+     * <br><b>Warning :</b> If a file exists at the new location, then it will be
+     * overwritten.  Moving files or directories across devices may not be
+     * possible.
+     * @param fromPath The full path to the original file (using / on all systems)
+     * @param toPath The full path to the new file (using / on all systems)
+     * @param pool The pool to use.
+     * @return the operation status
+     */
+    public static native int rename(String fromPath, String toPath, long pool);
+
+    /**
+     * Copy the specified file to another file.
+     * The new file does not need to exist, it will be created if required.
+     * <br><b>Warning :</b> If the new file already exists, its contents will be overwritten.
+     * @param fromPath The full path to the original file (using / on all systems)
+     * @param toPath The full path to the new file (using / on all systems)
+     * @param perms Access permissions for the new file if it is created.
+     *     In place of the usual or'd combination of file permissions, the
+     *     value APR_FILE_SOURCE_PERMS may be given, in which case the source
+     *     file's permissions are copied.
+     * @param pool The pool to use.
+     * @return the operation status
+     */
+    public static native int copy(String fromPath, String toPath, int perms, long pool);
+
+    /**
+     * Append the specified file to another file.
+     * The new file does not need to exist, it will be created if required.
+     * @param fromPath The full path to the source file (use / on all systems)
+     * @param toPath The full path to the destination file (use / on all systems)
+     * @param perms Access permissions for the destination file if it is created.
+     *     In place of the usual or'd combination of file permissions, the
+     *     value APR_FILE_SOURCE_PERMS may be given, in which case the source
+     *     file's permissions are copied.
+     * @param pool The pool to use.
+     * @return the operation status
+     */
+    public static native int append(String fromPath, String toPath, int perms, long pool);
+
+    /**
+     * Write the string into the specified file.
+     * @param str The string to write. Must be NUL terminated!
+     * @param thefile The file descriptor to write to
+     * @return the operation status
+     */
+    public static native int puts(byte [] str, long thefile);
+
+    /**
+     * Move the read/write file offset to a specified byte within a file.
+     * @param thefile The file descriptor
+     * @param where How to move the pointer, one of:
+     * <PRE>
+     * APR_SET  --  set the offset to offset
+     * APR_CUR  --  add the offset to the current position
+     * APR_END  --  add the offset to the current file size
+     * </PRE>
+     * @param offset The offset to move the pointer to.
+     * @return Offset the pointer was actually moved to.
+     * @throws Error If an error occurs reading the file
+     */
+    public static native long seek(long thefile, int where, long offset)
+        throws Error;
+
+    /**
+     * Write a character into the specified file.
+     * @param ch The character to write.
+     * @param thefile The file descriptor to write to
+     * @return the operation status
+     */
+    public static native int putc(byte ch, long thefile);
+
+    /**
+     * Put a character back onto a specified stream.
+     * @param ch The character to write.
+     * @param thefile The file descriptor to write to
+     * @return the operation status
+     */
+    public static native int ungetc(byte ch, long thefile);
+
+    /**
+     * Write data to the specified file.
+     *
+     * Write will write up to the specified number of
+     * bytes, but never more.  If the OS cannot write that many bytes, it
+     * will write as many as it can.  The third argument is modified to
+     * reflect the * number of bytes written.
+     *
+     * It is possible for both bytes to be written and an error to
+     * be returned.  APR_EINTR is never returned.
+     * @param thefile The file descriptor to write to.
+     * @param buf The buffer which contains the data.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to write
+     * @return The number of bytes written.
+     */
+    public static native int write(long thefile, byte[] buf, int offset, int nbytes);
+
+    /**
+     * Write data to the specified file.
+     *
+     * Write will write up to the specified number of
+     * bytes, but never more.  If the OS cannot write that many bytes, it
+     * will write as many as it can.  The third argument is modified to
+     * reflect the * number of bytes written.
+     *
+     * It is possible for both bytes to be written and an error to
+     * be returned.  APR_EINTR is never returned.
+     * @param thefile The file descriptor to write to.
+     * @param buf The direct Byte buffer which contains the data.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to write
+     * @return The number of bytes written.
+     */
+    public static native int writeb(long thefile, ByteBuffer buf, int offset, int nbytes);
+
+    /**
+     * Write data to the specified file, ensuring that all of the data is
+     * written before returning.
+     *
+     * Write will write up to the specified number of
+     * bytes, but never more.  If the OS cannot write that many bytes, the
+     * process/thread will block until they can be written. Exceptional
+     * error such as "out of space" or "pipe closed" will terminate with
+     * an error.
+     *
+     * It is possible for both bytes to be written and an error to
+     * be returned.  And if *bytes_written is less than nbytes, an
+     * accompanying error is _always_ returned.
+     *
+     * APR_EINTR is never returned.
+     * @param thefile The file descriptor to write to.
+     * @param buf The buffer which contains the data.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to write
+     * @return The number of bytes written.
+     */
+    public static native int writeFull(long thefile, byte[] buf, int offset, int nbytes);
+
+    /**
+     * Write data to the specified file, ensuring that all of the data is
+     * written before returning.
+     *
+     * Write will write up to the specified number of
+     * bytes, but never more.  If the OS cannot write that many bytes, the
+     * process/thread will block until they can be written. Exceptional
+     * error such as "out of space" or "pipe closed" will terminate with
+     * an error.
+     *
+     * It is possible for both bytes to be written and an error to
+     * be returned.  And if *bytes_written is less than nbytes, an
+     * accompanying error is _always_ returned.
+     *
+     * APR_EINTR is never returned.
+     * @param thefile The file descriptor to write to.
+     * @param buf The direct ByteBuffer which contains the data.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to write.
+     * @return The number of bytes written.
+     */
+    public static native int writeFullb(long thefile, ByteBuffer buf, int offset, int nbytes);
+
+    /**
+     * Write data from array of byte arrays to the specified file.
+     *
+     * It is possible for both bytes to be written and an error to
+     * be returned.  APR_EINTR is never returned.
+     *
+     * apr_file_writev is available even if the underlying
+     * operating system doesn't provide writev().
+     * @param thefile The file descriptor to write to.
+     * @param vec The array from which to get the data to write to the file.
+     * @return The number of bytes written.
+     */
+    public static native int writev(long thefile, byte[][] vec);
+
+    /**
+     * Write data from array of byte arrays to the specified file,
+     * ensuring that all of the data is written before returning.
+     *
+     * writevFull is available even if the underlying
+     * operating system doesn't provide writev().
+     * @param thefile The file descriptor to write to.
+     * @param vec The array from which to get the data to write to the file.
+     * @return The number of bytes written.
+     */
+    public static native int writevFull(long thefile, byte[][] vec);
+
+    /**
+     * Read data from the specified file.
+     *
+     * apr_file_read will read up to the specified number of
+     * bytes, but never more.  If there isn't enough data to fill that
+     * number of bytes, all of the available data is read.  The third
+     * argument is modified to reflect the number of bytes read.  If a
+     * char was put back into the stream via ungetc, it will be the first
+     * character returned.
+     *
+     * It is not possible for both bytes to be read and an APR_EOF
+     * or other error to be returned.  APR_EINTR is never returned.
+     * @param thefile The file descriptor to read from.
+     * @param buf The buffer to store the data to.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to read
+     * @return the number of bytes read.
+     */
+    public static native int read(long thefile, byte[] buf,  int offset, int nbytes);
+
+    /**
+     * Read data from the specified file.
+     *
+     * apr_file_read will read up to the specified number of
+     * bytes, but never more.  If there isn't enough data to fill that
+     * number of bytes, all of the available data is read.  The third
+     * argument is modified to reflect the number of bytes read.  If a
+     * char was put back into the stream via ungetc, it will be the first
+     * character returned.
+     *
+     * It is not possible for both bytes to be read and an APR_EOF
+     * or other error to be returned.  APR_EINTR is never returned.
+     * @param thefile The file descriptor to read from.
+     * @param buf The direct Byte buffer to store the data to.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to read.
+     * @return the number of bytes read.
+     */
+    public static native int readb(long thefile, ByteBuffer buf,  int offset, int nbytes);
+
+    /**
+     * Read data from the specified file, ensuring that the buffer is filled
+     * before returning.
+     *
+     * Read will read up to the specified number of
+     * bytes, but never more.  If there isn't enough data to fill that
+     * number of bytes, then the process/thread will block until it is
+     * available or EOF is reached.  If a char was put back into the
+     * stream via ungetc, it will be the first character returned.
+     *
+     * It is possible for both bytes to be read and an error to be
+     * returned.  And if *bytes_read is less than nbytes, an accompanying
+     * error is _always_ returned.
+     *
+     * APR_EINTR is never returned.
+     * @param thefile The file descriptor to read from.
+     * @param buf The buffer to store the data to.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to read
+     * @return the number of bytes read.
+     */
+    public static native int readFull(long thefile, byte[] buf,  int offset, int nbytes);
+
+    /**
+     * Read data from the specified file, ensuring that the buffer is filled
+     * before returning.
+     *
+     * Read will read up to the specified number of
+     * bytes, but never more.  If there isn't enough data to fill that
+     * number of bytes, then the process/thread will block until it is
+     * available or EOF is reached.  If a char was put back into the
+     * stream via ungetc, it will be the first character returned.
+     *
+     * It is possible for both bytes to be read and an error to be
+     * returned.  And if *bytes_read is less than nbytes, an accompanying
+     * error is _always_ returned.
+     *
+     * APR_EINTR is never returned.
+     * @param thefile The file descriptor to read from.
+     * @param buf The direct ByteBuffer to store the data to.
+     * @param offset Start offset in buf
+     * @param nbytes The number of bytes to read.
+     * @return the number of bytes read.
+     */
+    public static native int readFullb(long thefile, ByteBuffer buf,  int offset, int nbytes);
+
+    /**
+     * Read a string from the specified file.
+     * The buffer will be NUL-terminated if any characters are stored.
+     * @param buf The buffer to store the string in.
+     * @param offset Start offset in buf
+     * @param thefile The file descriptor to read from
+     * @return the number of bytes read.
+     */
+    public static native int gets(byte[] buf,  int offset, long thefile);
+
+
+    /**
+     * Read a character from the specified file.
+     * @param thefile The file descriptor to read from
+     * @return The read character
+     * @throws Error If an error occurs reading the file
+     */
+    public static native int getc(long thefile)
+        throws Error;
+
+    /**
+     * Are we at the end of the file
+     * @param fptr The apr file we are testing.
+     * @return Returns APR_EOF if we are at the end of file, APR_SUCCESS otherwise.
+     */
+    public static native int eof(long fptr);
+
+    /**
+     * Return the file name of the current file.
+     * @param thefile The currently open file.
+     * @return the name
+     */
+    public static native String nameGet(long thefile);
+
+    /**
+     * Set the specified file's permission bits.
+     * <br><b>Warning :</b> Some platforms may not be able to apply all of the
+     * available permission bits; APR_INCOMPLETE will be returned if some
+     * permissions are specified which could not be set.
+     * <br><b>Warning :</b> Platforms which do not implement this feature will return
+     * APR_ENOTIMPL.
+     * @param fname The file (name) to apply the permissions to.
+     * @param perms The permission bits to apply to the file.
+     * @return the operation status
+     */
+    public static native int permsSet(String fname, int perms);
+
+    /**
+     * Set attributes of the specified file.
+     * This function should be used in preference to explicit manipulation
+     *      of the file permissions, because the operations to provide these
+     *      attributes are platform specific and may involve more than simply
+     *      setting permission bits.
+     * <br><b>Warning :</b> Platforms which do not implement this feature will return
+     *      APR_ENOTIMPL.
+     * @param fname The full path to the file (using / on all systems)
+     * @param attributes Or'd combination of
+     * <PRE>
+     *            APR_FILE_ATTR_READONLY   - make the file readonly
+     *            APR_FILE_ATTR_EXECUTABLE - make the file executable
+     *            APR_FILE_ATTR_HIDDEN     - make the file hidden
+     * </PRE>
+     * @param mask Mask of valid bits in attributes.
+     * @param pool the pool to use.
+     * @return the operation status
+     */
+    public static native int  attrsSet(String fname, int attributes, int mask, long pool);
+
+    /**
+     * Set the mtime of the specified file.
+     * <br><b>Warning :</b> Platforms which do not implement this feature will return
+     *      APR_ENOTIMPL.
+     * @param fname The full path to the file (using / on all systems)
+     * @param mtime The mtime to apply to the file in microseconds
+     * @param pool The pool to use.
+     * @return the operation status
+     */
+    public static native int  mtimeSet(String fname, long mtime, long pool);
+
+    /**
+     * Establish a lock on the specified, open file. The lock may be advisory
+     * or mandatory, at the discretion of the platform. The lock applies to
+     * the file as a whole, rather than a specific range. Locks are established
+     * on a per-thread/process basis; a second lock by the same thread will not
+     * block.
+     * @param thefile The file to lock.
+     * @param type The type of lock to establish on the file.
+     * @return the operation status
+     */
+    public static native int lock(long thefile, int type);
+
+    /**
+     * Remove any outstanding locks on the file.
+     * @param thefile The file to unlock.
+     * @return the operation status
+     */
+    public static native int unlock(long thefile);
+
+    /**
+     * Retrieve the flags that were passed into apr_file_open()
+     * when the file was opened.
+     * @param file The file to retrieve flags.
+     * @return the flags
+     */
+    public static native int flagsGet(long file);
+
+    /**
+     * Truncate the file's length to the specified offset
+     * @param fp The file to truncate
+     * @param offset The offset to truncate to.
+     * @return the operation status
+     */
+    public static native int trunc(long fp, long offset);
+
+    /**
+     * Create an anonymous pipe.
+     * @param io io[0] The file descriptors to use as input to the pipe.
+     *           io[1] The file descriptor to use as output from the pipe.
+     * @param pool The pool to operate on.
+     * @return the operation status
+     */
+    public static native int pipeCreate(long [] io, long pool);
+
+    /**
+     * Get the timeout value for a pipe or manipulate the blocking state.
+     * @param thepipe The pipe we are getting a timeout for.
+     * @return The current timeout value in microseconds.
+     * @throws Error If an error occurs
+     */
+    public static native long pipeTimeoutGet(long thepipe)
+        throws Error;
+
+    /**
+     * Set the timeout value for a pipe or manipulate the blocking state.
+     * @param thepipe The pipe we are setting a timeout on.
+     * @param timeout The timeout value in microseconds.  Values &lt; 0 mean
+     *        wait forever, 0 means do not wait at all.
+     * @return the operation status
+     */
+    public static native int pipeTimeoutSet(long thepipe, long timeout);
+
+    /**
+     * Duplicate the specified file descriptor.
+     * @param newFile The file to duplicate.
+     * newFile must point to a valid apr_file_t, or point to NULL.
+     * @param oldFile The file to duplicate.
+     * @param pool The pool to use for the new file.
+     * @return Duplicated file structure.
+     * @throws Error If an error occurs reading the file descriptor
+     */
+    public static native long dup(long newFile, long oldFile, long pool)
+        throws Error;
+
+    /**
+     * Duplicate the specified file descriptor and close the original.
+     * @param newFile The old file that is to be closed and reused.
+     * newFile MUST point at a valid apr_file_t. It cannot be NULL.
+     * @param oldFile The file to duplicate.
+     * @param pool The pool to use for the new file.
+     * @return the operation status
+     */
+    public static native int dup2(long newFile, long oldFile, long pool);
+
+    /**
+     * Get the specified file's stats.  The file is specified by filename,
+     * instead of using a pre-opened file.
+     * @param finfo Where to store the information about the file, which is
+     * never touched if the call fails.
+     * @param fname The name of the file to stat.
+     * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values
+     * @param pool the pool to use to allocate the new file.
+     * @return the operation status
+     */
+    public static native int stat(FileInfo finfo, String fname, int wanted, long pool);
+
+    /**
+     * Get the specified file's stats.  The file is specified by filename,
+     * instead of using a pre-opened file.
+     * @param fname The name of the file to stat.
+     * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values
+     * @param pool the pool to use to allocate the new file.
+     * @return FileInfo object.
+     */
+    public static native FileInfo getStat(String fname, int wanted, long pool);
+
+    /**
+     * Get the specified file's stats.
+     * @param finfo Where to store the information about the file.
+     * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values
+     * @param thefile The file to get information about.
+     * @return the operation status
+     */
+    public static native int infoGet(FileInfo finfo, int wanted, long thefile);
+
+
+    /**
+     * Get the specified file's stats.
+     * @param wanted The desired apr_finfo_t fields, as a bit flag of APR_FINFO_ values
+     * @param thefile The file to get information about.
+     * @return FileInfo object.
+     */
+    public static native FileInfo getInfo(int wanted, long thefile);
+
+}
diff --git a/java/org/apache/tomcat/jni/FileInfo.java b/java/org/apache/tomcat/jni/FileInfo.java
new file mode 100644
index 0000000..9fb6bd3
--- /dev/null
+++ b/java/org/apache/tomcat/jni/FileInfo.java
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.tomcat.jni;
+
+/** Fileinfo
+ *
+ * @author Mladen Turk
+ */
+public class FileInfo {
+
+    /** Allocates memory and closes lingering handles in the specified pool */
+    public long pool;
+    /** The bitmask describing valid fields of this apr_finfo_t structure
+     *  including all available 'wanted' fields and potentially more */
+    public int valid;
+    /** The access permissions of the file.  Mimics Unix access rights. */
+    public int protection;
+    /** The type of file.  One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE,
+     * APR_LNK or APR_SOCK.  If the type is undetermined, the value is APR_NOFILE.
+     * If the type cannot be determined, the value is APR_UNKFILE.
+     */
+    public int filetype;
+    /** The user id that owns the file */
+    public int user;
+    /** The group id that owns the file */
+    public int group;
+    /** The inode of the file. */
+    public int inode;
+    /** The id of the device the file is on. */
+    public int device;
+    /** The number of hard links to the file. */
+    public int nlink;
+    /** The size of the file */
+    public long size;
+    /** The storage size consumed by the file */
+    public long csize;
+    /** The time the file was last accessed */
+    public long atime;
+    /** The time the file was last modified */
+    public long mtime;
+    /** The time the file was created, or the inode was last changed */
+    public long ctime;
+    /** The pathname of the file (possibly unrooted) */
+    public String fname;
+    /** The file's name (no path) in filesystem case */
+    public String name;
+    /** The file's handle, if accessed (can be submitted to apr_duphandle) */
+    public long filehand;
+
+}
diff --git a/java/org/apache/tomcat/jni/Global.java b/java/org/apache/tomcat/jni/Global.java
new file mode 100644
index 0000000..c1d1eb5
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Global.java
@@ -0,0 +1,100 @@
+/*
+ *  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.tomcat.jni;
+
+/** Global
+ *
+ * @author Mladen Turk
+ */
+public class Global {
+
+    /**
+     * Create and initialize a mutex that can be used to synchronize both
+     * processes and threads. Note: There is considerable overhead in using
+     * this API if only cross-process or cross-thread mutual exclusion is
+     * required. See apr_proc_mutex.h and apr_thread_mutex.h for more
+     * specialized lock routines.
+     * <br><b>Warning :</b> Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
+     *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
+     * @param fname A file name to use if the lock mechanism requires one.  This
+     *        argument should always be provided.  The lock code itself will
+     *        determine if it should be used.
+     * @param mech The mechanism to use for the interprocess lock, if any; one of
+     * <PRE>
+     *            APR_LOCK_FCNTL
+     *            APR_LOCK_FLOCK
+     *            APR_LOCK_SYSVSEM
+     *            APR_LOCK_POSIXSEM
+     *            APR_LOCK_PROC_PTHREAD
+     *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
+     * </PRE>
+     * @param pool the pool from which to allocate the mutex.
+     * @return Newly created mutex.
+     * @throws Error If an error occurred
+     */
+    public static native long create(String fname, int mech, long pool)
+        throws Error;
+
+    /**
+     * Re-open a mutex in a child process.
+     * @param fname A file name to use if the mutex mechanism requires one.  This
+     *              argument should always be provided.  The mutex code itself will
+     *              determine if it should be used.  This filename should be the
+     *              same one that was passed to apr_proc_mutex_create().
+     * @param pool The pool to operate on.
+     * This function must be called to maintain portability, even
+     *         if the underlying lock mechanism does not require it.
+     * @return Newly opened mutex.
+     * @throws Error If an error occurred
+     */
+    public static native long childInit(String fname, long pool)
+        throws Error;
+
+    /**
+     * Acquire the lock for the given mutex. If the mutex is already locked,
+     * the current thread will be put to sleep until the lock becomes available.
+     * @param mutex the mutex on which to acquire the lock.
+     * @return the operation status
+     */
+    public static native int lock(long mutex);
+
+    /**
+     * Attempt to acquire the lock for the given mutex. If the mutex has already
+     * been acquired, the call returns immediately with APR_EBUSY. Note: it
+     * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
+     * if the return value was APR_EBUSY, for portability reasons.
+     * @param mutex the mutex on which to attempt the lock acquiring.
+     * @return the operation status
+     */
+    public static native int trylock(long mutex);
+
+    /**
+     * Release the lock for the given mutex.
+     * @param mutex the mutex from which to release the lock.
+     * @return the operation status
+     */
+    public static native int unlock(long mutex);
+
+    /**
+     * Destroy the mutex and free the memory associated with the lock.
+     * @param mutex the mutex to destroy.
+     * @return the operation status
+     */
+    public static native int destroy(long mutex);
+
+}
diff --git a/java/org/apache/tomcat/jni/Library.java b/java/org/apache/tomcat/jni/Library.java
new file mode 100644
index 0000000..45956e1
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Library.java
@@ -0,0 +1,294 @@
+/*
+ *  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.tomcat.jni;
+
+import java.io.File;
+
+/** Library
+ *
+ * @author Mladen Turk
+ */
+public final class Library {
+
+    /* Default library names */
+    private static final String [] NAMES = {"tcnative-1", "libtcnative-1"};
+    /*
+     * A handle to the unique Library singleton instance.
+     */
+    private static Library _instance = null;
+
+    private Library() throws Exception {
+        boolean loaded = false;
+        StringBuilder err = new StringBuilder();
+        File binLib = new File(System.getProperty("catalina.home"), "bin");
+        for (int i = 0; i < NAMES.length; i++) {
+            File library = new File(binLib, System.mapLibraryName(NAMES[i]));
+            try {
+                System.load(library.getAbsolutePath());
+                loaded = true;
+            } catch (ThreadDeath t) {
+                throw t;
+            } catch (VirtualMachineError t) {
+                // Don't use a Java 7 multiple exception catch so we can keep
+                // the JNI code identical between Tomcat 6/7/8/9
+                throw t;
+            } catch (Throwable t) {
+                if (library.exists()) {
+                    // File exists but failed to load
+                    throw t;
+                }
+                if (i > 0) {
+                    err.append(", ");
+                }
+                err.append(t.getMessage());
+            }
+            if (loaded) {
+                break;
+            }
+        }
+        if (!loaded) {
+            String path = System.getProperty("java.library.path");
+            String [] paths = path.split(File.pathSeparator);
+            for (int i = 0; i < NAMES.length; i++) {
+                try {
+                    System.loadLibrary(NAMES[i]);
+                    loaded = true;
+                } catch (ThreadDeath t) {
+                    throw t;
+                } catch (VirtualMachineError t) {
+                    // Don't use a Java 7 multiple exception catch so we can keep
+                    // the JNI code identical between Tomcat 6/7/8/9
+                    throw t;
+                } catch (Throwable t) {
+                    String name = System.mapLibraryName(NAMES[i]);
+                    for (int j = 0; j < paths.length; j++) {
+                        java.io.File fd = new java.io.File(paths[j] , name);
+                        if (fd.exists()) {
+                            // File exists but failed to load
+                            throw t;
+                        }
+                    }
+                    if (err.length() > 0) {
+                        err.append(", ");
+                    }
+                    err.append(t.getMessage());
+                }
+                if (loaded) {
+                    break;
+                }
+            }
+        }
+        if (!loaded) {
+            StringBuilder names = new StringBuilder();
+            for (String name : NAMES) {
+                names.append(name);
+                names.append(", ");
+            }
+            throw new LibraryNotFoundError(names.substring(0, names.length() -2), err.toString());
+        }
+    }
+
+    private Library(String libraryName)
+    {
+        System.loadLibrary(libraryName);
+    }
+
+    /* create global TCN's APR pool
+     * This has to be the first call to TCN library.
+     */
+    private static native boolean initialize();
+    /* destroy global TCN's APR pool
+     * This has to be the last call to TCN library.
+     */
+    public static native void terminate();
+    /* Internal function for loading APR Features */
+    private static native boolean has(int what);
+    /* Internal function for loading APR Features */
+    private static native int version(int what);
+    /* Internal function for loading APR sizes */
+    private static native int size(int what);
+
+    /* TCN_MAJOR_VERSION */
+    public static int TCN_MAJOR_VERSION  = 0;
+    /* TCN_MINOR_VERSION */
+    public static int TCN_MINOR_VERSION  = 0;
+    /* TCN_PATCH_VERSION */
+    public static int TCN_PATCH_VERSION  = 0;
+    /* TCN_IS_DEV_VERSION */
+    public static int TCN_IS_DEV_VERSION = 0;
+    /* APR_MAJOR_VERSION */
+    public static int APR_MAJOR_VERSION  = 0;
+    /* APR_MINOR_VERSION */
+    public static int APR_MINOR_VERSION  = 0;
+    /* APR_PATCH_VERSION */
+    public static int APR_PATCH_VERSION  = 0;
+    /* APR_IS_DEV_VERSION */
+    public static int APR_IS_DEV_VERSION = 0;
+
+    /* TCN_VERSION_STRING */
+    public static native String versionString();
+    /* APR_VERSION_STRING */
+    public static native String aprVersionString();
+
+    /*  APR Feature Macros */
+    public static boolean APR_HAVE_IPV6           = false;
+    public static boolean APR_HAS_SHARED_MEMORY   = false;
+    public static boolean APR_HAS_THREADS         = false;
+    public static boolean APR_HAS_SENDFILE        = false;
+    public static boolean APR_HAS_MMAP            = false;
+    public static boolean APR_HAS_FORK            = false;
+    public static boolean APR_HAS_RANDOM          = false;
+    public static boolean APR_HAS_OTHER_CHILD     = false;
+    public static boolean APR_HAS_DSO             = false;
+    public static boolean APR_HAS_SO_ACCEPTFILTER = false;
+    public static boolean APR_HAS_UNICODE_FS      = false;
+    public static boolean APR_HAS_PROC_INVOKED    = false;
+    public static boolean APR_HAS_USER            = false;
+    public static boolean APR_HAS_LARGE_FILES     = false;
+    public static boolean APR_HAS_XTHREAD_FILES   = false;
+    public static boolean APR_HAS_OS_UUID         = false;
+    /* Are we big endian? */
+    public static boolean APR_IS_BIGENDIAN        = false;
+    /* APR sets APR_FILES_AS_SOCKETS to 1 on systems where it is possible
+     * to poll on files/pipes.
+     */
+    public static boolean APR_FILES_AS_SOCKETS    = false;
+    /* This macro indicates whether or not EBCDIC is the native character set.
+     */
+    public static boolean APR_CHARSET_EBCDIC      = false;
+    /* Is the TCP_NODELAY socket option inherited from listening sockets?
+     */
+    public static boolean APR_TCP_NODELAY_INHERITED = false;
+    /* Is the O_NONBLOCK flag inherited from listening sockets?
+     */
+    public static boolean APR_O_NONBLOCK_INHERITED  = false;
+
+
+    public static int APR_SIZEOF_VOIDP;
+    public static int APR_PATH_MAX;
+    public static int APRMAXHOSTLEN;
+    public static int APR_MAX_IOVEC_SIZE;
+    public static int APR_MAX_SECS_TO_LINGER;
+    public static int APR_MMAP_THRESHOLD;
+    public static int APR_MMAP_LIMIT;
+
+    /* return global TCN's APR pool */
+    public static native long globalPool();
+
+    /**
+     * Setup any APR internal data structures.  This MUST be the first function
+     * called for any APR library.
+     * @param libraryName the name of the library to load
+     *
+     * @return {@code true} if the native code was initialized successfully
+     *         otherwise {@code false}
+     *
+     * @throws Exception if a problem occurred during initialization
+     */
+    public static synchronized boolean initialize(String libraryName) throws Exception {
+        if (_instance == null) {
+            if (libraryName == null)
+                _instance = new Library();
+            else
+                _instance = new Library(libraryName);
+            TCN_MAJOR_VERSION  = version(0x01);
+            TCN_MINOR_VERSION  = version(0x02);
+            TCN_PATCH_VERSION  = version(0x03);
+            TCN_IS_DEV_VERSION = version(0x04);
+            APR_MAJOR_VERSION  = version(0x11);
+            APR_MINOR_VERSION  = version(0x12);
+            APR_PATCH_VERSION  = version(0x13);
+            APR_IS_DEV_VERSION = version(0x14);
+
+            APR_SIZEOF_VOIDP        = size(1);
+            APR_PATH_MAX            = size(2);
+            APRMAXHOSTLEN           = size(3);
+            APR_MAX_IOVEC_SIZE      = size(4);
+            APR_MAX_SECS_TO_LINGER  = size(5);
+            APR_MMAP_THRESHOLD      = size(6);
+            APR_MMAP_LIMIT          = size(7);
+
+            APR_HAVE_IPV6           = has(0);
+            APR_HAS_SHARED_MEMORY   = has(1);
+            APR_HAS_THREADS         = has(2);
+            APR_HAS_SENDFILE        = has(3);
+            APR_HAS_MMAP            = has(4);
+            APR_HAS_FORK            = has(5);
+            APR_HAS_RANDOM          = has(6);
+            APR_HAS_OTHER_CHILD     = has(7);
+            APR_HAS_DSO             = has(8);
+            APR_HAS_SO_ACCEPTFILTER = has(9);
+            APR_HAS_UNICODE_FS      = has(10);
+            APR_HAS_PROC_INVOKED    = has(11);
+            APR_HAS_USER            = has(12);
+            APR_HAS_LARGE_FILES     = has(13);
+            APR_HAS_XTHREAD_FILES   = has(14);
+            APR_HAS_OS_UUID         = has(15);
+            APR_IS_BIGENDIAN        = has(16);
+            APR_FILES_AS_SOCKETS    = has(17);
+            APR_CHARSET_EBCDIC      = has(18);
+            APR_TCP_NODELAY_INHERITED = has(19);
+            APR_O_NONBLOCK_INHERITED  = has(20);
+            if (APR_MAJOR_VERSION < 1) {
+                throw new UnsatisfiedLinkError("Unsupported APR Version (" +
+                                               aprVersionString() + ")");
+            }
+            if (!APR_HAS_THREADS) {
+                throw new UnsatisfiedLinkError("Missing APR_HAS_THREADS");
+            }
+        }
+        return initialize();
+    }
+
+    /**
+     * Calls System.load(filename). System.load() associates the
+     * loaded library with the class loader of the class that called
+     * the System method. A native library may not be loaded by more
+     * than one class loader, so calling the System method from a class that
+     * was loaded by a Webapp class loader will make it impossible for
+     * other Webapps to load it.
+     *
+     * Using this method will load the native library via a shared class
+     * loader (typically the Common class loader, but may vary in some
+     * configurations), so that it can be loaded by multiple Webapps.
+     *
+     * @param filename - absolute path of the native library
+     */
+    public static void load(String filename){
+        System.load(filename);
+    }
+
+    /**
+     * Calls System.loadLibrary(libname). System.loadLibrary() associates the
+     * loaded library with the class loader of the class that called
+     * the System method. A native library may not be loaded by more
+     * than one class loader, so calling the System method from a class that
+     * was loaded by a Webapp class loader will make it impossible for
+     * other Webapps to load it.
+     *
+     * Using this method will load the native library via a shared class
+     * loader (typically the Common class loader, but may vary in some
+     * configurations), so that it can be loaded by multiple Webapps.
+     *
+     * @param libname - the name of the native library
+     */
+    public static void loadLibrary(String libname){
+        System.loadLibrary(libname);
+    }
+
+}
diff --git a/java/org/apache/tomcat/jni/LibraryNotFoundError.java b/java/org/apache/tomcat/jni/LibraryNotFoundError.java
new file mode 100644
index 0000000..ab8a030
--- /dev/null
+++ b/java/org/apache/tomcat/jni/LibraryNotFoundError.java
@@ -0,0 +1,40 @@
+/*
+ * 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.tomcat.jni;
+
+public class LibraryNotFoundError extends UnsatisfiedLinkError {
+
+    private static final long serialVersionUID = 1L;
+
+    private final String libraryNames;
+
+    /**
+     *
+     * @param libraryNames A list of the file names of the native libraries that
+     *                     failed to load
+     * @param errors A list of the error messages received when trying to load
+     *               each of the libraries
+     */
+    public LibraryNotFoundError(String libraryNames, String errors){
+        super(errors);
+        this.libraryNames = libraryNames;
+    }
+
+    public String getLibraryNames(){
+        return libraryNames;
+    }
+}
diff --git a/java/org/apache/tomcat/jni/Local.java b/java/org/apache/tomcat/jni/Local.java
new file mode 100644
index 0000000..50ed955
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Local.java
@@ -0,0 +1,78 @@
+/*
+ *  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.tomcat.jni;
+
+/**
+ * Local socket.
+ *
+ * @author Mladen Turk
+ */
+public class Local {
+
+    /**
+     * Create a socket.
+     * @param path The address of the new socket.
+     * @param cont The parent pool to use
+     * @return The new socket that has been set up.
+     * @throws Exception If socket creation failed
+     */
+    public static native long create(String path, long cont)
+        throws Exception;
+
+    /**
+     * Bind the socket to its associated port
+     * @param sock The socket to bind
+     * @param sa The socket address to bind to
+     * This may be where we will find out if there is any other process
+     *      using the selected port.
+     * @return the operation status
+     */
+    public static native int bind(long sock, long sa);
+
+    /**
+     * Listen to a bound socket for connections.
+     * @param sock The socket to listen on
+     * @param backlog The number of outstanding connections allowed in the sockets
+     *                listen queue.  If this value is less than zero, for NT pipes
+     *                the number of instances is unlimited.
+     * @return the operation status
+     */
+    public static native int listen(long sock, int backlog);
+
+    /**
+     * Accept a new connection request
+     * @param sock The socket we are listening on.
+     * @return  A copy of the socket that is connected to the socket that
+     *          made the connection request.  This is the socket which should
+     *          be used for all future communication.
+     * @throws Exception If accept failed
+     */
+    public static native long accept(long sock)
+        throws Exception;
+
+    /**
+     * Issue a connection request to a socket either on the same machine
+     * or a different one.
+     * @param sock The socket we wish to use for our side of the connection
+     * @param sa The address of the machine we wish to connect to.
+     *           Unused for NT Pipes.
+     * @return the operation status
+     */
+    public static native int connect(long sock, long sa);
+
+}
diff --git a/java/org/apache/tomcat/jni/Lock.java b/java/org/apache/tomcat/jni/Lock.java
new file mode 100644
index 0000000..6bb789a
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Lock.java
@@ -0,0 +1,131 @@
+/*
+ *  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.tomcat.jni;
+
+/** Lock
+ *
+ * @author Mladen Turk
+ */
+public class Lock {
+
+    /**
+     * Enumerated potential types for APR process locking methods
+     * <br><b>Warning :</b> Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
+     *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
+     */
+
+    public static final int APR_LOCK_FCNTL        = 0; /** fcntl() */
+    public static final int APR_LOCK_FLOCK        = 1; /** flock() */
+    public static final int APR_LOCK_SYSVSEM      = 2; /** System V Semaphores */
+    public static final int APR_LOCK_PROC_PTHREAD = 3; /** POSIX pthread process-based locking */
+    public static final int APR_LOCK_POSIXSEM     = 4; /** POSIX semaphore process-based locking */
+    public static final int APR_LOCK_DEFAULT      = 5; /** Use the default process lock */
+
+    /**
+     * Create and initialize a mutex that can be used to synchronize processes.
+     * <br><b>Warning :</b> Check APR_HAS_foo_SERIALIZE defines to see if the platform supports
+     *          APR_LOCK_foo.  Only APR_LOCK_DEFAULT is portable.
+     * @param fname A file name to use if the lock mechanism requires one.  This
+     *        argument should always be provided.  The lock code itself will
+     *        determine if it should be used.
+     * @param mech The mechanism to use for the interprocess lock, if any; one of
+     * <PRE>
+     *            APR_LOCK_FCNTL
+     *            APR_LOCK_FLOCK
+     *            APR_LOCK_SYSVSEM
+     *            APR_LOCK_POSIXSEM
+     *            APR_LOCK_PROC_PTHREAD
+     *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
+     * </PRE>
+     * @param pool the pool from which to allocate the mutex.
+     * @return Newly created mutex.
+     * @throws Error An error occurred
+     */
+    public static native long create(String fname, int mech, long pool)
+        throws Error;
+
+    /**
+     * Re-open a mutex in a child process.
+     * This function must be called to maintain portability, even
+     * if the underlying lock mechanism does not require it.
+     * @param fname A file name to use if the mutex mechanism requires one.  This
+     *              argument should always be provided.  The mutex code itself will
+     *              determine if it should be used.  This filename should be the
+     *              same one that was passed to apr_proc_mutex_create().
+     * @param pool The pool to operate on.
+     * @return Newly opened mutex.
+     * @throws Error An error occurred
+     */
+    public static native long childInit(String fname, long pool)
+        throws Error;
+
+    /**
+     * Acquire the lock for the given mutex. If the mutex is already locked,
+     * the current thread will be put to sleep until the lock becomes available.
+     * @param mutex the mutex on which to acquire the lock.
+     * @return the operation status
+     */
+    public static native int lock(long mutex);
+
+    /**
+     * Attempt to acquire the lock for the given mutex. If the mutex has already
+     * been acquired, the call returns immediately with APR_EBUSY. Note: it
+     * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
+     * if the return value was APR_EBUSY, for portability reasons.
+     * @param mutex the mutex on which to attempt the lock acquiring.
+     * @return the operation status
+     */
+    public static native int trylock(long mutex);
+
+    /**
+     * Release the lock for the given mutex.
+     * @param mutex the mutex from which to release the lock.
+     * @return the operation status
+     */
+    public static native int unlock(long mutex);
+
+    /**
+     * Destroy the mutex and free the memory associated with the lock.
+     * @param mutex the mutex to destroy.
+     * @return the operation status
+     */
+    public static native int destroy(long mutex);
+
+    /**
+     * Return the name of the lockfile for the mutex, or NULL
+     * if the mutex doesn't use a lock file
+     * @param mutex the name of the mutex
+     * @return the name of the lock file
+     */
+    public static native String lockfile(long mutex);
+
+    /**
+     * Display the name of the mutex, as it relates to the actual method used.
+     * This matches the valid options for Apache's AcceptMutex directive
+     * @param mutex the name of the mutex
+     * @return the name of the mutex
+     */
+    public static native String name(long mutex);
+
+    /**
+     * Display the name of the default mutex: APR_LOCK_DEFAULT
+     * @return the default name
+     */
+    public static native String defname();
+
+}
diff --git a/java/org/apache/tomcat/jni/Mmap.java b/java/org/apache/tomcat/jni/Mmap.java
new file mode 100644
index 0000000..08bc795
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Mmap.java
@@ -0,0 +1,75 @@
+/*
+ *  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.tomcat.jni;
+
+/** Mmap
+ *
+ * @author Mladen Turk
+ */
+public class Mmap {
+    /** MMap opened for reading */
+    public static final int APR_MMAP_READ  = 1;
+    /** MMap opened for writing */
+    public static final int APR_MMAP_WRITE = 2;
+
+
+    /**
+     * Create a new mmap'ed file out of an existing APR file.
+     * @param file The file turn into an mmap.
+     * @param offset The offset into the file to start the data pointer at.
+     * @param size The size of the file
+     * @param flag bit-wise or of:
+     * <PRE>
+     * APR_MMAP_READ       MMap opened for reading
+     * APR_MMAP_WRITE      MMap opened for writing
+     * </PRE>
+     * @param pool The pool to use when creating the mmap.
+     * @return The newly created mmap'ed file.
+     * @throws Error Error creating memory mapping
+     */
+    public static native long create(long file, long offset, long size, int flag, long pool)
+        throws Error;
+
+    /**
+     * Duplicate the specified MMAP.
+     * @param mmap The mmap to duplicate.
+     * @param pool The pool to use for new_mmap.
+     * @return Duplicated mmap'ed file.
+     * @throws Error Error duplicating memory mapping
+     */
+    public static native long dup(long mmap, long pool)
+        throws Error;
+
+    /**
+     * Remove a mmap'ed.
+     * @param mm The mmap'ed file.
+     * @return the operation status
+     */
+    public static native int delete(long mm);
+
+    /**
+     * Move the pointer into the mmap'ed file to the specified offset.
+     * @param mm The mmap'ed file.
+     * @param offset The offset to move to.
+     * @return The pointer to the offset specified.
+     * @throws Error Error reading file
+     */
+    public static native long offset(long mm, long offset)
+        throws Error;
+
+}
diff --git a/java/org/apache/tomcat/jni/Multicast.java b/java/org/apache/tomcat/jni/Multicast.java
new file mode 100644
index 0000000..44d123b
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Multicast.java
@@ -0,0 +1,81 @@
+/*
+ *  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.tomcat.jni;
+
+/** Multicast
+ *
+ * @author Mladen Turk
+ */
+public class Multicast {
+
+    /**
+     * Join a Multicast Group
+     * @param sock The socket to join a multicast group
+     * @param join The address of the multicast group to join
+     * @param iface Address of the interface to use.  If NULL is passed, the
+     *              default multicast interface will be used. (OS Dependent)
+     * @param source Source Address to accept transmissions from (non-NULL
+     *               implies Source-Specific Multicast)
+     * @return the operation status
+     */
+    public static native int join(long sock, long join,
+                                  long iface, long source);
+
+    /**
+     * Leave a Multicast Group.  All arguments must be the same as
+     * apr_mcast_join.
+     * @param sock The socket to leave a multicast group
+     * @param addr The address of the multicast group to leave
+     * @param iface Address of the interface to use.  If NULL is passed, the
+     *              default multicast interface will be used. (OS Dependent)
+     * @param source Source Address to accept transmissions from (non-NULL
+     *               implies Source-Specific Multicast)
+     * @return the operation status
+     */
+    public static native int leave(long sock, long addr,
+                                   long iface, long source);
+
+    /**
+     * Set the Multicast Time to Live (ttl) for a multicast transmission.
+     * @param sock The socket to set the multicast ttl
+     * @param ttl Time to live to Assign. 0-255, default=1
+     * <br><b>Remark :</b> If the TTL is 0, packets will only be seen
+     * by sockets on the local machine,
+     * and only when multicast loopback is enabled.
+     * @return the operation status
+     */
+    public static native int hops(long sock, int ttl);
+
+    /**
+     * Toggle IP Multicast Loopback
+     * @param sock The socket to set multicast loopback
+     * @param opt false=disable, true=enable
+     * @return the operation status
+     */
+    public static native int loopback(long sock, boolean opt);
+
+
+    /**
+     * Set the Interface to be used for outgoing Multicast Transmissions.
+     * @param sock The socket to set the multicast interface on
+     * @param iface Address of the interface to use for Multicast
+     * @return the operation status
+     */
+    public static native int ointerface(long sock, long iface);
+
+}
diff --git a/java/org/apache/tomcat/jni/OS.java b/java/org/apache/tomcat/jni/OS.java
new file mode 100644
index 0000000..6796f23
--- /dev/null
+++ b/java/org/apache/tomcat/jni/OS.java
@@ -0,0 +1,137 @@
+/*
+ *  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.tomcat.jni;
+
+/** OS
+ *
+ * @author Mladen Turk
+ */
+public class OS {
+
+    /* OS Enums */
+    private static final int UNIX      = 1;
+    private static final int WIN32     = 3;
+    private static final int WIN64     = 4;
+    private static final int LINUX     = 5;
+    private static final int SOLARIS   = 6;
+    private static final int BSD       = 7;
+    private static final int MACOSX    = 8;
+
+    public static final int LOG_EMERG  = 1;
+    public static final int LOG_ERROR  = 2;
+    public static final int LOG_NOTICE = 3;
+    public static final int LOG_WARN   = 4;
+    public static final int LOG_INFO   = 5;
+    public static final int LOG_DEBUG  = 6;
+
+    /**
+     * Check for OS type.
+     * @param type OS type to test.
+     */
+    private static native boolean is(int type);
+
+    public static final boolean IS_UNIX    = is(UNIX);
+    /**
+     * @deprecated Hard-coded to false since there has not been a supported
+     *             Netware platform for many years.
+     *             This will be removed in Tomcat 10 onwards
+     */
+    @Deprecated
+    public static final boolean IS_NETWARE = false;
+    public static final boolean IS_WIN32   = is(WIN32);
+    public static final boolean IS_WIN64   = is(WIN64);
+    public static final boolean IS_LINUX   = is(LINUX);
+    public static final boolean IS_SOLARIS = is(SOLARIS);
+    public static final boolean IS_BSD     = is(BSD);
+    public static final boolean IS_MACOSX  = is(MACOSX);
+
+    /**
+     * Get the name of the system default character set.
+     * @param pool the pool to allocate the name from, if needed
+     * @return the encoding
+     */
+    public static native String defaultEncoding(long pool);
+
+    /**
+     * Get the name of the current locale character set.
+     * Defers to apr_os_default_encoding if the current locale's
+     * data can't be retrieved on this system.
+     * @param pool the pool to allocate the name from, if needed
+     * @return the encoding
+     */
+    public static native String localeEncoding(long pool);
+
+    /**
+     * Generate random bytes.
+     * @param buf Buffer to fill with random bytes
+     * @param len Length of buffer in bytes
+     * @return the operation status
+     */
+    public static native int random(byte [] buf, int len);
+
+    /**
+     * Gather system info.
+     * <PRE>
+     * On exit the inf array will be filled with:
+     * inf[0]  - Total usable main memory size
+     * inf[1]  - Available memory size
+     * inf[2]  - Total page file/swap space size
+     * inf[3]  - Page file/swap space still available
+     * inf[4]  - Amount of shared memory
+     * inf[5]  - Memory used by buffers
+     * inf[6]  - Memory Load
+     *
+     * inf[7]  - Idle Time in microseconds
+     * inf[8]  - Kernel Time in microseconds
+     * inf[9]  - User Time in microseconds
+     *
+     * inf[10] - Process creation time (apr_time_t)
+     * inf[11] - Process Kernel Time in microseconds
+     * inf[12] - Process User Time in microseconds
+     *
+     * inf[13] - Current working set size.
+     * inf[14] - Peak working set size.
+     * inf[15] - Number of page faults.
+     * </PRE>
+     * @param inf array that will be filled with system information.
+     *            Array length must be at least 16.
+     * @return the operation status
+     */
+    public static native int info(long [] inf);
+
+    /**
+     * Expand environment variables.
+     * @param str String to expand
+     * @return Expanded string with replaced environment variables.
+     */
+    public static native String expand(String str);
+
+    /**
+     * Initialize system logging.
+     * @param domain String that will be prepended to every message
+     */
+    public static native void sysloginit(String domain);
+
+    /**
+     * Log message.
+     * @param level Log message severity. See LOG_XXX enums.
+     * @param message Message to log
+     */
+    public static native void syslog(int level, String message);
+
+}
diff --git a/java/org/apache/tomcat/jni/PasswordCallback.java b/java/org/apache/tomcat/jni/PasswordCallback.java
new file mode 100644
index 0000000..13f5d9a
--- /dev/null
+++ b/java/org/apache/tomcat/jni/PasswordCallback.java
@@ -0,0 +1,32 @@
+/*
+ *  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.tomcat.jni;
+
+/** PasswordCallback Interface
+ *
+ * @author Mladen Turk
+ */
+public interface PasswordCallback {
+
+    /**
+     * Called when the password is required
+     * @param prompt Password prompt
+     * @return Valid password or null
+     */
+    public String callback(String prompt);
+}
diff --git a/java/org/apache/tomcat/jni/Poll.java b/java/org/apache/tomcat/jni/Poll.java
new file mode 100644
index 0000000..112d02e
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Poll.java
@@ -0,0 +1,188 @@
+/*
+ *  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.tomcat.jni;
+
+/** Poll
+ *
+ * @author Mladen Turk
+ */
+public class Poll {
+
+    /**
+     * Poll return values
+     */
+    /** Can read without blocking */
+    public static final int APR_POLLIN   = 0x001;
+    /** Priority data available */
+    public static final int APR_POLLPRI  = 0x002;
+    /** Can write without blocking */
+    public static final int APR_POLLOUT  = 0x004;
+    /** Pending error */
+    public static final int APR_POLLERR  = 0x010;
+    /** Hangup occurred */
+    public static final int APR_POLLHUP  = 0x020;
+    /** Descriptor invalid */
+    public static final int APR_POLLNVAL = 0x040;
+
+    /**
+     * Pollset Flags
+     */
+    /** Adding or Removing a Descriptor is thread safe */
+    public static final int APR_POLLSET_THREADSAFE = 0x001;
+
+
+    /** Used in apr_pollfd_t to determine what the apr_descriptor is
+     * apr_datatype_e enum
+     */
+    public static final int APR_NO_DESC       = 0; /** nothing here */
+    public static final int APR_POLL_SOCKET   = 1; /** descriptor refers to a socket */
+    public static final int APR_POLL_FILE     = 2; /** descriptor refers to a file */
+    public static final int APR_POLL_LASTDESC = 3; /** descriptor is the last one in the list */
+
+    /**
+     * Setup a pollset object.
+     * If flags equals APR_POLLSET_THREADSAFE, then a pollset is
+     * created on which it is safe to make concurrent calls to
+     * apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll() from
+     * separate threads.  This feature is only supported on some
+     * platforms; the apr_pollset_create() call will fail with
+     * APR_ENOTIMPL on platforms where it is not supported.
+     * @param size The maximum number of descriptors that this pollset can hold
+     * @param p The pool from which to allocate the pollset
+     * @param flags Optional flags to modify the operation of the pollset.
+     * @param ttl Maximum time to live for a particular socket.
+     * @return  The pointer in which to return the newly created object
+     * @throws Error Pollset creation failed
+     */
+    public static native long create(int size, long p, int flags, long ttl)
+        throws Error;
+    /**
+     * Destroy a pollset object
+     * @param pollset The pollset to destroy
+     * @return the operation status
+     */
+    public static native int destroy(long pollset);
+
+    /**
+     * Add a socket to a pollset with the default timeout.
+     * @param pollset The pollset to which to add the socket
+     * @param sock The sockets to add
+     * @param reqevents requested events
+     * @return the operation status
+     */
+    public static native int add(long pollset, long sock,
+                                 int reqevents);
+
+    /**
+     * Add a socket to a pollset with a specific timeout.
+     * @param pollset The pollset to which to add the socket
+     * @param sock The sockets to add
+     * @param reqevents requested events
+     * @param timeout requested timeout in microseconds (-1 for infinite)
+     * @return the operation status
+     */
+    public static native int addWithTimeout(long pollset, long sock,
+                                            int reqevents, long timeout);
+
+    /**
+     * Remove a descriptor from a pollset
+     * @param pollset The pollset from which to remove the descriptor
+     * @param sock The socket to remove
+     * @return the operation status
+     */
+    public static native int remove(long pollset, long sock);
+
+    /**
+     * Block for activity on the descriptor(s) in a pollset
+     * @param pollset The pollset to use
+     * @param timeout Timeout in microseconds
+     * @param descriptors Array of signaled descriptors (output parameter)
+     *        The descriptor array must be two times the size of pollset.
+     *        and are populated as follows:
+     * <PRE>
+     * descriptors[2n + 0] -&gt; returned events
+     * descriptors[2n + 1] -&gt; socket
+     * </PRE>
+     * @param remove Remove signaled descriptors from pollset
+     * @return Number of signaled descriptors (output parameter)
+     *         or negative APR error code.
+     */
+    public static native int poll(long pollset, long timeout,
+                                  long [] descriptors, boolean remove);
+
+    /**
+     * Maintain on the descriptor(s) in a pollset
+     * @param pollset The pollset to use
+     * @param descriptors Array of signaled descriptors (output parameter)
+     *        The descriptor array must be the size of pollset.
+     *        and are populated as follows:
+     * <PRE>
+     * descriptors[n] -&gt; socket
+     * </PRE>
+     * @param remove Remove signaled descriptors from pollset
+     * @return Number of signaled descriptors (output parameter)
+     *         or negative APR error code.
+     */
+    public static native int maintain(long pollset, long [] descriptors,
+                                      boolean remove);
+
+    /**
+     * Set the socket time to live.
+     * @param pollset The pollset to use
+     * @param ttl Timeout in microseconds
+     */
+    public static native void setTtl(long pollset, long ttl);
+
+    /**
+     * Get the socket time to live.
+     * @param pollset The pollset to use
+     * @return Timeout in microseconds
+     */
+    public static native long getTtl(long pollset);
+
+    /**
+     * Return all descriptor(s) in a pollset
+     * @param pollset The pollset to use
+     * @param descriptors Array of descriptors (output parameter)
+     *        The descriptor array must be two times the size of pollset.
+     *        and are populated as follows:
+     * <PRE>
+     * descriptors[2n + 0] -&gt; returned events
+     * descriptors[2n + 1] -&gt; socket
+     * </PRE>
+     * @return Number of descriptors (output parameter) in the Poll
+     *         or negative APR error code.
+     */
+    public static native int pollset(long pollset, long [] descriptors);
+
+    /**
+     * Make poll() return.
+     *
+     * @param   pollset The pollset to use
+     * @return  Negative APR error code
+     */
+    public static native int interrupt(long pollset);
+
+    /**
+     * Check if interrupt() is allowed.
+     *
+     * @param pollset The pollset to use
+     * @return  <code>true</code> if {@link #interrupt(long)} is allowed, else
+     *          <code>false</code>
+     */
+    public static native boolean wakeable(long pollset);
+}
diff --git a/java/org/apache/tomcat/jni/Pool.java b/java/org/apache/tomcat/jni/Pool.java
new file mode 100644
index 0000000..f08fa80
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Pool.java
@@ -0,0 +1,163 @@
+/*
+ *  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.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+/** Pool
+ *
+ * @author Mladen Turk
+ */
+public class Pool {
+
+    /**
+     * Create a new pool.
+     * @param parent The parent pool.  If this is 0, the new pool is a root
+     * pool.  If it is non-zero, the new pool will inherit all
+     * of its parent pool's attributes, except the apr_pool_t will
+     * be a sub-pool.
+     * @return The pool we have just created.
+    */
+    public static native long create(long parent);
+
+    /**
+     * Clear all memory in the pool and run all the cleanups. This also destroys all
+     * subpools.
+     * @param pool The pool to clear
+     * This does not actually free the memory, it just allows the pool
+     *         to re-use this memory for the next allocation.
+     */
+    public static native void clear(long pool);
+
+    /**
+     * Destroy the pool. This takes similar action as apr_pool_clear() and then
+     * frees all the memory.
+     * This will actually free the memory
+     * @param pool The pool to destroy
+     */
+    public static native void destroy(long pool);
+
+    /**
+     * Get the parent pool of the specified pool.
+     * @param pool The pool for retrieving the parent pool.
+     * @return The parent of the given pool.
+     */
+    public static native long parentGet(long pool);
+
+    /**
+     * Determine if pool a is an ancestor of pool b
+     * @param a The pool to search
+     * @param b The pool to search for
+     * @return True if a is an ancestor of b, NULL is considered an ancestor
+     * of all pools.
+     */
+    public static native boolean isAncestor(long a, long b);
+
+
+    /*
+     * Cleanup
+     *
+     * Cleanups are performed in the reverse order they were registered.  That is:
+     * Last In, First Out.  A cleanup function can safely allocate memory from
+     * the pool that is being cleaned up. It can also safely register additional
+     * cleanups which will be run LIFO, directly after the current cleanup
+     * terminates.  Cleanups have to take caution in calling functions that
+     * create subpools. Subpools, created during cleanup will NOT automatically
+     * be cleaned up.  In other words, cleanups are to clean up after themselves.
+     */
+
+    /**
+     * Register a function to be called when a pool is cleared or destroyed
+     * @param pool The pool register the cleanup with
+     * @param o The object to call when the pool is cleared
+     *                      or destroyed
+     * @return The cleanup handler.
+     */
+    public static native long cleanupRegister(long pool, Object o);
+
+    /**
+     * Remove a previously registered cleanup function
+     * @param pool The pool remove the cleanup from
+     * @param data The cleanup handler to remove from cleanup
+     */
+    public static native void cleanupKill(long pool, long data);
+
+    /**
+     * Register a process to be killed when a pool dies.
+     * @param a The pool to use to define the processes lifetime
+     * @param proc The process to register
+     * @param how How to kill the process, one of:
+     * <PRE>
+     * APR_KILL_NEVER         -- process is never sent any signals
+     * APR_KILL_ALWAYS        -- process is sent SIGKILL on apr_pool_t cleanup
+     * APR_KILL_AFTER_TIMEOUT -- SIGTERM, wait 3 seconds, SIGKILL
+     * APR_JUST_WAIT          -- wait forever for the process to complete
+     * APR_KILL_ONLY_ONCE     -- send SIGTERM and then wait
+     * </PRE>
+     */
+    public static native void noteSubprocess(long a, long proc, int how);
+
+    /**
+     * Allocate a block of memory from a pool
+     * @param p The pool to allocate from
+     * @param size The amount of memory to allocate
+     * @return The ByteBuffer with allocated memory
+     */
+    public static native ByteBuffer alloc(long p, int size);
+
+    /**
+     * Allocate a block of memory from a pool and set all of the memory to 0
+     * @param p The pool to allocate from
+     * @param size The amount of memory to allocate
+     * @return The ByteBuffer with allocated memory
+     */
+    public static native ByteBuffer calloc(long p, int size);
+
+    /*
+     * User data management
+     */
+
+    /**
+     * Set the data associated with the current pool
+     * @param data The user data associated with the pool.
+     * @param key The key to use for association
+     * @param pool The current pool
+     * <br><b>Warning :</b>
+     * The data to be attached to the pool should have a life span
+     * at least as long as the pool it is being attached to.
+     * Object attached to the pool will be globally referenced
+     * until the pool is cleared or dataSet is called with the null data.
+     * @return APR Status code.
+     */
+     public static native int dataSet(long pool, String key, Object data);
+
+    /**
+     * Return the data associated with the current pool.
+     * @param key The key for the data to retrieve
+     * @param pool The current pool.
+     * @return the data
+     */
+     public static native Object dataGet(long pool, String key);
+
+    /**
+     * Run all of the child_cleanups, so that any unnecessary files are
+     * closed because we are about to exec a new program
+     */
+    public static native void cleanupForExec();
+
+}
diff --git a/java/org/apache/tomcat/jni/PoolCallback.java b/java/org/apache/tomcat/jni/PoolCallback.java
new file mode 100644
index 0000000..5075a3e
--- /dev/null
+++ b/java/org/apache/tomcat/jni/PoolCallback.java
@@ -0,0 +1,31 @@
+/*
+ *  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.tomcat.jni;
+
+/** PoolCallback Interface
+ *
+ * @author Mladen Turk
+ */
+public interface PoolCallback {
+
+    /**
+     * Called when the pool is destroyed or cleared
+     * @return Function must return APR_SUCCESS
+     */
+    public int callback();
+}
diff --git a/java/org/apache/tomcat/jni/Proc.java b/java/org/apache/tomcat/jni/Proc.java
new file mode 100644
index 0000000..cbae420
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Proc.java
@@ -0,0 +1,213 @@
+/*
+ *  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.tomcat.jni;
+
+/** Proc
+ *
+ * @author Mladen Turk
+ */
+public class Proc {
+
+    /*
+     * apr_cmdtype_e enum
+     */
+    public static final int APR_SHELLCM      = 0; /** use the shell to invoke the program */
+    public static final int APR_PROGRAM      = 1; /** invoke the program directly, no copied env */
+    public static final int APR_PROGRAM_ENV  = 2; /** invoke the program, replicating our environment */
+    public static final int APR_PROGRAM_PATH = 3; /** find program on PATH, use our environment */
+    public static final int APR_SHELLCMD_ENV = 4; /** use the shell to invoke the program,
+                                                   *   replicating our environment
+                                                   */
+
+    /*
+     * apr_wait_how_e enum
+     */
+    public static final int APR_WAIT   = 0; /** wait for the specified process to finish */
+    public static final int APR_NOWAIT = 1; /** do not wait -- just see if it has finished */
+
+    /*
+     * apr_exit_why_e enum
+     */
+    public static final int APR_PROC_EXIT        = 1; /** process exited normally */
+    public static final int APR_PROC_SIGNAL      = 2; /** process exited due to a signal */
+    public static final int APR_PROC_SIGNAL_CORE = 4; /** process exited and dumped a core file */
+
+    public static final int APR_NO_PIPE       = 0;
+    public static final int APR_FULL_BLOCK    = 1;
+    public static final int APR_FULL_NONBLOCK = 2;
+    public static final int APR_PARENT_BLOCK  = 3;
+    public static final int APR_CHILD_BLOCK   = 4;
+
+    public static final int APR_LIMIT_CPU     = 0;
+    public static final int APR_LIMIT_MEM     = 1;
+    public static final int APR_LIMIT_NPROC   = 2;
+    public static final int APR_LIMIT_NOFILE  = 3;
+
+
+    /** child has died, caller must call unregister still */
+    public static final int APR_OC_REASON_DEATH      = 0;
+    /** write_fd is unwritable */
+    public static final int APR_OC_REASON_UNWRITABLE = 1;
+    /** a restart is occurring, perform any necessary cleanup (including
+     * sending a special signal to child)
+     */
+    public static final int APR_OC_REASON_RESTART    = 2;
+    /** unregister has been called, do whatever is necessary (including
+     * kill the child)
+     */
+    public static final int APR_OC_REASON_UNREGISTER = 3;
+    /** somehow the child exited without us knowing ... buggy os? */
+    public static final int APR_OC_REASON_LOST       = 4;
+    /** a health check is occurring, for most maintenance functions
+     * this is a no-op.
+     */
+    public static final int APR_OC_REASON_RUNNING    = 5;
+
+    /* apr_kill_conditions_e enumeration */
+    /** process is never sent any signals */
+    public static final int APR_KILL_NEVER         = 0;
+    /** process is sent SIGKILL on apr_pool_t cleanup */
+    public static final int APR_KILL_ALWAYS        = 1;
+    /** SIGTERM, wait 3 seconds, SIGKILL */
+    public static final int APR_KILL_AFTER_TIMEOUT = 2;
+    /** wait forever for the process to complete */
+    public static final int APR_JUST_WAIT          = 3;
+    /** send SIGTERM and then wait */
+    public static final int APR_KILL_ONLY_ONCE     = 4;
+
+    public static final int APR_PROC_DETACH_FOREGROUND = 0; /** Do not detach */
+    public static final int APR_PROC_DETACH_DAEMONIZE  = 1; /** Detach */
+
+    /* Maximum number of arguments for create process call */
+    public static final int MAX_ARGS_SIZE          = 1024;
+    /* Maximum number of environment variables for create process call */
+    public static final int MAX_ENV_SIZE           = 1024;
+
+    /**
+     * Allocate apr_proc_t structure from pool
+     * This is not an apr function.
+     * @param cont The pool to use.
+     * @return the pointer
+     */
+    public static native long alloc(long cont);
+
+    /**
+     * This is currently the only non-portable call in APR.  This executes
+     * a standard unix fork.
+     * @param proc The resulting process handle.
+     * @param cont The pool to use.
+     * @return APR_INCHILD for the child, and APR_INPARENT for the parent
+     * or an error.
+     */
+    public static native int fork(long [] proc, long cont);
+
+    /**
+     * Create a new process and execute a new program within that process.
+     * This function returns without waiting for the new process to terminate;
+     * use apr_proc_wait for that.
+     * @param proc The process handle
+     * @param progname The program to run
+     * @param args The arguments to pass to the new program.  The first
+     *             one should be the program name.
+     * @param env The new environment table for the new process.  This
+     *            should be a list of NULL-terminated strings. This argument
+     *            is ignored for APR_PROGRAM_ENV, APR_PROGRAM_PATH, and
+     *            APR_SHELLCMD_ENV types of commands.
+     * @param attr The procattr we should use to determine how to create the new
+     * process
+     * @param pool The pool to use.
+     * @return The resulting process handle.
+     */
+    public static native int create(long proc, String progname,
+                                    String [] args, String [] env,
+                                    long attr, long pool);
+
+    /**
+     * Wait for a child process to die
+     * @param proc The process handle that corresponds to the desired child process
+     * @param exit exit[0] The returned exit status of the child, if a child process
+     *                dies, or the signal that caused the child to die.
+     *                On platforms that don't support obtaining this information,
+     *                the status parameter will be returned as APR_ENOTIMPL.
+     * exit[1] Why the child died, the bitwise or of:
+     * <PRE>
+     * APR_PROC_EXIT         -- process terminated normally
+     * APR_PROC_SIGNAL       -- process was killed by a signal
+     * APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
+     *                          generated a core dump.
+     * </PRE>
+     * @param waithow How should we wait.  One of:
+     * <PRE>
+     * APR_WAIT   -- block until the child process dies.
+     * APR_NOWAIT -- return immediately regardless of if the
+     *               child is dead or not.
+     * </PRE>
+     * @return The childs status is in the return code to this process.  It is one of:
+     * <PRE>
+     * APR_CHILD_DONE     -- child is no longer running.
+     * APR_CHILD_NOTDONE  -- child is still running.
+     * </PRE>
+     */
+    public static native int wait(long proc, int [] exit, int waithow);
+
+    /**
+     * Wait for any current child process to die and return information
+     * about that child.
+     * @param proc Pointer to NULL on entry, will be filled out with child's
+     *             information
+     * @param exit exit[0] The returned exit status of the child, if a child process
+     *                dies, or the signal that caused the child to die.
+     *                On platforms that don't support obtaining this information,
+     *                the status parameter will be returned as APR_ENOTIMPL.
+     * exit[1] Why the child died, the bitwise or of:
+     * <PRE>
+     * APR_PROC_EXIT         -- process terminated normally
+     * APR_PROC_SIGNAL       -- process was killed by a signal
+     * APR_PROC_SIGNAL_CORE  -- process was killed by a signal, and
+     *                          generated a core dump.
+     * </PRE>
+     * @param waithow How should we wait.  One of:
+     * <PRE>
+     * APR_WAIT   -- block until the child process dies.
+     * APR_NOWAIT -- return immediately regardless of if the
+     *               child is dead or not.
+     * </PRE>
+     * @param pool Pool to allocate child information out of.
+     * @return the operation status
+     */
+    public static native int waitAllProcs(long proc, int [] exit,
+                                          int waithow, long pool);
+
+     /**
+     * Detach the process from the controlling terminal.
+     * @param daemonize set to non-zero if the process should daemonize
+     *                  and become a background process, else it will
+     *                  stay in the foreground.
+     * @return the operation status
+     */
+    public static native int detach(int daemonize);
+
+    /**
+     * Terminate a process.
+     * @param proc The process to terminate.
+     * @param sig How to kill the process.
+     * @return the operation status
+     */
+    public static native int kill(long proc, int sig);
+
+}
diff --git a/java/org/apache/tomcat/jni/ProcErrorCallback.java b/java/org/apache/tomcat/jni/ProcErrorCallback.java
new file mode 100644
index 0000000..60f53c8
--- /dev/null
+++ b/java/org/apache/tomcat/jni/ProcErrorCallback.java
@@ -0,0 +1,36 @@
+/*
+ *  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.tomcat.jni;
+
+/** ProcErrorCallback Interface
+ *
+ * @author Mladen Turk
+ */
+public interface ProcErrorCallback {
+
+    /**
+     * Called in the child process if APR encounters an error
+     * in the child prior to running the specified program.
+     * @param pool Pool associated with the apr_proc_t.  If your child
+     *             error function needs user data, associate it with this
+     *             pool.
+     * @param err APR error code describing the error
+     * @param description Text description of type of processing which failed
+     */
+    public void callback(long pool, int err, String description);
+}
diff --git a/java/org/apache/tomcat/jni/Procattr.java b/java/org/apache/tomcat/jni/Procattr.java
new file mode 100644
index 0000000..88e97c6
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Procattr.java
@@ -0,0 +1,182 @@
+/*
+ *  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.tomcat.jni;
+
+/** Procattr
+ *
+ * @author Mladen Turk
+ */
+public class Procattr {
+
+    /**
+     * Create and initialize a new procattr variable
+     * @param cont The pool to use
+     * @return The newly created procattr.
+     * @throws Error An error occurred
+     */
+    public static native long create(long cont)
+        throws Error;
+
+    /**
+     * Determine if any of stdin, stdout, or stderr should be linked to pipes
+     * when starting a child process.
+     * @param attr The procattr we care about.
+     * @param in Should stdin be a pipe back to the parent?
+     * @param out Should stdout be a pipe back to the parent?
+     * @param err Should stderr be a pipe back to the parent?
+     * @return the operation status
+     */
+    public static native int ioSet(long attr, int in, int out, int err);
+
+    /**
+     * Set the child_in and/or parent_in values to existing apr_file_t values.
+     * <br>
+     * This is NOT a required initializer function. This is
+     * useful if you have already opened a pipe (or multiple files)
+     * that you wish to use, perhaps persistently across multiple
+     * process invocations - such as a log file. You can save some
+     * extra function calls by not creating your own pipe since this
+     * creates one in the process space for you.
+     * @param attr The procattr we care about.
+     * @param in apr_file_t value to use as child_in. Must be a valid file.
+     * @param parent apr_file_t value to use as parent_in. Must be a valid file.
+     * @return the operation status
+     */
+    public static native int childInSet(long attr, long in, long parent);
+
+    /**
+     * Set the child_out and parent_out values to existing apr_file_t values.
+     * <br>
+     * This is NOT a required initializer function. This is
+     * useful if you have already opened a pipe (or multiple files)
+     * that you wish to use, perhaps persistently across multiple
+     * process invocations - such as a log file.
+     * @param attr The procattr we care about.
+     * @param out apr_file_t value to use as child_out. Must be a valid file.
+     * @param parent apr_file_t value to use as parent_out. Must be a valid file.
+     * @return the operation status
+     */
+    public static native int childOutSet(long attr, long out, long parent);
+
+    /**
+     * Set the child_err and parent_err values to existing apr_file_t values.
+     * <br>
+     * This is NOT a required initializer function. This is
+     * useful if you have already opened a pipe (or multiple files)
+     * that you wish to use, perhaps persistently across multiple
+     * process invocations - such as a log file.
+     * @param attr The procattr we care about.
+     * @param err apr_file_t value to use as child_err. Must be a valid file.
+     * @param parent apr_file_t value to use as parent_err. Must be a valid file.
+     * @return the operation status
+     */
+    public static native int childErrSet(long attr, long err, long parent);
+
+    /**
+     * Set which directory the child process should start executing in.
+     * @param attr The procattr we care about.
+     * @param dir Which dir to start in.  By default, this is the same dir as
+     *            the parent currently resides in, when the createprocess call
+     *            is made.
+     * @return the operation status
+     */
+    public static native int dirSet(long attr, String dir);
+
+    /**
+     * Set what type of command the child process will call.
+     * @param attr The procattr we care about.
+     * @param cmd The type of command.  One of:
+     * <PRE>
+     * APR_SHELLCMD     --  Anything that the shell can handle
+     * APR_PROGRAM      --  Executable program   (default)
+     * APR_PROGRAM_ENV  --  Executable program, copy environment
+     * APR_PROGRAM_PATH --  Executable program on PATH, copy env
+     * </PRE>
+     * @return the operation status
+     */
+    public static native int cmdtypeSet(long attr, int cmd);
+
+    /**
+     * Determine if the child should start in detached state.
+     * @param attr The procattr we care about.
+     * @param detach Should the child start in detached state?  Default is no.
+     * @return the operation status
+     */
+    public static native int detachSet(long attr, int detach);
+
+    /**
+     * Specify that apr_proc_create() should do whatever it can to report
+     * failures to the caller of apr_proc_create(), rather than find out in
+     * the child.
+     * @param attr The procattr describing the child process to be created.
+     * @param chk Flag to indicate whether or not extra work should be done
+     *            to try to report failures to the caller.
+     * <br>
+     * This flag only affects apr_proc_create() on platforms where
+     * fork() is used.  This leads to extra overhead in the calling
+     * process, but that may help the application handle such
+     * errors more gracefully.
+     * @return the operation status
+     */
+    public static native int errorCheckSet(long attr, int chk);
+
+    /**
+     * Determine if the child should start in its own address space or using the
+     * current one from its parent
+     * @param attr The procattr we care about.
+     * @param addrspace Should the child start in its own address space?
+     *                  Default is yes.
+     * @return the operation status
+     */
+    public static native int addrspaceSet(long attr, int addrspace);
+
+    /**
+     * Specify an error function to be called in the child process if APR
+     * encounters an error in the child prior to running the specified program.
+     * @param attr The procattr describing the child process to be created.
+     * @param pool The the pool to use.
+     * @param o The Object to call in the child process.
+     * <br>
+     * At the present time, it will only be called from apr_proc_create()
+     * on platforms where fork() is used.  It will never be called on other
+     * platforms, on those platforms apr_proc_create() will return the error
+     * in the parent process rather than invoke the callback in the now-forked
+     * child process.
+     */
+    public static native void errfnSet(long attr, long pool, Object o);
+
+    /**
+     * Set the username used for running process
+     * @param attr The procattr we care about.
+     * @param username The username used
+     * @param password User password if needed. Password is needed on WIN32
+     *                 or any other platform having
+     *                 APR_PROCATTR_USER_SET_REQUIRES_PASSWORD set.
+     * @return the operation status
+     */
+    public static native int userSet(long attr, String username, String password);
+
+    /**
+     * Set the group used for running process
+     * @param attr The procattr we care about.
+     * @param groupname The group name  used
+     * @return the operation status
+     */
+    public static native int groupSet(long attr, String groupname);
+
+}
diff --git a/java/org/apache/tomcat/jni/Registry.java b/java/org/apache/tomcat/jni/Registry.java
new file mode 100644
index 0000000..209e02f
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Registry.java
@@ -0,0 +1,243 @@
+/*
+ *  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.tomcat.jni;
+
+/** Windows Registry support
+ *
+ * @author Mladen Turk
+ */
+public class Registry {
+
+    /* Registry Enums */
+    public static final int HKEY_CLASSES_ROOT       = 1;
+    public static final int HKEY_CURRENT_CONFIG     = 2;
+    public static final int HKEY_CURRENT_USER       = 3;
+    public static final int HKEY_LOCAL_MACHINE      = 4;
+    public static final int HKEY_USERS              = 5;
+
+    public static final int KEY_ALL_ACCESS          = 0x0001;
+    public static final int KEY_CREATE_LINK         = 0x0002;
+    public static final int KEY_CREATE_SUB_KEY      = 0x0004;
+    public static final int KEY_ENUMERATE_SUB_KEYS  = 0x0008;
+    public static final int KEY_EXECUTE             = 0x0010;
+    public static final int KEY_NOTIFY              = 0x0020;
+    public static final int KEY_QUERY_VALUE         = 0x0040;
+    public static final int KEY_READ                = 0x0080;
+    public static final int KEY_SET_VALUE           = 0x0100;
+    public static final int KEY_WOW64_64KEY         = 0x0200;
+    public static final int KEY_WOW64_32KEY         = 0x0400;
+    public static final int KEY_WRITE               = 0x0800;
+
+    public static final int REG_BINARY              = 1;
+    public static final int REG_DWORD               = 2;
+    public static final int REG_EXPAND_SZ           = 3;
+    public static final int REG_MULTI_SZ            = 4;
+    public static final int REG_QWORD               = 5;
+    public static final int REG_SZ                  = 6;
+
+     /**
+     * Create or open a Registry Key.
+     * @param name Registry Subkey to open
+     * @param root Root key, one of HKEY_*
+     * @param sam Access mask that specifies the access rights for the key.
+     * @param pool Pool used for native memory allocation
+     * @return Opened Registry key
+     * @throws Error An error occurred
+     */
+    public static native long create(int root, String name, int sam, long pool)
+        throws Error;
+
+     /**
+     * Opens the specified Registry Key.
+     * @param name Registry Subkey to open
+     * @param root Root key, one of HKEY_*
+     * @param sam Access mask that specifies the access rights for the key.
+     * @param pool Pool used for native memory allocation
+     * @return Opened Registry key
+     * @throws Error An error occurred
+     */
+    public static native long open(int root, String name, int sam, long pool)
+        throws Error;
+
+    /**
+     * Close the specified Registry key.
+     * @param key The Registry key descriptor to close.
+     * @return the operation status
+     */
+    public static native int close(long key);
+
+    /**
+     * Get the Registry key type.
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Value type or negative error value
+     */
+    public static native int getType(long key, String name);
+
+    /**
+     * Get the Registry value for REG_DWORD
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Registry key value
+     * @throws Error An error occurred
+     */
+    public static native int getValueI(long key, String name)
+        throws Error;
+
+    /**
+     * Get the Registry value for REG_QWORD or REG_DWORD
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Registry key value
+     * @throws Error An error occurred
+     */
+    public static native long getValueJ(long key, String name)
+        throws Error;
+
+    /**
+     * Get the Registry key length.
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Value size or negative error value
+     */
+    public static native int getSize(long key, String name);
+
+    /**
+     * Get the Registry value for REG_SZ or REG_EXPAND_SZ
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Registry key value
+     * @throws Error An error occurred
+     */
+    public static native String getValueS(long key, String name)
+        throws Error;
+
+    /**
+     * Get the Registry value for REG_MULTI_SZ
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Registry key value
+     * @throws Error An error occurred
+     */
+    public static native String[] getValueA(long key, String name)
+        throws Error;
+
+    /**
+     * Get the Registry value for REG_BINARY
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to query
+     * @return Registry key value
+     * @throws Error An error occurred
+     */
+    public static native byte[] getValueB(long key, String name)
+        throws Error;
+
+
+    /**
+     * Set the Registry value for REG_DWORD
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to set
+     * @param val The the value to set
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int setValueI(long key, String name, int val);
+
+    /**
+     * Set the Registry value for REG_QWORD
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to set
+     * @param val The the value to set
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int setValueJ(long key, String name, long val);
+
+    /**
+     * Set the Registry value for REG_SZ
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to set
+     * @param val The the value to set
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int setValueS(long key, String name, String val);
+
+    /**
+     * Set the Registry value for REG_EXPAND_SZ
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to set
+     * @param val The the value to set
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int setValueE(long key, String name, String val);
+
+     /**
+     * Set the Registry value for REG_MULTI_SZ
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to set
+     * @param val The the value to set
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int setValueA(long key, String name, String[] val);
+
+     /**
+     * Set the Registry value for REG_BINARY
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to set
+     * @param val The the value to set
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int setValueB(long key, String name, byte[] val);
+
+    /**
+     * Enumerate the Registry subkeys
+     * @param key The Registry key descriptor to use.
+     * @return Array of all subkey names
+     * @throws Error An error occurred
+     */
+    public static native String[] enumKeys(long key)
+        throws Error;
+
+    /**
+     * Enumerate the Registry values
+     * @param key The Registry key descriptor to use.
+     * @return Array of all value names
+     * @throws Error An error occurred
+     */
+    public static native String[] enumValues(long key)
+        throws Error;
+
+     /**
+     * Delete the Registry value
+     * @param key The Registry key descriptor to use.
+     * @param name The name of the value to delete
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int deleteValue(long key, String name);
+
+     /**
+     * Delete the Registry subkey
+     * @param root Root key, one of HKEY_*
+     * @param name Subkey to delete
+     * @param onlyIfEmpty If true will not delete a key if
+     *                    it contains any subkeys or values
+     * @return If the function succeeds, the return value is 0
+     */
+    public static native int deleteKey(int root, String name,
+                                       boolean onlyIfEmpty);
+
+
+}
diff --git a/java/org/apache/tomcat/jni/SSL.java b/java/org/apache/tomcat/jni/SSL.java
new file mode 100644
index 0000000..6c3f2b4
--- /dev/null
+++ b/java/org/apache/tomcat/jni/SSL.java
@@ -0,0 +1,725 @@
+/*
+ *  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.tomcat.jni;
+
+/** SSL
+ *
+ * @author Mladen Turk
+ */
+public final class SSL {
+
+    /*
+     * Type definitions mostly from mod_ssl
+     */
+    public static final int UNSET            = -1;
+    /*
+     * Define the certificate algorithm types
+     */
+    public static final int SSL_ALGO_UNKNOWN = 0;
+    public static final int SSL_ALGO_RSA     = (1<<0);
+    public static final int SSL_ALGO_DSA     = (1<<1);
+    public static final int SSL_ALGO_ALL     = (SSL_ALGO_RSA|SSL_ALGO_DSA);
+
+    public static final int SSL_AIDX_RSA     = 0;
+    public static final int SSL_AIDX_DSA     = 1;
+    public static final int SSL_AIDX_ECC     = 3;
+    public static final int SSL_AIDX_MAX     = 4;
+    /*
+     * Define IDs for the temporary RSA keys and DH params
+     */
+
+    public static final int SSL_TMP_KEY_RSA_512  = 0;
+    public static final int SSL_TMP_KEY_RSA_1024 = 1;
+    public static final int SSL_TMP_KEY_RSA_2048 = 2;
+    public static final int SSL_TMP_KEY_RSA_4096 = 3;
+    public static final int SSL_TMP_KEY_DH_512   = 4;
+    public static final int SSL_TMP_KEY_DH_1024  = 5;
+    public static final int SSL_TMP_KEY_DH_2048  = 6;
+    public static final int SSL_TMP_KEY_DH_4096  = 7;
+    public static final int SSL_TMP_KEY_MAX      = 8;
+
+    /*
+     * Define the SSL options
+     */
+    public static final int SSL_OPT_NONE           = 0;
+    public static final int SSL_OPT_RELSET         = (1<<0);
+    public static final int SSL_OPT_STDENVVARS     = (1<<1);
+    public static final int SSL_OPT_EXPORTCERTDATA = (1<<3);
+    public static final int SSL_OPT_FAKEBASICAUTH  = (1<<4);
+    public static final int SSL_OPT_STRICTREQUIRE  = (1<<5);
+    public static final int SSL_OPT_OPTRENEGOTIATE = (1<<6);
+    public static final int SSL_OPT_ALL            = (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE);
+
+    /*
+     * Define the SSL Protocol options
+     */
+    public static final int SSL_PROTOCOL_NONE  = 0;
+    public static final int SSL_PROTOCOL_SSLV2 = (1<<0);
+    public static final int SSL_PROTOCOL_SSLV3 = (1<<1);
+    public static final int SSL_PROTOCOL_TLSV1 = (1<<2);
+    public static final int SSL_PROTOCOL_TLSV1_1 = (1<<3);
+    public static final int SSL_PROTOCOL_TLSV1_2 = (1<<4);
+    public static final int SSL_PROTOCOL_TLSV1_3 = (1<<5);
+    public static final int SSL_PROTOCOL_ALL;
+
+    static {
+        if (SSL.version() >= 0x1010100f) {
+            SSL_PROTOCOL_ALL = (SSL_PROTOCOL_TLSV1 | SSL_PROTOCOL_TLSV1_1 | SSL_PROTOCOL_TLSV1_2 |
+                    SSL_PROTOCOL_TLSV1_3);
+        } else {
+            SSL_PROTOCOL_ALL = (SSL_PROTOCOL_TLSV1 | SSL_PROTOCOL_TLSV1_1 | SSL_PROTOCOL_TLSV1_2);
+        }
+    }
+
+
+    /*
+     * Define the SSL verify levels
+     */
+    public static final int SSL_CVERIFY_UNSET          = UNSET;
+    public static final int SSL_CVERIFY_NONE           = 0;
+    public static final int SSL_CVERIFY_OPTIONAL       = 1;
+    public static final int SSL_CVERIFY_REQUIRE        = 2;
+    public static final int SSL_CVERIFY_OPTIONAL_NO_CA = 3;
+
+    /* Use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options
+     * are 'ored' with SSL_VERIFY_PEER if they are desired
+     */
+    public static final int SSL_VERIFY_NONE                 = 0;
+    public static final int SSL_VERIFY_PEER                 = 1;
+    public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2;
+    public static final int SSL_VERIFY_CLIENT_ONCE          = 4;
+    public static final int SSL_VERIFY_PEER_STRICT          = (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
+
+    public static final int SSL_OP_MICROSOFT_SESS_ID_BUG            = 0x00000001;
+    public static final int SSL_OP_NETSCAPE_CHALLENGE_BUG           = 0x00000002;
+    public static final int SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 0x00000008;
+    public static final int SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG      = 0x00000010;
+    public static final int SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER       = 0x00000020;
+    public static final int SSL_OP_MSIE_SSLV2_RSA_PADDING           = 0x00000040;
+    public static final int SSL_OP_SSLEAY_080_CLIENT_DH_BUG         = 0x00000080;
+    public static final int SSL_OP_TLS_D5_BUG                       = 0x00000100;
+    public static final int SSL_OP_TLS_BLOCK_PADDING_BUG            = 0x00000200;
+
+    /* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
+     * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
+     * the workaround is not needed.  Unfortunately some broken SSL/TLS
+     * implementations cannot handle it at all, which is why we include
+     * it in SSL_OP_ALL. */
+    public static final int SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS      = 0x00000800;
+
+    /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
+     *             This used to be 0x000FFFFFL before 0.9.7. */
+    public static final int SSL_OP_ALL                              = 0x00000FFF;
+    /* As server, disallow session resumption on renegotiation */
+    public static final int SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00010000;
+    /* Don't use compression even if supported */
+    public static final int SSL_OP_NO_COMPRESSION                         = 0x00020000;
+    /* Permit unsafe legacy renegotiation */
+    public static final int SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION      = 0x00040000;
+    /* If set, always create a new key when using tmp_eddh parameters */
+    public static final int SSL_OP_SINGLE_ECDH_USE                  = 0x00080000;
+    /* If set, always create a new key when using tmp_dh parameters */
+    public static final int SSL_OP_SINGLE_DH_USE                    = 0x00100000;
+    /* Set to always use the tmp_rsa key when doing RSA operations,
+     * even when this violates protocol specs */
+    public static final int SSL_OP_EPHEMERAL_RSA                    = 0x00200000;
+    /* Set on servers to choose the cipher according to the server's
+     * preferences */
+    public static final int SSL_OP_CIPHER_SERVER_PREFERENCE         = 0x00400000;
+    /* If set, a server will allow a client to issue a SSLv3.0 version number
+     * as latest version supported in the premaster secret, even when TLSv1.0
+     * (version 3.1) was announced in the client hello. Normally this is
+     * forbidden to prevent version rollback attacks. */
+    public static final int SSL_OP_TLS_ROLLBACK_BUG                 = 0x00800000;
+
+    public static final int SSL_OP_NO_SSLv2                         = 0x01000000;
+    public static final int SSL_OP_NO_SSLv3                         = 0x02000000;
+    public static final int SSL_OP_NO_TLSv1                         = 0x04000000;
+    public static final int SSL_OP_NO_TLSv1_2                       = 0x08000000;
+    public static final int SSL_OP_NO_TLSv1_1                       = 0x10000000;
+
+    public static final int SSL_OP_NO_TICKET                        = 0x00004000;
+
+    // SSL_OP_PKCS1_CHECK_1 and SSL_OP_PKCS1_CHECK_2 flags are unsupported
+    // in the current version of OpenSSL library. See ssl.h changes in commit
+    // 7409d7ad517650db332ae528915a570e4e0ab88b (30 Apr 2011) of OpenSSL.
+    /**
+     * @deprecated Unsupported in the current version of OpenSSL
+     */
+    @Deprecated
+    public static final int SSL_OP_PKCS1_CHECK_1                    = 0x08000000;
+    /**
+     * @deprecated Unsupported in the current version of OpenSSL
+     */
+    @Deprecated
+    public static final int SSL_OP_PKCS1_CHECK_2                    = 0x10000000;
+    public static final int SSL_OP_NETSCAPE_CA_DN_BUG               = 0x20000000;
+    public static final int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG  = 0x40000000;
+
+    public static final int SSL_CRT_FORMAT_UNDEF    = 0;
+    public static final int SSL_CRT_FORMAT_ASN1     = 1;
+    public static final int SSL_CRT_FORMAT_TEXT     = 2;
+    public static final int SSL_CRT_FORMAT_PEM      = 3;
+    public static final int SSL_CRT_FORMAT_NETSCAPE = 4;
+    public static final int SSL_CRT_FORMAT_PKCS12   = 5;
+    public static final int SSL_CRT_FORMAT_SMIME    = 6;
+    public static final int SSL_CRT_FORMAT_ENGINE   = 7;
+
+    public static final int SSL_MODE_CLIENT         = 0;
+    public static final int SSL_MODE_SERVER         = 1;
+    public static final int SSL_MODE_COMBINED       = 2;
+
+    public static final int SSL_CONF_FLAG_CMDLINE       = 0x0001;
+    public static final int SSL_CONF_FLAG_FILE          = 0x0002;
+    public static final int SSL_CONF_FLAG_CLIENT        = 0x0004;
+    public static final int SSL_CONF_FLAG_SERVER        = 0x0008;
+    public static final int SSL_CONF_FLAG_SHOW_ERRORS   = 0x0010;
+    public static final int SSL_CONF_FLAG_CERTIFICATE   = 0x0020;
+
+    public static final int SSL_CONF_TYPE_UNKNOWN   = 0x0000;
+    public static final int SSL_CONF_TYPE_STRING    = 0x0001;
+    public static final int SSL_CONF_TYPE_FILE      = 0x0002;
+    public static final int SSL_CONF_TYPE_DIR       = 0x0003;
+
+    public static final int SSL_SHUTDOWN_TYPE_UNSET    = 0;
+    public static final int SSL_SHUTDOWN_TYPE_STANDARD = 1;
+    public static final int SSL_SHUTDOWN_TYPE_UNCLEAN  = 2;
+    public static final int SSL_SHUTDOWN_TYPE_ACCURATE = 3;
+
+    public static final int SSL_INFO_SESSION_ID                = 0x0001;
+    public static final int SSL_INFO_CIPHER                    = 0x0002;
+    public static final int SSL_INFO_CIPHER_USEKEYSIZE         = 0x0003;
+    public static final int SSL_INFO_CIPHER_ALGKEYSIZE         = 0x0004;
+    public static final int SSL_INFO_CIPHER_VERSION            = 0x0005;
+    public static final int SSL_INFO_CIPHER_DESCRIPTION        = 0x0006;
+    public static final int SSL_INFO_PROTOCOL                  = 0x0007;
+
+    /* To obtain the CountryName of the Client Certificate Issuer
+     * use the SSL_INFO_CLIENT_I_DN + SSL_INFO_DN_COUNTRYNAME
+     */
+    public static final int SSL_INFO_CLIENT_S_DN               = 0x0010;
+    public static final int SSL_INFO_CLIENT_I_DN               = 0x0020;
+    public static final int SSL_INFO_SERVER_S_DN               = 0x0040;
+    public static final int SSL_INFO_SERVER_I_DN               = 0x0080;
+
+    public static final int SSL_INFO_DN_COUNTRYNAME            = 0x0001;
+    public static final int SSL_INFO_DN_STATEORPROVINCENAME    = 0x0002;
+    public static final int SSL_INFO_DN_LOCALITYNAME           = 0x0003;
+    public static final int SSL_INFO_DN_ORGANIZATIONNAME       = 0x0004;
+    public static final int SSL_INFO_DN_ORGANIZATIONALUNITNAME = 0x0005;
+    public static final int SSL_INFO_DN_COMMONNAME             = 0x0006;
+    public static final int SSL_INFO_DN_TITLE                  = 0x0007;
+    public static final int SSL_INFO_DN_INITIALS               = 0x0008;
+    public static final int SSL_INFO_DN_GIVENNAME              = 0x0009;
+    public static final int SSL_INFO_DN_SURNAME                = 0x000A;
+    public static final int SSL_INFO_DN_DESCRIPTION            = 0x000B;
+    public static final int SSL_INFO_DN_UNIQUEIDENTIFIER       = 0x000C;
+    public static final int SSL_INFO_DN_EMAILADDRESS           = 0x000D;
+
+    public static final int SSL_INFO_CLIENT_M_VERSION          = 0x0101;
+    public static final int SSL_INFO_CLIENT_M_SERIAL           = 0x0102;
+    public static final int SSL_INFO_CLIENT_V_START            = 0x0103;
+    public static final int SSL_INFO_CLIENT_V_END              = 0x0104;
+    public static final int SSL_INFO_CLIENT_A_SIG              = 0x0105;
+    public static final int SSL_INFO_CLIENT_A_KEY              = 0x0106;
+    public static final int SSL_INFO_CLIENT_CERT               = 0x0107;
+    public static final int SSL_INFO_CLIENT_V_REMAIN           = 0x0108;
+
+    public static final int SSL_INFO_SERVER_M_VERSION          = 0x0201;
+    public static final int SSL_INFO_SERVER_M_SERIAL           = 0x0202;
+    public static final int SSL_INFO_SERVER_V_START            = 0x0203;
+    public static final int SSL_INFO_SERVER_V_END              = 0x0204;
+    public static final int SSL_INFO_SERVER_A_SIG              = 0x0205;
+    public static final int SSL_INFO_SERVER_A_KEY              = 0x0206;
+    public static final int SSL_INFO_SERVER_CERT               = 0x0207;
+    /* Return client certificate chain.
+     * Add certificate chain number to that flag (0 ... verify depth)
+     */
+    public static final int SSL_INFO_CLIENT_CERT_CHAIN         = 0x0400;
+
+    /* Only support OFF and SERVER for now */
+    public static final long SSL_SESS_CACHE_OFF = 0x0000;
+    public static final long SSL_SESS_CACHE_SERVER = 0x0002;
+
+    public static final int SSL_SELECTOR_FAILURE_NO_ADVERTISE = 0;
+    public static final int SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL = 1;
+
+    /* Return OpenSSL version number (compile time version, if version < 1.1.0) */
+    public static native int version();
+
+    /* Return OpenSSL version string (run time version) */
+    public static native String versionString();
+
+    /**
+     * Initialize OpenSSL support.
+     * This function needs to be called once for the
+     * lifetime of JVM. Library.init() has to be called before.
+     * @param engine Support for external a Crypto Device ("engine"),
+     *                usually
+     * a hardware accelerator card for crypto operations.
+     * @return APR status code
+     */
+    public static native int initialize(String engine);
+
+    /**
+     * Get the status of FIPS Mode.
+     *
+     * @return FIPS_mode return code. It is <code>0</code> if OpenSSL is not
+     *  in FIPS mode, <code>1</code> if OpenSSL is in FIPS Mode.
+     * @throws Exception If tcnative was not compiled with FIPS Mode available.
+     * @see <a href="http://wiki.openssl.org/index.php/FIPS_mode%28%29">OpenSSL method FIPS_mode()</a>
+     */
+    public static native int fipsModeGet() throws Exception;
+
+    /**
+     * Enable/Disable FIPS Mode.
+     *
+     * @param mode 1 - enable, 0 - disable
+     *
+     * @return FIPS_mode_set return code
+     * @throws Exception If tcnative was not compiled with FIPS Mode available,
+     *  or if {@code FIPS_mode_set()} call returned an error value.
+     * @see <a href="http://wiki.openssl.org/index.php/FIPS_mode_set%28%29">OpenSSL method FIPS_mode_set()</a>
+     */
+    public static native int fipsModeSet(int mode) throws Exception;
+
+    /**
+     * Add content of the file to the PRNG
+     * @param filename Filename containing random data.
+     *        If null the default file will be tested.
+     *        The seed file is $RANDFILE if that environment variable is
+     *        set, $HOME/.rnd otherwise.
+     *        In case both files are unavailable builtin
+     *        random seed generator is used.
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean randLoad(String filename);
+
+    /**
+     * Writes a number of random bytes (currently 1024) to
+     * file <code>filename</code> which can be used to initialize the PRNG
+     * by calling randLoad in a later session.
+     * @param filename Filename to save the data
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean randSave(String filename);
+
+    /**
+     * Creates random data to filename
+     * @param filename Filename to save the data
+     * @param len The length of random sequence in bytes
+     * @param base64 Output the data in Base64 encoded format
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean randMake(String filename, int len,
+                                          boolean base64);
+
+    /**
+     * Sets global random filename.
+     * @param filename Filename to use.
+     *        If set it will be used for SSL initialization
+     *        and all contexts where explicitly not set.
+     */
+    public static native void randSet(String filename);
+
+    /**
+     * Initialize new BIO
+     * @param pool The pool to use.
+     * @param callback BIOCallback to use
+     * @return New BIO handle
+     * @throws Exception An error occurred
+     */
+     public static native long newBIO(long pool, BIOCallback callback)
+            throws Exception;
+
+    /**
+     * Close BIO and dereference callback object
+     * @param bio BIO to close and destroy.
+     * @return APR Status code
+     */
+     public static native int closeBIO(long bio);
+
+    /**
+     * Set global Password callback for obtaining passwords.
+     * @param callback PasswordCallback implementation to use.
+     */
+     public static native void setPasswordCallback(PasswordCallback callback);
+
+    /**
+     * Set global Password for decrypting certificates and keys.
+     * @param password Password to use.
+     */
+     public static native void setPassword(String password);
+
+    /**
+     * Return last SSL error string
+     * @return the error string
+     */
+    public static native String getLastError();
+
+    /**
+     * Return true if all the requested SSL_OP_* are supported by OpenSSL.
+     *
+     * <i>Note that for versions of tcnative &lt; 1.1.25, this method will
+     * return <code>true</code> if and only if <code>op</code>=
+     * {@link #SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION} and tcnative
+     * supports that flag.</i>
+     *
+     * @param op Bitwise-OR of all SSL_OP_* to test.
+     *
+     * @return true if all SSL_OP_* are supported by OpenSSL library.
+     */
+    public static native boolean hasOp(int op);
+
+    /**
+     * Return the handshake completed count.
+     * @param ssl SSL pointer
+     * @return the count
+     */
+    public static native int getHandshakeCount(long ssl);
+
+    /*
+     * Begin Twitter API additions
+     */
+
+    public static final int SSL_SENT_SHUTDOWN = 1;
+    public static final int SSL_RECEIVED_SHUTDOWN = 2;
+
+    public static final int SSL_ERROR_NONE             = 0;
+    public static final int SSL_ERROR_SSL              = 1;
+    public static final int SSL_ERROR_WANT_READ        = 2;
+    public static final int SSL_ERROR_WANT_WRITE       = 3;
+    public static final int SSL_ERROR_WANT_X509_LOOKUP = 4;
+    public static final int SSL_ERROR_SYSCALL          = 5; /* look at error stack/return value/errno */
+    public static final int SSL_ERROR_ZERO_RETURN      = 6;
+    public static final int SSL_ERROR_WANT_CONNECT     = 7;
+    public static final int SSL_ERROR_WANT_ACCEPT      = 8;
+
+    /**
+     * SSL_new
+     * @param ctx Server or Client context to use.
+     * @param server if true configure SSL instance to use accept handshake routines
+     *               if false configure SSL instance to use connect handshake routines
+     * @return pointer to SSL instance (SSL *)
+     */
+    public static native long newSSL(long ctx, boolean server);
+
+    /**
+     * SSL_set_bio
+     * @param ssl SSL pointer (SSL *)
+     * @param rbio read BIO pointer (BIO *)
+     * @param wbio write BIO pointer (BIO *)
+     */
+    public static native void setBIO(long ssl, long rbio, long wbio);
+
+    /**
+     * SSL_get_error
+     * @param ssl SSL pointer (SSL *)
+     * @param ret TLS/SSL I/O return value
+     * @return the error status
+     */
+    public static native int getError(long ssl, int ret);
+
+    /**
+     * BIO_ctrl_pending.
+     * @param bio BIO pointer (BIO *)
+     * @return the pending bytes count
+     */
+    public static native int pendingWrittenBytesInBIO(long bio);
+
+    /**
+     * SSL_pending.
+     * @param ssl SSL pointer (SSL *)
+     * @return the pending bytes count
+     */
+    public static native int pendingReadableBytesInSSL(long ssl);
+
+    /**
+     * BIO_write.
+     * @param bio BIO pointer
+     * @param wbuf Buffer pointer
+     * @param wlen Write length
+     * @return the bytes count written
+     */
+    public static native int writeToBIO(long bio, long wbuf, int wlen);
+
+    /**
+     * BIO_read.
+     * @param bio BIO pointer
+     * @param rbuf Buffer pointer
+     * @param rlen Read length
+     * @return the bytes count read
+     */
+    public static native int readFromBIO(long bio, long rbuf, int rlen);
+
+    /**
+     * SSL_write.
+     * @param ssl the SSL instance (SSL *)
+     * @param wbuf Buffer pointer
+     * @param wlen Write length
+     * @return the bytes count written
+     */
+    public static native int writeToSSL(long ssl, long wbuf, int wlen);
+
+    /**
+     * SSL_read
+     * @param ssl the SSL instance (SSL *)
+     * @param rbuf Buffer pointer
+     * @param rlen Read length
+     * @return the bytes count read
+     */
+    public static native int readFromSSL(long ssl, long rbuf, int rlen);
+
+    /**
+     * SSL_get_shutdown
+     * @param ssl the SSL instance (SSL *)
+     * @return the operation status
+     */
+    public static native int getShutdown(long ssl);
+
+    /**
+     * SSL_set_shutdown
+     * @param ssl the SSL instance (SSL *)
+     * @param mode Shutdown mode
+     */
+    public static native void setShutdown(long ssl, int mode);
+
+    /**
+     * SSL_free
+     * @param ssl the SSL instance (SSL *)
+     */
+    public static native void freeSSL(long ssl);
+
+    /**
+     * Wire up internal and network BIOs for the given SSL instance.
+     *
+     * <b>Warning: you must explicitly free this resource by calling freeBIO</b>
+     *
+     * While the SSL's internal/application data BIO will be freed when freeSSL is called on
+     * the provided SSL instance, you must call freeBIO on the returned network BIO.
+     *
+     * @param ssl the SSL instance (SSL *)
+     * @return pointer to the Network BIO (BIO *)
+     */
+    public static native long makeNetworkBIO(long ssl);
+
+    /**
+     * BIO_free
+     * @param bio BIO pointer
+     */
+    public static native void freeBIO(long bio);
+
+    /**
+     * SSL_shutdown
+     * @param ssl the SSL instance (SSL *)
+     * @return the operation status
+     */
+    public static native int shutdownSSL(long ssl);
+
+    /**
+     * Get the error number representing the last error OpenSSL encountered on
+     * this thread.
+     * @return the last error number
+     */
+    public static native int getLastErrorNumber();
+
+    /**
+     * SSL_get_cipher.
+     * @param ssl the SSL instance (SSL *)
+     * @return the cipher name
+     */
+    public static native String getCipherForSSL(long ssl);
+
+    /**
+     * SSL_get_version
+     * @param ssl the SSL instance (SSL *)
+     * @return the SSL version in use
+     */
+    public static native String getVersion(long ssl);
+
+    /**
+     * SSL_do_handshake
+     * @param ssl the SSL instance (SSL *)
+     * @return the handshake status
+     */
+    public static native int doHandshake(long ssl);
+
+    /**
+     * SSL_renegotiate
+     * @param ssl the SSL instance (SSL *)
+     * @return the operation status
+     */
+    public static native int renegotiate(long ssl);
+
+    /**
+     * SSL_renegotiate_pending
+     * @param ssl the SSL instance (SSL *)
+     * @return the operation status
+     */
+    public static native int renegotiatePending(long ssl);
+
+    /**
+     * SSL_verify_client_post_handshake
+     * @param ssl the SSL instance (SSL *)
+     * @return the operation status
+     */
+    public static native int verifyClientPostHandshake(long ssl);
+
+    /**
+     * Is post handshake authentication in progress on this connection?
+     * @param ssl the SSL instance (SSL *)
+     * @return the operation status
+     */
+    public static native int getPostHandshakeAuthInProgress(long ssl);
+
+    /**
+     * SSL_in_init.
+     * @param ssl the SSL instance (SSL *)
+     * @return the status
+     */
+    public static native int isInInit(long ssl);
+
+    /**
+     * SSL_get0_next_proto_negotiated
+     * @param ssl the SSL instance (SSL *)
+     * @return the NPN protocol negotiated
+     */
+    public static native String getNextProtoNegotiated(long ssl);
+
+    /*
+     * End Twitter API Additions
+     */
+
+    /**
+     * SSL_get0_alpn_selected
+     * @param ssl the SSL instance (SSL *)
+     * @return the ALPN protocol negotiated
+     */
+    public static native String getAlpnSelected(long ssl);
+
+    /**
+     * Get the peer certificate chain or {@code null} if non was send.
+     * @param ssl the SSL instance (SSL *)
+     * @return the certificate chain bytes
+     */
+    public static native byte[][] getPeerCertChain(long ssl);
+
+    /**
+     * Get the peer certificate or {@code null} if non was send.
+     * @param ssl the SSL instance (SSL *)
+     * @return the certificate bytes
+     */
+    public static native byte[] getPeerCertificate(long ssl);
+
+    /**
+     * Get the error number representing for the given {@code errorNumber}.
+     * @param errorNumber The error code
+     * @return an error message
+     */
+    public static native String getErrorString(long errorNumber);
+
+    /**
+     * SSL_get_time
+     * @param ssl the SSL instance (SSL *)
+     * @return returns the time at which the session ssl was established. The time is given in seconds since the Epoch
+     */
+    public static native long getTime(long ssl);
+
+    /**
+     * Set Type of Client Certificate verification and Maximum depth of CA Certificates
+     * in Client Certificate verification.
+     * <br>
+     * This directive sets the Certificate verification level for the Client
+     * Authentication. Notice that this directive can be used both in per-server
+     * and per-directory context. In per-server context it applies to the client
+     * authentication process used in the standard SSL handshake when a connection
+     * is established. In per-directory context it forces a SSL renegotiation with
+     * the reconfigured client verification level after the HTTP request was read
+     * but before the HTTP response is sent.
+     * <br>
+     * The following levels are available for level:
+     * <pre>
+     * SSL_CVERIFY_NONE           - No client Certificate is required at all
+     * SSL_CVERIFY_OPTIONAL       - The client may present a valid Certificate
+     * SSL_CVERIFY_REQUIRE        - The client has to present a valid Certificate
+     * SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
+     *                              but it need not to be (successfully) verifiable
+     * </pre>
+     * <br>
+     * The depth actually is the maximum number of intermediate certificate issuers,
+     * i.e. the number of CA certificates which are max allowed to be followed while
+     * verifying the client certificate. A depth of 0 means that self-signed client
+     * certificates are accepted only, the default depth of 1 means the client
+     * certificate can be self-signed or has to be signed by a CA which is directly
+     * known to the server (i.e. the CA's certificate is under
+     * {@code setCACertificatePath}, etc.
+     *
+     * @param ssl the SSL instance (SSL *)
+     * @param level Type of Client Certificate verification.
+     * @param depth Maximum depth of CA Certificates in Client Certificate
+     *              verification.
+     */
+    public static native void setVerify(long ssl, int level, int depth);
+
+    /**
+     * Set OpenSSL Option.
+     * @param ssl the SSL instance (SSL *)
+     * @param options  See SSL.SSL_OP_* for option flags.
+     */
+    public static native void setOptions(long ssl, int options);
+
+    /**
+     * Get OpenSSL Option.
+     * @param ssl the SSL instance (SSL *)
+     * @return options  See SSL.SSL_OP_* for option flags.
+     */
+    public static native int getOptions(long ssl);
+
+    /**
+     * Returns all cipher suites that are enabled for negotiation in an SSL handshake.
+     * @param ssl the SSL instance (SSL *)
+     * @return ciphers
+     */
+    public static native String[] getCiphers(long ssl);
+
+    /**
+     * Returns the cipher suites available for negotiation in SSL handshake.
+     * <br>
+     * This complex directive uses a colon-separated cipher-spec string consisting
+     * of OpenSSL cipher specifications to configure the Cipher Suite the client
+     * is permitted to negotiate in the SSL handshake phase. Notice that this
+     * directive can be used both in per-server and per-directory context.
+     * In per-server context it applies to the standard SSL handshake when a
+     * connection is established. In per-directory context it forces a SSL
+     * renegotiation with the reconfigured Cipher Suite after the HTTP request
+     * was read but before the HTTP response is sent.
+     * @param ssl the SSL instance (SSL *)
+     * @param ciphers an SSL cipher specification
+     * @return <code>true</code> if the operation was successful
+     * @throws Exception An error occurred
+     */
+    public static native boolean setCipherSuites(long ssl, String ciphers)
+            throws Exception;
+
+    /**
+     * Returns the ID of the session as byte array representation.
+     *
+     * @param ssl the SSL instance (SSL *)
+     * @return the session as byte array representation obtained via SSL_SESSION_get_id.
+     */
+    public static native byte[] getSessionId(long ssl);
+}
diff --git a/java/org/apache/tomcat/jni/SSLConf.java b/java/org/apache/tomcat/jni/SSLConf.java
new file mode 100644
index 0000000..272c0a1
--- /dev/null
+++ b/java/org/apache/tomcat/jni/SSLConf.java
@@ -0,0 +1,113 @@
+/*
+ *  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.tomcat.jni;
+
+/** SSL Conf
+ */
+public final class SSLConf {
+
+    /**
+     * Create a new SSL_CONF context.
+     *
+     * @param pool The pool to use.
+     * @param flags The SSL_CONF flags to use. It can be any combination of
+     * the following:
+     * <PRE>
+     * {@link SSL#SSL_CONF_FLAG_CMDLINE}
+     * {@link SSL#SSL_CONF_FLAG_FILE}
+     * {@link SSL#SSL_CONF_FLAG_CLIENT}
+     * {@link SSL#SSL_CONF_FLAG_SERVER}
+     * {@link SSL#SSL_CONF_FLAG_SHOW_ERRORS}
+     * {@link SSL#SSL_CONF_FLAG_CERTIFICATE}
+     * </PRE>
+     *
+     * @return The Java representation of a pointer to the newly created
+     *         SSL_CONF Context
+     *
+     * @throws Exception If the SSL_CONF context could not be created
+     *
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_CTX_new.html">OpenSSL SSL_CONF_CTX_new</a>
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_CTX_set_flags.html">OpenSSL SSL_CONF_CTX_set_flags</a>
+     */
+    public static native long make(long pool, int flags) throws Exception;
+
+    /**
+     * Free the resources used by the context
+     *
+     * @param cctx SSL_CONF context to free.
+     *
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_CTX_new.html">OpenSSL SSL_CONF_CTX_free</a>
+     */
+    public static native void free(long cctx);
+
+    /**
+     * Check a command with an SSL_CONF context.
+     *
+     * @param cctx SSL_CONF context to use.
+     * @param name command name.
+     * @param value command value.
+     *
+     * @return The result of the check based on the {@code SSL_CONF_cmd_value_type}
+     * call. Unknown types will result in an exception, as well as
+     * file and directory types with invalid file or directory names.
+     *
+     * @throws Exception If the check fails.
+     *
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_cmd.html">OpenSSL SSL_CONF_cmd_value_type</a>
+     */
+    public static native int check(long cctx, String name, String value) throws Exception;
+
+    /**
+     * Assign an SSL context to a SSL_CONF context.
+     * All following calls to {@link #apply(long, String, String)} will be
+     * applied to this SSL context.
+     *
+     * @param cctx SSL_CONF context to use.
+     * @param ctx SSL context to assign to the given SSL_CONF context.
+     *
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_CTX_set_ssl_ctx.html">OpenSSL SSL_CONF_CTX_set_ssl_ctx</a>
+     */
+    public static native void assign(long cctx, long ctx);
+
+    /**
+     * Apply a command to an SSL_CONF context.
+     *
+     * @param cctx SSL_CONF context to use.
+     * @param name command name.
+     * @param value command value.
+     *
+     * @return The result of the native {@code SSL_CONF_cmd} call
+     *
+     * @throws Exception If the SSL_CONF context is {@code 0}
+     *
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_cmd.html">OpenSSL SSL_CONF_cmd</a>
+     */
+    public static native int apply(long cctx, String name, String value) throws Exception;
+
+    /**
+     * Finish commands for an SSL_CONF context.
+     *
+     * @param cctx SSL_CONF context to use.
+     *
+     * @return The result of the native {@code SSL_CONF_CTX_finish} call
+     *
+     * @see <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CONF_CTX_set_flags.html">OpenSSL SSL_CONF_CTX_finish</a>
+     */
+    public static native int finish(long cctx);
+
+}
diff --git a/java/org/apache/tomcat/jni/SSLContext.java b/java/org/apache/tomcat/jni/SSLContext.java
new file mode 100644
index 0000000..45fcc48
--- /dev/null
+++ b/java/org/apache/tomcat/jni/SSLContext.java
@@ -0,0 +1,584 @@
+/*
+ *  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.tomcat.jni;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/** SSL Context
+ *
+ * @author Mladen Turk
+ */
+public final class SSLContext {
+
+    public static final byte[] DEFAULT_SESSION_ID_CONTEXT =
+            new byte[] { 'd', 'e', 'f', 'a', 'u', 'l', 't' };
+
+    /**
+     * Create a new SSL context.
+     *
+     * @param pool The pool to use.
+     * @param protocol The SSL protocol to use. It can be any combination of
+     * the following:
+     * <PRE>
+     * {@link SSL#SSL_PROTOCOL_SSLV2}
+     * {@link SSL#SSL_PROTOCOL_SSLV3}
+     * {@link SSL#SSL_PROTOCOL_TLSV1}
+     * {@link SSL#SSL_PROTOCOL_TLSV1_1}
+     * {@link SSL#SSL_PROTOCOL_TLSV1_2}
+     * {@link SSL#SSL_PROTOCOL_TLSV1_3}
+     * {@link SSL#SSL_PROTOCOL_ALL} ( == all TLS versions, no SSL)
+     * </PRE>
+     * @param mode SSL mode to use
+     * <PRE>
+     * SSL_MODE_CLIENT
+     * SSL_MODE_SERVER
+     * SSL_MODE_COMBINED
+     * </PRE>
+     *
+     * @return The Java representation of a pointer to the newly created SSL
+     *         Context
+     *
+     * @throws Exception If the SSL Context could not be created
+     */
+    public static native long make(long pool, int protocol, int mode) throws Exception;
+
+    /**
+     * Free the resources used by the Context
+     * @param ctx Server or Client context to free.
+     * @return APR Status code.
+     */
+    public static native int free(long ctx);
+
+    /**
+     * Set Session context id. Usually host:port combination.
+     * @param ctx Context to use.
+     * @param id  String that uniquely identifies this context.
+     */
+    public static native void setContextId(long ctx, String id);
+
+    /**
+     * Associate BIOCallback for input or output data capture.
+     * <br>
+     * First word in the output string will contain error
+     * level in the form:
+     * <PRE>
+     * [ERROR]  -- Critical error messages
+     * [WARN]   -- Warning messages
+     * [INFO]   -- Informational messages
+     * [DEBUG]  -- Debugging messaged
+     * </PRE>
+     * Callback can use that word to determine application logging level
+     * by intercepting <b>write</b> call.
+     * If the <b>bio</b> is set to 0 no error messages will be displayed.
+     * Default is to use the stderr output stream.
+     * @param ctx Server or Client context to use.
+     * @param bio BIO handle to use, created with SSL.newBIO
+     * @param dir BIO direction (1 for input 0 for output).
+     */
+    public static native void setBIO(long ctx, long bio, int dir);
+
+    /**
+     * Set OpenSSL Option.
+     * @param ctx Server or Client context to use.
+     * @param options  See SSL.SSL_OP_* for option flags.
+     */
+    public static native void setOptions(long ctx, int options);
+
+    /**
+     * Get OpenSSL Option.
+     * @param ctx Server or Client context to use.
+     * @return options  See SSL.SSL_OP_* for option flags.
+     */
+    public static native int getOptions(long ctx);
+
+    /**
+     * Clears OpenSSL Options.
+     * @param ctx Server or Client context to use.
+     * @param options  See SSL.SSL_OP_* for option flags.
+     */
+    public static native void clearOptions(long ctx, int options);
+
+    /**
+     * Returns all cipher suites that are enabled for negotiation in an SSL handshake.
+     * @param ctx Server or Client context to use.
+     * @return ciphers
+     */
+    public static native String[] getCiphers(long ctx);
+
+    /**
+     * Sets the "quiet shutdown" flag for <b>ctx</b> to be
+     * <b>mode</b>. SSL objects created from <b>ctx</b> inherit the
+     * <b>mode</b> valid at the time and may be 0 or 1.
+     * <br>
+     * Normally when a SSL connection is finished, the parties must send out
+     * "close notify" alert messages using L&lt;SSL_shutdown(3)|SSL_shutdown(3)&gt;
+     * for a clean shutdown.
+     * <br>
+     * When setting the "quiet shutdown" flag to 1, <b>SSL.shutdown</b>
+     * will set the internal flags to SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN.
+     * (<b>SSL_shutdown</b> then behaves like called with
+     * SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN.)
+     * The session is thus considered to be shutdown, but no "close notify" alert
+     * is sent to the peer. This behaviour violates the TLS standard.
+     * The default is normal shutdown behaviour as described by the TLS standard.
+     * @param ctx Server or Client context to use.
+     * @param mode True to set the quiet shutdown.
+     */
+    public static native void setQuietShutdown(long ctx, boolean mode);
+
+    /**
+     * Cipher Suite available for negotiation in SSL handshake.
+     * <br>
+     * This complex directive uses a colon-separated cipher-spec string consisting
+     * of OpenSSL cipher specifications to configure the Cipher Suite the client
+     * is permitted to negotiate in the SSL handshake phase. Notice that this
+     * directive can be used both in per-server and per-directory context.
+     * In per-server context it applies to the standard SSL handshake when a
+     * connection is established. In per-directory context it forces a SSL
+     * renegotiation with the reconfigured Cipher Suite after the HTTP request
+     * was read but before the HTTP response is sent.
+     * @param ctx Server or Client context to use.
+     * @param ciphers An OpenSSL cipher specification.
+     * @return <code>true</code> if the operation was successful
+     * @throws Exception An error occurred
+     */
+    public static native boolean setCipherSuite(long ctx, String ciphers)
+        throws Exception;
+
+    /**
+     * Set File of concatenated PEM-encoded CA CRLs or
+     * directory of PEM-encoded CA Certificates for Client Auth
+     * <br>
+     * This directive sets the all-in-one file where you can assemble the
+     * Certificate Revocation Lists (CRL) of Certification Authorities (CA)
+     * whose clients you deal with. These are used for Client Authentication.
+     * Such a file is simply the concatenation of the various PEM-encoded CRL
+     * files, in order of preference.
+     * <br>
+     * The files in this directory have to be PEM-encoded and are accessed through
+     * hash filenames. So usually you can't just place the Certificate files there:
+     * you also have to create symbolic links named hash-value.N. And you should
+     * always make sure this directory contains the appropriate symbolic links.
+     * Use the Makefile which comes with mod_ssl to accomplish this task.
+     * @param ctx Server or Client context to use.
+     * @param file File of concatenated PEM-encoded CA CRLs for Client Auth.
+     * @param path Directory of PEM-encoded CA Certificates for Client Auth.
+     * @return <code>true</code> if the operation was successful
+     * @throws Exception An error occurred
+     */
+    public static native boolean setCARevocation(long ctx, String file,
+                                                 String path)
+        throws Exception;
+
+    /**
+     * Set File of PEM-encoded Server CA Certificates
+     * <br>
+     * This directive sets the optional all-in-one file where you can assemble the
+     * certificates of Certification Authorities (CA) which form the certificate
+     * chain of the server certificate. This starts with the issuing CA certificate
+     * of of the server certificate and can range up to the root CA certificate.
+     * Such a file is simply the concatenation of the various PEM-encoded CA
+     * Certificate files, usually in certificate chain order.
+     * <br>
+     * But be careful: Providing the certificate chain works only if you are using
+     * a single (either RSA or DSA) based server certificate. If you are using a
+     * coupled RSA+DSA certificate pair, this will work only if actually both
+     * certificates use the same certificate chain. Else the browsers will be
+     * confused in this situation.
+     * @param ctx Server or Client context to use.
+     * @param file File of PEM-encoded Server CA Certificates.
+     * @param skipfirst Skip first certificate if chain file is inside
+     *                  certificate file.
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean setCertificateChainFile(long ctx, String file,
+                                                         boolean skipfirst);
+
+    /**
+     * Set Certificate
+     * <br>
+     * Point setCertificateFile at a PEM encoded certificate.  If
+     * the certificate is encrypted, then you will be prompted for a
+     * pass phrase.  Note that a kill -HUP will prompt again. A test
+     * certificate can be generated with `make certificate' under
+     * built time. Keep in mind that if you've both a RSA and a DSA
+     * certificate you can configure both in parallel (to also allow
+     * the use of DSA ciphers, etc.)
+     * <br>
+     * If the key is not combined with the certificate, use key param
+     * to point at the key file.  Keep in mind that if
+     * you've both a RSA and a DSA private key you can configure
+     * both in parallel (to also allow the use of DSA ciphers, etc.)
+     * @param ctx Server or Client context to use.
+     * @param cert Certificate file.
+     * @param key Private Key file to use if not in cert.
+     * @param password Certificate password. If null and certificate
+     *                 is encrypted, password prompt will be displayed.
+     * @param idx Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
+     * @return <code>true</code> if the operation was successful
+     * @throws Exception An error occurred
+     */
+    public static native boolean setCertificate(long ctx, String cert,
+                                                String key, String password,
+                                                int idx)
+        throws Exception;
+
+    /**
+     * Set the size of the internal session cache.
+     * http://www.openssl.org/docs/ssl/SSL_CTX_sess_set_cache_size.html
+     * @param ctx Server or Client context to use.
+     * @param size The cache size
+     * @return the value set
+     */
+    public static native long setSessionCacheSize(long ctx, long size);
+
+    /**
+     * Get the size of the internal session cache.
+     * http://www.openssl.org/docs/ssl/SSL_CTX_sess_get_cache_size.html
+     * @param ctx Server or Client context to use.
+     * @return the size
+     */
+    public static native long getSessionCacheSize(long ctx);
+
+    /**
+     * Set the timeout for the internal session cache in seconds.
+     * http://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html
+     * @param ctx Server or Client context to use.
+     * @param timeoutSeconds Timeout value
+     * @return the value set
+     */
+    public static native long setSessionCacheTimeout(long ctx, long timeoutSeconds);
+
+    /**
+     * Get the timeout for the internal session cache in seconds.
+     * http://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html
+     * @param ctx Server or Client context to use.
+     * @return the timeout
+     */
+    public static native long getSessionCacheTimeout(long ctx);
+
+    /**
+     * Set the mode of the internal session cache and return the previous used mode.
+     * @param ctx Server or Client context to use.
+     * @param mode The mode to set
+     * @return the value set
+     */
+    public static native long setSessionCacheMode(long ctx, long mode);
+
+    /**
+     * Get the mode of the current used internal session cache.
+     * @param ctx Server or Client context to use.
+     * @return the value set
+     */
+    public static native long getSessionCacheMode(long ctx);
+
+    /*
+     * Session resumption statistics methods.
+     * http://www.openssl.org/docs/ssl/SSL_CTX_sess_number.html
+     */
+    public static native long sessionAccept(long ctx);
+    public static native long sessionAcceptGood(long ctx);
+    public static native long sessionAcceptRenegotiate(long ctx);
+    public static native long sessionCacheFull(long ctx);
+    public static native long sessionCbHits(long ctx);
+    public static native long sessionConnect(long ctx);
+    public static native long sessionConnectGood(long ctx);
+    public static native long sessionConnectRenegotiate(long ctx);
+    public static native long sessionHits(long ctx);
+    public static native long sessionMisses(long ctx);
+    public static native long sessionNumber(long ctx);
+    public static native long sessionTimeouts(long ctx);
+
+    /**
+     * Set TLS session keys. This allows us to share keys across TFEs.
+     * @param ctx Server or Client context to use.
+     * @param keys Some session keys
+     */
+    public static native void setSessionTicketKeys(long ctx, byte[] keys);
+
+    /**
+     * Set File and Directory of concatenated PEM-encoded CA Certificates
+     * for Client Auth
+     * <br>
+     * This directive sets the all-in-one file where you can assemble the
+     * Certificates of Certification Authorities (CA) whose clients you deal with.
+     * These are used for Client Authentication. Such a file is simply the
+     * concatenation of the various PEM-encoded Certificate files, in order of
+     * preference. This can be used alternatively and/or additionally to
+     * path.
+     * <br>
+     * The files in this directory have to be PEM-encoded and are accessed through
+     * hash filenames. So usually you can't just place the Certificate files there:
+     * you also have to create symbolic links named hash-value.N. And you should
+     * always make sure this directory contains the appropriate symbolic links.
+     * Use the Makefile which comes with mod_ssl to accomplish this task.
+     * @param ctx Server or Client context to use.
+     * @param file File of concatenated PEM-encoded CA Certificates for
+     *             Client Auth.
+     * @param path Directory of PEM-encoded CA Certificates for Client Auth.
+     * @return <code>true</code> if the operation was successful
+     * @throws Exception An error occurred
+     */
+    public static native boolean setCACertificate(long ctx, String file,
+                                                  String path)
+        throws Exception;
+
+    /**
+     * Set file for randomness
+     * @param ctx Server or Client context to use.
+     * @param file random file.
+     */
+    public static native void setRandom(long ctx, String file);
+
+    /**
+     * Set SSL connection shutdown type
+     * <br>
+     * The following levels are available for level:
+     * <PRE>
+     * SSL_SHUTDOWN_TYPE_STANDARD
+     * SSL_SHUTDOWN_TYPE_UNCLEAN
+     * SSL_SHUTDOWN_TYPE_ACCURATE
+     * </PRE>
+     * @param ctx Server or Client context to use.
+     * @param type Shutdown type to use.
+     */
+    public static native void setShutdownType(long ctx, int type);
+
+    /**
+     * Set Type of Client Certificate verification and Maximum depth of CA Certificates
+     * in Client Certificate verification.
+     * <br>
+     * This directive sets the Certificate verification level for the Client
+     * Authentication. Notice that this directive can be used both in per-server
+     * and per-directory context. In per-server context it applies to the client
+     * authentication process used in the standard SSL handshake when a connection
+     * is established. In per-directory context it forces a SSL renegotiation with
+     * the reconfigured client verification level after the HTTP request was read
+     * but before the HTTP response is sent.
+     * <br>
+     * The following levels are available for level:
+     * <PRE>
+     * SSL_CVERIFY_NONE           - No client Certificate is required at all
+     * SSL_CVERIFY_OPTIONAL       - The client may present a valid Certificate
+     * SSL_CVERIFY_REQUIRE        - The client has to present a valid Certificate
+     * SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
+     *                              but it need not to be (successfully) verifiable
+     * </PRE>
+     * <br>
+     * The depth actually is the maximum number of intermediate certificate issuers,
+     * i.e. the number of CA certificates which are max allowed to be followed while
+     * verifying the client certificate. A depth of 0 means that self-signed client
+     * certificates are accepted only, the default depth of 1 means the client
+     * certificate can be self-signed or has to be signed by a CA which is directly
+     * known to the server (i.e. the CA's certificate is under
+     * <code>setCACertificatePath</code>), etc.
+     * @param ctx Server or Client context to use.
+     * @param level Type of Client Certificate verification.
+     * @param depth Maximum depth of CA Certificates in Client Certificate
+     *              verification.
+     */
+    public static native void setVerify(long ctx, int level, int depth);
+
+    public static native int setALPN(long ctx, byte[] proto, int len);
+
+    /**
+     * When tc-native encounters a SNI extension in the TLS handshake it will
+     * call this method to determine which OpenSSL SSLContext to use for the
+     * connection.
+     *
+     * @param currentCtx   The OpenSSL SSLContext that the handshake started to
+     *                     use. This will be the default OpenSSL SSLContext for
+     *                     the endpoint associated with the socket.
+     * @param sniHostName  The host name requested by the client
+     *
+     * @return The Java representation of the pointer to the OpenSSL SSLContext
+     *         to use for the given host or zero if no SSLContext could be
+     *         identified
+     */
+    public static long sniCallBack(long currentCtx, String sniHostName) {
+        SNICallBack sniCallBack = sniCallBacks.get(Long.valueOf(currentCtx));
+        if (sniCallBack == null) {
+            return 0;
+        }
+        return sniCallBack.getSslContext(sniHostName);
+    }
+
+    /**
+     * A map of default SSL Contexts to SNICallBack instances (in Tomcat these
+     * are instances of AprEndpoint) that will be used to determine the SSL
+     * Context to use bases on the SNI host name. It is structured this way
+     * since a Tomcat instance may have several TLS enabled endpoints that each
+     * have different SSL Context mappings for the same host name.
+     */
+    private static final Map<Long,SNICallBack> sniCallBacks = new ConcurrentHashMap<>();
+
+    /**
+     * Register an OpenSSL SSLContext that will be used to initiate TLS
+     * connections that may use the SNI extension with the component that will
+     * be used to map the requested hostname to the correct OpenSSL SSLContext
+     * for the remainder of the connection.
+     *
+     * @param defaultSSLContext The Java representation of a pointer to the
+     *                          OpenSSL SSLContext that will be used to
+     *                          initiate TLS connections
+     * @param sniCallBack The component that will map SNI hosts names received
+     *                    via connections initiated using
+     *                    <code>defaultSSLContext</code> to the correct  OpenSSL
+     *                    SSLContext
+     */
+    public static void registerDefault(Long defaultSSLContext,
+            SNICallBack sniCallBack) {
+        sniCallBacks.put(defaultSSLContext, sniCallBack);
+    }
+
+    /**
+     * Unregister an OpenSSL SSLContext that will no longer be used to initiate
+     * TLS connections that may use the SNI extension.
+     *
+     * @param defaultSSLContext The Java representation of a pointer to the
+     *                          OpenSSL SSLContext that will no longer be used
+     */
+    public static void unregisterDefault(Long defaultSSLContext) {
+        sniCallBacks.remove(defaultSSLContext);
+    }
+
+
+    /**
+     * Interface implemented by components that will receive the call back to
+     * select an OpenSSL SSLContext based on the host name requested by the
+     * client.
+     */
+    public static interface SNICallBack {
+
+        /**
+         * This callback is made during the TLS handshake when the client uses
+         * the SNI extension to request a specific TLS host.
+         *
+         * @param sniHostName The host name requested by the client
+         *
+         * @return The Java representation of the pointer to the OpenSSL
+         *         SSLContext to use for the given host or zero if no SSLContext
+         *         could be identified
+         */
+        public long getSslContext(String sniHostName);
+    }
+
+    /**
+     * Allow to hook {@link CertificateVerifier} into the handshake processing.
+     * This will call {@code SSL_CTX_set_cert_verify_callback} and so replace the default verification
+     * callback used by openssl
+     * @param ctx Server or Client context to use.
+     * @param verifier the verifier to call during handshake.
+     */
+    public static native void setCertVerifyCallback(long ctx, CertificateVerifier verifier);
+
+    /**
+     * Set next protocol for next protocol negotiation extension
+     * @param ctx Server context to use.
+     * @param nextProtos comma delimited list of protocols in priority order
+     *
+     * @deprecated use {@link #setNpnProtos(long, String[], int)}
+     */
+    @Deprecated
+    public static void setNextProtos(long ctx, String nextProtos) {
+        setNpnProtos(ctx, nextProtos.split(","), SSL.SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL);
+    }
+
+    /**
+     * Set next protocol for next protocol negotiation extension
+     * @param ctx Server context to use.
+     * @param nextProtos protocols in priority order
+     * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE}
+     *                                and {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL}
+     */
+    public static native void setNpnProtos(long ctx, String[] nextProtos, int selectorFailureBehavior);
+
+    /**
+     * Set application layer protocol for application layer protocol negotiation extension
+     * @param ctx Server context to use.
+     * @param alpnProtos protocols in priority order
+     * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE}
+     *                                and {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL}
+     */
+    public static native void setAlpnProtos(long ctx, String[] alpnProtos, int selectorFailureBehavior);
+
+    /**
+     * Set DH parameters
+     * @param ctx Server context to use.
+     * @param cert DH param file (can be generated from e.g. {@code openssl dhparam -rand - 2048 > dhparam.pem} -
+     *             see the <a href="https://www.openssl.org/docs/apps/dhparam.html">OpenSSL documentation</a>).
+     * @throws Exception An error occurred
+     */
+    public static native void setTmpDH(long ctx, String cert)
+            throws Exception;
+
+    /**
+     * Set ECDH elliptic curve by name
+     * @param ctx Server context to use.
+     * @param curveName the name of the elliptic curve to use
+     *             (available names can be obtained from {@code openssl ecparam -list_curves}).
+     * @throws Exception An error occurred
+     */
+    public static native void setTmpECDHByCurveName(long ctx, String curveName)
+            throws Exception;
+
+    /**
+     * Set the context within which session be reused (server side only)
+     * http://www.openssl.org/docs/ssl/SSL_CTX_set_session_id_context.html
+     *
+     * @param ctx Server context to use.
+     * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name
+     *               of the application and/or the hostname and/or service name
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    public static native boolean setSessionIdContext(long ctx, byte[] sidCtx);
+
+    /**
+     * Set CertificateRaw
+     * <br>
+     * Use keystore a certificate and key to fill the BIOP
+     * @param ctx Server or Client context to use.
+     * @param cert Byte array with the certificate in DER encoding.
+     * @param key Byte array with the Private Key file in PEM format.
+     * @param sslAidxRsa Certificate index SSL_AIDX_RSA or SSL_AIDX_DSA.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    public static native boolean setCertificateRaw(long ctx, byte[] cert, byte[] key, int sslAidxRsa);
+
+    /**
+     * Add a certificate to the certificate chain. Certs should be added in
+     * order starting with the issuer of the host certs and working up the
+     * certificate chain to the CA.
+     *
+     * <br>
+     * Use keystore a certificate chain to fill the BIOP
+     * @param ctx Server or Client context to use.
+     * @param cert Byte array with the certificate in DER encoding.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    public static native boolean addChainCertificateRaw(long ctx, byte[] cert);
+
+    /**
+     * Add a CA certificate we accept as issuer for peer certs
+     * @param ctx Server or Client context to use.
+     * @param cert Byte array with the certificate in DER encoding.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    public static native boolean addClientCACertificateRaw(long ctx, byte[] cert);
+}
diff --git a/java/org/apache/tomcat/jni/SSLSocket.java b/java/org/apache/tomcat/jni/SSLSocket.java
new file mode 100644
index 0000000..c8108a0
--- /dev/null
+++ b/java/org/apache/tomcat/jni/SSLSocket.java
@@ -0,0 +1,131 @@
+/*
+ *  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.tomcat.jni;
+
+/** SSL Socket
+ *
+ * @author Mladen Turk
+ */
+public class SSLSocket {
+
+    /**
+     * Attach APR socket on a SSL connection.
+     * @param ctx SSLContext to use.
+     * @param sock APR Socket that already did physical connect or accept.
+     * @return APR_STATUS code.
+     * @throws Exception An error occurred
+     */
+    public static native int attach(long ctx, long sock)
+        throws Exception;
+
+    /**
+     * Do a SSL handshake.
+     * @param thesocket The socket to use
+     * @return the handshake status
+     */
+    public static native int handshake(long thesocket);
+
+    /**
+     * Do a SSL renegotiation.
+     * SSL supports per-directory re-configuration of SSL parameters.
+     * This is implemented by performing an SSL renegotiation of the
+     * re-configured parameters after the request is read, but before the
+     * response is sent. In more detail: the renegotiation happens after the
+     * request line and MIME headers were read, but _before_ the attached
+     * request body is read. The reason simply is that in the HTTP protocol
+     * usually there is no acknowledgment step between the headers and the
+     * body (there is the 100-continue feature and the chunking facility
+     * only), so Apache has no API hook for this step.
+     *
+     * @param thesocket The socket to use
+     * @return the operation status
+     */
+    public static native int renegotiate(long thesocket);
+
+    /**
+     * Set Type of Client Certificate verification and Maximum depth of CA
+     * Certificates in Client Certificate verification.
+     * <br>
+     * This is used to change the verification level for a connection prior to
+     * starting a re-negotiation.
+     * <br>
+     * The following levels are available for level:
+     * <PRE>
+     * SSL_CVERIFY_NONE           - No client Certificate is required at all
+     * SSL_CVERIFY_OPTIONAL       - The client may present a valid Certificate
+     * SSL_CVERIFY_REQUIRE        - The client has to present a valid
+     *                              Certificate
+     * SSL_CVERIFY_OPTIONAL_NO_CA - The client may present a valid Certificate
+     *                              but it need not to be (successfully)
+     *                              verifiable
+     * </PRE>
+     * <br>
+     * @param sock  The socket to change.
+     * @param level Type of Client Certificate verification.
+     * @param depth Maximum number of certificates to permit in chain from
+     *              client to trusted CA. Use a value of 0 or less to leave the
+     *              current value unchanged
+     */
+    public static native void setVerify(long sock, int level, int depth);
+
+    /**
+     * Return SSL Info parameter as byte array.
+     *
+     * @param sock The socket to read the data from.
+     * @param id Parameter id.
+     * @return Byte array containing info id value.
+     * @throws Exception An error occurred
+     */
+    public static native byte[] getInfoB(long sock, int id)
+        throws Exception;
+
+    /**
+     * Return SSL Info parameter as String.
+     *
+     * @param sock The socket to read the data from.
+     * @param id Parameter id.
+     * @return String containing info id value.
+     * @throws Exception An error occurred
+     */
+    public static native String getInfoS(long sock, int id)
+        throws Exception;
+
+    /**
+     * Return SSL Info parameter as integer.
+     *
+     * @param sock The socket to read the data from.
+     * @param id Parameter id.
+     * @return Integer containing info id value or -1 on error.
+     * @throws Exception An error occurred
+     */
+    public static native int getInfoI(long sock, int id)
+        throws Exception;
+
+
+    /**
+     * Obtain the name of the protocol negotiated via ALPN. Only valid after the
+     * TLS handshake has completed.
+     *
+     * @param sock                  Socket
+     * @param negotiatedProtocol    Byte array in which to store agreed protocol
+     *
+     * @return Length of agreed protocol. Zero means no protocol agreed.
+     */
+    public static native int getALPN(long sock, byte[] negotiatedProtocol);
+
+}
diff --git a/java/org/apache/tomcat/jni/Shm.java b/java/org/apache/tomcat/jni/Shm.java
new file mode 100644
index 0000000..43c662c
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Shm.java
@@ -0,0 +1,127 @@
+/*
+ *  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.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+/** Shm
+ *
+ * @author Mladen Turk
+ */
+public class Shm {
+
+    /**
+     * Create and make accessible a shared memory segment.
+     * <br>
+     * A note about Anonymous vs. Named shared memory segments:<br>
+     *         Not all platforms support anonymous shared memory segments, but in
+     *         some cases it is preferred over other types of shared memory
+     *         implementations. Passing a NULL 'file' parameter to this function
+     *         will cause the subsystem to use anonymous shared memory segments.
+     *         If such a system is not available, APR_ENOTIMPL is returned.
+     * <br>
+     * A note about allocation sizes:<br>
+     *         On some platforms it is necessary to store some metainformation
+     *         about the segment within the actual segment. In order to supply
+     *         the caller with the requested size it may be necessary for the
+     *         implementation to request a slightly greater segment length
+     *         from the subsystem. In all cases, the apr_shm_baseaddr_get()
+     *         function will return the first usable byte of memory.
+     * @param reqsize The desired size of the segment.
+     * @param filename The file to use for shared memory on platforms that
+     *        require it.
+     * @param pool the pool from which to allocate the shared memory
+     *        structure.
+     * @return The created shared memory structure.
+     * @throws Error An error occurred
+     */
+    public static native long create(long reqsize, String filename, long pool)
+        throws Error;
+
+    /**
+     * Remove shared memory segment associated with a filename.
+     * <br>
+     * This function is only supported on platforms which support
+     * name-based shared memory segments, and will return APR_ENOTIMPL on
+     * platforms without such support.
+     * @param filename The filename associated with shared-memory segment which
+     *        needs to be removed
+     * @param pool The pool used for file operations
+     * @return the operation status
+     */
+    public static native int remove(String filename, long pool);
+
+    /**
+     * Destroy a shared memory segment and associated memory.
+     * @param m The shared memory segment structure to destroy.
+     * @return the operation status
+     */
+    public static native int destroy(long m);
+
+    /**
+     * Attach to a shared memory segment that was created
+     * by another process.
+     * @param filename The file used to create the original segment.
+     *        (This MUST match the original filename.)
+     * @param pool the pool from which to allocate the shared memory
+     *        structure for this process.
+     * @return The created shared memory structure.
+     * @throws Error An error occurred
+     */
+    public static native long attach(String filename, long pool)
+        throws Error;
+
+    /**
+     * Detach from a shared memory segment without destroying it.
+     * @param m The shared memory structure representing the segment
+     *        to detach from.
+     * @return the operation status
+     */
+    public static native int detach(long m);
+
+    /**
+     * Retrieve the base address of the shared memory segment.
+     * NOTE: This address is only usable within the callers address
+     * space, since this API does not guarantee that other attaching
+     * processes will maintain the same address mapping.
+     * @param m The shared memory segment from which to retrieve
+     *        the base address.
+     * @return address, aligned by APR_ALIGN_DEFAULT.
+     */
+    public static native long baseaddr(long m);
+
+    /**
+     * Retrieve the length of a shared memory segment in bytes.
+     * @param m The shared memory segment from which to retrieve
+     *        the segment length.
+     * @return the length of the segment
+     */
+    public static native long size(long m);
+
+    /**
+     * Retrieve new ByteBuffer base address of the shared memory segment.
+     * NOTE: This address is only usable within the callers address
+     * space, since this API does not guarantee that other attaching
+     * processes will maintain the same address mapping.
+     * @param m The shared memory segment from which to retrieve
+     *        the base address.
+     * @return address, aligned by APR_ALIGN_DEFAULT.
+     */
+    public static native ByteBuffer buffer(long m);
+
+}
diff --git a/java/org/apache/tomcat/jni/Sockaddr.java b/java/org/apache/tomcat/jni/Sockaddr.java
new file mode 100644
index 0000000..f5262a7
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Sockaddr.java
@@ -0,0 +1,40 @@
+/*
+ *  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.tomcat.jni;
+
+/** Sockaddr
+ *
+ * @author Mladen Turk
+ */
+public class Sockaddr {
+
+   /** The pool to use... */
+    public long pool;
+    /** The hostname */
+    public String hostname;
+    /** Either a string of the port number or the service name for the port */
+    public String servname;
+    /** The numeric port */
+    public int port;
+    /** The family */
+    public int family;
+    /** If multiple addresses were found by apr_sockaddr_info_get(), this
+     *  points to a representation of the next address. */
+    public long next;
+
+}
diff --git a/java/org/apache/tomcat/jni/Socket.java b/java/org/apache/tomcat/jni/Socket.java
new file mode 100644
index 0000000..976dd38
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Socket.java
@@ -0,0 +1,629 @@
+/*
+ *  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.tomcat.jni;
+
+/* Import needed classes */
+import java.nio.ByteBuffer;
+
+/** Socket
+ *
+ * @author Mladen Turk
+ */
+public class Socket {
+
+    /* Standard socket defines */
+    public static final int SOCK_STREAM = 0;
+    public static final int SOCK_DGRAM  = 1;
+    /*
+     * apr_sockopt Socket option definitions
+     */
+    public static final int APR_SO_LINGER       = 1;    /** Linger */
+    public static final int APR_SO_KEEPALIVE    = 2;    /** Keepalive */
+    public static final int APR_SO_DEBUG        = 4;    /** Debug */
+    public static final int APR_SO_NONBLOCK     = 8;    /** Non-blocking IO */
+    public static final int APR_SO_REUSEADDR    = 16;   /** Reuse addresses */
+    public static final int APR_SO_SNDBUF       = 64;   /** Send buffer */
+    public static final int APR_SO_RCVBUF       = 128;  /** Receive buffer */
+    public static final int APR_SO_DISCONNECTED = 256;  /** Disconnected */
+    /** For SCTP sockets, this is mapped to STCP_NODELAY internally. */
+    public static final int APR_TCP_NODELAY     = 512;
+    public static final int APR_TCP_NOPUSH      = 1024; /** No push */
+    /** This flag is ONLY set internally when we set APR_TCP_NOPUSH with
+     * APR_TCP_NODELAY set to tell us that APR_TCP_NODELAY should be turned on
+     * again when NOPUSH is turned off
+     */
+    public static final int APR_RESET_NODELAY   = 2048;
+    /** Set on non-blocking sockets (timeout != 0) on which the
+     * previous read() did not fill a buffer completely.  the next
+     * apr_socket_recv()  will first call select()/poll() rather than
+     * going straight into read().  (Can also be set by an application to
+     * force a select()/poll() call before the next read, in cases where
+     * the app expects that an immediate read would fail.)
+     */
+    public static final int APR_INCOMPLETE_READ = 4096;
+    /** like APR_INCOMPLETE_READ, but for write
+     */
+    public static final int APR_INCOMPLETE_WRITE = 8192;
+    /** Don't accept IPv4 connections on an IPv6 listening socket.
+     */
+    public static final int APR_IPV6_V6ONLY      = 16384;
+    /** Delay accepting of new connections until data is available.
+     */
+    public static final int APR_TCP_DEFER_ACCEPT = 32768;
+
+    /** Define what type of socket shutdown should occur.
+     * apr_shutdown_how_e enum
+     */
+    public static final int APR_SHUTDOWN_READ      = 0; /** no longer allow read request */
+    public static final int APR_SHUTDOWN_WRITE     = 1; /** no longer allow write requests */
+    public static final int APR_SHUTDOWN_READWRITE = 2; /** no longer allow read or write requests */
+
+    public static final int APR_IPV4_ADDR_OK = 0x01;
+    public static final int APR_IPV6_ADDR_OK = 0x02;
+
+    public static final int APR_UNSPEC = 0;
+    public static final int APR_INET   = 1;
+    public static final int APR_INET6  = 2;
+
+    public static final int APR_PROTO_TCP  =   6; /** TCP  */
+    public static final int APR_PROTO_UDP  =  17; /** UDP  */
+    public static final int APR_PROTO_SCTP = 132; /** SCTP */
+
+    /**
+     * Enum to tell us if we're interested in remote or local socket
+     * apr_interface_e
+     */
+    public static final int APR_LOCAL  = 0;
+    public static final int APR_REMOTE = 1;
+
+    /* Socket.get types */
+    public static final int SOCKET_GET_POOL = 0;
+    public static final int SOCKET_GET_IMPL = 1;
+    public static final int SOCKET_GET_APRS = 2;
+    public static final int SOCKET_GET_TYPE = 3;
+
+    /**
+     * Create a socket.
+     * @param family The address family of the socket (e.g., APR_INET).
+     * @param type The type of the socket (e.g., SOCK_STREAM).
+     * @param protocol The protocol of the socket (e.g., APR_PROTO_TCP).
+     * @param cont The parent pool to use
+     * @return The new socket that has been set up.
+     * @throws Exception Error creating socket
+     */
+    public static native long create(int family, int type,
+                                     int protocol, long cont)
+        throws Exception;
+
+
+    /**
+     * Shutdown either reading, writing, or both sides of a socket.
+     * <br>
+     * This does not actually close the socket descriptor, it just
+     *      controls which calls are still valid on the socket.
+     * @param thesocket The socket to close
+     * @param how How to shutdown the socket.  One of:
+     * <PRE>
+     * APR_SHUTDOWN_READ         no longer allow read requests
+     * APR_SHUTDOWN_WRITE        no longer allow write requests
+     * APR_SHUTDOWN_READWRITE    no longer allow read or write requests
+     * </PRE>
+     * @return the operation status
+     */
+    public static native int shutdown(long thesocket, int how);
+
+    /**
+     * Close a socket.
+     * @param thesocket The socket to close
+     * @return the operation status
+     */
+    public static native int close(long thesocket);
+
+    /**
+     * Destroy a pool associated with socket
+     * @param thesocket The destroy
+     */
+    public static native void destroy(long thesocket);
+
+    /**
+     * Bind the socket to its associated port
+     * @param sock The socket to bind
+     * @param sa The socket address to bind to
+     * This may be where we will find out if there is any other process
+     *      using the selected port.
+     * @return the operation status
+     */
+    public static native int bind(long sock, long sa);
+
+    /**
+     * Listen to a bound socket for connections.
+     * @param sock The socket to listen on
+     * @param backlog The number of outstanding connections allowed in the sockets
+     *                listen queue.  If this value is less than zero, the listen
+     *                queue size is set to zero.
+     * @return the operation status
+     */
+    public static native int listen(long sock, int backlog);
+
+    /**
+     * Accept a new connection request
+     * @param sock The socket we are listening on.
+     * @param pool The pool for the new socket.
+     * @return  A copy of the socket that is connected to the socket that
+     *          made the connection request.  This is the socket which should
+     *          be used for all future communication.
+     * @throws Exception Socket accept error
+     */
+    public static native long acceptx(long sock, long pool)
+        throws Exception;
+
+    /**
+     * Accept a new connection request
+     * @param sock The socket we are listening on.
+     * @return  A copy of the socket that is connected to the socket that
+     *          made the connection request.  This is the socket which should
+     *          be used for all future communication.
+     * @throws Exception Socket accept error
+     */
+    public static native long accept(long sock)
+        throws Exception;
+
+    /**
+     * Set an OS level accept filter.
+     * @param sock The socket to put the accept filter on.
+     * @param name The accept filter
+     * @param args Any extra args to the accept filter.  Passing NULL here removes
+     *             the accept filter.
+     * @return the operation status
+     */
+    public static native int acceptfilter(long sock, String name, String args);
+
+    /**
+     * Query the specified socket if at the OOB/Urgent data mark
+     * @param sock The socket to query
+     * @return <code>true</code> if socket is at the OOB/urgent mark,
+     *         otherwise <code>false</code>.
+     */
+    public static native boolean atmark(long sock);
+
+    /**
+     * Issue a connection request to a socket either on the same machine
+     * or a different one.
+     * @param sock The socket we wish to use for our side of the connection
+     * @param sa The address of the machine we wish to connect to.
+     * @return the operation status
+     */
+    public static native int connect(long sock, long sa);
+
+    /**
+     * Send data over a network.
+     * <PRE>
+     * This functions acts like a blocking write by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     *
+     * It is possible for both bytes to be sent and an error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to send the data over.
+     * @param buf The buffer which contains the data to be sent.
+     * @param offset Offset in the byte buffer.
+     * @param len The number of bytes to write; (-1) for full array.
+     * @return The number of bytes sent
+     */
+    public static native int send(long sock, byte[] buf, int offset, int len);
+
+    /**
+     * Send data over a network.
+     * <PRE>
+     * This functions acts like a blocking write by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     *
+     * It is possible for both bytes to be sent and an error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to send the data over.
+     * @param buf The Byte buffer which contains the data to be sent.
+     * @param offset The offset within the buffer array of the first buffer from
+     *               which bytes are to be retrieved; must be non-negative
+     *               and no larger than buf.length
+     * @param len The maximum number of buffers to be accessed; must be non-negative
+     *            and no larger than buf.length - offset
+     * @return The number of bytes sent
+     */
+    public static native int sendb(long sock, ByteBuffer buf,
+                                   int offset, int len);
+
+    /**
+     * Send data over a network without retry
+     * <PRE>
+     * This functions acts like a blocking write by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     *
+     * It is possible for both bytes to be sent and an error to be returned.
+     *
+     * </PRE>
+     * @param sock The socket to send the data over.
+     * @param buf The Byte buffer which contains the data to be sent.
+     * @param offset The offset within the buffer array of the first buffer from
+     *               which bytes are to be retrieved; must be non-negative
+     *               and no larger than buf.length
+     * @param len The maximum number of buffers to be accessed; must be non-negative
+     *            and no larger than buf.length - offset
+     * @return The number of bytes sent
+     */
+    public static native int sendib(long sock, ByteBuffer buf,
+                                    int offset, int len);
+
+    /**
+     * Send data over a network using internally set ByteBuffer
+     * @param sock The socket to send the data over.
+     * @param offset The offset within the buffer array of the first buffer from
+     *               which bytes are to be retrieved; must be non-negative
+     *               and no larger than buf.length
+     * @param len The maximum number of buffers to be accessed; must be non-negative
+     *            and no larger than buf.length - offset
+     * @return The number of bytes sent
+     */
+    public static native int sendbb(long sock,
+                                   int offset, int len);
+
+    /**
+     * Send data over a network using internally set ByteBuffer
+     * without internal retry.
+     * @param sock The socket to send the data over.
+     * @param offset The offset within the buffer array of the first buffer from
+     *               which bytes are to be retrieved; must be non-negative
+     *               and no larger than buf.length
+     * @param len The maximum number of buffers to be accessed; must be non-negative
+     *            and no larger than buf.length - offset
+     * @return The number of bytes sent
+     */
+    public static native int sendibb(long sock,
+                                     int offset, int len);
+
+    /**
+     * Send multiple packets of data over a network.
+     * <PRE>
+     * This functions acts like a blocking write by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     * The number of bytes actually sent is stored in argument 3.
+     *
+     * It is possible for both bytes to be sent and an error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to send the data over.
+     * @param vec The array from which to get the data to send.
+     * @return The number of bytes sent
+     */
+    public static native int sendv(long sock, byte[][] vec);
+
+    /**
+     * @param sock The socket to send from
+     * @param where The apr_sockaddr_t describing where to send the data
+     * @param flags The flags to use
+     * @param buf  The data to send
+     * @param offset Offset in the byte buffer.
+     * @param len  The length of the data to send
+     * @return The number of bytes sent
+     */
+    public static native int sendto(long sock, long where, int flags,
+                                    byte[] buf, int offset, int len);
+
+    /**
+     * Read data from a network.
+     *
+     * <PRE>
+     * This functions acts like a blocking read by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     * The number of bytes actually received is stored in argument 3.
+     *
+     * It is possible for both bytes to be received and an APR_EOF or
+     * other error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to read the data from.
+     * @param buf The buffer to store the data in.
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @return the number of bytes received.
+     */
+    public static native int recv(long sock, byte[] buf, int offset, int nbytes);
+
+    /**
+     * Read data from a network with timeout.
+     *
+     * <PRE>
+     * This functions acts like a blocking read by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     * The number of bytes actually received is stored in argument 3.
+     *
+     * It is possible for both bytes to be received and an APR_EOF or
+     * other error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to read the data from.
+     * @param buf The buffer to store the data in.
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @param timeout The socket timeout in microseconds.
+     * @return the number of bytes received.
+     */
+    public static native int recvt(long sock, byte[] buf, int offset,
+                                   int nbytes, long timeout);
+
+    /**
+     * Read data from a network.
+     *
+     * <PRE>
+     * This functions acts like a blocking read by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     * The number of bytes actually received is stored in argument 3.
+     *
+     * It is possible for both bytes to be received and an APR_EOF or
+     * other error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to read the data from.
+     * @param buf The buffer to store the data in.
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @return If &ge; 0, the return value is the number of bytes read. Note a
+     *         non-blocking read with no data current available will return
+     *         {@link Status#EAGAIN} and EOF will return {@link Status#APR_EOF}.
+     */
+    public static native int recvb(long sock, ByteBuffer buf,
+                                   int offset, int nbytes);
+
+    /**
+     * Read data from a network using internally set ByteBuffer.
+     *
+     * @param sock The socket to read the data from.
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @return If &gt; 0, the return value is the number of bytes read. If == 0,
+     *         the return value indicates EOF and if &lt; 0 the return value is the
+     *         error code. Note a non-blocking read with no data current
+     *         available will return {@link Status#EAGAIN} not zero.
+     */
+    public static native int recvbb(long sock,
+                                    int offset, int nbytes);
+    /**
+     * Read data from a network with timeout.
+     *
+     * <PRE>
+     * This functions acts like a blocking read by default.  To change
+     * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+     * socket option.
+     * The number of bytes actually received is stored in argument 3.
+     *
+     * It is possible for both bytes to be received and an APR_EOF or
+     * other error to be returned.
+     *
+     * APR_EINTR is never returned.
+     * </PRE>
+     * @param sock The socket to read the data from.
+     * @param buf The buffer to store the data in.
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @param timeout The socket timeout in microseconds.
+     * @return the number of bytes received.
+     */
+    public static native int recvbt(long sock, ByteBuffer buf,
+                                    int offset, int nbytes, long timeout);
+    /**
+     * Read data from a network with timeout using internally set ByteBuffer
+     * @param sock The socket to read the data from.
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @param timeout The socket timeout in microseconds.
+     * @return the number of bytes received.
+     */
+    public static native int recvbbt(long sock,
+                                     int offset, int nbytes, long timeout);
+
+    /**
+     * @param from The apr_sockaddr_t to fill in the recipient info
+     * @param sock The socket to use
+     * @param flags The flags to use
+     * @param buf  The buffer to use
+     * @param offset Offset in the byte buffer.
+     * @param nbytes The number of bytes to read (-1) for full array.
+     * @return the number of bytes received.
+     */
+    public static native int recvfrom(long from, long sock, int flags,
+                                      byte[] buf, int offset, int nbytes);
+
+    /**
+     * Setup socket options for the specified socket
+     * @param sock The socket to set up.
+     * @param opt The option we would like to configure.  One of:
+     * <PRE>
+     * APR_SO_DEBUG      --  turn on debugging information
+     * APR_SO_KEEPALIVE  --  keep connections active
+     * APR_SO_LINGER     --  lingers on close if data is present
+     * APR_SO_NONBLOCK   --  Turns blocking on/off for socket
+     *                       When this option is enabled, use
+     *                       the APR_STATUS_IS_EAGAIN() macro to
+     *                       see if a send or receive function
+     *                       could not transfer data without
+     *                       blocking.
+     * APR_SO_REUSEADDR  --  The rules used in validating addresses
+     *                       supplied to bind should allow reuse
+     *                       of local addresses.
+     * APR_SO_SNDBUF     --  Set the SendBufferSize
+     * APR_SO_RCVBUF     --  Set the ReceiveBufferSize
+     * </PRE>
+     * @param on Value for the option.
+     * @return the operation status
+     */
+    public static native int optSet(long sock, int opt, int on);
+
+    /**
+     * Query socket options for the specified socket
+     * @param sock The socket to query
+     * @param opt The option we would like to query.  One of:
+     * <PRE>
+     * APR_SO_DEBUG      --  turn on debugging information
+     * APR_SO_KEEPALIVE  --  keep connections active
+     * APR_SO_LINGER     --  lingers on close if data is present
+     * APR_SO_NONBLOCK   --  Turns blocking on/off for socket
+     * APR_SO_REUSEADDR  --  The rules used in validating addresses
+     *                       supplied to bind should allow reuse
+     *                       of local addresses.
+     * APR_SO_SNDBUF     --  Set the SendBufferSize
+     * APR_SO_RCVBUF     --  Set the ReceiveBufferSize
+     * APR_SO_DISCONNECTED -- Query the disconnected state of the socket.
+     *                       (Currently only used on Windows)
+     * </PRE>
+     * @return Socket option returned on the call.
+     * @throws Exception An error occurred
+     */
+    public static native int optGet(long sock, int opt)
+        throws Exception;
+
+    /**
+     * Setup socket timeout for the specified socket
+     * @param sock The socket to set up.
+     * @param t Value for the timeout in microseconds.
+     * <PRE>
+     * t &gt; 0  -- read and write calls return APR_TIMEUP if specified time
+     *           elapses with no data read or written
+     * t == 0 -- read and write calls never block
+     * t &lt; 0  -- read and write calls block
+     * </PRE>
+     * @return the operation status
+     */
+    public static native int timeoutSet(long sock, long t);
+
+    /**
+     * Query socket timeout for the specified socket
+     * @param sock The socket to query
+     * @return Socket timeout returned from the query.
+     * @throws Exception An error occurred
+     */
+    public static native long timeoutGet(long sock)
+        throws Exception;
+
+    /**
+     * Send a file from an open file descriptor to a socket, along with
+     * optional headers and trailers.
+     * <br>
+     * This functions acts like a blocking write by default.  To change
+     *         this behavior, use apr_socket_timeout_set() or the
+     *         APR_SO_NONBLOCK socket option.
+     * The number of bytes actually sent is stored in the len parameter.
+     * The offset parameter is passed by reference for no reason; its
+     * value will never be modified by the apr_socket_sendfile() function.
+     * @param sock The socket to which we're writing
+     * @param file The open file from which to read
+     * @param headers Array containing the headers to send
+     * @param trailers Array containing the trailers to send
+     * @param offset Offset into the file where we should begin writing
+     * @param len Number of bytes to send from the file
+     * @param flags APR flags that are mapped to OS specific flags
+     * @return Number of bytes actually sent, including headers,
+     *         file, and trailers
+     */
+    public static native long sendfile(long sock, long file, byte [][] headers,
+                                       byte[][] trailers, long offset,
+                                       long len, int flags);
+
+    /**
+     * Send a file without header and trailer arrays.
+     * @param sock The socket to which we're writing
+     * @param file The open file from which to read
+     * @param offset Offset into the file where we should begin writing
+     * @param len Number of bytes to send from the file
+     * @param flags APR flags that are mapped to OS specific flags
+     * @return Number of bytes actually sent
+     */
+    public static native long sendfilen(long sock, long file, long offset,
+                                        long len, int flags);
+
+    /**
+     * Create a child pool from associated socket pool.
+     * @param thesocket The socket to use
+     * @return a pointer to the pool
+     * @throws Exception An error occurred
+     */
+    public static native long pool(long thesocket)
+        throws Exception;
+
+    /**
+     * Private method for getting the socket struct members
+     * @param socket The socket to use
+     * @param what Struct member to obtain
+     * <PRE>
+     * SOCKET_GET_POOL  - The socket pool
+     * SOCKET_GET_IMPL  - The socket implementation object
+     * SOCKET_GET_APRS  - APR socket
+     * SOCKET_GET_TYPE  - Socket type
+     * </PRE>
+     * @return The structure member address
+     */
+    private static native long get(long socket, int what);
+
+    /**
+     * Set internal send ByteBuffer.
+     * This function will preset internal Java ByteBuffer for
+     * consecutive sendbb calls.
+     * @param sock The socket to use
+     * @param buf The ByteBuffer
+     */
+    public static native void setsbb(long sock, ByteBuffer buf);
+
+    /**
+     * Set internal receive ByteBuffer.
+     * This function will preset internal Java ByteBuffer for
+     * consecutive revcvbb/recvbbt calls.
+     * @param sock The socket to use
+     * @param buf The ByteBuffer
+     */
+    public static native void setrbb(long sock, ByteBuffer buf);
+
+    /**
+     * Set the data associated with the current socket.
+     * @param sock The currently open socket.
+     * @param data The user data to associate with the socket.
+     * @param key The key to associate with the data.
+     * @return the operation status
+     */
+      public static native int dataSet(long sock, String key, Object data);
+
+    /**
+     * Return the data associated with the current socket
+     * @param sock The currently open socket.
+     * @param key The key to associate with the user data.
+     * @return Data or null in case of error.
+     */
+     public static native Object dataGet(long sock, String key);
+
+}
diff --git a/java/org/apache/tomcat/jni/Status.java b/java/org/apache/tomcat/jni/Status.java
new file mode 100644
index 0000000..56d9445
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Status.java
@@ -0,0 +1,263 @@
+/*
+ *  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.tomcat.jni;
+
+/** Status
+ *
+ * @author Mladen Turk
+ */
+public class Status {
+
+    /**
+     * APR_OS_START_ERROR is where the APR specific error values start.
+     */
+     public static final int APR_OS_START_ERROR   = 20000;
+    /**
+     * APR_OS_ERRSPACE_SIZE is the maximum number of errors you can fit
+     *    into one of the error/status ranges below -- except for
+     *    APR_OS_START_USERERR, which see.
+     */
+     public static final int APR_OS_ERRSPACE_SIZE = 50000;
+    /**
+     * APR_OS_START_STATUS is where the APR specific status codes start.
+     */
+     public static final int APR_OS_START_STATUS  = (APR_OS_START_ERROR + APR_OS_ERRSPACE_SIZE);
+
+    /**
+     * APR_OS_START_USERERR are reserved for applications that use APR that
+     *     layer their own error codes along with APR's.  Note that the
+     *     error immediately following this one is set ten times farther
+     *     away than usual, so that users of apr have a lot of room in
+     *     which to declare custom error codes.
+     */
+    public static final int APR_OS_START_USERERR  = (APR_OS_START_STATUS + APR_OS_ERRSPACE_SIZE);
+    /**
+     * APR_OS_START_USEERR is obsolete, defined for compatibility only.
+     * Use APR_OS_START_USERERR instead.
+     */
+    public static final int APR_OS_START_USEERR    = APR_OS_START_USERERR;
+    /**
+     * APR_OS_START_CANONERR is where APR versions of errno values are defined
+     *     on systems which don't have the corresponding errno.
+     */
+    public static final int APR_OS_START_CANONERR  = (APR_OS_START_USERERR + (APR_OS_ERRSPACE_SIZE * 10));
+
+    /**
+     * APR_OS_START_EAIERR folds EAI_ error codes from getaddrinfo() into
+     *     apr_status_t values.
+     */
+    public static final int APR_OS_START_EAIERR  = (APR_OS_START_CANONERR + APR_OS_ERRSPACE_SIZE);
+    /**
+     * APR_OS_START_SYSERR folds platform-specific system error values into
+     *     apr_status_t values.
+     */
+    public static final int APR_OS_START_SYSERR  = (APR_OS_START_EAIERR + APR_OS_ERRSPACE_SIZE);
+
+    /** no error. */
+    public static final int APR_SUCCESS = 0;
+
+    /**
+     * APR Error Values
+     * <PRE>
+     * <b>APR ERROR VALUES</b>
+     * APR_ENOSTAT      APR was unable to perform a stat on the file
+     * APR_ENOPOOL      APR was not provided a pool with which to allocate memory
+     * APR_EBADDATE     APR was given an invalid date
+     * APR_EINVALSOCK   APR was given an invalid socket
+     * APR_ENOPROC      APR was not given a process structure
+     * APR_ENOTIME      APR was not given a time structure
+     * APR_ENODIR       APR was not given a directory structure
+     * APR_ENOLOCK      APR was not given a lock structure
+     * APR_ENOPOLL      APR was not given a poll structure
+     * APR_ENOSOCKET    APR was not given a socket
+     * APR_ENOTHREAD    APR was not given a thread structure
+     * APR_ENOTHDKEY    APR was not given a thread key structure
+     * APR_ENOSHMAVAIL  There is no more shared memory available
+     * APR_EDSOOPEN     APR was unable to open the dso object.  For more
+     *                  information call apr_dso_error().
+     * APR_EGENERAL     General failure (specific information not available)
+     * APR_EBADIP       The specified IP address is invalid
+     * APR_EBADMASK     The specified netmask is invalid
+     * APR_ESYMNOTFOUND Could not find the requested symbol
+     * </PRE>
+     *
+     */
+    public static final int APR_ENOSTAT       = (APR_OS_START_ERROR + 1);
+    public static final int APR_ENOPOOL       = (APR_OS_START_ERROR + 2);
+    public static final int APR_EBADDATE      = (APR_OS_START_ERROR + 4);
+    public static final int APR_EINVALSOCK    = (APR_OS_START_ERROR + 5);
+    public static final int APR_ENOPROC       = (APR_OS_START_ERROR + 6);
+    public static final int APR_ENOTIME       = (APR_OS_START_ERROR + 7);
+    public static final int APR_ENODIR        = (APR_OS_START_ERROR + 8);
+    public static final int APR_ENOLOCK       = (APR_OS_START_ERROR + 9);
+    public static final int APR_ENOPOLL       = (APR_OS_START_ERROR + 10);
+    public static final int APR_ENOSOCKET     = (APR_OS_START_ERROR + 11);
+    public static final int APR_ENOTHREAD     = (APR_OS_START_ERROR + 12);
+    public static final int APR_ENOTHDKEY     = (APR_OS_START_ERROR + 13);
+    public static final int APR_EGENERAL      = (APR_OS_START_ERROR + 14);
+    public static final int APR_ENOSHMAVAIL   = (APR_OS_START_ERROR + 15);
+    public static final int APR_EBADIP        = (APR_OS_START_ERROR + 16);
+    public static final int APR_EBADMASK      = (APR_OS_START_ERROR + 17);
+    public static final int APR_EDSOOPEN      = (APR_OS_START_ERROR + 19);
+    public static final int APR_EABSOLUTE     = (APR_OS_START_ERROR + 20);
+    public static final int APR_ERELATIVE     = (APR_OS_START_ERROR + 21);
+    public static final int APR_EINCOMPLETE   = (APR_OS_START_ERROR + 22);
+    public static final int APR_EABOVEROOT    = (APR_OS_START_ERROR + 23);
+    public static final int APR_EBADPATH      = (APR_OS_START_ERROR + 24);
+    public static final int APR_EPATHWILD     = (APR_OS_START_ERROR + 25);
+    public static final int APR_ESYMNOTFOUND  = (APR_OS_START_ERROR + 26);
+    public static final int APR_EPROC_UNKNOWN = (APR_OS_START_ERROR + 27);
+    public static final int APR_ENOTENOUGHENTROPY = (APR_OS_START_ERROR + 28);
+
+    /** APR Status Values
+     * <PRE>
+     * <b>APR STATUS VALUES</b>
+     * APR_INCHILD        Program is currently executing in the child
+     * APR_INPARENT       Program is currently executing in the parent
+     * APR_DETACH         The thread is detached
+     * APR_NOTDETACH      The thread is not detached
+     * APR_CHILD_DONE     The child has finished executing
+     * APR_CHILD_NOTDONE  The child has not finished executing
+     * APR_TIMEUP         The operation did not finish before the timeout
+     * APR_INCOMPLETE     The operation was incomplete although some processing
+     *                    was performed and the results are partially valid
+     * APR_BADCH          Getopt found an option not in the option string
+     * APR_BADARG         Getopt found an option that is missing an argument
+     *                    and an argument was specified in the option string
+     * APR_EOF            APR has encountered the end of the file
+     * APR_NOTFOUND       APR was unable to find the socket in the poll structure
+     * APR_ANONYMOUS      APR is using anonymous shared memory
+     * APR_FILEBASED      APR is using a file name as the key to the shared memory
+     * APR_KEYBASED       APR is using a shared key as the key to the shared memory
+     * APR_EINIT          Initializer value.  If no option has been found, but
+     *                    the status variable requires a value, this should be used
+     * APR_ENOTIMPL       The APR function has not been implemented on this
+     *                    platform, either because nobody has gotten to it yet,
+     *                    or the function is impossible on this platform.
+     * APR_EMISMATCH      Two passwords do not match.
+     * APR_EBUSY          The given lock was busy.
+     * </PRE>
+     *
+     */
+    public static final int APR_INCHILD       = (APR_OS_START_STATUS + 1);
+    public static final int APR_INPARENT      = (APR_OS_START_STATUS + 2);
+    public static final int APR_DETACH        = (APR_OS_START_STATUS + 3);
+    public static final int APR_NOTDETACH     = (APR_OS_START_STATUS + 4);
+    public static final int APR_CHILD_DONE    = (APR_OS_START_STATUS + 5);
+    public static final int APR_CHILD_NOTDONE = (APR_OS_START_STATUS + 6);
+    public static final int APR_TIMEUP        = (APR_OS_START_STATUS + 7);
+    public static final int APR_INCOMPLETE    = (APR_OS_START_STATUS + 8);
+    public static final int APR_BADCH         = (APR_OS_START_STATUS + 12);
+    public static final int APR_BADARG        = (APR_OS_START_STATUS + 13);
+    public static final int APR_EOF           = (APR_OS_START_STATUS + 14);
+    public static final int APR_NOTFOUND      = (APR_OS_START_STATUS + 15);
+    public static final int APR_ANONYMOUS     = (APR_OS_START_STATUS + 19);
+    public static final int APR_FILEBASED     = (APR_OS_START_STATUS + 20);
+    public static final int APR_KEYBASED      = (APR_OS_START_STATUS + 21);
+    public static final int APR_EINIT         = (APR_OS_START_STATUS + 22);
+    public static final int APR_ENOTIMPL      = (APR_OS_START_STATUS + 23);
+    public static final int APR_EMISMATCH     = (APR_OS_START_STATUS + 24);
+    public static final int APR_EBUSY         = (APR_OS_START_STATUS + 25);
+
+    public static final int TIMEUP            = (APR_OS_START_USERERR + 1);
+    public static final int EAGAIN            = (APR_OS_START_USERERR + 2);
+    public static final int EINTR             = (APR_OS_START_USERERR + 3);
+    public static final int EINPROGRESS       = (APR_OS_START_USERERR + 4);
+    public static final int ETIMEDOUT         = (APR_OS_START_USERERR + 5);
+
+    private static native boolean is(int err, int idx);
+    /*
+     * APR_STATUS_IS Status Value Tests
+     * <br><b>Warning :</b> For any particular error condition, more than one of these tests
+     *      may match. This is because platform-specific error codes may not
+     *      always match the semantics of the POSIX codes these tests (and the
+     *      corresponding APR error codes) are named after. A notable example
+     *      are the APR_STATUS_IS_ENOENT and APR_STATUS_IS_ENOTDIR tests on
+     *      Win32 platforms. The programmer should always be aware of this and
+     *      adjust the order of the tests accordingly.
+     *
+     */
+    public static final boolean APR_STATUS_IS_ENOSTAT(int s)    { return is(s, 1); }
+    public static final boolean APR_STATUS_IS_ENOPOOL(int s)    { return is(s, 2); }
+    /* empty slot: +3 */
+    public static final boolean APR_STATUS_IS_EBADDATE(int s)   { return is(s, 4); }
+    public static final boolean APR_STATUS_IS_EINVALSOCK(int s) { return is(s, 5); }
+    public static final boolean APR_STATUS_IS_ENOPROC(int s)    { return is(s, 6); }
+    public static final boolean APR_STATUS_IS_ENOTIME(int s)    { return is(s, 7); }
+    public static final boolean APR_STATUS_IS_ENODIR(int s)     { return is(s, 8); }
+    public static final boolean APR_STATUS_IS_ENOLOCK(int s)    { return is(s, 9); }
+    public static final boolean APR_STATUS_IS_ENOPOLL(int s)    { return is(s, 10); }
+    public static final boolean APR_STATUS_IS_ENOSOCKET(int s)  { return is(s, 11); }
+    public static final boolean APR_STATUS_IS_ENOTHREAD(int s)  { return is(s, 12); }
+    public static final boolean APR_STATUS_IS_ENOTHDKEY(int s)  { return is(s, 13); }
+    public static final boolean APR_STATUS_IS_EGENERAL(int s)   { return is(s, 14); }
+    public static final boolean APR_STATUS_IS_ENOSHMAVAIL(int s){ return is(s, 15); }
+    public static final boolean APR_STATUS_IS_EBADIP(int s)     { return is(s, 16); }
+    public static final boolean APR_STATUS_IS_EBADMASK(int s)   { return is(s, 17); }
+    /* empty slot: +18 */
+    public static final boolean APR_STATUS_IS_EDSOPEN(int s)    { return is(s, 19); }
+    public static final boolean APR_STATUS_IS_EABSOLUTE(int s)  { return is(s, 20); }
+    public static final boolean APR_STATUS_IS_ERELATIVE(int s)  { return is(s, 21); }
+    public static final boolean APR_STATUS_IS_EINCOMPLETE(int s){ return is(s, 22); }
+    public static final boolean APR_STATUS_IS_EABOVEROOT(int s) { return is(s, 23); }
+    public static final boolean APR_STATUS_IS_EBADPATH(int s)   { return is(s, 24); }
+    public static final boolean APR_STATUS_IS_EPATHWILD(int s)  { return is(s, 25); }
+    public static final boolean APR_STATUS_IS_ESYMNOTFOUND(int s)      { return is(s, 26); }
+    public static final boolean APR_STATUS_IS_EPROC_UNKNOWN(int s)     { return is(s, 27); }
+    public static final boolean APR_STATUS_IS_ENOTENOUGHENTROPY(int s) { return is(s, 28); }
+
+    /*
+     * APR_Error
+     */
+    public static final boolean APR_STATUS_IS_INCHILD(int s)    { return is(s, 51); }
+    public static final boolean APR_STATUS_IS_INPARENT(int s)   { return is(s, 52); }
+    public static final boolean APR_STATUS_IS_DETACH(int s)     { return is(s, 53); }
+    public static final boolean APR_STATUS_IS_NOTDETACH(int s)  { return is(s, 54); }
+    public static final boolean APR_STATUS_IS_CHILD_DONE(int s) { return is(s, 55); }
+    public static final boolean APR_STATUS_IS_CHILD_NOTDONE(int s)  { return is(s, 56); }
+    public static final boolean APR_STATUS_IS_TIMEUP(int s)     { return is(s, 57); }
+    public static final boolean APR_STATUS_IS_INCOMPLETE(int s) { return is(s, 58); }
+    /* empty slot: +9 */
+    /* empty slot: +10 */
+    /* empty slot: +11 */
+    public static final boolean APR_STATUS_IS_BADCH(int s)      { return is(s, 62); }
+    public static final boolean APR_STATUS_IS_BADARG(int s)     { return is(s, 63); }
+    public static final boolean APR_STATUS_IS_EOF(int s)        { return is(s, 64); }
+    public static final boolean APR_STATUS_IS_NOTFOUND(int s)   { return is(s, 65); }
+    /* empty slot: +16 */
+    /* empty slot: +17 */
+    /* empty slot: +18 */
+    public static final boolean APR_STATUS_IS_ANONYMOUS(int s)  { return is(s, 69); }
+    public static final boolean APR_STATUS_IS_FILEBASED(int s)  { return is(s, 70); }
+    public static final boolean APR_STATUS_IS_KEYBASED(int s)   { return is(s, 71); }
+    public static final boolean APR_STATUS_IS_EINIT(int s)      { return is(s, 72); }
+    public static final boolean APR_STATUS_IS_ENOTIMPL(int s)   { return is(s, 73); }
+    public static final boolean APR_STATUS_IS_EMISMATCH(int s)  { return is(s, 74); }
+    public static final boolean APR_STATUS_IS_EBUSY(int s)      { return is(s, 75); }
+
+    /* Socket errors */
+    public static final boolean APR_STATUS_IS_EAGAIN(int s)     { return is(s, 90); }
+    public static final boolean APR_STATUS_IS_ETIMEDOUT(int s)  { return is(s, 91); }
+    public static final boolean APR_STATUS_IS_ECONNABORTED(int s) { return is(s, 92); }
+    public static final boolean APR_STATUS_IS_ECONNRESET(int s)   { return is(s, 93); }
+    public static final boolean APR_STATUS_IS_EINPROGRESS(int s)  { return is(s, 94); }
+    public static final boolean APR_STATUS_IS_EINTR(int s)      { return is(s, 95); }
+    public static final boolean APR_STATUS_IS_ENOTSOCK(int s)   { return is(s, 96); }
+    public static final boolean APR_STATUS_IS_EINVAL(int s)     { return is(s, 97); }
+
+}
diff --git a/java/org/apache/tomcat/jni/Stdlib.java b/java/org/apache/tomcat/jni/Stdlib.java
new file mode 100644
index 0000000..b2fa630
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Stdlib.java
@@ -0,0 +1,94 @@
+/*
+ *  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.tomcat.jni;
+
+/** Stdlib
+ *
+ * @author Mladen Turk
+ */
+public class Stdlib {
+
+    /**
+     * Read from plain memory
+     * @param dst Destination byte array
+     * @param src Source memory address
+     * @param sz Number of bytes to copy.
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean memread(byte [] dst, long src, int sz);
+
+    /**
+     * Write to plain memory
+     * @param dst Destination memory address
+     * @param src Source byte array
+     * @param sz Number of bytes to copy.
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean memwrite(long dst, byte [] src, int sz);
+
+    /**
+     * Sets buffers to a specified character
+     * @param dst Destination memory address
+     * @param c Character to set.
+     * @param sz Number of characters.
+     * @return <code>true</code> if the operation was successful
+     */
+    public static native boolean memset(long dst, int c, int sz);
+
+    /**
+     * Allocates memory blocks.
+     * @param sz Bytes to allocate.
+     * @return a pointer
+     */
+    public static native long malloc(int sz);
+
+    /**
+     * Reallocate memory blocks.
+     * @param mem Pointer to previously allocated memory block.
+     * @param sz New size in bytes.
+     * @return a pointer
+     */
+    public static native long realloc(long mem, int sz);
+
+    /**
+     * Allocates an array in memory with elements initialized to 0.
+     * @param num Number of elements.
+     * @param sz Length in bytes of each element.
+     * @return a pointer
+     */
+    public static native long calloc(int num, int sz);
+
+    /**
+     * Deallocates or frees a memory block.
+     * @param mem Previously allocated memory block to be freed.
+     */
+    public static native void free(long mem);
+
+    /**
+     * Get current process pid.
+     * @return current pid or &lt; 1 in case of error.
+     */
+    public static native int getpid();
+
+    /**
+     * Get current process parent pid.
+     * @return parent pid or &lt; 1 in case of error.
+     */
+    public static native int getppid();
+
+}
diff --git a/java/org/apache/tomcat/jni/Thread.java b/java/org/apache/tomcat/jni/Thread.java
new file mode 100644
index 0000000..7435bf3
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Thread.java
@@ -0,0 +1,31 @@
+/*
+ *  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.tomcat.jni;
+
+/** Thread
+ *
+ * @author Mladen Turk
+ */
+public class Thread {
+
+    /**
+     * @return the current thread ID handle.
+     */
+    public static native long current();
+
+}
diff --git a/java/org/apache/tomcat/jni/Time.java b/java/org/apache/tomcat/jni/Time.java
new file mode 100644
index 0000000..22aeb25
--- /dev/null
+++ b/java/org/apache/tomcat/jni/Time.java
@@ -0,0 +1,80 @@
+/*
+ *  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.tomcat.jni;
+
+/** Time
+ *
+ * @author Mladen Turk
+ */
+public class Time {
+
+    /** number of microseconds per second */
+    public static final long APR_USEC_PER_SEC  = 1000000L;
+    /** number of milliseconds per microsecond */
+    public static final long APR_MSEC_PER_USEC = 1000L;
+
+    /**
+     * @param t The time
+     * @return apr_time_t as a second
+     */
+    public static long sec(long t)
+    {
+        return t / APR_USEC_PER_SEC;
+    }
+
+    /**
+     * @param t The time
+     * @return apr_time_t as a msec
+     */
+    public static long msec(long t)
+    {
+        return t / APR_MSEC_PER_USEC;
+    }
+
+    /**
+     * number of microseconds since 00:00:00 January 1, 1970 UTC
+     * @return the current time
+     */
+    public static native long now();
+
+    /**
+     * Formats dates in the RFC822
+     * format in an efficient manner.
+     * @param t the time to convert
+     * @return the formatted date
+     */
+    public static native String rfc822(long t);
+
+    /**
+     * Formats dates in the ctime() format
+     * in an efficient manner.
+     * Unlike ANSI/ISO C ctime(), apr_ctime() does not include
+     * a \n at the end of the string.
+     * @param t the time to convert
+     * @return the formatted date
+     */
+    public static native String ctime(long t);
+
+    /**
+     * Sleep for the specified number of micro-seconds.
+     * <br><b>Warning :</b> May sleep for longer than the specified time.
+     * @param t desired amount of time to sleep.
+     */
+    public static native void sleep(long t);
+
+}
diff --git a/java/org/apache/tomcat/jni/User.java b/java/org/apache/tomcat/jni/User.java
new file mode 100644
index 0000000..20bb762
--- /dev/null
+++ b/java/org/apache/tomcat/jni/User.java
@@ -0,0 +1,133 @@
+/*
+ *  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.tomcat.jni;
+
+/** User
+ *
+ * @author Mladen Turk
+ */
+public class User {
+
+    /**
+     * Get the userid (and groupid) of the calling process
+     * This function is available only if APR_HAS_USER is defined.
+     * @param p The pool from which to allocate working space
+     * @return Returns the user id
+     * @throws Error If an error occurred
+     */
+     public static native long uidCurrent(long p)
+        throws Error;
+
+    /**
+     * Get the groupid of the calling process
+     * This function is available only if APR_HAS_USER is defined.
+     * @param p The pool from which to allocate working space
+     * @return Returns the group id
+     * @throws Error If an error occurred
+     */
+     public static native long gidCurrent(long p)
+        throws Error;
+
+
+    /**
+     * Get the userid for the specified username
+     * This function is available only if APR_HAS_USER is defined.
+     * @param username The username to lookup
+     * @param p The pool from which to allocate working space
+     * @return Returns the user id
+     * @throws Error If an error occurred
+     */
+     public static native long uid(String username, long p)
+        throws Error;
+
+    /**
+     * Get the groupid for the specified username
+     * This function is available only if APR_HAS_USER is defined.
+     * @param username The username to lookup
+     * @param p The pool from which to allocate working space
+     * @return  Returns the user's group id
+     * @throws Error If an error occurred
+     */
+     public static native long usergid(String username, long p)
+        throws Error;
+
+    /**
+     * Get the groupid for a specified group name
+     * This function is available only if APR_HAS_USER is defined.
+     * @param groupname The group name to look up
+     * @param p The pool from which to allocate working space
+     * @return  Returns the user's group id
+     * @throws Error If an error occurred
+     */
+     public static native long gid(String groupname, long p)
+        throws Error;
+
+    /**
+     * Get the user name for a specified userid
+     * This function is available only if APR_HAS_USER is defined.
+     * @param userid The userid
+     * @param p The pool from which to allocate the string
+     * @return New string containing user name
+     * @throws Error If an error occurred
+     */
+     public static native String username(long userid, long p)
+        throws Error;
+
+    /**
+     * Get the group name for a specified groupid
+     * This function is available only if APR_HAS_USER is defined.
+     * @param groupid The groupid
+     * @param p The pool from which to allocate the string
+     * @return New string containing group name
+     * @throws Error If an error occurred
+     */
+     public static native String groupname(long groupid, long p)
+        throws Error;
+
+    /**
+     * Compare two user identifiers for equality.
+     * This function is available only if APR_HAS_USER is defined.
+     * @param left One uid to test
+     * @param right Another uid to test
+     * @return APR_SUCCESS if the apr_uid_t structures identify the same user,
+     * APR_EMISMATCH if not, APR_BADARG if an apr_uid_t is invalid.
+     */
+     public static native int uidcompare(long left, long right);
+
+    /**
+     * Compare two group identifiers for equality.
+     * This function is available only if APR_HAS_USER is defined.
+     * @param left One gid to test
+     * @param right Another gid to test
+     * @return APR_SUCCESS if the apr_gid_t structures identify the same group,
+     * APR_EMISMATCH if not, APR_BADARG if an apr_gid_t is invalid.
+     */
+     public static native int gidcompare(long left, long right);
+
+    /**
+     * Get the home directory for the named user
+     * This function is available only if APR_HAS_USER is defined.
+     * @param username The named user
+     * @param p The pool from which to allocate the string
+     * @return New string containing directory name
+     * @throws Error If an error occurred
+     */
+     public static native String homepath(String username, long p)
+        throws Error;
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org