docs: function parse_PropertySetStream(file, PIDSI) {
  	var blob = file.content;
  	prep_blob(blob, 0);
  
  	var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
  	blob.chk('feff', 'Byte Order: ');
  
  	var vers = blob.read_shift(2); // TODO: check version
  	var SystemIdentifier = blob.read_shift(4);
  	blob.chk(CFB.utils.consts.HEADER_CLSID, 'CLSID: ');
  	NumSets = blob.read_shift(4);
  	if(NumSets !== 1 && NumSets !== 2) throw new Error("Unrecognized #Sets: " + NumSets);
  	FMTID0 = blob.read_shift(16); Offset0 = blob.read_shift(4);
  
  	if(NumSets === 1 && Offset0 !== blob.l) throw new Error("Length mismatch: " + Offset0 + " !== " + blob.l);
  	else if(NumSets === 2) { FMTID1 = blob.read_shift(16); Offset1 = blob.read_shift(4); }
  	var PSet0 = parse_PropertySet(blob, PIDSI);
  
  	var rval = ({ SystemIdentifier: SystemIdentifier });
  	for(var y in PSet0) rval[y] = PSet0[y];
  	//rval.blob = blob;
  	rval.FMTID = FMTID0;
  	//rval.PSet0 = PSet0;
  	if(NumSets === 1) return rval;
  	if(blob.l !== Offset1) throw new Error("Length mismatch 2: " + blob.l + " !== " + Offset1);
  	var PSet1;
  	try { PSet1 = parse_PropertySet(blob, null); } catch(e) {/* empty */}
  	for(y in PSet1) rval[y] = PSet1[y];
  	rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
  	return rval;
  }