public Frame parse(ByteBuffer downloadBuffer) throws WebSocketException {
		ByteBuffer buffer = null;
		try {
			if (State.DONE.equals(state)) {
				transitionTo(State.HEADER);
				buffer = downloadBuffer;
			} else {
				buffer = bufferManager.getBuffer(downloadBuffer);
			}

			if (State.HEADER.equals(state)) {
				int position = buffer.position();
				header = createFrameHeader(buffer);
				if (header == null) {
					buffer.position(position);
					bufferManager.storeFragmentBuffer(buffer);
					return null;
				}
				if (header.getContentsLength() - 1 > Integer.MAX_VALUE) {
					throw new IllegalArgumentException(
							"large data is not support yet");
				}
				transitionTo(State.FRAME);
			}

			if (State.FRAME.equals(state)) {
				if (header.getContentsLength() > buffer.remaining()) {
					bufferManager.storeFragmentBuffer(buffer);
					return null;
				}

				byte[] bodyBuf = new byte[(int) header.getContentsLength()];
				buffer.get(bodyBuf, 0, bodyBuf.length);
				Frame frame = createFrame(header, bodyBuf);
				transitionTo(State.DONE);
				bufferManager.init();

				header = null;
				return frame;
			}
			return null;
		} finally {
			if (buffer != null && buffer != downloadBuffer) {
				downloadBuffer.position(downloadBuffer.limit()
						- buffer.remaining());
			}
		}
	}