public static Collection<String> getPossibleEncodings(byte [] data) {

		Collection<String> possibleEncodings = new TreeSet<>();
		if(data == null || data.length == 0) {
			return possibleEncodings;
		}

		// We may have to take account of a BOM (Byte Order Mark) as this could be present at the beginning of
		// the source byte array. These sequences may match valid bytes at the beginning of binary data but this shouldn't
		// match any encodings anyway.

		String encoding = null;
		for(Iterator<String> it = supportedEncodings.iterator(); it.hasNext();) {
			// This will eliminate encodings it can't possibly be from the supported encodings
			// by converting the source byte array to a String using each encoding in turn and
			// then getting the resultant byte array and checking it against the passed in data.

			try {
				// One problem to overcome is that the passed in data may be terminated by an
				// incomplete character for the current encoding so we need to remove the last character
				// then get the resulting bytes and only match this against the source byte array.

				encoding = (String)it.next();

				// Check if this encoding has a known bom and if so does it match the beginning of the data array ?
				// returns either 0 or the length of the bom
				int lengthBOM = getLengthBOM(encoding, data);

				// Don't use the BOM when constructing the String
				String test = new String(getByteArraySubArray(data, lengthBOM, data.length - lengthBOM), encoding);

				// Only remove the last character if the String is more than 1 character long
				if(test.length() > 1) {
					// Remove last character from the test string.
					test = test.substring(0, test.length()-2);
				}

				// This is the byte array we will compare with the passed in source array copy
				byte [] compare = null;
				try {
					compare = test.getBytes(encoding);
				}catch(UnsupportedOperationException ignore) {
					continue;
				}

				// Check if source and destination byte arrays are equal
				if(!compareByteArrays(data, lengthBOM, compare, 0, compare.length)) {
					// dosn't match so ignore this encoding as it is unlikely to be correct
					// even if it does contain valid text data.
					continue;
				}

				// If we get this far and the lengthBOM is not 0 then we have a match for this encoding.
				if(lengthBOM != 0) {
					// We know we have a perfect match for this encoding so ditch the rest and return just this one
					possibleEncodings.clear();
					possibleEncodings.add(encoding);
					return possibleEncodings;
				}

				// This is a possible match.
				possibleEncodings.add(encoding);
			}catch(UnsupportedEncodingException uee) {
				log.error("The encoding [" + encoding + "] is not supported by your JVM.");
			}catch(Exception e) {
				// Log the error but carry on with the next encoding
				log.error(e.getLocalizedMessage(), e);
			}
		}
		return possibleEncodings;
	}