public void update(ByteBuffer buffer) {
		length += buffer.remaining();
		//Save current position to leave given buffer unchanged
		int position = buffer.position();

		//Complete the final buffer if needed
		completeFinalBuffer(buffer);

		if(!buffer.hasArray() || buffer.isDirect())
		{
			if(cacheBlock == null) // only allocate if we process direct byte buffers
				cacheBlock = new byte[cacheSize];
			while(buffer.remaining() >= 64)
			{
				int toProcess = Math.min(buffer.remaining()-buffer.remaining()%64,cacheSize);
				buffer.get(cacheBlock, 0, toProcess);
				for(int i = 0;i < toProcess; i+=64)
					transform(cacheBlock,i);
			}
		} else // use direct array access for heap buffers
		{
			final int endPos = buffer.position()+buffer.remaining()-buffer.remaining()%64;
			final int internalEndPos = endPos+buffer.arrayOffset(); 
			for(int i = buffer.arrayOffset()+buffer.position();i < internalEndPos;i+=64)
				transform(buffer.array(),i);
			buffer.position(endPos);
		}


		if(buffer.remaining() != 0) {
			finalBuffer.put(buffer);
		}

		buffer.position(position);
	}