/*
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package javax.obex;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * This class defines a set of helper methods for the implementation of Obex.
 * @hide
 */
public final class ObexHelper {

    /**
     * Defines the basic packet length used by OBEX. Every OBEX packet has the
     * same basic format:<BR>
     * Byte 0: Request or Response Code Byte 1&2: Length of the packet.
     */
    public static final int BASE_PACKET_LENGTH = 3;

    /** Prevent object construction of helper class */
    private ObexHelper() {
    }

    /**
     * The maximum packet size for OBEX packets that this client can handle. At
     * present, this must be changed for each port. TODO: The max packet size
     * should be the Max incoming MTU minus TODO: L2CAP package headers and
     * RFCOMM package headers. TODO: Retrieve the max incoming MTU from TODO:
     * LocalDevice.getProperty().
     */
    /*
     * android note set as 0xFFFE to match remote MPS
     */
    public static final int MAX_PACKET_SIZE_INT = 0xFFFE;

    /**
     * Temporary workaround to be able to push files to Windows 7.
     * TODO: Should be removed as soon as Microsoft updates their driver.
     */
    public static final int MAX_CLIENT_PACKET_SIZE = 0xFC00;

    public static final int OBEX_OPCODE_CONNECT = 0x80;

    public static final int OBEX_OPCODE_DISCONNECT = 0x81;

    public static final int OBEX_OPCODE_PUT = 0x02;

    public static final int OBEX_OPCODE_PUT_FINAL = 0x82;

    public static final int OBEX_OPCODE_GET = 0x03;

    public static final int OBEX_OPCODE_GET_FINAL = 0x83;

    public static final int OBEX_OPCODE_RESERVED = 0x04;

    public static final int OBEX_OPCODE_RESERVED_FINAL = 0x84;

    public static final int OBEX_OPCODE_SETPATH = 0x85;

    public static final int OBEX_OPCODE_ABORT = 0xFF;

    public static final int OBEX_AUTH_REALM_CHARSET_ASCII = 0x00;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_1 = 0x01;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_2 = 0x02;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_3 = 0x03;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_4 = 0x04;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_5 = 0x05;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_6 = 0x06;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_7 = 0x07;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_8 = 0x08;

    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_9 = 0x09;

    public static final int OBEX_AUTH_REALM_CHARSET_UNICODE = 0xFF;

    /**
     * Updates the HeaderSet with the headers received in the byte array
     * provided. Invalid headers are ignored.
     * <P>
     * The first two bits of an OBEX Header specifies the type of object that is
     * being sent. The table below specifies the meaning of the high bits.
     * <TABLE>
     * <TR>
     * <TH>Bits 8 and 7</TH>
     * <TH>Value</TH>
     * <TH>Description</TH>
     * </TR>
     * <TR>
     * <TD>00</TD>
     * <TD>0x00</TD>
     * <TD>Null Terminated Unicode text, prefixed with 2 byte unsigned integer</TD>
     * </TR>
     * <TR>
     * <TD>01</TD>
     * <TD>0x40</TD>
     * <TD>Byte Sequence, length prefixed with 2 byte unsigned integer</TD>
     * </TR>
     * <TR>
     * <TD>10</TD>
     * <TD>0x80</TD>
     * <TD>1 byte quantity</TD>
     * </TR>
     * <TR>
     * <TD>11</TD>
     * <TD>0xC0</TD>
     * <TD>4 byte quantity - transmitted in network byte order (high byte first</TD>
     * </TR>
     * </TABLE>
     * This method uses the information in this table to determine the type of
     * Java object to create and passes that object with the full header to
     * setHeader() to update the HeaderSet object. Invalid headers will cause an
     * exception to be thrown. When it is thrown, it is ignored.
     * @param header the HeaderSet to update
     * @param headerArray the byte array containing headers
     * @return the result of the last start body or end body header provided;
     *         the first byte in the result will specify if a body or end of
     *         body is received
     * @throws IOException if an invalid header was found
     */
    public static byte[] updateHeaderSet(HeaderSet header, byte[] headerArray) throws IOException {
        int index = 0;
        int length = 0;
        int headerID;
        byte[] value = null;
        byte[] body = null;
        HeaderSet headerImpl = header;
        try {
            while (index < headerArray.length) {
                headerID = 0xFF & headerArray[index];
                switch (headerID & (0xC0)) {

                    /*
                     * 0x00 is a unicode null terminate string with the first
                     * two bytes after the header identifier being the length
                     */
                    case 0x00:
                        // Fall through
                        /*
                         * 0x40 is a byte sequence with the first
                         * two bytes after the header identifier being the length
                         */
                    case 0x40:
                        boolean trimTail = true;
                        index++;
                        length = 0xFF & headerArray[index];
                        length = length << 8;
                        index++;
                        length += 0xFF & headerArray[index];
                        length -= 3;
                        index++;
                        value = new byte[length];
                        System.arraycopy(headerArray, index, value, 0, length);
                        if (length == 0 || (length > 0 && (value[length - 1] != 0))) {
                            trimTail = false;
                        }
                        switch (headerID) {
                            case HeaderSet.TYPE:
                                try {
                                    // Remove trailing null
                                    if (trimTail == false) {
                                        headerImpl.setHeader(headerID, new String(value, 0,
                                                value.length, "ISO8859_1"));
                                    } else {
                                        headerImpl.setHeader(headerID, new String(value, 0,
                                                value.length - 1, "ISO8859_1"));
                                    }
                                } catch (UnsupportedEncodingException e) {
                                    throw e;
                                }
                                break;

                            case HeaderSet.AUTH_CHALLENGE:
                                headerImpl.mAuthChall = new byte[length];
                                System.arraycopy(headerArray, index, headerImpl.mAuthChall, 0,
                                        length);
                                break;

                            case HeaderSet.AUTH_RESPONSE:
                                headerImpl.mAuthResp = new byte[length];
                                System.arraycopy(headerArray, index, headerImpl.mAuthResp, 0,
                                        length);
                                break;

                            case HeaderSet.BODY:
                                /* Fall Through */
                            case HeaderSet.END_OF_BODY:
                                body = new byte[length + 1];
                                body[0] = (byte)headerID;
                                System.arraycopy(headerArray, index, body, 1, length);
                                break;

                            case HeaderSet.TIME_ISO_8601:
                                try {
                                    String dateString = new String(value, "ISO8859_1");
                                    Calendar temp = Calendar.getInstance();
                                    if ((dateString.length() == 16)
                                            && (dateString.charAt(15) == 'Z')) {
                                        temp.setTimeZone(TimeZone.getTimeZone("UTC"));
                                    }
                                    temp.set(Calendar.YEAR, Integer.parseInt(dateString.substring(
                                            0, 4)));
                                    temp.set(Calendar.MONTH, Integer.parseInt(dateString.substring(
                                            4, 6)));
                                    temp.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateString
                                            .substring(6, 8)));
                                    temp.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateString
                                            .substring(9, 11)));
                                    temp.set(Calendar.MINUTE, Integer.parseInt(dateString
                                            .substring(11, 13)));
                                    temp.set(Calendar.SECOND, Integer.parseInt(dateString
                                            .substring(13, 15)));
                                    headerImpl.setHeader(HeaderSet.TIME_ISO_8601, temp);
                                } catch (UnsupportedEncodingException e) {
                                    throw e;
                                }
                                break;

                            default:
                                if ((headerID & 0xC0) == 0x00) {
                                    headerImpl.setHeader(headerID, ObexHelper.convertToUnicode(
                                            value, true));
                                } else {
                                    headerImpl.setHeader(headerID, value);
                                }
                        }

                        index += length;
                        break;

                    /*
                     * 0x80 is a byte header.  The only valid byte headers are
                     * the 16 user defined byte headers.
                     */
                    case 0x80:
                        index++;
                        try {
                            headerImpl.setHeader(headerID, Byte.valueOf(headerArray[index]));
                        } catch (Exception e) {
                            // Not a valid header so ignore
                        }
                        index++;
                        break;

                    /*
                     * 0xC0 is a 4 byte unsigned integer header and with the
                     * exception of TIME_4_BYTE will be converted to a Long
                     * and added.
                     */
                    case 0xC0:
                        index++;
                        value = new byte[4];
                        System.arraycopy(headerArray, index, value, 0, 4);
                        try {
                            if (headerID != HeaderSet.TIME_4_BYTE) {
                                // Determine if it is a connection ID.  These
                                // need to be handled differently
                                if (headerID == HeaderSet.CONNECTION_ID) {
                                    headerImpl.mConnectionID = new byte[4];
                                    System.arraycopy(value, 0, headerImpl.mConnectionID, 0, 4);
                                } else {
                                    headerImpl.setHeader(headerID, Long
                                            .valueOf(convertToLong(value)));
                                }
                            } else {
                                Calendar temp = Calendar.getInstance();
                                temp.setTime(new Date(convertToLong(value) * 1000L));
                                headerImpl.setHeader(HeaderSet.TIME_4_BYTE, temp);
                            }
                        } catch (Exception e) {
                            // Not a valid header so ignore
                            throw new IOException("Header was not formatted properly");
                        }
                        index += 4;
                        break;
                }

            }
        } catch (IOException e) {
            throw new IOException("Header was not formatted properly");
        }

        return body;
    }

    /**
     * Creates the header part of OBEX packet based on the header provided.
     * TODO: Could use getHeaderList() to get the array of headers to include
     * and then use the high two bits to determine the the type of the object
     * and construct the byte array from that. This will make the size smaller.
     * @param head the header used to construct the byte array
     * @param nullOut <code>true</code> if the header should be set to
     *        <code>null</code> once it is added to the array or
     *        <code>false</code> if it should not be nulled out
     * @return the header of an OBEX packet
     */
    public static byte[] createHeader(HeaderSet head, boolean nullOut) {
        Long intHeader = null;
        String stringHeader = null;
        Calendar dateHeader = null;
        Byte byteHeader = null;
        StringBuffer buffer = null;
        byte[] value = null;
        byte[] result = null;
        byte[] lengthArray = new byte[2];
        int length;
        HeaderSet headImpl = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        headImpl = head;

        try {
            /*
             * Determine if there is a connection ID to send.  If there is,
             * then it should be the first header in the packet.
             */
            if ((headImpl.mConnectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) {

                out.write((byte)HeaderSet.CONNECTION_ID);
                out.write(headImpl.mConnectionID);
            }

            // Count Header
            intHeader = (Long)headImpl.getHeader(HeaderSet.COUNT);
            if (intHeader != null) {
                out.write((byte)HeaderSet.COUNT);
                value = ObexHelper.convertToByteArray(intHeader.longValue());
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.COUNT, null);
                }
            }

            // Name Header
            stringHeader = (String)headImpl.getHeader(HeaderSet.NAME);
            if (stringHeader != null) {
                out.write((byte)HeaderSet.NAME);
                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
                length = value.length + 3;
                lengthArray[0] = (byte)(0xFF & (length >> 8));
                lengthArray[1] = (byte)(0xFF & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.NAME, null);
                }
            }

            // Type Header
            stringHeader = (String)headImpl.getHeader(HeaderSet.TYPE);
            if (stringHeader != null) {
                out.write((byte)HeaderSet.TYPE);
                try {
                    value = stringHeader.getBytes("ISO8859_1");
                } catch (UnsupportedEncodingException e) {
                    throw e;
                }

                length = value.length + 4;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                out.write(0x00);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TYPE, null);
                }
            }

            // Length Header
            intHeader = (Long)headImpl.getHeader(HeaderSet.LENGTH);
            if (intHeader != null) {
                out.write((byte)HeaderSet.LENGTH);
                value = ObexHelper.convertToByteArray(intHeader.longValue());
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.LENGTH, null);
                }
            }

            // Time ISO Header
            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_ISO_8601);
            if (dateHeader != null) {

                /*
                 * The ISO Header should take the form YYYYMMDDTHHMMSSZ.  The
                 * 'Z' will only be included if it is a UTC time.
                 */
                buffer = new StringBuffer();
                int temp = dateHeader.get(Calendar.YEAR);
                for (int i = temp; i < 1000; i = i * 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.MONTH);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.DAY_OF_MONTH);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                buffer.append("T");
                temp = dateHeader.get(Calendar.HOUR_OF_DAY);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.MINUTE);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);
                temp = dateHeader.get(Calendar.SECOND);
                if (temp < 10) {
                    buffer.append("0");
                }
                buffer.append(temp);

                if (dateHeader.getTimeZone().getID().equals("UTC")) {
                    buffer.append("Z");
                }

                try {
                    value = buffer.toString().getBytes("ISO8859_1");
                } catch (UnsupportedEncodingException e) {
                    throw e;
                }

                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(HeaderSet.TIME_ISO_8601);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TIME_ISO_8601, null);
                }
            }

            // Time 4 Byte Header
            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_4_BYTE);
            if (dateHeader != null) {
                out.write(HeaderSet.TIME_4_BYTE);

                /*
                 * Need to call getTime() twice.  The first call will return
                 * a java.util.Date object.  The second call returns the number
                 * of milliseconds since January 1, 1970.  We need to convert
                 * it to seconds since the TIME_4_BYTE expects the number of
                 * seconds since January 1, 1970.
                 */
                value = ObexHelper.convertToByteArray(dateHeader.getTime().getTime() / 1000L);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TIME_4_BYTE, null);
                }
            }

            // Description Header
            stringHeader = (String)headImpl.getHeader(HeaderSet.DESCRIPTION);
            if (stringHeader != null) {
                out.write((byte)HeaderSet.DESCRIPTION);
                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.DESCRIPTION, null);
                }
            }

            // Target Header
            value = (byte[])headImpl.getHeader(HeaderSet.TARGET);
            if (value != null) {
                out.write((byte)HeaderSet.TARGET);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.TARGET, null);
                }
            }

            // HTTP Header
            value = (byte[])headImpl.getHeader(HeaderSet.HTTP);
            if (value != null) {
                out.write((byte)HeaderSet.HTTP);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.HTTP, null);
                }
            }

            // Who Header
            value = (byte[])headImpl.getHeader(HeaderSet.WHO);
            if (value != null) {
                out.write((byte)HeaderSet.WHO);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.WHO, null);
                }
            }

            // Connection ID Header
            value = (byte[])headImpl.getHeader(HeaderSet.APPLICATION_PARAMETER);
            if (value != null) {
                out.write((byte)HeaderSet.APPLICATION_PARAMETER);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.APPLICATION_PARAMETER, null);
                }
            }

            // Object Class Header
            value = (byte[])headImpl.getHeader(HeaderSet.OBJECT_CLASS);
            if (value != null) {
                out.write((byte)HeaderSet.OBJECT_CLASS);
                length = value.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(value);
                if (nullOut) {
                    headImpl.setHeader(HeaderSet.OBJECT_CLASS, null);
                }
            }

            // Check User Defined Headers
            for (int i = 0; i < 16; i++) {

                //Unicode String Header
                stringHeader = (String)headImpl.getHeader(i + 0x30);
                if (stringHeader != null) {
                    out.write((byte)i + 0x30);
                    value = ObexHelper.convertToUnicodeByteArray(stringHeader);
                    length = value.length + 3;
                    lengthArray[0] = (byte)(255 & (length >> 8));
                    lengthArray[1] = (byte)(255 & length);
                    out.write(lengthArray);
                    out.write(value);
                    if (nullOut) {
                        headImpl.setHeader(i + 0x30, null);
                    }
                }

                // Byte Sequence Header
                value = (byte[])headImpl.getHeader(i + 0x70);
                if (value != null) {
                    out.write((byte)i + 0x70);
                    length = value.length + 3;
                    lengthArray[0] = (byte)(255 & (length >> 8));
                    lengthArray[1] = (byte)(255 & length);
                    out.write(lengthArray);
                    out.write(value);
                    if (nullOut) {
                        headImpl.setHeader(i + 0x70, null);
                    }
                }

                // Byte Header
                byteHeader = (Byte)headImpl.getHeader(i + 0xB0);
                if (byteHeader != null) {
                    out.write((byte)i + 0xB0);
                    out.write(byteHeader.byteValue());
                    if (nullOut) {
                        headImpl.setHeader(i + 0xB0, null);
                    }
                }

                // Integer header
                intHeader = (Long)headImpl.getHeader(i + 0xF0);
                if (intHeader != null) {
                    out.write((byte)i + 0xF0);
                    out.write(ObexHelper.convertToByteArray(intHeader.longValue()));
                    if (nullOut) {
                        headImpl.setHeader(i + 0xF0, null);
                    }
                }
            }

            // Add the authentication challenge header
            if (headImpl.mAuthChall != null) {
                out.write((byte)HeaderSet.AUTH_CHALLENGE);
                length = headImpl.mAuthChall.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(headImpl.mAuthChall);
                if (nullOut) {
                    headImpl.mAuthChall = null;
                }
            }

            // Add the authentication response header
            if (headImpl.mAuthResp != null) {
                out.write((byte)HeaderSet.AUTH_RESPONSE);
                length = headImpl.mAuthResp.length + 3;
                lengthArray[0] = (byte)(255 & (length >> 8));
                lengthArray[1] = (byte)(255 & length);
                out.write(lengthArray);
                out.write(headImpl.mAuthResp);
                if (nullOut) {
                    headImpl.mAuthResp = null;
                }
            }

        } catch (IOException e) {
        } finally {
            result = out.toByteArray();
            try {
                out.close();
            } catch (Exception ex) {
            }
        }

        return result;

    }

    /**
     * Determines where the maximum divide is between headers. This method is
     * used by put and get operations to separate headers to a size that meets
     * the max packet size allowed.
     * @param headerArray the headers to separate
     * @param start the starting index to search
     * @param maxSize the maximum size of a packet
     * @return the index of the end of the header block to send or -1 if the
     *         header could not be divided because the header is too large
     */
    public static int findHeaderEnd(byte[] headerArray, int start, int maxSize) {

        int fullLength = 0;
        int lastLength = -1;
        int index = start;
        int length = 0;

        while ((fullLength < maxSize) && (index < headerArray.length)) {
            int headerID = (headerArray[index] < 0 ? headerArray[index] + 256 : headerArray[index]);
            lastLength = fullLength;

            switch (headerID & (0xC0)) {

                case 0x00:
                    // Fall through
                case 0x40:

                    index++;
                    length = (headerArray[index] < 0 ? headerArray[index] + 256
                            : headerArray[index]);
                    length = length << 8;
                    index++;
                    length += (headerArray[index] < 0 ? headerArray[index] + 256
                            : headerArray[index]);
                    length -= 3;
                    index++;
                    index += length;
                    fullLength += length + 3;
                    break;

                case 0x80:

                    index++;
                    index++;
                    fullLength += 2;
                    break;

                case 0xC0:

                    index += 5;
                    fullLength += 5;
                    break;

            }

        }

        /*
         * Determine if this is the last header or not
         */
        if (lastLength == 0) {
            /*
             * Since this is the last header, check to see if the size of this
             * header is less then maxSize.  If it is, return the length of the
             * header, otherwise return -1.  The length of the header is
             * returned since it would be the start of the next header
             */
            if (fullLength < maxSize) {
                return headerArray.length;
            } else {
                return -1;
            }
        } else {
            return lastLength + start;
        }
    }

    /**
     * Converts the byte array to a long.
     * @param b the byte array to convert to a long
     * @return the byte array as a long
     */
    public static long convertToLong(byte[] b) {
        long result = 0;
        long value = 0;
        long power = 0;

        for (int i = (b.length - 1); i >= 0; i--) {
            value = b[i];
            if (value < 0) {
                value += 256;
            }

            result = result | (value << power);
            power += 8;
        }

        return result;
    }

    /**
     * Converts the long to a 4 byte array. The long must be non negative.
     * @param l the long to convert
     * @return a byte array that is the same as the long
     */
    public static byte[] convertToByteArray(long l) {
        byte[] b = new byte[4];

        b[0] = (byte)(255 & (l >> 24));
        b[1] = (byte)(255 & (l >> 16));
        b[2] = (byte)(255 & (l >> 8));
        b[3] = (byte)(255 & l);

        return b;
    }

    /**
     * Converts the String to a UNICODE byte array. It will also add the ending
     * null characters to the end of the string.
     * @param s the string to convert
     * @return the unicode byte array of the string
     */
    public static byte[] convertToUnicodeByteArray(String s) {
        if (s == null) {
            return null;
        }

        char c[] = s.toCharArray();
        byte[] result = new byte[(c.length * 2) + 2];
        for (int i = 0; i < c.length; i++) {
            result[(i * 2)] = (byte)(c[i] >> 8);
            result[((i * 2) + 1)] = (byte)c[i];
        }

        // Add the UNICODE null character
        result[result.length - 2] = 0;
        result[result.length - 1] = 0;

        return result;
    }

    /**
     * Retrieves the value from the byte array for the tag value specified. The
     * array should be of the form Tag - Length - Value triplet.
     * @param tag the tag to retrieve from the byte array
     * @param triplet the byte sequence containing the tag length value form
     * @return the value of the specified tag
     */
    public static byte[] getTagValue(byte tag, byte[] triplet) {

        int index = findTag(tag, triplet);
        if (index == -1) {
            return null;
        }

        index++;
        int length = triplet[index] & 0xFF;

        byte[] result = new byte[length];
        index++;
        System.arraycopy(triplet, index, result, 0, length);

        return result;
    }

    /**
     * Finds the index that starts the tag value pair in the byte array provide.
     * @param tag the tag to look for
     * @param value the byte array to search
     * @return the starting index of the tag or -1 if the tag could not be found
     */
    public static int findTag(byte tag, byte[] value) {
        int length = 0;

        if (value == null) {
            return -1;
        }

        int index = 0;

        while ((index < value.length) && (value[index] != tag)) {
            length = value[index + 1] & 0xFF;
            index += length + 2;
        }

        if (index >= value.length) {
            return -1;
        }

        return index;
    }

    /**
     * Converts the byte array provided to a unicode string.
     * @param b the byte array to convert to a string
     * @param includesNull determine if the byte string provided contains the
     *        UNICODE null character at the end or not; if it does, it will be
     *        removed
     * @return a Unicode string
     * @throws IllegalArgumentException if the byte array has an odd length
     */
    public static String convertToUnicode(byte[] b, boolean includesNull) {
        if (b == null || b.length == 0) {
            return null;
        }
        int arrayLength = b.length;
        if (!((arrayLength % 2) == 0)) {
            throw new IllegalArgumentException("Byte array not of a valid form");
        }
        arrayLength = (arrayLength >> 1);
        if (includesNull) {
            arrayLength -= 1;
        }

        char[] c = new char[arrayLength];
        for (int i = 0; i < arrayLength; i++) {
            int upper = b[2 * i];
            int lower = b[(2 * i) + 1];
            if (upper < 0) {
                upper += 256;
            }
            if (lower < 0) {
                lower += 256;
            }
            // If upper and lower both equal 0, it should be the end of string.
            // Ignore left bytes from array to avoid potential issues
            if (upper == 0 && lower == 0) {
                return new String(c, 0, i);
            }

            c[i] = (char)((upper << 8) | lower);
        }

        return new String(c);
    }

    /**
     * Compute the MD5 hash of the byte array provided. Does not accumulate
     * input.
     * @param in the byte array to hash
     * @return the MD5 hash of the byte array
     */
    public static byte[] computeMd5Hash(byte[] in) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            return md5.digest(in);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Computes an authentication challenge header.
     * @param nonce the challenge that will be provided to the peer; the
     *        challenge must be 16 bytes long
     * @param realm a short description that describes what password to use
     * @param access if <code>true</code> then full access will be granted if
     *        successful; if <code>false</code> then read only access will be
     *        granted if successful
     * @param userID if <code>true</code>, a user ID is required in the reply;
     *        if <code>false</code>, no user ID is required
     * @throws IllegalArgumentException if the challenge is not 16 bytes long;
     *         if the realm can not be encoded in less then 255 bytes
     * @throws IOException if the encoding scheme ISO 8859-1 is not supported
     */
    public static byte[] computeAuthenticationChallenge(byte[] nonce, String realm, boolean access,
            boolean userID) throws IOException {
        byte[] authChall = null;

        if (nonce.length != 16) {
            throw new IllegalArgumentException("Nonce must be 16 bytes long");
        }

        /*
         * The authentication challenge is a byte sequence of the following form
         * byte 0: 0x00 - the tag for the challenge
         * byte 1: 0x10 - the length of the challenge; must be 16
         * byte 2-17: the authentication challenge
         * byte 18: 0x01 - the options tag; this is optional in the spec, but
         *                 we are going to include it in every message
         * byte 19: 0x01 - length of the options; must be 1
         * byte 20: the value of the options; bit 0 is set if user ID is
         *          required; bit 1 is set if access mode is read only
         * byte 21: 0x02 - the tag for authentication realm; only included if
         *                 an authentication realm is specified
         * byte 22: the length of the authentication realm; only included if
         *          the authentication realm is specified
         * byte 23: the encoding scheme of the authentication realm; we will use
         *          the ISO 8859-1 encoding scheme since it is part of the KVM
         * byte 24 & up: the realm if one is specified.
         */
        if (realm == null) {
            authChall = new byte[21];
        } else {
            if (realm.length() >= 255) {
                throw new IllegalArgumentException("Realm must be less then 255 bytes");
            }
            authChall = new byte[24 + realm.length()];
            authChall[21] = 0x02;
            authChall[22] = (byte)(realm.length() + 1);
            authChall[23] = 0x01; // ISO 8859-1 Encoding
            System.arraycopy(realm.getBytes("ISO8859_1"), 0, authChall, 24, realm.length());
        }

        // Include the nonce field in the header
        authChall[0] = 0x00;
        authChall[1] = 0x10;
        System.arraycopy(nonce, 0, authChall, 2, 16);

        // Include the options header
        authChall[18] = 0x01;
        authChall[19] = 0x01;
        authChall[20] = 0x00;

        if (!access) {
            authChall[20] = (byte)(authChall[20] | 0x02);
        }
        if (userID) {
            authChall[20] = (byte)(authChall[20] | 0x01);
        }

        return authChall;
    }
}
