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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-net.git


The following commit(s) were added to refs/heads/master by this push:
     new 3439e4e1 Javadoc @see tags do not need to use a FQCN for classes in 
java.lang
3439e4e1 is described below

commit 3439e4e1576b74ff486a05cab6a0ddb4c0850aac
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Mon Aug 29 07:17:36 2022 -0400

    Javadoc @see tags do not need to use a FQCN for classes in java.lang
---
 .../org/apache/commons/net/ftp/FTPSClient.java     | 1828 ++++++++++----------
 .../java/org/apache/commons/net/ntp/TimeStamp.java |  936 +++++-----
 2 files changed, 1382 insertions(+), 1382 deletions(-)

diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSClient.java 
b/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
index 7f0875b8..df4de5cf 100644
--- a/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
@@ -1,914 +1,914 @@
-/*
- * 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.commons.net.ftp;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.Socket;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-import org.apache.commons.net.util.Base64;
-import org.apache.commons.net.util.SSLContextUtils;
-import org.apache.commons.net.util.SSLSocketUtils;
-import org.apache.commons.net.util.TrustManagerUtils;
-
-/**
- * FTP over SSL processing. If desired, the JVM property -Djavax.net.debug=all 
can be used to
- * see wire-level SSL details.
- *
- * Warning: the hostname is not verified against the certificate by default, 
use
- * {@link #setHostnameVerifier(HostnameVerifier)} or {@link 
#setEndpointCheckingEnabled(boolean)}
- * (on Java 1.7+) to enable verification. Verification is only performed on 
client mode connections.
- * @since 2.0
- */
-public class FTPSClient extends FTPClient {
-
-// From http://www.iana.org/assignments/port-numbers
-
-//    ftps-data   989/tcp    ftp protocol, data, over TLS/SSL
-//    ftps-data   989/udp    ftp protocol, data, over TLS/SSL
-//    ftps        990/tcp    ftp protocol, control, over TLS/SSL
-//    ftps        990/udp    ftp protocol, control, over TLS/SSL
-
-    public static final int DEFAULT_FTPS_DATA_PORT = 989;
-    public static final int DEFAULT_FTPS_PORT = 990;
-
-    /** The value that I can set in PROT command  (C = Clear, P = Protected) */
-    private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"};
-    /** Default PROT Command */
-    private static final String DEFAULT_PROT = "C";
-    /** Default secure socket protocol name, i.e. TLS */
-    private static final String DEFAULT_PROTOCOL = "TLS";
-
-    /** The AUTH (Authentication/Security Mechanism) command. */
-    private static final String CMD_AUTH = "AUTH";
-    /**  The ADAT (Authentication/Security Data) command. */
-    private static final String CMD_ADAT = "ADAT";
-    /**  The PROT (Data Channel Protection Level) command. */
-    private static final String CMD_PROT = "PROT";
-    /**  The PBSZ (Protection Buffer Size) command. */
-    private static final String CMD_PBSZ = "PBSZ";
-    /**  The MIC (Integrity Protected Command) command. */
-    private static final String CMD_MIC = "MIC";
-    /**  The CONF (Confidentiality Protected Command) command. */
-    private static final String CMD_CONF = "CONF";
-    /**  The ENC (Privacy Protected Command) command. */
-    private static final String CMD_ENC = "ENC";
-    /**  The CCC (Clear Command Channel) command. */
-    private static final String CMD_CCC = "CCC";
-
-    /** @deprecated - not used - may be removed in a future release */
-    @Deprecated
-    public static String KEYSTORE_ALGORITHM;
-    /** @deprecated - not used - may be removed in a future release */
-    @Deprecated
-    public static String TRUSTSTORE_ALGORITHM;
-    /** @deprecated - not used - may be removed in a future release */
-    @Deprecated
-    public static String PROVIDER;
-    /** @deprecated - not used - may be removed in a future release */
-    @Deprecated
-    public static String STORE_TYPE;
-    /** The security mode. (True - Implicit Mode / False - Explicit Mode) */
-    private final boolean isImplicit;
-    /** The secure socket protocol to be used, e.g. SSL/TLS. */
-    private final String protocol;
-    /** The AUTH Command value */
-    private String auth = DEFAULT_PROTOCOL;
-    /** The context object. */
-    private SSLContext context;
-    /** The socket object. */
-    private Socket plainSocket;
-    /** Controls whether a new SSL session may be established by this socket. 
Default true. */
-    private boolean isCreation = true;
-    /** The use client mode flag. */
-    private boolean isClientMode = true;
-
-    /** The need client auth flag. */
-    private boolean isNeedClientAuth;
-
-    /** The want client auth flag. */
-    private boolean isWantClientAuth;
-
-    /** The cipher suites */
-    private String[] suites;
-
-    /** The protocol versions */
-    private String[] protocols;
-
-    /** The FTPS {@link TrustManager} implementation, default validate only
-     * {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}.
-     */
-    private TrustManager trustManager = 
TrustManagerUtils.getValidateServerCertificateTrustManager();
-
-    /** The {@link KeyManager}, default null (i.e. use system default). */
-    private KeyManager keyManager;
-
-    /** The {@link HostnameVerifier} to use post-TLS, default null (i.e. no 
verification). */
-    private HostnameVerifier hostnameVerifier;
-
-    /** Use Java 1.7+ HTTPS Endpoint Identification Algorithm. */
-    private boolean tlsEndpointChecking;
-
-    /**
-     * Constructor for FTPSClient, calls {@link #FTPSClient(String, boolean)}.
-     *
-     * Sets protocol to {@link #DEFAULT_PROTOCOL} - i.e. TLS - and security 
mode to explicit (isImplicit = false)
-     */
-    public FTPSClient() {
-        this(DEFAULT_PROTOCOL, false);
-    }
-
-    /**
-     * Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
-     * Calls {@link #FTPSClient(String, boolean)}
-     * @param isImplicit The security mode (Implicit/Explicit).
-     */
-    public FTPSClient(final boolean isImplicit) {
-        this(DEFAULT_PROTOCOL, isImplicit);
-    }
-
-
-    /**
-     * Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
-     * The default TrustManager is set from {@link 
TrustManagerUtils#getValidateServerCertificateTrustManager()}
-     * @param isImplicit The security mode(Implicit/Explicit).
-     * @param context A pre-configured SSL Context
-     */
-    public FTPSClient(final boolean isImplicit, final SSLContext context) {
-        this(DEFAULT_PROTOCOL, isImplicit);
-        this.context = context;
-    }
-
-    /**
-     * Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
-     * and isImplicit {@code false}
-     * Calls {@link #FTPSClient(boolean, SSLContext)}
-     * @param context A pre-configured SSL Context
-     */
-    public FTPSClient(final SSLContext context) {
-        this(false, context);
-    }
-
-
-    /**
-     * Constructor for FTPSClient, using explict mode, calls {@link 
#FTPSClient(String, boolean)}.
-     *
-     * @param protocol the protocol to use
-     */
-    public FTPSClient(final String protocol) {
-        this(protocol, false);
-    }
-
-    /**
-     * Constructor for FTPSClient allowing specification of protocol
-     * and security mode. If isImplicit is true, the port is set to
-     * {@link #DEFAULT_FTPS_PORT} i.e. 990.
-     * The default TrustManager is set from {@link 
TrustManagerUtils#getValidateServerCertificateTrustManager()}
-     * @param protocol the protocol
-     * @param isImplicit The security mode(Implicit/Explicit).
-     */
-    public FTPSClient(final String protocol, final boolean isImplicit) {
-        this.protocol = protocol;
-        this.isImplicit = isImplicit;
-        if (isImplicit) {
-            setDefaultPort(DEFAULT_FTPS_PORT);
-        }
-    }
-
-    /**
-     * Because there are so many connect() methods,
-     * the _connectAction_() method is provided as a means of performing
-     * some action immediately after establishing a connection,
-     * rather than reimplementing all of the connect() methods.
-     * @throws IOException If it throw by _connectAction_.
-     * @see org.apache.commons.net.SocketClient#_connectAction_()
-     */
-    @Override
-    protected void _connectAction_() throws IOException {
-        // Implicit mode.
-        if (isImplicit) {
-            applySocketAttributes();
-            sslNegotiation();
-        }
-        super._connectAction_();
-        // Explicit mode.
-        if (!isImplicit) {
-            execAUTH();
-            sslNegotiation();
-        }
-    }
-
-    /**
-     * Returns a socket of the data connection.
-     * Wrapped as an {@link SSLSocket}, which carries out handshake processing.
-     * @param command The int representation of the FTP command to send.
-     * @param arg The arguments to the FTP command.
-     * If this parameter is set to null, then the command is sent with
-     * no arguments.
-     * @return corresponding to the established data connection.
-     * Null is returned if an FTP protocol error is reported at any point
-     * during the establishment and initialization of the connection.
-     * @throws IOException If there is any problem with the connection.
-     * @see FTPClient#_openDataConnection_(int, String)
-     * @deprecated (3.3) Use {@link FTPClient#_openDataConnection_(FTPCmd, 
String)} instead
-     */
-    @Override
-    // Strictly speaking this is not needed, but it works round a Clirr bug
-    // So rather than invoke the parent code, we do it here
-    @Deprecated
-    protected Socket _openDataConnection_(final int command, final String arg)
-            throws IOException {
-        return _openDataConnection_(FTPCommand.getCommand(command), arg);
-    }
-
-    /**
-     * Returns a socket of the data connection. Wrapped as an {@link 
SSLSocket}, which carries out handshake processing.
-     *
-     * @param command The textual representation of the FTP command to send.
-     * @param arg The arguments to the FTP command. If this parameter is set 
to null, then the command is sent with no
-     *        arguments.
-     * @return corresponding to the established data connection. Null is 
returned if an FTP protocol error is reported
-     *         at any point during the establishment and initialization of the 
connection.
-     * @throws IOException If there is any problem with the connection.
-     * @see FTPClient#_openDataConnection_(int, String)
-     * @since 3.2
-     */
-    @Override
-    protected Socket _openDataConnection_(final String command, final String 
arg) throws IOException {
-        final Socket socket = super._openDataConnection_(command, arg);
-        _prepareDataSocket_(socket);
-        if (socket instanceof SSLSocket) {
-            final SSLSocket sslSocket = (SSLSocket) socket;
-
-            sslSocket.setUseClientMode(isClientMode);
-            sslSocket.setEnableSessionCreation(isCreation);
-
-            // server mode
-            if (!isClientMode) {
-                sslSocket.setNeedClientAuth(isNeedClientAuth);
-                sslSocket.setWantClientAuth(isWantClientAuth);
-            }
-            if (suites != null) {
-                sslSocket.setEnabledCipherSuites(suites);
-            }
-            if (protocols != null) {
-                sslSocket.setEnabledProtocols(protocols);
-            }
-            sslSocket.startHandshake();
-        }
-
-        return socket;
-    }
-
-        /**
-         * Performs any custom initialization for a newly created SSLSocket 
(before the SSL handshake happens). Called
-         * by {@link #_openDataConnection_(int, String)} immediately after 
creating the socket. The default
-         * implementation is a no-op
-         *
-         * @param socket the socket to set up
-         * @throws IOException on error
-         * @since 3.1
-         */
-        protected void _prepareDataSocket_(final Socket socket)
-            throws IOException {
-    }
-
-    /**
-     * Check the value that can be set in PROT Command value.
-     * @param prot Data Channel Protection Level.
-     * @return True - A set point is right / False - A set point is not right
-     */
-    private boolean checkPROTValue(final String prot) {
-        for (final String element : PROT_COMMAND_VALUE)
-        {
-            if (element.equals(prot)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Create SSL socket from plain socket.
-     *
-     * @param socket
-     * @return SSL Socket
-     * @throws IOException
-     */
-    private SSLSocket createSSLSocket(final Socket socket) throws IOException {
-        if (socket != null) {
-            final SSLSocketFactory f = context.getSocketFactory();
-            return (SSLSocket) f.createSocket(socket, _hostname_, 
socket.getPort(), false);
-        }
-        return null;
-    }
-
-    /**
-     * Closes the connection to the FTP server and restores
-     * connection parameters to the default values.
-     * <p>
-     * Calls {@code setSocketFactory(null)} and {@code 
setServerSocketFactory(null)}
-     * to reset the factories that may have been changed during the session,
-     * e.g. by {@link #execPROT(String)}
-     * @throws IOException If an error occurs while disconnecting.
-     * @since 3.0
-     */
-    @Override
-    public void disconnect() throws IOException
-    {
-        super.disconnect();
-        if (plainSocket != null) {
-            plainSocket.close();
-        }
-        setSocketFactory(null);
-        setServerSocketFactory(null);
-    }
-
-    /**
-     * Send the ADAT command with the specified authentication data.
-     * @param data The data to send with the command.
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @since 3.0
-     */
-    public int execADAT(final byte[] data) throws IOException
-    {
-        if (data != null)
-        {
-            return sendCommand(CMD_ADAT, 
Base64.encodeBase64StringUnChunked(data));
-        }
-        return sendCommand(CMD_ADAT);
-    }
-
-    /**
-     * AUTH command.
-     * @throws SSLException If it server reply code not equal "234" and "334".
-     * @throws IOException If an I/O error occurs while either sending
-     * the command.
-     */
-    protected void execAUTH() throws SSLException, IOException {
-        final int replyCode = sendCommand(CMD_AUTH, auth);
-        if (FTPReply.SECURITY_MECHANISM_IS_OK == replyCode) {
-            // replyCode = 334
-            // I carry out an ADAT command.
-        } else if (FTPReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
-            throw new SSLException(getReplyString());
-        }
-    }
-
-    /**
-     * Send the AUTH command with the specified mechanism.
-     * @param mechanism The mechanism name to send with the command.
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @since 3.0
-     */
-    public int execAUTH(final String mechanism) throws IOException
-    {
-        return sendCommand(CMD_AUTH, mechanism);
-    }
-
-    /**
-     * Send the CCC command to the server.
-     * The CCC (Clear Command Channel) command causes the underlying {@link 
SSLSocket} instance  to be assigned
-     * to a plain {@link Socket} instances
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @since 3.0
-     */
-    public int execCCC() throws IOException
-    {
-        final int repCode = sendCommand(CMD_CCC);
-// This will be performed by sendCommand(String, String)
-//        if (FTPReply.isPositiveCompletion(repCode)) {
-//            _socket_.close();
-//            _socket_ = plainSocket;
-//            _controlInput_ = new BufferedReader(
-//                new InputStreamReader(
-//                    _socket_.getInputStream(), getControlEncoding()));
-//            _controlOutput_ = new BufferedWriter(
-//                new OutputStreamWriter(
-//                    _socket_.getOutputStream(), getControlEncoding()));
-//        }
-        return repCode;
-    }
-
-    /**
-     * Send the CONF command with the specified data.
-     * @param data The data to send with the command.
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @since 3.0
-     */
-    public int execCONF(final byte[] data) throws IOException
-    {
-        if (data != null)
-        {
-            return sendCommand(CMD_CONF, 
Base64.encodeBase64StringUnChunked(data));
-        }
-        return sendCommand(CMD_CONF, ""); // perhaps "=" or just 
sendCommand(String)?
-    }
-
-    /**
-     * Send the ENC command with the specified data.
-     * @param data The data to send with the command.
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @since 3.0
-     */
-    public int execENC(final byte[] data) throws IOException
-    {
-        if (data != null)
-        {
-            return sendCommand(CMD_ENC, 
Base64.encodeBase64StringUnChunked(data));
-        }
-        return sendCommand(CMD_ENC, ""); // perhaps "=" or just 
sendCommand(String)?
-    }
-
-    /**
-     * Send the MIC command with the specified data.
-     * @param data The data to send with the command.
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @since 3.0
-     */
-    public int execMIC(final byte[] data) throws IOException
-    {
-        if (data != null)
-        {
-            return sendCommand(CMD_MIC, 
Base64.encodeBase64StringUnChunked(data));
-        }
-        return sendCommand(CMD_MIC, ""); // perhaps "=" or just 
sendCommand(String)?
-    }
-
-    /**
-     * PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
-     * @param pbsz Protection Buffer Size.
-     * @throws SSLException If the server reply code does not equal "200".
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @see #parsePBSZ(long)
-     */
-    public void execPBSZ(final long pbsz) throws SSLException, IOException {
-        if (pbsz < 0 || 4294967295L < pbsz) { // 32-bit unsigned number
-            throw new IllegalArgumentException();
-        }
-        final int status = sendCommand(CMD_PBSZ, String.valueOf(pbsz));
-        if (FTPReply.COMMAND_OK != status) {
-            throw new SSLException(getReplyString());
-        }
-    }
-
-    /**
-     * PROT command.
-     * <ul>
-     * <li>C - Clear</li>
-     * <li>S - Safe(SSL protocol only)</li>
-     * <li>E - Confidential(SSL protocol only)</li>
-     * <li>P - Private</li>
-     * </ul>
-     * <b>N.B.</b> the method calls
-     *  {@link #setSocketFactory(javax.net.SocketFactory)} and
-     *  {@link #setServerSocketFactory(javax.net.ServerSocketFactory)}
-     *
-     * @param prot Data Channel Protection Level, if {@code null}, use {@link 
#DEFAULT_PROT}.
-     * @throws SSLException If the server reply code does not equal  {@code 
200}.
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     */
-    public void execPROT(String prot) throws SSLException, IOException {
-        if (prot == null) {
-            prot = DEFAULT_PROT;
-        }
-        if (!checkPROTValue(prot)) {
-            throw new IllegalArgumentException();
-        }
-        if (FTPReply.COMMAND_OK != sendCommand(CMD_PROT, prot)) {
-            throw new SSLException(getReplyString());
-        }
-        if (DEFAULT_PROT.equals(prot)) {
-            setSocketFactory(null);
-            setServerSocketFactory(null);
-        } else {
-            setSocketFactory(new FTPSSocketFactory(context));
-            setServerSocketFactory(new FTPSServerSocketFactory(context));
-            initSslContext();
-        }
-    }
-
-    /**
-     * Extract the data from a reply with a prefix, e.g. PBSZ=1234 => 1234
-     * @param prefix the prefix to find
-     * @param reply where to find the prefix
-     * @return the remainder of the string after the prefix, or null if the 
prefix was not present.
-     */
-    private String extractPrefixedData(final String prefix, final String 
reply) {
-        final int idx = reply.indexOf(prefix);
-        if (idx == -1) {
-            return null;
-        }
-        // N.B. Cannot use trim before substring as leading space would affect 
the offset.
-        return reply.substring(idx+prefix.length()).trim();
-    }
-
-    /**
-     * Return AUTH command use value.
-     * @return AUTH command use value.
-     */
-    public String getAuthValue() {
-        return this.auth;
-    }
-
-    /**
-     * Returns the names of the cipher suites which could be enabled
-     * for use on this connection.
-     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns null.
-     * @return An array of cipher suite names, or <code>null</code>
-     */
-    public String[] getEnabledCipherSuites() {
-        if (_socket_ instanceof SSLSocket) {
-            return ((SSLSocket)_socket_).getEnabledCipherSuites();
-        }
-        return null;
-    }
-
-    /**
-     * Returns the names of the protocol versions which are currently
-     * enabled for use on this connection.
-     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns null.
-     * @return An array of protocols, or <code>null</code>
-     */
-    public String[] getEnabledProtocols() {
-        if (_socket_ instanceof SSLSocket) {
-            return ((SSLSocket)_socket_).getEnabledProtocols();
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if new SSL sessions may be established by this socket.
-     * When the underlying {@link Socket} instance is not SSL-enabled (i.e. an
-     * instance of {@link SSLSocket} with {@link SSLSocket}{@link 
#getEnableSessionCreation()}) enabled,
-     * this returns False.
-     * @return true - Indicates that sessions may be created;
-     * this is the default.
-     * false - indicates that an existing session must be resumed.
-     */
-    public boolean getEnableSessionCreation() {
-        if (_socket_ instanceof SSLSocket) {
-            return ((SSLSocket)_socket_).getEnableSessionCreation();
-        }
-        return false;
-    }
-
-    /**
-     * Get the currently configured {@link HostnameVerifier}.
-     * The verifier is only used on client mode connections.
-     * @return A HostnameVerifier instance.
-     * @since 3.4
-     */
-    public HostnameVerifier getHostnameVerifier()
-    {
-        return hostnameVerifier;
-    }
-
-    /**
-     * Gets the {@link KeyManager} instance.
-     *
-     * @return The {@link KeyManager} instance
-     */
-    private KeyManager getKeyManager() {
-        return keyManager;
-    }
-
-    /**
-     * Returns true if the socket will require client authentication.
-     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns false.
-     * @return true - If the server mode socket should request
-     * that the client authenticate itself.
-     */
-    public boolean getNeedClientAuth() {
-        if (_socket_ instanceof SSLSocket) {
-            return ((SSLSocket)_socket_).getNeedClientAuth();
-        }
-        return false;
-    }
-
-    /**
-     * Get the currently configured {@link TrustManager}.
-     *
-     * @return A TrustManager instance.
-     */
-    public TrustManager getTrustManager() {
-        return trustManager;
-    }
-
-    /**
-     * Returns true if the socket is set to use client mode
-     * in its first handshake.
-     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns false.
-     * @return true - If the socket should start its first handshake
-     * in "client" mode.
-     */
-    public boolean getUseClientMode() {
-        if (_socket_ instanceof SSLSocket) {
-            return ((SSLSocket)_socket_).getUseClientMode();
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the socket will request client authentication.
-     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns false.
-     * @return true - If the server mode socket should request
-     * that the client authenticate itself.
-     */
-    public boolean getWantClientAuth() {
-        if (_socket_ instanceof SSLSocket) {
-            return ((SSLSocket)_socket_).getWantClientAuth();
-        }
-        return false;
-    }
-
-    /**
-     * Performs a lazy init of the SSL context
-     * @throws IOException
-     */
-    private void initSslContext() throws IOException {
-        if (context == null) {
-            context = SSLContextUtils.createSSLContext(protocol, 
getKeyManager(), getTrustManager());
-        }
-    }
-
-    /**
-     * Return whether or not endpoint identification using the HTTPS algorithm
-     * on Java 1.7+ is enabled. The default behavior is for this to be 
disabled.
-     *
-     * This check is only performed on client mode connections.
-     *
-     * @return True if enabled, false if not.
-     * @since 3.4
-     */
-    public boolean isEndpointCheckingEnabled()
-    {
-        return tlsEndpointChecking;
-    }
-
-    /**
-     * Parses the given ADAT response line and base64-decodes the data.
-     * @param reply The ADAT reply to parse.
-     * @return the data in the reply, base64-decoded.
-     * @since 3.0
-     */
-    public byte[] parseADATReply(final String reply)
-    {
-        if (reply == null) {
-            return null;
-        }
-        return Base64.decodeBase64(extractPrefixedData("ADAT=", reply));
-    }
-
-    /**
-     * PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
-     * Issues the command and parses the response to return the negotiated 
value.
-     *
-     * @param pbsz Protection Buffer Size.
-     * @throws SSLException If the server reply code does not equal "200".
-     * @throws IOException If an I/O error occurs while sending
-     * the command.
-     * @return the negotiated value.
-     * @see #execPBSZ(long)
-     * @since 3.0
-     */
-    public long parsePBSZ(final long pbsz) throws SSLException, IOException {
-        execPBSZ(pbsz);
-        long minvalue = pbsz;
-        final String remainder = extractPrefixedData("PBSZ=", 
getReplyString());
-        if (remainder != null) {
-            final long replysz = Long.parseLong(remainder);
-            if (replysz < minvalue) {
-                minvalue = replysz;
-            }
-        }
-        return minvalue;
-    }
-
-    /**
-     * Send an FTP command.
-     * A successful CCC (Clear Command Channel) command causes the underlying 
{@link SSLSocket}
-     * instance to be assigned to a plain {@link Socket}
-     * @param command The FTP command.
-     * @return server reply.
-     * @throws IOException If an I/O error occurs while sending the command.
-     * @throws SSLException if a CCC command fails
-     * @see org.apache.commons.net.ftp.FTP#sendCommand(java.lang.String)
-     */
-    // Would like to remove this method, but that will break any existing 
clients that are using CCC
-    @Override
-    public int sendCommand(final String command, final String args) throws 
IOException {
-        final int repCode = super.sendCommand(command, args);
-        /* If CCC is issued, restore socket i/o streams to unsecured versions 
*/
-        if (CMD_CCC.equals(command)) {
-            if (FTPReply.COMMAND_OK != repCode) {
-                throw new SSLException(getReplyString());
-            }
-            _socket_.close();
-            _socket_ = plainSocket;
-            _controlInput_ = new BufferedReader(
-                new InputStreamReader(
-                    _socket_ .getInputStream(), getControlEncoding()));
-            _controlOutput_ = new BufferedWriter(
-                new OutputStreamWriter(
-                    _socket_.getOutputStream(), getControlEncoding()));
-        }
-        return repCode;
-    }
-
-    /**
-     * Set AUTH command use value.
-     * This processing is done before connected processing.
-     * @param auth AUTH command use value.
-     */
-    public void setAuthValue(final String auth) {
-        this.auth = auth;
-    }
-
-    /**
-     * Controls which particular cipher suites are enabled for use on this
-     * connection. Called before server negotiation.
-     * @param cipherSuites The cipher suites.
-     */
-    public void setEnabledCipherSuites(final String[] cipherSuites) {
-        suites = cipherSuites.clone();
-    }
-
-    /**
-     * Controls which particular protocol versions are enabled for use on this
-     * connection. I perform setting before a server negotiation.
-     * @param protocolVersions The protocol versions.
-     */
-    public void setEnabledProtocols(final String[] protocolVersions) {
-        protocols = protocolVersions.clone();
-    }
-
-    /**
-     * Controls whether a new SSL session may be established by this socket.
-     * @param isCreation The established socket flag.
-     */
-    public void setEnabledSessionCreation(final boolean isCreation) {
-        this.isCreation = isCreation;
-    }
-
-    /**
-     * Automatic endpoint identification checking using the HTTPS algorithm
-     * is supported on Java 1.7+. The default behavior is for this to be 
disabled.
-     *
-     * This check is only performed on client mode connections.
-     *
-     * @param enable Enable automatic endpoint identification checking using 
the HTTPS algorithm on Java 1.7+.
-     * @since 3.4
-     */
-    public void setEndpointCheckingEnabled(final boolean enable)
-    {
-        tlsEndpointChecking = enable;
-    }
-
-    /**
-     * Override the default {@link HostnameVerifier} to use.
-     * The verifier is only used on client mode connections.
-     * @param newHostnameVerifier The HostnameVerifier implementation to set 
or <code>null</code> to disable.
-     * @since 3.4
-     */
-    public void setHostnameVerifier(final HostnameVerifier newHostnameVerifier)
-    {
-        hostnameVerifier = newHostnameVerifier;
-    }
-
-    /**
-    * Set a {@link KeyManager} to use
-    *
-    * @param keyManager The KeyManager implementation to set.
-    * @see org.apache.commons.net.util.KeyManagerUtils
-    */
-    public void setKeyManager(final KeyManager keyManager) {
-        this.keyManager = keyManager;
-    }
-
-    /**
-     * Configures the socket to require client authentication.
-     * @param isNeedClientAuth The need client auth flag.
-     */
-    public void setNeedClientAuth(final boolean isNeedClientAuth) {
-        this.isNeedClientAuth = isNeedClientAuth;
-    }
-
-    // DEPRECATED - for API compatibility only - DO NOT USE
-
-    /**
-     * Override the default {@link TrustManager} to use; if set to {@code 
null},
-     * the default TrustManager from the JVM will be used.
-     *
-     * @param trustManager The TrustManager implementation to set, may be 
{@code null}
-     * @see org.apache.commons.net.util.TrustManagerUtils
-     */
-    public void setTrustManager(final TrustManager trustManager) {
-        this.trustManager = trustManager;
-    }
-
-    /**
-     * Configures the socket to use client (or server) mode in its first
-     * handshake.
-     * @param isClientMode The use client mode flag.
-     */
-    public void setUseClientMode(final boolean isClientMode) {
-        this.isClientMode = isClientMode;
-    }
-
-    /**
-     * Configures the socket to request client authentication,
-     * but only if such a request is appropriate to the cipher
-     * suite negotiated.
-     * @param isWantClientAuth The want client auth flag.
-     */
-    public void setWantClientAuth(final boolean isWantClientAuth) {
-        this.isWantClientAuth = isWantClientAuth;
-    }
-
-    /**
-     * SSL/TLS negotiation. Acquires an SSL socket of a control
-     * connection and carries out handshake processing.
-     * @throws IOException If server negotiation fails
-     */
-    protected void sslNegotiation() throws IOException {
-        plainSocket = _socket_;
-        initSslContext();
-        final SSLSocket socket = createSSLSocket(_socket_);
-        socket.setEnableSessionCreation(isCreation);
-        socket.setUseClientMode(isClientMode);
-
-        // client mode
-        if (isClientMode) {
-            if (tlsEndpointChecking) {
-                SSLSocketUtils.enableEndpointNameVerification(socket);
-            }
-        } else { // server mode
-            socket.setNeedClientAuth(isNeedClientAuth);
-            socket.setWantClientAuth(isWantClientAuth);
-        }
-
-        if (protocols != null) {
-            socket.setEnabledProtocols(protocols);
-        }
-        if (suites != null) {
-            socket.setEnabledCipherSuites(suites);
-        }
-        socket.startHandshake();
-
-        // TODO the following setup appears to duplicate that in the super 
class methods
-        _socket_ = socket;
-        _controlInput_ = new BufferedReader(new InputStreamReader(
-                socket .getInputStream(), getControlEncoding()));
-        _controlOutput_ = new BufferedWriter(new OutputStreamWriter(
-                socket.getOutputStream(), getControlEncoding()));
-
-        if (isClientMode && (hostnameVerifier != null &&
-            !hostnameVerifier.verify(_hostname_, socket.getSession()))) {
-            throw new SSLHandshakeException("Hostname doesn't match 
certificate");
-        }
-    }
-
-}
-/* kate: indent-width 4; replace-tabs on; */
+/*
+ * 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.commons.net.ftp;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import org.apache.commons.net.util.Base64;
+import org.apache.commons.net.util.SSLContextUtils;
+import org.apache.commons.net.util.SSLSocketUtils;
+import org.apache.commons.net.util.TrustManagerUtils;
+
+/**
+ * FTP over SSL processing. If desired, the JVM property -Djavax.net.debug=all 
can be used to
+ * see wire-level SSL details.
+ *
+ * Warning: the hostname is not verified against the certificate by default, 
use
+ * {@link #setHostnameVerifier(HostnameVerifier)} or {@link 
#setEndpointCheckingEnabled(boolean)}
+ * (on Java 1.7+) to enable verification. Verification is only performed on 
client mode connections.
+ * @since 2.0
+ */
+public class FTPSClient extends FTPClient {
+
+// From http://www.iana.org/assignments/port-numbers
+
+//    ftps-data   989/tcp    ftp protocol, data, over TLS/SSL
+//    ftps-data   989/udp    ftp protocol, data, over TLS/SSL
+//    ftps        990/tcp    ftp protocol, control, over TLS/SSL
+//    ftps        990/udp    ftp protocol, control, over TLS/SSL
+
+    public static final int DEFAULT_FTPS_DATA_PORT = 989;
+    public static final int DEFAULT_FTPS_PORT = 990;
+
+    /** The value that I can set in PROT command  (C = Clear, P = Protected) */
+    private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"};
+    /** Default PROT Command */
+    private static final String DEFAULT_PROT = "C";
+    /** Default secure socket protocol name, i.e. TLS */
+    private static final String DEFAULT_PROTOCOL = "TLS";
+
+    /** The AUTH (Authentication/Security Mechanism) command. */
+    private static final String CMD_AUTH = "AUTH";
+    /**  The ADAT (Authentication/Security Data) command. */
+    private static final String CMD_ADAT = "ADAT";
+    /**  The PROT (Data Channel Protection Level) command. */
+    private static final String CMD_PROT = "PROT";
+    /**  The PBSZ (Protection Buffer Size) command. */
+    private static final String CMD_PBSZ = "PBSZ";
+    /**  The MIC (Integrity Protected Command) command. */
+    private static final String CMD_MIC = "MIC";
+    /**  The CONF (Confidentiality Protected Command) command. */
+    private static final String CMD_CONF = "CONF";
+    /**  The ENC (Privacy Protected Command) command. */
+    private static final String CMD_ENC = "ENC";
+    /**  The CCC (Clear Command Channel) command. */
+    private static final String CMD_CCC = "CCC";
+
+    /** @deprecated - not used - may be removed in a future release */
+    @Deprecated
+    public static String KEYSTORE_ALGORITHM;
+    /** @deprecated - not used - may be removed in a future release */
+    @Deprecated
+    public static String TRUSTSTORE_ALGORITHM;
+    /** @deprecated - not used - may be removed in a future release */
+    @Deprecated
+    public static String PROVIDER;
+    /** @deprecated - not used - may be removed in a future release */
+    @Deprecated
+    public static String STORE_TYPE;
+    /** The security mode. (True - Implicit Mode / False - Explicit Mode) */
+    private final boolean isImplicit;
+    /** The secure socket protocol to be used, e.g. SSL/TLS. */
+    private final String protocol;
+    /** The AUTH Command value */
+    private String auth = DEFAULT_PROTOCOL;
+    /** The context object. */
+    private SSLContext context;
+    /** The socket object. */
+    private Socket plainSocket;
+    /** Controls whether a new SSL session may be established by this socket. 
Default true. */
+    private boolean isCreation = true;
+    /** The use client mode flag. */
+    private boolean isClientMode = true;
+
+    /** The need client auth flag. */
+    private boolean isNeedClientAuth;
+
+    /** The want client auth flag. */
+    private boolean isWantClientAuth;
+
+    /** The cipher suites */
+    private String[] suites;
+
+    /** The protocol versions */
+    private String[] protocols;
+
+    /** The FTPS {@link TrustManager} implementation, default validate only
+     * {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}.
+     */
+    private TrustManager trustManager = 
TrustManagerUtils.getValidateServerCertificateTrustManager();
+
+    /** The {@link KeyManager}, default null (i.e. use system default). */
+    private KeyManager keyManager;
+
+    /** The {@link HostnameVerifier} to use post-TLS, default null (i.e. no 
verification). */
+    private HostnameVerifier hostnameVerifier;
+
+    /** Use Java 1.7+ HTTPS Endpoint Identification Algorithm. */
+    private boolean tlsEndpointChecking;
+
+    /**
+     * Constructor for FTPSClient, calls {@link #FTPSClient(String, boolean)}.
+     *
+     * Sets protocol to {@link #DEFAULT_PROTOCOL} - i.e. TLS - and security 
mode to explicit (isImplicit = false)
+     */
+    public FTPSClient() {
+        this(DEFAULT_PROTOCOL, false);
+    }
+
+    /**
+     * Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
+     * Calls {@link #FTPSClient(String, boolean)}
+     * @param isImplicit The security mode (Implicit/Explicit).
+     */
+    public FTPSClient(final boolean isImplicit) {
+        this(DEFAULT_PROTOCOL, isImplicit);
+    }
+
+
+    /**
+     * Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
+     * The default TrustManager is set from {@link 
TrustManagerUtils#getValidateServerCertificateTrustManager()}
+     * @param isImplicit The security mode(Implicit/Explicit).
+     * @param context A pre-configured SSL Context
+     */
+    public FTPSClient(final boolean isImplicit, final SSLContext context) {
+        this(DEFAULT_PROTOCOL, isImplicit);
+        this.context = context;
+    }
+
+    /**
+     * Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
+     * and isImplicit {@code false}
+     * Calls {@link #FTPSClient(boolean, SSLContext)}
+     * @param context A pre-configured SSL Context
+     */
+    public FTPSClient(final SSLContext context) {
+        this(false, context);
+    }
+
+
+    /**
+     * Constructor for FTPSClient, using explict mode, calls {@link 
#FTPSClient(String, boolean)}.
+     *
+     * @param protocol the protocol to use
+     */
+    public FTPSClient(final String protocol) {
+        this(protocol, false);
+    }
+
+    /**
+     * Constructor for FTPSClient allowing specification of protocol
+     * and security mode. If isImplicit is true, the port is set to
+     * {@link #DEFAULT_FTPS_PORT} i.e. 990.
+     * The default TrustManager is set from {@link 
TrustManagerUtils#getValidateServerCertificateTrustManager()}
+     * @param protocol the protocol
+     * @param isImplicit The security mode(Implicit/Explicit).
+     */
+    public FTPSClient(final String protocol, final boolean isImplicit) {
+        this.protocol = protocol;
+        this.isImplicit = isImplicit;
+        if (isImplicit) {
+            setDefaultPort(DEFAULT_FTPS_PORT);
+        }
+    }
+
+    /**
+     * Because there are so many connect() methods,
+     * the _connectAction_() method is provided as a means of performing
+     * some action immediately after establishing a connection,
+     * rather than reimplementing all of the connect() methods.
+     * @throws IOException If it throw by _connectAction_.
+     * @see org.apache.commons.net.SocketClient#_connectAction_()
+     */
+    @Override
+    protected void _connectAction_() throws IOException {
+        // Implicit mode.
+        if (isImplicit) {
+            applySocketAttributes();
+            sslNegotiation();
+        }
+        super._connectAction_();
+        // Explicit mode.
+        if (!isImplicit) {
+            execAUTH();
+            sslNegotiation();
+        }
+    }
+
+    /**
+     * Returns a socket of the data connection.
+     * Wrapped as an {@link SSLSocket}, which carries out handshake processing.
+     * @param command The int representation of the FTP command to send.
+     * @param arg The arguments to the FTP command.
+     * If this parameter is set to null, then the command is sent with
+     * no arguments.
+     * @return corresponding to the established data connection.
+     * Null is returned if an FTP protocol error is reported at any point
+     * during the establishment and initialization of the connection.
+     * @throws IOException If there is any problem with the connection.
+     * @see FTPClient#_openDataConnection_(int, String)
+     * @deprecated (3.3) Use {@link FTPClient#_openDataConnection_(FTPCmd, 
String)} instead
+     */
+    @Override
+    // Strictly speaking this is not needed, but it works round a Clirr bug
+    // So rather than invoke the parent code, we do it here
+    @Deprecated
+    protected Socket _openDataConnection_(final int command, final String arg)
+            throws IOException {
+        return _openDataConnection_(FTPCommand.getCommand(command), arg);
+    }
+
+    /**
+     * Returns a socket of the data connection. Wrapped as an {@link 
SSLSocket}, which carries out handshake processing.
+     *
+     * @param command The textual representation of the FTP command to send.
+     * @param arg The arguments to the FTP command. If this parameter is set 
to null, then the command is sent with no
+     *        arguments.
+     * @return corresponding to the established data connection. Null is 
returned if an FTP protocol error is reported
+     *         at any point during the establishment and initialization of the 
connection.
+     * @throws IOException If there is any problem with the connection.
+     * @see FTPClient#_openDataConnection_(int, String)
+     * @since 3.2
+     */
+    @Override
+    protected Socket _openDataConnection_(final String command, final String 
arg) throws IOException {
+        final Socket socket = super._openDataConnection_(command, arg);
+        _prepareDataSocket_(socket);
+        if (socket instanceof SSLSocket) {
+            final SSLSocket sslSocket = (SSLSocket) socket;
+
+            sslSocket.setUseClientMode(isClientMode);
+            sslSocket.setEnableSessionCreation(isCreation);
+
+            // server mode
+            if (!isClientMode) {
+                sslSocket.setNeedClientAuth(isNeedClientAuth);
+                sslSocket.setWantClientAuth(isWantClientAuth);
+            }
+            if (suites != null) {
+                sslSocket.setEnabledCipherSuites(suites);
+            }
+            if (protocols != null) {
+                sslSocket.setEnabledProtocols(protocols);
+            }
+            sslSocket.startHandshake();
+        }
+
+        return socket;
+    }
+
+        /**
+         * Performs any custom initialization for a newly created SSLSocket 
(before the SSL handshake happens). Called
+         * by {@link #_openDataConnection_(int, String)} immediately after 
creating the socket. The default
+         * implementation is a no-op
+         *
+         * @param socket the socket to set up
+         * @throws IOException on error
+         * @since 3.1
+         */
+        protected void _prepareDataSocket_(final Socket socket)
+            throws IOException {
+    }
+
+    /**
+     * Check the value that can be set in PROT Command value.
+     * @param prot Data Channel Protection Level.
+     * @return True - A set point is right / False - A set point is not right
+     */
+    private boolean checkPROTValue(final String prot) {
+        for (final String element : PROT_COMMAND_VALUE)
+        {
+            if (element.equals(prot)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Create SSL socket from plain socket.
+     *
+     * @param socket
+     * @return SSL Socket
+     * @throws IOException
+     */
+    private SSLSocket createSSLSocket(final Socket socket) throws IOException {
+        if (socket != null) {
+            final SSLSocketFactory f = context.getSocketFactory();
+            return (SSLSocket) f.createSocket(socket, _hostname_, 
socket.getPort(), false);
+        }
+        return null;
+    }
+
+    /**
+     * Closes the connection to the FTP server and restores
+     * connection parameters to the default values.
+     * <p>
+     * Calls {@code setSocketFactory(null)} and {@code 
setServerSocketFactory(null)}
+     * to reset the factories that may have been changed during the session,
+     * e.g. by {@link #execPROT(String)}
+     * @throws IOException If an error occurs while disconnecting.
+     * @since 3.0
+     */
+    @Override
+    public void disconnect() throws IOException
+    {
+        super.disconnect();
+        if (plainSocket != null) {
+            plainSocket.close();
+        }
+        setSocketFactory(null);
+        setServerSocketFactory(null);
+    }
+
+    /**
+     * Send the ADAT command with the specified authentication data.
+     * @param data The data to send with the command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @since 3.0
+     */
+    public int execADAT(final byte[] data) throws IOException
+    {
+        if (data != null)
+        {
+            return sendCommand(CMD_ADAT, 
Base64.encodeBase64StringUnChunked(data));
+        }
+        return sendCommand(CMD_ADAT);
+    }
+
+    /**
+     * AUTH command.
+     * @throws SSLException If it server reply code not equal "234" and "334".
+     * @throws IOException If an I/O error occurs while either sending
+     * the command.
+     */
+    protected void execAUTH() throws SSLException, IOException {
+        final int replyCode = sendCommand(CMD_AUTH, auth);
+        if (FTPReply.SECURITY_MECHANISM_IS_OK == replyCode) {
+            // replyCode = 334
+            // I carry out an ADAT command.
+        } else if (FTPReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
+            throw new SSLException(getReplyString());
+        }
+    }
+
+    /**
+     * Send the AUTH command with the specified mechanism.
+     * @param mechanism The mechanism name to send with the command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @since 3.0
+     */
+    public int execAUTH(final String mechanism) throws IOException
+    {
+        return sendCommand(CMD_AUTH, mechanism);
+    }
+
+    /**
+     * Send the CCC command to the server.
+     * The CCC (Clear Command Channel) command causes the underlying {@link 
SSLSocket} instance  to be assigned
+     * to a plain {@link Socket} instances
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @since 3.0
+     */
+    public int execCCC() throws IOException
+    {
+        final int repCode = sendCommand(CMD_CCC);
+// This will be performed by sendCommand(String, String)
+//        if (FTPReply.isPositiveCompletion(repCode)) {
+//            _socket_.close();
+//            _socket_ = plainSocket;
+//            _controlInput_ = new BufferedReader(
+//                new InputStreamReader(
+//                    _socket_.getInputStream(), getControlEncoding()));
+//            _controlOutput_ = new BufferedWriter(
+//                new OutputStreamWriter(
+//                    _socket_.getOutputStream(), getControlEncoding()));
+//        }
+        return repCode;
+    }
+
+    /**
+     * Send the CONF command with the specified data.
+     * @param data The data to send with the command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @since 3.0
+     */
+    public int execCONF(final byte[] data) throws IOException
+    {
+        if (data != null)
+        {
+            return sendCommand(CMD_CONF, 
Base64.encodeBase64StringUnChunked(data));
+        }
+        return sendCommand(CMD_CONF, ""); // perhaps "=" or just 
sendCommand(String)?
+    }
+
+    /**
+     * Send the ENC command with the specified data.
+     * @param data The data to send with the command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @since 3.0
+     */
+    public int execENC(final byte[] data) throws IOException
+    {
+        if (data != null)
+        {
+            return sendCommand(CMD_ENC, 
Base64.encodeBase64StringUnChunked(data));
+        }
+        return sendCommand(CMD_ENC, ""); // perhaps "=" or just 
sendCommand(String)?
+    }
+
+    /**
+     * Send the MIC command with the specified data.
+     * @param data The data to send with the command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @since 3.0
+     */
+    public int execMIC(final byte[] data) throws IOException
+    {
+        if (data != null)
+        {
+            return sendCommand(CMD_MIC, 
Base64.encodeBase64StringUnChunked(data));
+        }
+        return sendCommand(CMD_MIC, ""); // perhaps "=" or just 
sendCommand(String)?
+    }
+
+    /**
+     * PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
+     * @param pbsz Protection Buffer Size.
+     * @throws SSLException If the server reply code does not equal "200".
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @see #parsePBSZ(long)
+     */
+    public void execPBSZ(final long pbsz) throws SSLException, IOException {
+        if (pbsz < 0 || 4294967295L < pbsz) { // 32-bit unsigned number
+            throw new IllegalArgumentException();
+        }
+        final int status = sendCommand(CMD_PBSZ, String.valueOf(pbsz));
+        if (FTPReply.COMMAND_OK != status) {
+            throw new SSLException(getReplyString());
+        }
+    }
+
+    /**
+     * PROT command.
+     * <ul>
+     * <li>C - Clear</li>
+     * <li>S - Safe(SSL protocol only)</li>
+     * <li>E - Confidential(SSL protocol only)</li>
+     * <li>P - Private</li>
+     * </ul>
+     * <b>N.B.</b> the method calls
+     *  {@link #setSocketFactory(javax.net.SocketFactory)} and
+     *  {@link #setServerSocketFactory(javax.net.ServerSocketFactory)}
+     *
+     * @param prot Data Channel Protection Level, if {@code null}, use {@link 
#DEFAULT_PROT}.
+     * @throws SSLException If the server reply code does not equal  {@code 
200}.
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     */
+    public void execPROT(String prot) throws SSLException, IOException {
+        if (prot == null) {
+            prot = DEFAULT_PROT;
+        }
+        if (!checkPROTValue(prot)) {
+            throw new IllegalArgumentException();
+        }
+        if (FTPReply.COMMAND_OK != sendCommand(CMD_PROT, prot)) {
+            throw new SSLException(getReplyString());
+        }
+        if (DEFAULT_PROT.equals(prot)) {
+            setSocketFactory(null);
+            setServerSocketFactory(null);
+        } else {
+            setSocketFactory(new FTPSSocketFactory(context));
+            setServerSocketFactory(new FTPSServerSocketFactory(context));
+            initSslContext();
+        }
+    }
+
+    /**
+     * Extract the data from a reply with a prefix, e.g. PBSZ=1234 => 1234
+     * @param prefix the prefix to find
+     * @param reply where to find the prefix
+     * @return the remainder of the string after the prefix, or null if the 
prefix was not present.
+     */
+    private String extractPrefixedData(final String prefix, final String 
reply) {
+        final int idx = reply.indexOf(prefix);
+        if (idx == -1) {
+            return null;
+        }
+        // N.B. Cannot use trim before substring as leading space would affect 
the offset.
+        return reply.substring(idx+prefix.length()).trim();
+    }
+
+    /**
+     * Return AUTH command use value.
+     * @return AUTH command use value.
+     */
+    public String getAuthValue() {
+        return this.auth;
+    }
+
+    /**
+     * Returns the names of the cipher suites which could be enabled
+     * for use on this connection.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns null.
+     * @return An array of cipher suite names, or <code>null</code>
+     */
+    public String[] getEnabledCipherSuites() {
+        if (_socket_ instanceof SSLSocket) {
+            return ((SSLSocket)_socket_).getEnabledCipherSuites();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the names of the protocol versions which are currently
+     * enabled for use on this connection.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns null.
+     * @return An array of protocols, or <code>null</code>
+     */
+    public String[] getEnabledProtocols() {
+        if (_socket_ instanceof SSLSocket) {
+            return ((SSLSocket)_socket_).getEnabledProtocols();
+        }
+        return null;
+    }
+
+    /**
+     * Returns true if new SSL sessions may be established by this socket.
+     * When the underlying {@link Socket} instance is not SSL-enabled (i.e. an
+     * instance of {@link SSLSocket} with {@link SSLSocket}{@link 
#getEnableSessionCreation()}) enabled,
+     * this returns False.
+     * @return true - Indicates that sessions may be created;
+     * this is the default.
+     * false - indicates that an existing session must be resumed.
+     */
+    public boolean getEnableSessionCreation() {
+        if (_socket_ instanceof SSLSocket) {
+            return ((SSLSocket)_socket_).getEnableSessionCreation();
+        }
+        return false;
+    }
+
+    /**
+     * Get the currently configured {@link HostnameVerifier}.
+     * The verifier is only used on client mode connections.
+     * @return A HostnameVerifier instance.
+     * @since 3.4
+     */
+    public HostnameVerifier getHostnameVerifier()
+    {
+        return hostnameVerifier;
+    }
+
+    /**
+     * Gets the {@link KeyManager} instance.
+     *
+     * @return The {@link KeyManager} instance
+     */
+    private KeyManager getKeyManager() {
+        return keyManager;
+    }
+
+    /**
+     * Returns true if the socket will require client authentication.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns false.
+     * @return true - If the server mode socket should request
+     * that the client authenticate itself.
+     */
+    public boolean getNeedClientAuth() {
+        if (_socket_ instanceof SSLSocket) {
+            return ((SSLSocket)_socket_).getNeedClientAuth();
+        }
+        return false;
+    }
+
+    /**
+     * Get the currently configured {@link TrustManager}.
+     *
+     * @return A TrustManager instance.
+     */
+    public TrustManager getTrustManager() {
+        return trustManager;
+    }
+
+    /**
+     * Returns true if the socket is set to use client mode
+     * in its first handshake.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns false.
+     * @return true - If the socket should start its first handshake
+     * in "client" mode.
+     */
+    public boolean getUseClientMode() {
+        if (_socket_ instanceof SSLSocket) {
+            return ((SSLSocket)_socket_).getUseClientMode();
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the socket will request client authentication.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} 
instance, returns false.
+     * @return true - If the server mode socket should request
+     * that the client authenticate itself.
+     */
+    public boolean getWantClientAuth() {
+        if (_socket_ instanceof SSLSocket) {
+            return ((SSLSocket)_socket_).getWantClientAuth();
+        }
+        return false;
+    }
+
+    /**
+     * Performs a lazy init of the SSL context
+     * @throws IOException
+     */
+    private void initSslContext() throws IOException {
+        if (context == null) {
+            context = SSLContextUtils.createSSLContext(protocol, 
getKeyManager(), getTrustManager());
+        }
+    }
+
+    /**
+     * Return whether or not endpoint identification using the HTTPS algorithm
+     * on Java 1.7+ is enabled. The default behavior is for this to be 
disabled.
+     *
+     * This check is only performed on client mode connections.
+     *
+     * @return True if enabled, false if not.
+     * @since 3.4
+     */
+    public boolean isEndpointCheckingEnabled()
+    {
+        return tlsEndpointChecking;
+    }
+
+    /**
+     * Parses the given ADAT response line and base64-decodes the data.
+     * @param reply The ADAT reply to parse.
+     * @return the data in the reply, base64-decoded.
+     * @since 3.0
+     */
+    public byte[] parseADATReply(final String reply)
+    {
+        if (reply == null) {
+            return null;
+        }
+        return Base64.decodeBase64(extractPrefixedData("ADAT=", reply));
+    }
+
+    /**
+     * PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
+     * Issues the command and parses the response to return the negotiated 
value.
+     *
+     * @param pbsz Protection Buffer Size.
+     * @throws SSLException If the server reply code does not equal "200".
+     * @throws IOException If an I/O error occurs while sending
+     * the command.
+     * @return the negotiated value.
+     * @see #execPBSZ(long)
+     * @since 3.0
+     */
+    public long parsePBSZ(final long pbsz) throws SSLException, IOException {
+        execPBSZ(pbsz);
+        long minvalue = pbsz;
+        final String remainder = extractPrefixedData("PBSZ=", 
getReplyString());
+        if (remainder != null) {
+            final long replysz = Long.parseLong(remainder);
+            if (replysz < minvalue) {
+                minvalue = replysz;
+            }
+        }
+        return minvalue;
+    }
+
+    /**
+     * Send an FTP command.
+     * A successful CCC (Clear Command Channel) command causes the underlying 
{@link SSLSocket}
+     * instance to be assigned to a plain {@link Socket}
+     * @param command The FTP command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending the command.
+     * @throws SSLException if a CCC command fails
+     * @see org.apache.commons.net.ftp.FTP#sendCommand(String)
+     */
+    // Would like to remove this method, but that will break any existing 
clients that are using CCC
+    @Override
+    public int sendCommand(final String command, final String args) throws 
IOException {
+        final int repCode = super.sendCommand(command, args);
+        /* If CCC is issued, restore socket i/o streams to unsecured versions 
*/
+        if (CMD_CCC.equals(command)) {
+            if (FTPReply.COMMAND_OK != repCode) {
+                throw new SSLException(getReplyString());
+            }
+            _socket_.close();
+            _socket_ = plainSocket;
+            _controlInput_ = new BufferedReader(
+                new InputStreamReader(
+                    _socket_ .getInputStream(), getControlEncoding()));
+            _controlOutput_ = new BufferedWriter(
+                new OutputStreamWriter(
+                    _socket_.getOutputStream(), getControlEncoding()));
+        }
+        return repCode;
+    }
+
+    /**
+     * Set AUTH command use value.
+     * This processing is done before connected processing.
+     * @param auth AUTH command use value.
+     */
+    public void setAuthValue(final String auth) {
+        this.auth = auth;
+    }
+
+    /**
+     * Controls which particular cipher suites are enabled for use on this
+     * connection. Called before server negotiation.
+     * @param cipherSuites The cipher suites.
+     */
+    public void setEnabledCipherSuites(final String[] cipherSuites) {
+        suites = cipherSuites.clone();
+    }
+
+    /**
+     * Controls which particular protocol versions are enabled for use on this
+     * connection. I perform setting before a server negotiation.
+     * @param protocolVersions The protocol versions.
+     */
+    public void setEnabledProtocols(final String[] protocolVersions) {
+        protocols = protocolVersions.clone();
+    }
+
+    /**
+     * Controls whether a new SSL session may be established by this socket.
+     * @param isCreation The established socket flag.
+     */
+    public void setEnabledSessionCreation(final boolean isCreation) {
+        this.isCreation = isCreation;
+    }
+
+    /**
+     * Automatic endpoint identification checking using the HTTPS algorithm
+     * is supported on Java 1.7+. The default behavior is for this to be 
disabled.
+     *
+     * This check is only performed on client mode connections.
+     *
+     * @param enable Enable automatic endpoint identification checking using 
the HTTPS algorithm on Java 1.7+.
+     * @since 3.4
+     */
+    public void setEndpointCheckingEnabled(final boolean enable)
+    {
+        tlsEndpointChecking = enable;
+    }
+
+    /**
+     * Override the default {@link HostnameVerifier} to use.
+     * The verifier is only used on client mode connections.
+     * @param newHostnameVerifier The HostnameVerifier implementation to set 
or <code>null</code> to disable.
+     * @since 3.4
+     */
+    public void setHostnameVerifier(final HostnameVerifier newHostnameVerifier)
+    {
+        hostnameVerifier = newHostnameVerifier;
+    }
+
+    /**
+    * Set a {@link KeyManager} to use
+    *
+    * @param keyManager The KeyManager implementation to set.
+    * @see org.apache.commons.net.util.KeyManagerUtils
+    */
+    public void setKeyManager(final KeyManager keyManager) {
+        this.keyManager = keyManager;
+    }
+
+    /**
+     * Configures the socket to require client authentication.
+     * @param isNeedClientAuth The need client auth flag.
+     */
+    public void setNeedClientAuth(final boolean isNeedClientAuth) {
+        this.isNeedClientAuth = isNeedClientAuth;
+    }
+
+    // DEPRECATED - for API compatibility only - DO NOT USE
+
+    /**
+     * Override the default {@link TrustManager} to use; if set to {@code 
null},
+     * the default TrustManager from the JVM will be used.
+     *
+     * @param trustManager The TrustManager implementation to set, may be 
{@code null}
+     * @see org.apache.commons.net.util.TrustManagerUtils
+     */
+    public void setTrustManager(final TrustManager trustManager) {
+        this.trustManager = trustManager;
+    }
+
+    /**
+     * Configures the socket to use client (or server) mode in its first
+     * handshake.
+     * @param isClientMode The use client mode flag.
+     */
+    public void setUseClientMode(final boolean isClientMode) {
+        this.isClientMode = isClientMode;
+    }
+
+    /**
+     * Configures the socket to request client authentication,
+     * but only if such a request is appropriate to the cipher
+     * suite negotiated.
+     * @param isWantClientAuth The want client auth flag.
+     */
+    public void setWantClientAuth(final boolean isWantClientAuth) {
+        this.isWantClientAuth = isWantClientAuth;
+    }
+
+    /**
+     * SSL/TLS negotiation. Acquires an SSL socket of a control
+     * connection and carries out handshake processing.
+     * @throws IOException If server negotiation fails
+     */
+    protected void sslNegotiation() throws IOException {
+        plainSocket = _socket_;
+        initSslContext();
+        final SSLSocket socket = createSSLSocket(_socket_);
+        socket.setEnableSessionCreation(isCreation);
+        socket.setUseClientMode(isClientMode);
+
+        // client mode
+        if (isClientMode) {
+            if (tlsEndpointChecking) {
+                SSLSocketUtils.enableEndpointNameVerification(socket);
+            }
+        } else { // server mode
+            socket.setNeedClientAuth(isNeedClientAuth);
+            socket.setWantClientAuth(isWantClientAuth);
+        }
+
+        if (protocols != null) {
+            socket.setEnabledProtocols(protocols);
+        }
+        if (suites != null) {
+            socket.setEnabledCipherSuites(suites);
+        }
+        socket.startHandshake();
+
+        // TODO the following setup appears to duplicate that in the super 
class methods
+        _socket_ = socket;
+        _controlInput_ = new BufferedReader(new InputStreamReader(
+                socket .getInputStream(), getControlEncoding()));
+        _controlOutput_ = new BufferedWriter(new OutputStreamWriter(
+                socket.getOutputStream(), getControlEncoding()));
+
+        if (isClientMode && (hostnameVerifier != null &&
+            !hostnameVerifier.verify(_hostname_, socket.getSession()))) {
+            throw new SSLHandshakeException("Hostname doesn't match 
certificate");
+        }
+    }
+
+}
+/* kate: indent-width 4; replace-tabs on; */
diff --git a/src/main/java/org/apache/commons/net/ntp/TimeStamp.java 
b/src/main/java/org/apache/commons/net/ntp/TimeStamp.java
index 20a10755..f9aa8b95 100644
--- a/src/main/java/org/apache/commons/net/ntp/TimeStamp.java
+++ b/src/main/java/org/apache/commons/net/ntp/TimeStamp.java
@@ -1,468 +1,468 @@
-package org.apache.commons.net.ntp;
-/*
- * 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.
- */
-
-
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * TimeStamp class represents the Network Time Protocol (NTP) timestamp
- * as defined in RFC-1305 and SNTP (RFC-2030). It is represented as a
- * 64-bit unsigned fixed-point number in seconds relative to 0-hour on 
1-January-1900.
- * The 32-bit low-order bits are the fractional seconds whose precision is
- * about 200 picoseconds. Assumes overflow date when date passes MAX_LONG
- * and reverts back to 0 is 2036 and not 1900. Test for most significant
- * bit: if MSB=0 then 2036 basis is used otherwise 1900 if MSB=1.
- * <p>
- * Methods exist to convert NTP timestamps to and from the equivalent Java date
- * representation, which is the number of milliseconds since the standard base
- * time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
- * </p>
- *
- * @see java.util.Date
- */
-public class TimeStamp implements java.io.Serializable, Comparable<TimeStamp>
-{
-    private static final long serialVersionUID = 8139806907588338737L;
-
-    /**
-     * Baseline NTP time if bit-0=0 is 7-Feb-2036 @ 06:28:16 UTC
-     */
-    protected static final long msb0baseTime = 2085978496000L;
-
-    /**
-     * Baseline NTP time if bit-0=1 is 1-Jan-1900 @ 01:00:00 UTC
-     */
-    protected static final long msb1baseTime = -2208988800000L;
-
-    /**
-     * Default NTP date string format. E.g. Fri, Sep 12 2003 21:06:23.860.
-     * See <code>java.text.SimpleDateFormat</code> for code descriptions.
-     */
-    public static final String NTP_DATE_FORMAT = "EEE, MMM dd yyyy 
HH:mm:ss.SSS";
-
-    /**
-     * Left-pad 8-character hex string with 0's
-     *
-     * @param buf - StringBuilder which is appended with leading 0's.
-     * @param l - a long.
-     */
-    private static void appendHexString(final StringBuilder buf, final long l)
-    {
-        final String s = Long.toHexString(l);
-        for (int i = s.length(); i < 8; i++) {
-            buf.append('0');
-        }
-        buf.append(s);
-    }
-
-    /**
-     * Convert NTP timestamp hexstring (e.g. "c1a089bd.fc904f6d") to the NTP
-     * 64-bit unsigned fixed-point number.
-     * @param hexString the string to convert
-     *
-     * @return NTP 64-bit timestamp value.
-     * @throws NumberFormatException - if the string does not contain a 
parsable timestamp.
-     */
-    protected static long decodeNtpHexString(final String hexString)
-            throws NumberFormatException
-    {
-        if (hexString == null) {
-            throw new NumberFormatException("null");
-        }
-        final int ind = hexString.indexOf('.');
-        if (ind == -1) {
-            if (hexString.isEmpty()) {
-                return 0;
-            }
-            return Long.parseLong(hexString, 16) << 32; // no decimal
-        }
-
-        return Long.parseLong(hexString.substring(0, ind), 16) << 32 |
-                Long.parseLong(hexString.substring(ind + 1), 16);
-    }
-    /**
-     * Constructs a NTP timestamp object and initializes it so that
-     * it represents the time at which it was allocated, measured to the
-     * nearest millisecond.
-     * @return NTP timestamp object set to the current time.
-     * @see     java.lang.System#currentTimeMillis()
-     */
-    public static TimeStamp getCurrentTime()
-    {
-        return getNtpTime(System.currentTimeMillis());
-    }
-
-    // initialization of static time bases
-    /*
-    static {
-        TimeZone utcZone = TimeZone.getTimeZone("UTC");
-        Calendar calendar = Calendar.getInstance(utcZone);
-        calendar.set(1900, Calendar.JANUARY, 1, 0, 0, 0);
-        calendar.set(Calendar.MILLISECOND, 0);
-        msb1baseTime = calendar.getTime().getTime();
-        calendar.set(2036, Calendar.FEBRUARY, 7, 6, 28, 16);
-        calendar.set(Calendar.MILLISECOND, 0);
-        msb0baseTime = calendar.getTime().getTime();
-    }
-    */
-
-    /**
-     * Helper method to convert Java time to NTP timestamp object.
-     * Note that Java time (milliseconds) by definition has less precision
-     * then NTP time (picoseconds) so converting Ntptime to Javatime and back
-     * to Ntptime loses precision. For example, Tue, Dec 17 2002 09:07:24.810
-     * is represented by a single Java-based time value of f22cd1fc8a, but its
-     * NTP equivalent are all values from c1a9ae1c.cf5c28f5 to 
c1a9ae1c.cf9db22c.
-     * @param   dateMillis   the milliseconds since January 1, 1970, 00:00:00 
GMT.
-     * @return NTP timestamp object at the specified date.
-     */
-    public static TimeStamp getNtpTime(final long dateMillis)
-    {
-        return new TimeStamp(toNtpTime(dateMillis));
-    }
-
-    /**
-     * Converts 64-bit NTP timestamp to Java standard time.
-     *
-     * Note that java time (milliseconds) by definition has less precision
-     * then NTP time (picoseconds) so converting NTP timestamp to java time 
and back
-     * to NTP timestamp loses precision. For example, Tue, Dec 17 2002 
09:07:24.810 EST
-     * is represented by a single Java-based time value of f22cd1fc8a, but its
-     * NTP equivalent are all values ranging from c1a9ae1c.cf5c28f5 to 
c1a9ae1c.cf9db22c.
-     *
-     * @param ntpTimeValue the input time
-     * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
-     * represented by this NTP timestamp value.
-     */
-    public static long getTime(final long ntpTimeValue)
-    {
-        final long seconds = (ntpTimeValue >>> 32) & 0xffffffffL;     // 
high-order 32-bits
-        long fraction = ntpTimeValue & 0xffffffffL;             // low-order 
32-bits
-
-        // Use round-off on fractional part to preserve going to lower 
precision
-        fraction = Math.round(1000D * fraction / 0x100000000L);
-
-        /*
-         * If the most significant bit (MSB) on the seconds field is set we use
-         * a different time base. The following text is a quote from RFC-2030 
(SNTP v4):
-         *
-         *  If bit 0 is set, the UTC time is in the range 1968-2036 and UTC 
time
-         *  is reckoned from 0h 0m 0s UTC on 1 January 1900. If bit 0 is not 
set,
-         *  the time is in the range 2036-2104 and UTC time is reckoned from
-         *  6h 28m 16s UTC on 7 February 2036.
-         */
-        final long msb = seconds & 0x80000000L;
-        if (msb == 0) {
-            // use base: 7-Feb-2036 @ 06:28:16 UTC
-            return msb0baseTime + (seconds * 1000) + fraction;
-        }
-        // use base: 1-Jan-1900 @ 01:00:00 UTC
-        return msb1baseTime + (seconds * 1000) + fraction;
-    }
-
-    /**
-     * Parses the string argument as a NTP hexidecimal timestamp 
representation string
-     * (e.g. "c1a089bd.fc904f6d").
-     *
-     * @param s - hexstring.
-     * @return the Timestamp represented by the argument in hexidecimal.
-     * @throws NumberFormatException - if the string does not contain a 
parsable timestamp.
-     */
-    public static TimeStamp parseNtpString(final String s)
-            throws NumberFormatException
-    {
-        return new TimeStamp(decodeNtpHexString(s));
-    }
-
-    /**
-     * Converts Java time to 64-bit NTP time representation.
-     *
-     * @param millis Java time
-     * @return NTP timestamp representation of Java time value.
-     */
-    protected static long toNtpTime(final long millis)
-    {
-        final boolean useBase1 = millis < msb0baseTime;    // time < Feb-2036
-        final long baseTimeMillis;
-        if (useBase1) {
-            baseTimeMillis = millis - msb1baseTime; // dates <= Feb-2036
-        } else {
-            // if base0 needed for dates >= Feb-2036
-            baseTimeMillis = millis - msb0baseTime;
-        }
-
-        long seconds = baseTimeMillis / 1000;
-        final long fraction = ((baseTimeMillis % 1000) * 0x100000000L) / 1000;
-
-        if (useBase1) {
-            seconds |= 0x80000000L; // set high-order bit if msb1baseTime 1900 
used
-        }
-
-        return seconds << 32 | fraction;
-    }
-
-    /**
-     * Converts 64-bit NTP timestamp value to a <code>String</code>.
-     * The NTP timestamp value is represented as hex string with
-     * seconds separated by fractional seconds by a decimal point;
-     * e.g. c1a089bd.fc904f6d == Tue, Dec 10 2002 10:41:49.986
-     * @param ntpTime the 64 bit timestamp
-     *
-     * @return NTP timestamp 64-bit long value as hex string with seconds
-     * separated by fractional seconds.
-     */
-    public static String toString(final long ntpTime)
-    {
-        final StringBuilder buf = new StringBuilder();
-        // high-order second bits (32..63) as hexstring
-        appendHexString(buf, (ntpTime >>> 32) & 0xffffffffL);
-
-        // low-order fractional seconds bits (0..31) as hexstring
-        buf.append('.');
-        appendHexString(buf, ntpTime & 0xffffffffL);
-
-        return buf.toString();
-    }
-
-    /**
-     * NTP timestamp value: 64-bit unsigned fixed-point number as defined in 
RFC-1305
-     * with high-order 32 bits the seconds field and the low-order 32-bits the
-     * fractional field.
-     */
-    private final long ntpTime;
-
-    private DateFormat simpleFormatter;
-
-    private DateFormat utcFormatter;
-
-    /**
-     * Constructs a newly allocated NTP timestamp object
-     * that represents the Java Date argument.
-     *
-     * @param d - the Date to be represented by the Timestamp object.
-     */
-    public TimeStamp(final Date d)
-    {
-        ntpTime = d == null ? 0 : toNtpTime(d.getTime());
-    }
-
-    /**
-     * Constructs a newly allocated NTP timestamp object
-     * that represents the native 64-bit long argument.
-     * @param ntpTime the timestamp
-     */
-    public TimeStamp(final long ntpTime)
-    {
-        this.ntpTime = ntpTime;
-    }
-
-    /**
-     * Constructs a newly allocated NTP timestamp object
-     * that represents the value represented by the string
-     * in hexdecimal form (e.g. "c1a089bd.fc904f6d").
-     * @param hexStamp the hex timestamp
-     *
-     * @throws NumberFormatException - if the string does not contain a 
parsable timestamp.
-     */
-    public TimeStamp(final String hexStamp) throws NumberFormatException
-    {
-        ntpTime = decodeNtpHexString(hexStamp);
-    }
-
-    /**
-     * Compares two Timestamps numerically.
-     *
-     * @param   anotherTimeStamp - the <code>TimeStamp</code> to be compared.
-     * @return  the value <code>0</code> if the argument TimeStamp is equal to
-     *          this TimeStamp; a value less than <code>0</code> if this 
TimeStamp
-     *          is numerically less than the TimeStamp argument; and a
-     *          value greater than <code>0</code> if this TimeStamp is
-     *          numerically greater than the TimeStamp argument
-     *          (signed comparison).
-     */
-    @Override
-    public int compareTo(final TimeStamp anotherTimeStamp)
-    {
-        final long thisVal = this.ntpTime;
-        final long anotherVal = anotherTimeStamp.ntpTime;
-        return (Long.compare(thisVal, anotherVal));
-    }
-
-    /**
-     * Compares this object against the specified object.
-     * The result is <code>true</code> if and only if the argument is
-     * not <code>null</code> and is a <code>Long</code> object that
-     * contains the same <code>long</code> value as this object.
-     *
-     * @param   obj   the object to compare with.
-     * @return  <code>true</code> if the objects are the same;
-     *          <code>false</code> otherwise.
-     */
-    @Override
-    public boolean equals(final Object obj)
-    {
-        if (obj instanceof TimeStamp) {
-            return ntpTime == ((TimeStamp) obj).ntpValue();
-        }
-        return false;
-    }
-
-    /**
-     * Converts NTP timestamp to Java Date object.
-     *
-     * @return NTP Timestamp in Java Date
-     */
-    public Date getDate()
-    {
-        return new Date(getTime(ntpTime));
-    }
-
-    /**
-     * Returns low-order 32-bits representing the fractional seconds.
-     *
-     * @return fractional seconds represented by this NTP timestamp.
-     */
-    public long getFraction()
-    {
-        return ntpTime & 0xffffffffL;
-    }
-
-    /**
-     * Returns high-order 32-bits representing the seconds of this NTP 
timestamp.
-     *
-     * @return seconds represented by this NTP timestamp.
-     */
-    public long getSeconds()
-    {
-        return (ntpTime >>> 32) & 0xffffffffL;
-    }
-
-    /**
-     * Converts NTP timestamp to Java standard time.
-     *
-     * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
-     * represented by this NTP timestamp value.
-     */
-    public long getTime()
-    {
-        return getTime(ntpTime);
-    }
-
-    /**
-     * Computes a hashcode for this Timestamp. The result is the exclusive
-     * OR of the two halves of the primitive <code>long</code> value
-     * represented by this <code>TimeStamp</code> object. That is, the hashcode
-     * is the value of the expression:
-     * <blockquote><pre>
-     * {@code (int)(this.ntpValue()^(this.ntpValue() >>> 32))}
-     * </pre></blockquote>
-     *
-     * @return  a hash code value for this object.
-     */
-    @Override
-    public int hashCode()
-    {
-        return (int) (ntpTime ^ (ntpTime >>> 32));
-    }
-
-    /**
-     * Returns the value of this Timestamp as a long value.
-     *
-     * @return the 64-bit long value represented by this object.
-     */
-    public long ntpValue()
-    {
-        return ntpTime;
-    }
-
-    /**
-     * Converts this <code>TimeStamp</code> object to a <code>String</code>
-     * of the form:
-     * <blockquote><pre>
-     * EEE, MMM dd yyyy HH:mm:ss.SSS</pre></blockquote>
-     * See java.text.SimpleDataFormat for code descriptions.
-     *
-     * @return  a string representation of this date.
-     */
-    public String toDateString()
-    {
-        if (simpleFormatter == null) {
-            simpleFormatter = new SimpleDateFormat(NTP_DATE_FORMAT, Locale.US);
-            simpleFormatter.setTimeZone(TimeZone.getDefault());
-        }
-        final Date ntpDate = getDate();
-        return simpleFormatter.format(ntpDate);
-    }
-
-    /**
-     * Converts this <code>TimeStamp</code> object to a <code>String</code>.
-     * The NTP timestamp 64-bit long value is represented as hex string with
-     * seconds separated by fractional seconds by a decimal point;
-     * e.g. c1a089bd.fc904f6d == Tue, Dec 10 2002 10:41:49.986
-     *
-     * @return NTP timestamp 64-bit long value as hex string with seconds
-     * separated by fractional seconds.
-     */
-    @Override
-    public String toString()
-    {
-        return toString(ntpTime);
-    }
-
-    /**
-     * Converts this <code>TimeStamp</code> object to a <code>String</code>
-     * of the form:
-     * <blockquote><pre>
-     * EEE, MMM dd yyyy HH:mm:ss.SSS UTC</pre></blockquote>
-     * See java.text.SimpleDataFormat for code descriptions.
-     *
-     * @return  a string representation of this date in UTC.
-     */
-    public String toUTCString()
-    {
-        if (utcFormatter == null) {
-            utcFormatter = new SimpleDateFormat(NTP_DATE_FORMAT + " 'UTC'",
-                    Locale.US);
-            utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
-        }
-        final Date ntpDate = getDate();
-        return utcFormatter.format(ntpDate);
-    }
-
-    /*
-        Serialization is unnecessary for this class.
-        Reject attempts to do so until such time as the Serializable attribute 
can be dropped.
-     */
-
-    private void writeObject(final java.io.ObjectOutputStream out) throws 
IOException
-    {
-        throw new UnsupportedOperationException("Serialization is not 
supported");
-    }
-
-    private void readObject(final java.io.ObjectInputStream in) throws 
IOException, ClassNotFoundException
-    {
-        throw new UnsupportedOperationException("Serialization is not 
supported");
-    }
-
-}
+package org.apache.commons.net.ntp;
+/*
+ * 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.
+ */
+
+
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * TimeStamp class represents the Network Time Protocol (NTP) timestamp
+ * as defined in RFC-1305 and SNTP (RFC-2030). It is represented as a
+ * 64-bit unsigned fixed-point number in seconds relative to 0-hour on 
1-January-1900.
+ * The 32-bit low-order bits are the fractional seconds whose precision is
+ * about 200 picoseconds. Assumes overflow date when date passes MAX_LONG
+ * and reverts back to 0 is 2036 and not 1900. Test for most significant
+ * bit: if MSB=0 then 2036 basis is used otherwise 1900 if MSB=1.
+ * <p>
+ * Methods exist to convert NTP timestamps to and from the equivalent Java date
+ * representation, which is the number of milliseconds since the standard base
+ * time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
+ * </p>
+ *
+ * @see java.util.Date
+ */
+public class TimeStamp implements java.io.Serializable, Comparable<TimeStamp>
+{
+    private static final long serialVersionUID = 8139806907588338737L;
+
+    /**
+     * Baseline NTP time if bit-0=0 is 7-Feb-2036 @ 06:28:16 UTC
+     */
+    protected static final long msb0baseTime = 2085978496000L;
+
+    /**
+     * Baseline NTP time if bit-0=1 is 1-Jan-1900 @ 01:00:00 UTC
+     */
+    protected static final long msb1baseTime = -2208988800000L;
+
+    /**
+     * Default NTP date string format. E.g. Fri, Sep 12 2003 21:06:23.860.
+     * See <code>java.text.SimpleDateFormat</code> for code descriptions.
+     */
+    public static final String NTP_DATE_FORMAT = "EEE, MMM dd yyyy 
HH:mm:ss.SSS";
+
+    /**
+     * Left-pad 8-character hex string with 0's
+     *
+     * @param buf - StringBuilder which is appended with leading 0's.
+     * @param l - a long.
+     */
+    private static void appendHexString(final StringBuilder buf, final long l)
+    {
+        final String s = Long.toHexString(l);
+        for (int i = s.length(); i < 8; i++) {
+            buf.append('0');
+        }
+        buf.append(s);
+    }
+
+    /**
+     * Convert NTP timestamp hexstring (e.g. "c1a089bd.fc904f6d") to the NTP
+     * 64-bit unsigned fixed-point number.
+     * @param hexString the string to convert
+     *
+     * @return NTP 64-bit timestamp value.
+     * @throws NumberFormatException - if the string does not contain a 
parsable timestamp.
+     */
+    protected static long decodeNtpHexString(final String hexString)
+            throws NumberFormatException
+    {
+        if (hexString == null) {
+            throw new NumberFormatException("null");
+        }
+        final int ind = hexString.indexOf('.');
+        if (ind == -1) {
+            if (hexString.isEmpty()) {
+                return 0;
+            }
+            return Long.parseLong(hexString, 16) << 32; // no decimal
+        }
+
+        return Long.parseLong(hexString.substring(0, ind), 16) << 32 |
+                Long.parseLong(hexString.substring(ind + 1), 16);
+    }
+    /**
+     * Constructs a NTP timestamp object and initializes it so that
+     * it represents the time at which it was allocated, measured to the
+     * nearest millisecond.
+     * @return NTP timestamp object set to the current time.
+     * @see     System#currentTimeMillis()
+     */
+    public static TimeStamp getCurrentTime()
+    {
+        return getNtpTime(System.currentTimeMillis());
+    }
+
+    // initialization of static time bases
+    /*
+    static {
+        TimeZone utcZone = TimeZone.getTimeZone("UTC");
+        Calendar calendar = Calendar.getInstance(utcZone);
+        calendar.set(1900, Calendar.JANUARY, 1, 0, 0, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        msb1baseTime = calendar.getTime().getTime();
+        calendar.set(2036, Calendar.FEBRUARY, 7, 6, 28, 16);
+        calendar.set(Calendar.MILLISECOND, 0);
+        msb0baseTime = calendar.getTime().getTime();
+    }
+    */
+
+    /**
+     * Helper method to convert Java time to NTP timestamp object.
+     * Note that Java time (milliseconds) by definition has less precision
+     * then NTP time (picoseconds) so converting Ntptime to Javatime and back
+     * to Ntptime loses precision. For example, Tue, Dec 17 2002 09:07:24.810
+     * is represented by a single Java-based time value of f22cd1fc8a, but its
+     * NTP equivalent are all values from c1a9ae1c.cf5c28f5 to 
c1a9ae1c.cf9db22c.
+     * @param   dateMillis   the milliseconds since January 1, 1970, 00:00:00 
GMT.
+     * @return NTP timestamp object at the specified date.
+     */
+    public static TimeStamp getNtpTime(final long dateMillis)
+    {
+        return new TimeStamp(toNtpTime(dateMillis));
+    }
+
+    /**
+     * Converts 64-bit NTP timestamp to Java standard time.
+     *
+     * Note that java time (milliseconds) by definition has less precision
+     * then NTP time (picoseconds) so converting NTP timestamp to java time 
and back
+     * to NTP timestamp loses precision. For example, Tue, Dec 17 2002 
09:07:24.810 EST
+     * is represented by a single Java-based time value of f22cd1fc8a, but its
+     * NTP equivalent are all values ranging from c1a9ae1c.cf5c28f5 to 
c1a9ae1c.cf9db22c.
+     *
+     * @param ntpTimeValue the input time
+     * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
+     * represented by this NTP timestamp value.
+     */
+    public static long getTime(final long ntpTimeValue)
+    {
+        final long seconds = (ntpTimeValue >>> 32) & 0xffffffffL;     // 
high-order 32-bits
+        long fraction = ntpTimeValue & 0xffffffffL;             // low-order 
32-bits
+
+        // Use round-off on fractional part to preserve going to lower 
precision
+        fraction = Math.round(1000D * fraction / 0x100000000L);
+
+        /*
+         * If the most significant bit (MSB) on the seconds field is set we use
+         * a different time base. The following text is a quote from RFC-2030 
(SNTP v4):
+         *
+         *  If bit 0 is set, the UTC time is in the range 1968-2036 and UTC 
time
+         *  is reckoned from 0h 0m 0s UTC on 1 January 1900. If bit 0 is not 
set,
+         *  the time is in the range 2036-2104 and UTC time is reckoned from
+         *  6h 28m 16s UTC on 7 February 2036.
+         */
+        final long msb = seconds & 0x80000000L;
+        if (msb == 0) {
+            // use base: 7-Feb-2036 @ 06:28:16 UTC
+            return msb0baseTime + (seconds * 1000) + fraction;
+        }
+        // use base: 1-Jan-1900 @ 01:00:00 UTC
+        return msb1baseTime + (seconds * 1000) + fraction;
+    }
+
+    /**
+     * Parses the string argument as a NTP hexidecimal timestamp 
representation string
+     * (e.g. "c1a089bd.fc904f6d").
+     *
+     * @param s - hexstring.
+     * @return the Timestamp represented by the argument in hexidecimal.
+     * @throws NumberFormatException - if the string does not contain a 
parsable timestamp.
+     */
+    public static TimeStamp parseNtpString(final String s)
+            throws NumberFormatException
+    {
+        return new TimeStamp(decodeNtpHexString(s));
+    }
+
+    /**
+     * Converts Java time to 64-bit NTP time representation.
+     *
+     * @param millis Java time
+     * @return NTP timestamp representation of Java time value.
+     */
+    protected static long toNtpTime(final long millis)
+    {
+        final boolean useBase1 = millis < msb0baseTime;    // time < Feb-2036
+        final long baseTimeMillis;
+        if (useBase1) {
+            baseTimeMillis = millis - msb1baseTime; // dates <= Feb-2036
+        } else {
+            // if base0 needed for dates >= Feb-2036
+            baseTimeMillis = millis - msb0baseTime;
+        }
+
+        long seconds = baseTimeMillis / 1000;
+        final long fraction = ((baseTimeMillis % 1000) * 0x100000000L) / 1000;
+
+        if (useBase1) {
+            seconds |= 0x80000000L; // set high-order bit if msb1baseTime 1900 
used
+        }
+
+        return seconds << 32 | fraction;
+    }
+
+    /**
+     * Converts 64-bit NTP timestamp value to a <code>String</code>.
+     * The NTP timestamp value is represented as hex string with
+     * seconds separated by fractional seconds by a decimal point;
+     * e.g. c1a089bd.fc904f6d == Tue, Dec 10 2002 10:41:49.986
+     * @param ntpTime the 64 bit timestamp
+     *
+     * @return NTP timestamp 64-bit long value as hex string with seconds
+     * separated by fractional seconds.
+     */
+    public static String toString(final long ntpTime)
+    {
+        final StringBuilder buf = new StringBuilder();
+        // high-order second bits (32..63) as hexstring
+        appendHexString(buf, (ntpTime >>> 32) & 0xffffffffL);
+
+        // low-order fractional seconds bits (0..31) as hexstring
+        buf.append('.');
+        appendHexString(buf, ntpTime & 0xffffffffL);
+
+        return buf.toString();
+    }
+
+    /**
+     * NTP timestamp value: 64-bit unsigned fixed-point number as defined in 
RFC-1305
+     * with high-order 32 bits the seconds field and the low-order 32-bits the
+     * fractional field.
+     */
+    private final long ntpTime;
+
+    private DateFormat simpleFormatter;
+
+    private DateFormat utcFormatter;
+
+    /**
+     * Constructs a newly allocated NTP timestamp object
+     * that represents the Java Date argument.
+     *
+     * @param d - the Date to be represented by the Timestamp object.
+     */
+    public TimeStamp(final Date d)
+    {
+        ntpTime = d == null ? 0 : toNtpTime(d.getTime());
+    }
+
+    /**
+     * Constructs a newly allocated NTP timestamp object
+     * that represents the native 64-bit long argument.
+     * @param ntpTime the timestamp
+     */
+    public TimeStamp(final long ntpTime)
+    {
+        this.ntpTime = ntpTime;
+    }
+
+    /**
+     * Constructs a newly allocated NTP timestamp object
+     * that represents the value represented by the string
+     * in hexdecimal form (e.g. "c1a089bd.fc904f6d").
+     * @param hexStamp the hex timestamp
+     *
+     * @throws NumberFormatException - if the string does not contain a 
parsable timestamp.
+     */
+    public TimeStamp(final String hexStamp) throws NumberFormatException
+    {
+        ntpTime = decodeNtpHexString(hexStamp);
+    }
+
+    /**
+     * Compares two Timestamps numerically.
+     *
+     * @param   anotherTimeStamp - the <code>TimeStamp</code> to be compared.
+     * @return  the value <code>0</code> if the argument TimeStamp is equal to
+     *          this TimeStamp; a value less than <code>0</code> if this 
TimeStamp
+     *          is numerically less than the TimeStamp argument; and a
+     *          value greater than <code>0</code> if this TimeStamp is
+     *          numerically greater than the TimeStamp argument
+     *          (signed comparison).
+     */
+    @Override
+    public int compareTo(final TimeStamp anotherTimeStamp)
+    {
+        final long thisVal = this.ntpTime;
+        final long anotherVal = anotherTimeStamp.ntpTime;
+        return (Long.compare(thisVal, anotherVal));
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is <code>true</code> if and only if the argument is
+     * not <code>null</code> and is a <code>Long</code> object that
+     * contains the same <code>long</code> value as this object.
+     *
+     * @param   obj   the object to compare with.
+     * @return  <code>true</code> if the objects are the same;
+     *          <code>false</code> otherwise.
+     */
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (obj instanceof TimeStamp) {
+            return ntpTime == ((TimeStamp) obj).ntpValue();
+        }
+        return false;
+    }
+
+    /**
+     * Converts NTP timestamp to Java Date object.
+     *
+     * @return NTP Timestamp in Java Date
+     */
+    public Date getDate()
+    {
+        return new Date(getTime(ntpTime));
+    }
+
+    /**
+     * Returns low-order 32-bits representing the fractional seconds.
+     *
+     * @return fractional seconds represented by this NTP timestamp.
+     */
+    public long getFraction()
+    {
+        return ntpTime & 0xffffffffL;
+    }
+
+    /**
+     * Returns high-order 32-bits representing the seconds of this NTP 
timestamp.
+     *
+     * @return seconds represented by this NTP timestamp.
+     */
+    public long getSeconds()
+    {
+        return (ntpTime >>> 32) & 0xffffffffL;
+    }
+
+    /**
+     * Converts NTP timestamp to Java standard time.
+     *
+     * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
+     * represented by this NTP timestamp value.
+     */
+    public long getTime()
+    {
+        return getTime(ntpTime);
+    }
+
+    /**
+     * Computes a hashcode for this Timestamp. The result is the exclusive
+     * OR of the two halves of the primitive <code>long</code> value
+     * represented by this <code>TimeStamp</code> object. That is, the hashcode
+     * is the value of the expression:
+     * <blockquote><pre>
+     * {@code (int)(this.ntpValue()^(this.ntpValue() >>> 32))}
+     * </pre></blockquote>
+     *
+     * @return  a hash code value for this object.
+     */
+    @Override
+    public int hashCode()
+    {
+        return (int) (ntpTime ^ (ntpTime >>> 32));
+    }
+
+    /**
+     * Returns the value of this Timestamp as a long value.
+     *
+     * @return the 64-bit long value represented by this object.
+     */
+    public long ntpValue()
+    {
+        return ntpTime;
+    }
+
+    /**
+     * Converts this <code>TimeStamp</code> object to a <code>String</code>
+     * of the form:
+     * <blockquote><pre>
+     * EEE, MMM dd yyyy HH:mm:ss.SSS</pre></blockquote>
+     * See java.text.SimpleDataFormat for code descriptions.
+     *
+     * @return  a string representation of this date.
+     */
+    public String toDateString()
+    {
+        if (simpleFormatter == null) {
+            simpleFormatter = new SimpleDateFormat(NTP_DATE_FORMAT, Locale.US);
+            simpleFormatter.setTimeZone(TimeZone.getDefault());
+        }
+        final Date ntpDate = getDate();
+        return simpleFormatter.format(ntpDate);
+    }
+
+    /**
+     * Converts this <code>TimeStamp</code> object to a <code>String</code>.
+     * The NTP timestamp 64-bit long value is represented as hex string with
+     * seconds separated by fractional seconds by a decimal point;
+     * e.g. c1a089bd.fc904f6d == Tue, Dec 10 2002 10:41:49.986
+     *
+     * @return NTP timestamp 64-bit long value as hex string with seconds
+     * separated by fractional seconds.
+     */
+    @Override
+    public String toString()
+    {
+        return toString(ntpTime);
+    }
+
+    /**
+     * Converts this <code>TimeStamp</code> object to a <code>String</code>
+     * of the form:
+     * <blockquote><pre>
+     * EEE, MMM dd yyyy HH:mm:ss.SSS UTC</pre></blockquote>
+     * See java.text.SimpleDataFormat for code descriptions.
+     *
+     * @return  a string representation of this date in UTC.
+     */
+    public String toUTCString()
+    {
+        if (utcFormatter == null) {
+            utcFormatter = new SimpleDateFormat(NTP_DATE_FORMAT + " 'UTC'",
+                    Locale.US);
+            utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+        }
+        final Date ntpDate = getDate();
+        return utcFormatter.format(ntpDate);
+    }
+
+    /*
+        Serialization is unnecessary for this class.
+        Reject attempts to do so until such time as the Serializable attribute 
can be dropped.
+     */
+
+    private void writeObject(final java.io.ObjectOutputStream out) throws 
IOException
+    {
+        throw new UnsupportedOperationException("Serialization is not 
supported");
+    }
+
+    private void readObject(final java.io.ObjectInputStream in) throws 
IOException, ClassNotFoundException
+    {
+        throw new UnsupportedOperationException("Serialization is not 
supported");
+    }
+
+}

Reply via email to