code: public static Message from_header(byte[] header)
  	{
  		if(header==null || header.length!=HEADER_SIZE)
  			throw new PyroException("header data size mismatch");
  		
  		if(header[0]!='P'||header[1]!='Y'||header[2]!='R'||header[3]!='O') 
  			throw new PyroException("invalid message");    		
  
  		int version = ((header[4]&0xff) << 8)|(header[5]&0xff);
  		if(version!=Config.PROTOCOL_VERSION)
  			throw new PyroException("invalid protocol version: "+version);
  		
  		int msg_type = ((header[6]&0xff) << 8)|(header[7]&0xff);
  		int flags = ((header[8]&0xff) << 8)|(header[9]&0xff);
  		int seq = ((header[10]&0xff) << 8)|(header[11]&0xff);
  		int data_size=header[12]&0xff;
  		data_size<<=8;
  		data_size|=header[13]&0xff;
  		data_size<<=8;
  		data_size|=header[14]&0xff;
  		data_size<<=8;
  		data_size|=header[15]&0xff;
  		int serializer_id = ((header[16]&0xff) << 8)|(header[17]&0xff);
  		int annotations_size = ((header[18]&0xff) <<8)|(header[19]&0xff);
  		// byte 20 and 21 are reserved.
  		int checksum = ((header[22]&0xff) << 8)|(header[23]&0xff);
  		int actual_checksum = (msg_type+version+data_size+annotations_size+flags+serializer_id+seq+CHECKSUM_MAGIC)&0xffff;
  		if(checksum!=actual_checksum)
  			throw new PyroException("header checksum mismatch");
  		
  		Message msg = new Message(msg_type, serializer_id, flags, seq);
  		msg.data_size = data_size;
  		msg.annotations_size = annotations_size;
  		return msg;
  	}
docs: Parses a message header. Does not yet process the annotations chunks and message data.