gt: 		String s = Integer.toHexString(b);
context: /*
   *  This file is part of Gjokii.
   *
   *  Gjokii is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU Lesser General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  Gjokii is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU Lesser General Public License for more details.
   *
   *  You should have received a copy of the GNU Lesser General Public License
   *  along with Gjokii.  If not, see <http://www.gnu.org/licenses/>.
   */
  package net.tuxed.misc;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.UnsupportedEncodingException;
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  import java.util.Arrays;
  
  /**
   * General purpose class with all kinds of useful methods
   * 
   * @author F. Kooman <fkooman@tuxed.net>
   * 
   */
  public class Utils {
  
  	private Utils() {
  	}
  
  	/**
  	 * Append a byte array to another byte array
  	 * 
  	 * @param first
  	 *            the byte array to append to
  	 * @param second
  	 *            the byte array to append
  	 * @return the appended array
  	 */
  	public static byte[] appendToByteArray(byte[] first, byte[] second) {
  		int secondLength = (second != null) ? second.length : 0;
  		return appendToByteArray(first, second, 0, secondLength);
  	}
  
  	/**
  	 * Append a byte array to another byte array specifying which part of the
  	 * second byte array should be appended to the first
  	 * 
  	 * @param first
  	 *            the byte array to append to
  	 * @param second
  	 *            the byte array to append
  	 * @param offset
  	 *            offset in second array to start appending from
  	 * @param length
  	 *            number of bytes to append from second to first array
  	 * @return the appended array
  	 */
  	public static byte[] appendToByteArray(byte[] first, byte[] second,
  			int offset, int length) {
  		if (second == null || second.length == 0) {
  			// if (first == null)
  			// return new byte[0];
  			return first;
  		}
  		int firstLength = (first != null) ? first.length : 0;
  
  		if (length < 0 || offset < 0 || second.length < length + offset)
  			throw new ArrayIndexOutOfBoundsException();
  		byte[] result = new byte[firstLength + length];
  		if (firstLength > 0)
  			System.arraycopy(first, 0, result, 0, firstLength);
  		System.arraycopy(second, offset, result, firstLength, length);
  		return result;
  	}
  
  	/**
  	 * Convert a (part of) a byte array to integer
  	 * 
  	 * @param data
  	 *            the byte array
  	 * @param offset
  	 *            the offset in the byte array to start from
  	 * @return the integer value represented by the byte array
  	 */
  	public static int byteArrayToInt(byte[] data, int offset) {
  		return (int) ((data[offset] << 24 & 0xff000000)
  				| (data[offset + 1] << 16 & 0x00ff0000)
  				| (data[offset + 2] << 8 & 0x0000ff00) | (data[offset + 3] & 0x000000ff));
  	}
  
  	/**
  	 * Convert a (part of) a byte array to integer assuming the byte array is
  	 * Little Endian encoded
  	 * 
  	 * @param data
  	 *            the byte array
  	 * @param offset
  	 *            the offset in the byte array to start from
  	 * @return the integer value represented by the byte array
  	 */
  	public static int byteArrayToIntLE(byte[] data, int offset) {
  		return (int) ((data[offset] & 0x000000ff)
  				| (data[offset + 1] << 8 & 0x0000ff00)
  				| (data[offset + 2] << 16 & 0x00ff0000) | (data[offset + 3] << 24 & 0xff000000));
  	}
  
  	/**
  	 * Convert a (part of) a byte array to short
  	 * 
  	 * @param data
  	 *            the byte array
  	 * @param offset
  	 *            the offset in the byte array to start from
  	 * @return the short value represented by the byte array
  	 */
  	public static short byteArrayToShort(byte[] data, int offset) {
  		return (short) (((data[offset] << 8)) | ((data[offset + 1] & 0xff)));
  	}
  
  	/**
  	 * Convert a (part of) a byte array to short assuming the byte array is
  	 * Little Endian encoded
  	 * 
  	 * @param data
  	 *            the byte array
  	 * @param offset
  	 *            the offset in the byte array to start from
  	 * @return the short value represented by the byte array
  	 */
  	public static short byteArrayToShortLE(byte[] data, int offset) {
  		return (short) (((data[offset + 1] << 8)) | ((data[offset] & 0xff)));
  	}
  
  	/**
  	 * Converts a byte array to readable string
  	 * 
  	 * @param a
  	 *            array to print
  	 * @return readable byte array string
  	 */
  	public static String byteArrayToString(byte[] a) {
  		return byteArrayToString(a, 0, (a != null) ? a.length : 0);
  	}
  
  	public static String byteArrayToString(byte[] a, int offset, int length) {
  		if (a == null)
  			return "[null]";
  		if (a.length == 0)
  			return "[empty]";
  		if (offset < 0 || length < 0 || length + offset > a.length) {
  			throw new IndexOutOfBoundsException();
  		}
  		String result = "";
  		for (int i = offset; i < offset + length; i++) {
  			result += byteToString(a[i]);
  		}
  		return result;
  	}
  
  	/**
  	 * Decode a byte array which contains UTF-16 bytes to string.
  	 * 
  	 * @param data
  	 *            the byte array containing the UTF-16 bytes NOT terminated by
  	 *            0x00 0x00
  	 * @param offset
  	 *            the offset in the array
  	 * @param length
  	 *            the length of the array
  	 * @return the decoded bytes
  	 */
  	public static String bytesToString(byte[] data, int offset, int length) {
  		if (data == null)
  			return null;
  		String s = null;
  		try {
  			s = new String(data, offset, length, "UTF-16");
  		} catch (UnsupportedEncodingException e) {
  		}
  		return s;
  	}
  
  	/**
  	 * Decode a byte array which contains UTF-16 Little Endian bytes to string.
  	 * We assume the byte array terminates with 0x00 0x00.
  	 * 
  	 * @param data
  	 *            the byte array containing the UTF-16 LE bytes terminated by
  	 *            0x00 0x00
  	 * @return the decoded string
  	 */
  	public static String bytesToStringLE(byte[] data) {
  		if (data != null && data.length >= 2)
  			return bytesToStringLE(data, 0, data.length - 2);
  		else
  			return "";
  	}
  
  	/**
  	 * Decode a byte array which contains UTF-16 Little Endian bytes to string.
  	 * 
  	 * @param data
  	 *            the byte array containing the UTF-16 LE bytes NOT terminated
  	 *            by 0x00 0x00
  	 * @param offset
  	 *            the offset in the array
  	 * @param length
  	 *            the length of the array
  	 * @return the decoded bytes
  	 */
  	public static String bytesToStringLE(byte[] data, int offset, int length) {
  		if (data == null)
  			return null;
  		String s = null;
  		try {
  			s = new String(data, offset, length, "UTF-16LE");
  		} catch (UnsupportedEncodingException e) {
  		}
  		return s;
  	}
  
  	/**
  	 * Convert a byte to a human readable representation
  	 * 
  	 * @param b
  	 *            the byte
  	 * @return the human readable representation
  	 */
  	public static String byteToString(int b) {
  