LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfc3RvYy5oeHgiCgojaW5jbHVkZSA8c2FsL21haW4uaD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvaW1wbGJhc2UxLmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvaW1wbGJhc2U0Lmh4eD4KI2luY2x1ZGUgPGNwcHVoZWxwZXIvc2VydmljZWZhY3RvcnkuaHh4PgojaW5jbHVkZSA8b3NsL2RpYWdub3NlLmg+CgovLyNpbmNsdWRlIDx2b3MvZHlubG9hZC5oeHg+CgojaW5jbHVkZSA8TW9kdWxlQS9YSW50cm9UZXN0LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9YUHJvcGVydHlTZXQuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL1hJbnRyb3NwZWN0aW9uLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9Qcm9wZXJ0eUF0dHJpYnV0ZS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvYmVhbnMvUHJvcGVydHlDb25jZXB0LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9NZXRob2RDb25jZXB0LmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9iZWFucy9YRXhhY3ROYW1lLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvWEVsZW1lbnRBY2Nlc3MuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2NvbnRhaW5lci9YTmFtZUFjY2Vzcy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvY29udGFpbmVyL1hJbmRleEFjY2Vzcy5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvbGFuZy9YTXVsdGlTZXJ2aWNlRmFjdG9yeS5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvcmVmbGVjdGlvbi9YSWRsUmVmbGVjdGlvbi5ocHA+Ci8vI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9yZWdpc3RyeS9YU2ltcGxlUmVnaXN0cnkuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3JlZ2lzdHJ5L1hJbXBsZW1lbnRhdGlvblJlZ2lzdHJhdGlvbi5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvbGFuZy9YQ29tcG9uZW50LmhwcD4KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgoKdXNpbmcgbmFtZXNwYWNlIHJ0bDsKdXNpbmcgbmFtZXNwYWNlIGNwcHU7Ci8vdXNpbmcgbmFtZXNwYWNlIHZvczsKdXNpbmcgbmFtZXNwYWNlIE1vZHVsZUE7Ci8vdXNpbmcgbmFtZXNwYWNlIE1vZHVsZUI7Ci8vdXNpbmcgbmFtZXNwYWNlIE1vZHVsZUM7Ci8vdXNpbmcgbmFtZXNwYWNlIE1vZHVsZUE6Ok1vZHVsZUI7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6Omxhbmc7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6YmVhbnM7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6cmVnaXN0cnk7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6cmVmbGVjdGlvbjsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI7CnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6YmVhbnM6OlByb3BlcnR5QXR0cmlidXRlOwoKCnR5cGVkZWYgV2Vha0ltcGxIZWxwZXI0PCBYSW50cm9UZXN0LCBYUHJvcGVydHlTZXQsIFhOYW1lQWNjZXNzLCBYSW5kZXhBY2Nlc3MgPiBJbXBsSW50cm9UZXN0SGVscGVyOwp0eXBlZGVmIFdlYWtJbXBsSGVscGVyMTwgWFByb3BlcnR5U2V0SW5mbyA+IEltcGxQcm9wZXJ0eVNldEluZm9IZWxwZXI7CgoKI2RlZmluZSBERUZBVUxUX0lOREVYX0FDQ0VTU19DT1VOVAkxMAojZGVmaW5lIERFRkFVTFRfTkFNRV9BQ0NFU1NfQ09VTlQJNQoKI2lmIE9TTF9ERUJVR19MRVZFTCA+IDAKI2RlZmluZSBURVNUX0VOU0hVUkUoYywgbSkgICBPU0xfRU5TVVJFKGMsIG0pCiNlbHNlCiNkZWZpbmUgVEVTVF9FTlNIVVJFKGMsIG0pICAgT1NMX1ZFUklGWShjKQojZW5kaWYKCi8vY2xhc3MgSW50cm9UZXN0V3JpdGVsbk91dHB1dDsKCgoKLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyoqKiBIaWxmcy1GdW5rdGlvbiwgdW0gdm9tIFR5cGUgZWluZSBYSWRsQ2xhc3MgenUgYmVrb21tZW4gKioqCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKUmVmZXJlbmNlPFhJZGxDbGFzcz4gVHlwZVRvSWRsQ2xhc3MoIGNvbnN0IFR5cGUmIHJUeXBlLCBjb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4gJiB4TWdyICkKewoJc3RhdGljIFJlZmVyZW5jZTwgWElkbFJlZmxlY3Rpb24gPiB4UmVmbDsKCgkvLyB2b2lkIGFscyBEZWZhdWx0LUtsYXNzZSBlaW50cmFnZW4KCVJlZmVyZW5jZTxYSWRsQ2xhc3M+IHhSZXRDbGFzczsKCXR5cGVsaWJfVHlwZURlc2NyaXB0aW9uICogcFREID0gMDsKCXJUeXBlLmdldERlc2NyaXB0aW9uKCAmcFREICk7CglpZiggcFREICkKCXsKCQlPVVN0cmluZyBzT1dOYW1lKCBwVEQtPnBUeXBlTmFtZSApOwoJCWlmKCAheFJlZmwuaXMoKSApCgkJewoJCQl4UmVmbCA9IFJlZmVyZW5jZTwgWElkbFJlZmxlY3Rpb24gPiggeE1nci0+Y3JlYXRlSW5zdGFuY2UoCgkJCQlPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIucmVmbGVjdGlvbi5Db3JlUmVmbGVjdGlvbiIpICksIFVOT19RVUVSWSApOwoJCQlPU0xfRU5TVVJFKCB4UmVmbC5pcygpLCAiIyMjIG5vIGNvcmVyZWZsZWN0aW9uISIgKTsKCQl9CgkJeFJldENsYXNzID0geFJlZmwtPmZvck5hbWUoIHNPV05hbWUgKTsKCX0KCXJldHVybiB4UmV0Q2xhc3M7Cn0KCgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8qKiogSGlsZnMtRnVua3Rpb24sIHVtIEFueSBhbHMgVVN0cmluZyBhdXN6dWdlYmVuICoqKgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLy8gQUNIVFVORzogS2FubiBtYWwgYW4gZWluZSB6ZW50cmFsZSBTdGVsbGUgdWViZXJub21tZW4gd2VyZGVuCi8vIFdpcmQgenVuYWVjaHN0IG51ciBmdWVyIGVpbmZhY2hlIERhdGVudHlwZW4gYXVzZ2VmdWVocnQKCk9VU3RyaW5nIEFueVRvU3RyaW5nKCBjb25zdCBBbnkmIGFWYWx1ZSwgc2FsX0Jvb2wgYkluY2x1ZGVUeXBlLCBjb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4gJiB4TWdyICkKewoJVHlwZSBhVmFsVHlwZSA9IGFWYWx1ZS5nZXRWYWx1ZVR5cGUoKTsKCVR5cGVDbGFzcyBlVHlwZSA9IGFWYWxUeXBlLmdldFR5cGVDbGFzcygpOwoJY2hhciBwQnVmZmVyWzUwXTsKCglPVVN0cmluZyBhUmV0U3RyOwoJc3dpdGNoKCBlVHlwZSApCgl7CgkJY2FzZSBUeXBlQ2xhc3NfVFlQRToJCQlhUmV0U3RyID0gT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiVFlQRSBUWVBFIik7CQkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0lOVEVSRkFDRToJCWFSZXRTdHIgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJUWVBFIElOVEVSRkFDRSIpOwkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfU0VSVklDRToJCQlhUmV0U3RyID0gT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiVFlQRSBTRVJWSUNFIik7CQkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfU1RSVUNUOgkJCWFSZXRTdHIgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJUWVBFIFNUUlVDVCIpOwkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX1RZUEVERUY6CQkJYVJldFN0ciA9IE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlRZUEUgVFlQRURFRiIpOwkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX1VOSU9OOgkJCWFSZXRTdHIgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJUWVBFIFVOSU9OIik7CQkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfRU5VTToJCQlhUmV0U3RyID0gT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiVFlQRSBFTlVNIik7CQkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0VYQ0VQVElPTjoJCWFSZXRTdHIgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJUWVBFIEVYQ0VQVElPTiIpOwkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfQVJSQVk6CQkJYVJldFN0ciA9IE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlRZUEUgQVJSQVkiKTsJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19TRVFVRU5DRToJCWFSZXRTdHIgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJUWVBFIFNFUVVFTkNFIik7CQkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfVk9JRDoJCQlhUmV0U3RyID0gT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiVFlQRSB2b2lkIik7CQkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0FOWToJCQkJYVJldFN0ciA9IE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlRZUEUgYW55Iik7CQkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX1VOS05PV046CQkJYVJldFN0ciA9IE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlRZUEUgdW5rbm93biIpOwkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0JPT0xFQU46CgkJewoJCQlzYWxfQm9vbCBiID0gKihzYWxfQm9vbCopYVZhbHVlLmdldFZhbHVlKCk7CgkJCS8vYVJldC5zZXRWYWx1ZSggJmIsIGdldENwcHVCb29sZWFuVHlwZSgpICk7CgkJCS8vYVZhbHVlID4+PSBiOwoJCQlhUmV0U3RyID0gT1VTdHJpbmc6OnZhbHVlT2YoIGIgKTsKCQkJYnJlYWs7CgkJfQoJCWNhc2UgVHlwZUNsYXNzX0NIQVI6CgkJewoJCQlzYWxfVW5pY29kZSBjID0gKihzYWxfVW5pY29kZSopYVZhbHVlLmdldFZhbHVlKCk7CgkJCS8vYVZhbHVlID4+PSBjOwoJCQkvL2dldENwcHVDaGFyVHlwZSgpCgkJCWFSZXRTdHIgPSBPVVN0cmluZzo6dmFsdWVPZiggYyApOwoJCQlicmVhazsKCQl9CgkJY2FzZSBUeXBlQ2xhc3NfU1RSSU5HOgoJCXsKCQkJYVZhbHVlID4+PSBhUmV0U3RyOwoJCQlicmVhazsKCQl9CgkJY2FzZSBUeXBlQ2xhc3NfRkxPQVQ6CgkJewoJCQlmbG9hdCBmKDAuMCk7CgkJCWFWYWx1ZSA+Pj0gZjsKICAgICAgICAgICAgc25wcmludGYoIHBCdWZmZXIsIHNpemVvZiggcEJ1ZmZlciApLCAiJWYiLCBmICk7CgkJCWFSZXRTdHIgPSBPVVN0cmluZyggcEJ1ZmZlciwgc3RybGVuKCBwQnVmZmVyICksIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCQkJYnJlYWs7CgkJfQoJCWNhc2UgVHlwZUNsYXNzX0RPVUJMRToKCQl7CgkJCWRvdWJsZSBkKDAuMCk7CgkJCWFWYWx1ZSA+Pj0gZDsKICAgICAgICAgICAgc25wcmludGYoIHBCdWZmZXIsIHNpemVvZiggcEJ1ZmZlciApLCAiJWYiLCBkICk7CgkJCWFSZXRTdHIgPSBPVVN0cmluZyggcEJ1ZmZlciwgc3RybGVuKCBwQnVmZmVyICksIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCQkJYnJlYWs7CgkJfQoJCWNhc2UgVHlwZUNsYXNzX0JZVEU6CgkJewoJCQlzYWxfSW50OCBuKDApOwoJCQlhVmFsdWUgPj49IG47CgkJCWFSZXRTdHIgPSBPVVN0cmluZzo6dmFsdWVPZiggKHNhbF9JbnQzMikgbiApOwoJCQlicmVhazsKCQl9CgkJY2FzZSBUeXBlQ2xhc3NfU0hPUlQ6CgkJewoJCQlzYWxfSW50MTYgbigwKTsKCQkJYVZhbHVlID4+PSBuOwoJCQlhUmV0U3RyID0gT1VTdHJpbmc6OnZhbHVlT2YoIChzYWxfSW50MzIpIG4gKTsKCQkJYnJlYWs7CgkJfQoJCWNhc2UgVHlwZUNsYXNzX0xPTkc6CgkJewoJCQlzYWxfSW50MzIgbigwKTsKCQkJYVZhbHVlID4+PSBuOwoJCQlhUmV0U3RyID0gT1VTdHJpbmc6OnZhbHVlT2YoIG4gKTsKCQkJYnJlYWs7CgkJfQoJCS8qCgkJY2FzZSBUeXBlQ2xhc3NfSFlQRVI6CgkJewoJCQlhUmV0U3RyID0gTCJUWVBFIEhZUEVSIjsKCQkJYnJlYWs7CgkJfQoJCWNhc2UgVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUOgoJCXsKCQkJYVJldFN0ciA9IFN0cmluZ1RvVVN0cmluZyhXU1N0cmluZyhhVmFsdWUuZ2V0VUlOVDE2KCkpLCBDSEFSU0VUX1NZU1RFTSk7CgkJCWJyZWFrOwoJCX0KCQljYXNlIFR5cGVDbGFzc19VTlNJR05FRF9MT05HOgoJCXsKCQkJYVJldFN0ciA9IFN0cmluZ1RvVVN0cmluZyhXU1N0cmluZyhhVmFsdWUuZ2V0VUlOVDMyKCkpLCBDSEFSU0VUX1NZU1RFTSk7CgkJCWJyZWFrOwoJCX0KCQljYXNlIFR5cGVDbGFzc19VTlNJR05FRF9IWVBFUjoKCQl7CgkJCWFSZXRTdHIgPSBMIlRZUEUgVU5TSUdORURfSFlQRVIiOwoJCQlicmVhazsKCQl9CgkJKi8KCWRlZmF1bHQ6IDsKCX0KCglpZiggYkluY2x1ZGVUeXBlICkKCXsKCQlSZWZlcmVuY2U8IFhJZGxDbGFzcyA+IHhJZGxDbGFzcyA9IFR5cGVUb0lkbENsYXNzKCBhVmFsVHlwZSwgeE1nciApOwoJCWFSZXRTdHIgPSBhUmV0U3RyICsgT1VTdHJpbmcoIE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiAoVHlwOiAiKSApICsgeElkbENsYXNzLT5nZXROYW1lKCkgKyBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIpIik7Cgl9CglyZXR1cm4gYVJldFN0cjsKfQoKLyoKLy8gSGlsZnMtRnVua3Rpb24sIHVtIGVpbiBVU3RyaW5nIGluIGVpbmVuIEFueSB6dSBrb252ZXJ0aWVyZW4KVXNyQW55IFN0cmluZ1RvQW55KCBVU3RyaW5nIGFTdHIsIFR5cGVDbGFzcyBlVGFyZ2V0VHlwZSApCnsKCVVzckFueSBhUmV0QW55OwoJc3dpdGNoKCBlVGFyZ2V0VHlwZSApCgl7CgkJY2FzZSBUeXBlQ2xhc3NfSU5URVJGQUNFOgkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfU0VSVklDRToJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19TVFJVQ1Q6CQkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfVFlQRURFRjoJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19VTklPTjoJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19FTlVNOgkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0VYQ0VQVElPTjoJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0FSUkFZOgkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX1NFUVVFTkNFOgkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfVk9JRDoJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19BTlk6CQkJCWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX1VOS05PV046CQkJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfQk9PTEVBTjoJCQlhUmV0QW55LnNldEJPT0woIHNob3J0KGFTdHIpIT0wICk7CWJyZWFrOwoJCWNhc2UgVHlwZUNsYXNzX0NIQVI6CQkJYVJldEFueS5zZXRDaGFyKCBjaGFyKGFTdHIpICk7CQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19TVFJJTkc6CQkJYVJldEFueS5zZXRTdHJpbmcoIGFTdHIgKTsJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19GTE9BVDoJCQlhUmV0QW55LnNldEZsb2F0KCAoZmxvYXQpc3RydG9kKCBhU3RyLkdldFN0cigpLCBOVUxMICkgKTsJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfRE9VQkxFOgkJCWFSZXRBbnkuc2V0RG91YmxlKCBzdHJ0b2QoIGFTdHIuR2V0U3RyKCksIE5VTEwgKSApOwlicmVhazsKCQljYXNlIFR5cGVDbGFzc19CWVRFOgkJCWFSZXRBbnkuc2V0QllURSggQllURShzaG9ydChhU3RyKSkgKTsJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfU0hPUlQ6CQkJYVJldEFueS5zZXRJTlQxNiggc2hvcnQoYVN0cikgKTsJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfTE9ORzoJCQlhUmV0QW55LnNldElOVDMyKCBsb25nKGFTdHIpICk7CQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19IWVBFUjoJCQlicmVhazsKCQljYXNlIFR5cGVDbGFzc19VTlNJR05FRF9TSE9SVDoJYVJldEFueS5zZXRVSU5UMTYoIFVTSE9SVChhU3RyKSApOwlicmVhazsKCQljYXNlIFR5cGVDbGFzc19VTlNJR05FRF9MT05HOglhUmV0QW55LnNldFVJTlQzMiggVUxPTkcoYVN0cikgKTsJYnJlYWs7CgkJY2FzZSBUeXBlQ2xhc3NfVU5TSUdORURfSFlQRVI6CWJyZWFrOwoJfQoJcmV0dXJuIGFSZXRBbnk7Cn0KKi8KCgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vKioqIFhQcm9wZXJ0eVNldEluZm8gZnVlciBUZXN0LUtsYXNzZSAqKioKLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKY2xhc3MgSW1wbFByb3BlcnR5U2V0SW5mbyA6IHB1YmxpYyBJbXBsUHJvcGVydHlTZXRJbmZvSGVscGVyCnsKIAlmcmllbmQgY2xhc3MgSW1wbEludHJvVGVzdDsKCiAgCVJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiBteE1ncjsKCnB1YmxpYzoKCUltcGxQcm9wZXJ0eVNldEluZm8oIGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiAmIHhNZ3IgKQoJCTogbXhNZ3IoIHhNZ3IgKSB7fQoJCS8vOiBteE1nciggeE1nciApLCBJbXBsUHJvcGVydHlTZXRJbmZvSGVscGVyKCB4TWdyICkge30KCi8qCgkvLyBNZXRob2RlbiB2b24gWEludGVyZmFjZQoJdmlydHVhbCBzYWxfQm9vbAlTQUxfQ0FMTCBxdWVyeUludGVyZmFjZSggY29uc3QgVWlrICYgclVpaywgQW55ICYgaWZjICkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKTsKCXZpcnR1YWwgdm9pZAkJU0FMX0NBTEwgYWNxdWlyZSgpIHRocm93KCkgeyBPV2Vha09iamVjdDo6YWNxdWlyZSgpOyB9Cgl2aXJ0dWFsIHZvaWQJCVNBTF9DQUxMIHJlbGVhc2UoKSB0aHJvdygpIHsgT1dlYWtPYmplY3Q6OnJlbGVhc2UoKTsgfQoJLy9BTFQ6IHNhbF9Cb29sIHF1ZXJ5SW50ZXJmYWNlKCBVaWsgYVVpaywgUmVmZXJlbmNlPFhJbnRlcmZhY2U+ICYgck91dCApOwoqLwoKICAgIC8vIE1ldGhvZHMgb2YgWFByb3BlcnR5U2V0SW5mbwogICAgdmlydHVhbCBTZXF1ZW5jZTwgUHJvcGVydHkgPiBTQUxfQ0FMTCBnZXRQcm9wZXJ0aWVzKCAgKQoJCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pOwogICAgdmlydHVhbCBQcm9wZXJ0eSBTQUxfQ0FMTCBnZXRQcm9wZXJ0eUJ5TmFtZSggY29uc3QgT1VTdHJpbmcmIGFOYW1lICkKCQl0aHJvdyhVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pOwogICAgdmlydHVhbCBzYWxfQm9vbCBTQUxfQ0FMTCBoYXNQcm9wZXJ0eUJ5TmFtZSggY29uc3QgT1VTdHJpbmcmIE5hbWUgKQoJCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pOwogICAgLy92aXJ0dWFsIFNlcXVlbmNlPCBQcm9wZXJ0eSA+IFNBTF9DQUxMIGdldFByb3BlcnRpZXModm9pZCkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKTsKICAgIC8vdmlydHVhbCBQcm9wZXJ0eSBTQUxfQ0FMTCBnZXRQcm9wZXJ0eUJ5TmFtZShjb25zdCBPVVN0cmluZyYgTmFtZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKTsKICAgIC8vdmlydHVhbCBzYWxfQm9vbCBTQUxfQ0FMTCBoYXNQcm9wZXJ0eUJ5TmFtZShjb25zdCBPVVN0cmluZyYgTmFtZSkgdGhyb3coIFJ1bnRpbWVFeGNlcHRpb24gKTsKfTsKCgovKgovLyBNZXRob2RlbiB2b24gWEludGVyZmFjZQpzYWxfQm9vbCBTQUxfQ0FMTCBJbXBsUHJvcGVydHlTZXRJbmZvOjpxdWVyeUludGVyZmFjZSggY29uc3QgVWlrICYgclVpaywgQW55ICYgaWZjICkKCXRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJLy8gUHJvcGVydHlTZXQtSW1wbGVtZW50YXRpb24KCWlmKCBjb206OnN1bjo6c3Rhcjo6dW5vOjpxdWVyeUludGVyZmFjZSggclVpaywgaWZjLAoJCQkJCQkJCQkJCSBTQUxfU1RBVElDX0NBU1QoWFByb3BlcnR5U2V0SW5mbyosIHRoaXMpICkgKQoJCXJldHVybiBzYWxfVHJ1ZTsKCglyZXR1cm4gT1dlYWtPYmplY3Q6OnF1ZXJ5SW50ZXJmYWNlKCByVWlrLCBpZmMgKTsKfQoKc2FsX0Jvb2wgSW1wbFByb3BlcnR5U2V0SW5mbzo6cXVlcnlJbnRlcmZhY2UoIFVpayBhVWlrLCBSZWZlcmVuY2U8WEludGVyZmFjZT4gJiByT3V0ICkKewoJaWYoIGFVaWsgPT0gWFByb3BlcnR5U2V0SW5mbzo6Z2V0U21hcnRVaWsoKSApCgkJck91dCA9IChYUHJvcGVydHlTZXRJbmZvICopdGhpczsKCWVsc2UKCQlVc3JPYmplY3Q6OnF1ZXJ5SW50ZXJmYWNlKCBhVWlrLCByT3V0ICk7CglyZXR1cm4gck91dC5pcygpOwp9CiovCgpTZXF1ZW5jZTwgUHJvcGVydHkgPiBJbXBsUHJvcGVydHlTZXRJbmZvOjpnZXRQcm9wZXJ0aWVzKHZvaWQpCgl0aHJvdyggUnVudGltZUV4Y2VwdGlvbiApCnsKCXN0YXRpYyBTZXF1ZW5jZTxQcm9wZXJ0eT4gKiBwU2VxID0gTlVMTDsKCglpZiggIXBTZXEgKQoJewoJCS8vIGRpZSBJbmZvcm1hdGlvbmVuIGb8ciBkaWUgUHJvcGVydGllcyAiV2lkdGgiLCAiSGVpZ2h0IiB1bmQgIk5hbWUiIGFubGVnZW4KCQlwU2VxID0gbmV3IFNlcXVlbmNlPFByb3BlcnR5PiggMyApOwoJCVByb3BlcnR5ICogcEFyeSA9IHBTZXEtPmdldEFycmF5KCk7CgoJCXBBcnlbMF0uTmFtZSA9IE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIkZhY3RvciIpOwoJCXBBcnlbMF0uSGFuZGxlID0gLTE7CgkJcEFyeVswXS5UeXBlID0gZ2V0Q3BwdVR5cGUoIChkb3VibGUqKSBOVUxMICk7CgkJLy9wQXJ5WzBdLlR5cGUgPSBUeXBlVG9JZGxDbGFzcyggZ2V0Q3BwdVR5cGUoIChkb3VibGUqKSBOVUxMICksIG14TWdyICk7CgkJLy9wQXJ5WzBdLlR5cGUgPSBEb3VibGVfZ2V0UmVmbGVjdGlvbigpLT5nZXRJZGxDbGFzcygpOwoJCXBBcnlbMF0uQXR0cmlidXRlcyA9IEJPVU5EIHwgVFJBTlNJRU5UOwoKCQlwQXJ5WzFdLk5hbWUgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJNeUNvdW50Iik7CgkJcEFyeVsxXS5IYW5kbGUgPSAtMTsKCQlwQXJ5WzFdLlR5cGUgPSBnZXRDcHB1VHlwZSggKHNhbF9JbnQzMiopIE5VTEwgKTsKCQkvL3BBcnlbMV0uVHlwZSA9IFR5cGVUb0lkbENsYXNzKCBnZXRDcHB1VHlwZSggKHNhbF9JbnQzMiopIE5VTEwgKSwgbXhNZ3IgKTsKCQkvL3BBcnlbMV0uVHlwZSA9IElOVDMyX2dldFJlZmxlY3Rpb24oKS0+Z2V0SWRsQ2xhc3MoKTsKCQlwQXJ5WzFdLkF0dHJpYnV0ZXMgPSBCT1VORCB8IFRSQU5TSUVOVDsKCgkJcEFyeVsyXS5OYW1lID0gT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiSW5mbyIpOwoJCXBBcnlbMl0uSGFuZGxlID0gLTE7CgkJcEFyeVsyXS5UeXBlID0gZ2V0Q3BwdVR5cGUoIChPVVN0cmluZyopIE5VTEwgKTsKCQkvL3BBcnlbMl0uVHlwZSA9IFR5cGVUb0lkbENsYXNzKCBnZXRDcHB1VHlwZSggKE9VU3RyaW5nKikgTlVMTCApLCBteE1nciApOwoJCS8vcEFyeVsyXS5UeXBlID0gT1VTdHJpbmdfZ2V0UmVmbGVjdGlvbigpLT5nZXRJZGxDbGFzcygpOwoJCXBBcnlbMl0uQXR0cmlidXRlcyA9IFRSQU5TSUVOVDsKCX0KCS8vIERpZSBJbmZvcm1hdGlvbiD8YmVyIGFsbGUgZHJlaSBQcm9wZXJ0aWVzIGxpZWZlcm4uCglyZXR1cm4gKnBTZXE7Cn0KClByb3BlcnR5IEltcGxQcm9wZXJ0eVNldEluZm86OmdldFByb3BlcnR5QnlOYW1lKGNvbnN0IE9VU3RyaW5nJiBOYW1lKQoJdGhyb3coIFVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbiApCnsKCVNlcXVlbmNlPFByb3BlcnR5PiBhU2VxID0gZ2V0UHJvcGVydGllcygpOwoJY29uc3QgUHJvcGVydHkgKiBwQXJ5ID0gYVNlcS5nZXRDb25zdEFycmF5KCk7CgoJZm9yKCBzYWxfSW50MzIgaSA9IGFTZXEuZ2V0TGVuZ3RoKCk7IGktLTsgKQoJewoJCWlmKCBwQXJ5W2ldLk5hbWUgPT0gTmFtZSApCgkJCXJldHVybiBwQXJ5W2ldOwoJfQoJLy8gUHJvcGVydHkgdW5iZWthbm50LCBhbHNvIGxlZXJlIGxpZWZlcm4KCXJldHVybiBQcm9wZXJ0eSgpOwp9CgpzYWxfQm9vbCBJbXBsUHJvcGVydHlTZXRJbmZvOjpoYXNQcm9wZXJ0eUJ5TmFtZShjb25zdCBPVVN0cmluZyYgTmFtZSkKCXRocm93KCBSdW50aW1lRXhjZXB0aW9uICkKewoJU2VxdWVuY2U8UHJvcGVydHk+IGFTZXEgPSBnZXRQcm9wZXJ0aWVzKCk7Cgljb25zdCBQcm9wZXJ0eSAqIHBBcnkgPSBhU2VxLmdldENvbnN0QXJyYXkoKTsKCglmb3IoIHNhbF9JbnQzMiBpID0gYVNlcS5nZXRMZW5ndGgoKTsgaS0tOyApCgl7CgkJaWYoIHBBcnlbaV0uTmFtZSA9PSBOYW1lICkKCQkJcmV0dXJuIHNhbF9UcnVlOwoJfQoJLy8gUHJvcGVydHkgdW5iZWthbm50LCBhbHNvIGxlZXJlIGxpZWZlcm4KCXJldHVybiBzYWxfRmFsc2U7Cn0KCgoKCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCgoKY2xhc3MgSW1wbEludHJvVGVzdCA6IHB1YmxpYyBJbXBsSW50cm9UZXN0SGVscGVyCnsKICAJUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+IG14TWdyOwoKCWZyaWVuZCBjbGFzcyBJbXBsUHJvcGVydHlTZXRJbmZvOwoKCS8vIFByb3BlcnRpZXMgZnVlciBkYXMgUHJvcGVydHlTZXQKCUFueSBhQW55QXJyYXlbMTBdOwoKCS8vIE9wdGlvbmFsZSBTY2huaXR0c3RlbGxlIGZ1ZXIgZGllIHdyaXRlbG4tQXVzZ2FiZQoJLy9JbnRyb1Rlc3RXcml0ZWxuT3V0cHV0KiBtX3BPdXRwdXQ7CgoJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4gbV94TXlJbmZvOwoKCU9VU3RyaW5nIG1fT2JqZWN0TmFtZTsKCglzYWxfSW50MTYgbV9uTWFya3VzQWdlOwoJc2FsX0ludDE2IG1fbk1hcmt1c0NoaWxkcmVuQ291bnQ7CgoJbG9uZyBtX2xEcm9lbms7CglzYWxfSW50MTYgbV9uQmxhOwoJc2FsX0ludDE2IG1fbkJsdWI7CglzYWxfSW50MTYgbV9uR3VscDsKCXNhbF9JbnQxNiBtX25MYWJlcjsKCVR5cGVDbGFzcyBlVHlwZUNsYXNzOwoJU2VxdWVuY2U8IE9VU3RyaW5nID4gYVN0cmluZ1NlcTsKCVNlcXVlbmNlPCBTZXF1ZW5jZTwgU2VxdWVuY2U8IHNhbF9JbnQxNiA+ID4gPiBhTXVsdFNlcTsKCVJlZmVyZW5jZTwgWEludHJvVGVzdCA+IG1feEludHJvVGVzdDsKCgkvLyBEYXRlbiBmdWVyIE5hbWVBY2Nlc3MKCVJlZmVyZW5jZTwgWEludHJvVGVzdCA+KiBwTmFtZUFjY2Vzc1RhYjsKCgkvLyBEYXRlbiBmdWVyIEluZGV4QWNjZXNzCglSZWZlcmVuY2U8IFhJbnRyb1Rlc3QgPiogcEluZGV4QWNjZXNzVGFiOwoJc2FsX0ludDE2IGlJbmRleEFjY2Vzc0NvdW50OwoKCS8vIHN0cnVjdC1Qcm9wZXJ0aWVzCiAgICBQcm9wZXJ0eSBtX2FGaXJzdFN0cnVjdDsKICAgIFByb3BlcnR5VmFsdWUgbV9hU2Vjb25kU3RydWN0OwoKCS8vIExpc3RlbmVyIG1lcmtlbiAoenVuYWVjaHN0IGVpbmZhY2gsIG51ciBlaW5lbiBwcm8gUHJvcGVydHkpCglSZWZlcmVuY2U8IFhQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyID4gYVByb3BDaGFuZ2VMaXN0ZW5lcjsKCU9VU3RyaW5nIGFQcm9wQ2hhbmdlTGlzdGVuZXJTdHI7CglSZWZlcmVuY2U8IFhWZXRvYWJsZUNoYW5nZUxpc3RlbmVyID4gYVZldG9Qcm9wQ2hhbmdlTGlzdGVuZXI7CglPVVN0cmluZyBhVmV0b1Byb3BDaGFuZ2VMaXN0ZW5lclN0cjsKCgl2b2lkIEluaXQoIHZvaWQgKTsKCnB1YmxpYzoKCUltcGxJbnRyb1Rlc3QoIGNvbnN0IFJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiAmIHhNZ3IgKQoJCTogbXhNZ3IoIHhNZ3IgKQoJCS8vOiBteE1nciggeE1nciApLCBJbXBsSW50cm9UZXN0SGVscGVyKCB4TWdyICkKCXsKCQlJbml0KCk7Cgl9CgoJLyoKCUltcGxJbnRyb1Rlc3QoIEludHJvVGVzdFdyaXRlbG5PdXRwdXQqIHBPdXRwdXRfICkKCXsKCQlJbml0KCk7CgkJbV9wT3V0cHV0ID0gcE91dHB1dF87Cgl9CgkqLwoKCS8vU01BUlRfVU5PX0RFQ0xBUkFUSU9OKEltcGxJbnRyb1Rlc3QsVXNyT2JqZWN0KTsKCgkvL0JPT0wgcXVlcnlJbnRlcmZhY2UoIFVpayBhVWlrLCBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiAmIHJPdXQgKTsKCS8vUmVmZXJlbmNlPCBYSWRsQ2xhc3MgPiBnZXRJZGxDbGFzcygpOwoKCS8vIFRyb3R6IHZpcnR1YWwgaW5saW5lLCB1bSBTY2hyZWliYXJiZWl0IHp1IHNwYXJlbiAobnVyIGZ1ZXIgVGVzdHp3ZWNrZSkKCS8vIFhQcm9wZXJ0eVNldAogICAgdmlydHVhbCBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiBTQUxfQ0FMTCBnZXRQcm9wZXJ0eVNldEluZm8oICApCgkJdGhyb3coUnVudGltZUV4Y2VwdGlvbik7CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0UHJvcGVydHlWYWx1ZSggY29uc3QgT1VTdHJpbmcmIGFQcm9wZXJ0eU5hbWUsIGNvbnN0IEFueSYgYVZhbHVlICkKCQl0aHJvdyhVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIFByb3BlcnR5VmV0b0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKTsKICAgIHZpcnR1YWwgQW55IFNBTF9DQUxMIGdldFByb3BlcnR5VmFsdWUoIGNvbnN0IE9VU3RyaW5nJiBQcm9wZXJ0eU5hbWUgKQoJCXRocm93KFVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgV3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbik7CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciggY29uc3QgT1VTdHJpbmcmIC8qYVByb3BlcnR5TmFtZSovLCBjb25zdCBSZWZlcmVuY2U8IFhQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyID4mIC8qeExpc3RlbmVyKi8gKQoJCXRocm93KFVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgV3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKCQkJe30KICAgIHZpcnR1YWwgdm9pZCBTQUxfQ0FMTCByZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCBjb25zdCBPVVN0cmluZyYgLyphUHJvcGVydHlOYW1lKi8sIGNvbnN0IFJlZmVyZW5jZTwgWFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgPiYgLyphTGlzdGVuZXIqLyApCgkJdGhyb3coVW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQoJCQl7fQogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIGFkZFZldG9hYmxlQ2hhbmdlTGlzdGVuZXIoIGNvbnN0IE9VU3RyaW5nJiAvKlByb3BlcnR5TmFtZSovLCBjb25zdCBSZWZlcmVuY2U8IFhWZXRvYWJsZUNoYW5nZUxpc3RlbmVyID4mIC8qYUxpc3RlbmVyKi8gKQoJCXRocm93KFVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgV3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKCQkJe30KICAgIHZpcnR1YWwgdm9pZCBTQUxfQ0FMTCByZW1vdmVWZXRvYWJsZUNoYW5nZUxpc3RlbmVyKCBjb25zdCBPVVN0cmluZyYgLypQcm9wZXJ0eU5hbWUqLywgY29uc3QgUmVmZXJlbmNlPCBYVmV0b2FibGVDaGFuZ2VMaXN0ZW5lciA+JiAvKmFMaXN0ZW5lciovICkKCQl0aHJvdyhVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIFdyYXBwZWRUYXJnZXRFeGNlcHRpb24sIFJ1bnRpbWVFeGNlcHRpb24pCgkJCXt9CgoJLyoKICAgIHZpcnR1YWwgdm9pZCBzZXRJbmRleGVkUHJvcGVydHlWYWx1ZShjb25zdCBPVVN0cmluZyYgYVByb3BlcnR5TmFtZSwgSU5UMzIgbkluZGV4LCBjb25zdCBBbnkmIGFWYWx1ZSkge30KICAgIHZpcnR1YWwgQW55IGdldEluZGV4ZWRQcm9wZXJ0eVZhbHVlKGNvbnN0IFVTdHJpbmcmIGFQcm9wZXJ0eU5hbWUsIElOVDMyIG5JbmRleCkgY29uc3QgeyByZXR1cm4gQW55KCk7IH0KICAgIHZpcnR1YWwgdm9pZCBhZGRQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKGNvbnN0IFVTdHJpbmcmIGFQcm9wZXJ0eU5hbWUsIGNvbnN0IFhQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUmVmJiBhTGlzdGVuZXIpCgkJVEhST1dTKCAoVW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICkge30KICAgIHZpcnR1YWwgdm9pZCByZW1vdmVQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKGNvbnN0IFVTdHJpbmcmIGFQcm9wZXJ0eU5hbWUsIGNvbnN0IFhQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyUmVmJiBhTGlzdGVuZXIpCgkJVEhST1dTKCAoVW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICkge30KICAgIHZpcnR1YWwgdm9pZCBhZGRWZXRvYWJsZUNoYW5nZUxpc3RlbmVyKGNvbnN0IFVTdHJpbmcmIGFQcm9wZXJ0eU5hbWUsIGNvbnN0IFhWZXRvYWJsZUNoYW5nZUxpc3RlbmVyUmVmJiBhTGlzdGVuZXIpCgkJVEhST1dTKCAoVW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICkge30KICAgIHZpcnR1YWwgdm9pZCByZW1vdmVWZXRvYWJsZUNoYW5nZUxpc3RlbmVyKGNvbnN0IFVTdHJpbmcmIGFQcm9wZXJ0eU5hbWUsIGNvbnN0IFhWZXRvYWJsZUNoYW5nZUxpc3RlbmVyUmVmJiBhTGlzdGVuZXIpCgkJVEhST1dTKCAoVW5rbm93blByb3BlcnR5RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICkge30KCQkqLwoKCS8vIFhJbnRyb1Rlc3QtTWV0aG9kZW4KICAgIC8vIEF0dHJpYnV0ZXMKICAgIHZpcnR1YWwgT1VTdHJpbmcgU0FMX0NBTEwgZ2V0T2JqZWN0TmFtZSgpIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyByZXR1cm4gbV9PYmplY3ROYW1lOyB9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0T2JqZWN0TmFtZSggY29uc3QgT1VTdHJpbmcmIF9vYmplY3RuYW1lICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IG1fT2JqZWN0TmFtZSA9IF9vYmplY3RuYW1lOyB9CiAgICB2aXJ0dWFsIE9VU3RyaW5nIFNBTF9DQUxMIGdldEZpcnN0TmFtZSgpCgkJdGhyb3coUnVudGltZUV4Y2VwdGlvbik7CiAgICB2aXJ0dWFsIE9VU3RyaW5nIFNBTF9DQUxMIGdldExhc3ROYW1lKCkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IHJldHVybiBPVVN0cmluZyggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiTWV5ZXIiKSApOyB9CiAgICB2aXJ0dWFsIHNhbF9JbnQxNiBTQUxfQ0FMTCBnZXRBZ2UoKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQoJCXsgcmV0dXJuIG1fbk1hcmt1c0FnZTsgfQogICAgdmlydHVhbCBzYWxfSW50MTYgU0FMX0NBTEwgZ2V0Q2hpbGRyZW5Db3VudCgpIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyByZXR1cm4gbV9uTWFya3VzQ2hpbGRyZW5Db3VudDsgfQogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIHNldENoaWxkcmVuQ291bnQoIHNhbF9JbnQxNiBfY2hpbGRyZW5jb3VudCApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyBtX25NYXJrdXNDaGlsZHJlbkNvdW50ID0gX2NoaWxkcmVuY291bnQ7IH0KICAgIHZpcnR1YWwgUHJvcGVydHkgU0FMX0NBTEwgZ2V0Rmlyc3RTdHJ1Y3QoKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQoJCXsgcmV0dXJuIG1fYUZpcnN0U3RydWN0OyB9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0Rmlyc3RTdHJ1Y3QoIGNvbnN0IFByb3BlcnR5JiBfZmlyc3RzdHJ1Y3QgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQoJCXsgbV9hRmlyc3RTdHJ1Y3QgPSBfZmlyc3RzdHJ1Y3Q7IH0KICAgIHZpcnR1YWwgUHJvcGVydHlWYWx1ZSBTQUxfQ0FMTCBnZXRTZWNvbmRTdHJ1Y3QoKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQoJCXsgcmV0dXJuIG1fYVNlY29uZFN0cnVjdDsgfQogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIHNldFNlY29uZFN0cnVjdCggY29uc3QgUHJvcGVydHlWYWx1ZSYgX3NlY29uZHN0cnVjdCApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyBtX2FTZWNvbmRTdHJ1Y3QgPSBfc2Vjb25kc3RydWN0OyB9CgogICAgLy8gTWV0aG9kcwogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIHdyaXRlbG4oIGNvbnN0IE9VU3RyaW5nJiBUZXh0ICkKCQl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKTsKICAgIHZpcnR1YWwgc2FsX0ludDMyIFNBTF9DQUxMIGdldERyb2VuayggICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IHJldHVybiBtX2xEcm9lbms7IH0KICAgIHZpcnR1YWwgUmVmZXJlbmNlPCA6Ok1vZHVsZUE6OlhJbnRyb1Rlc3QgPiBTQUxfQ0FMTCBnZXRJbnRyb1Rlc3QoICApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pOwogICAgdmlydHVhbCBzYWxfSW50MzIgU0FMX0NBTEwgZ2V0VXBzKCBzYWxfSW50MzIgbCApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyByZXR1cm4gMipsOyB9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0RHJvZW5rKCBzYWxfSW50MzIgbCApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyBtX2xEcm9lbmsgPSBsOyB9CiAgICB2aXJ0dWFsIHNhbF9JbnQxNiBTQUxfQ0FMTCBnZXRCbGEoICApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyByZXR1cm4gbV9uQmxhOyB9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0QmxhKCBzYWxfSW50MzIgbiApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyBtX25CbGEgPSAoc2FsX0ludDE2KW47IH0KICAgIHZpcnR1YWwgc2FsX0ludDE2IFNBTF9DQUxMIGdldEJsdWIoICApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyByZXR1cm4gbV9uQmx1YjsgfQogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIHNldEJsdWIoIHNhbF9JbnQxNiBuICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IG1fbkJsdWIgPSBuOyB9CiAgICB2aXJ0dWFsIHNhbF9JbnQxNiBTQUxfQ0FMTCBnZXRHdWxwKCAgKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQoJCXsgcmV0dXJuIG1fbkd1bHA7IH0KICAgIHZpcnR1YWwgc2FsX0ludDE2IFNBTF9DQUxMIHNldEd1bHAoIHNhbF9JbnQxNiBuICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IG1fbkd1bHAgPSBuOyByZXR1cm4gMTsgfQogICAgdmlydHVhbCBUeXBlQ2xhc3MgU0FMX0NBTEwgZ2V0VHlwZUNsYXNzKCBzYWxfSW50MTYgLypuKi8gKSB0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQoJCXsgcmV0dXJuIGVUeXBlQ2xhc3M7IH0KICAgIHZpcnR1YWwgdm9pZCBTQUxfQ0FMTCBzZXRUeXBlQ2xhc3MoIFR5cGVDbGFzcyB0LCBkb3VibGUgLypkMSovLCBkb3VibGUgLypkMiovICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IGVUeXBlQ2xhc3MgPSB0OyB9CiAgICB2aXJ0dWFsIFNlcXVlbmNlPCBPVVN0cmluZyA+IFNBTF9DQUxMIGdldFN0cmluZ3MoICApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyByZXR1cm4gYVN0cmluZ1NlcTsgfQogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIHNldFN0cmluZ3MoIGNvbnN0IFNlcXVlbmNlPCBPVVN0cmluZyA+JiBTdHJpbmdzICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IGFTdHJpbmdTZXEgPSBTdHJpbmdzOyB9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgc2V0U3RyaW5nc1Blck1ldGhvZCggY29uc3QgU2VxdWVuY2U8IE9VU3RyaW5nID4mIFN0cmluZ3MsIHNhbF9JbnQxNiAvKm4qLyApIHRocm93KFJ1bnRpbWVFeGNlcHRpb24pCgkJeyBhU3RyaW5nU2VxID0gU3RyaW5nczsgfQogICAgdmlydHVhbCBTZXF1ZW5jZTwgU2VxdWVuY2U8IFNlcXVlbmNlPCBzYWxfSW50MTYgPiA+ID4gU0FMX0NBTEwgZ2V0TXVsdGlTZXF1ZW5jZSggICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IHJldHVybiBhTXVsdFNlcTsgfQogICAgdmlydHVhbCB2b2lkIFNBTF9DQUxMIHNldE11bHRpU2VxdWVuY2UoIGNvbnN0IFNlcXVlbmNlPCBTZXF1ZW5jZTwgU2VxdWVuY2U8IHNhbF9JbnQxNiA+ID4gPiYgU2VxICkgdGhyb3coUnVudGltZUV4Y2VwdGlvbikKCQl7IGFNdWx0U2VxID0gU2VxOyB9CiAgICB2aXJ0dWFsIHZvaWQgU0FMX0NBTEwgYWRkUHJvcGVydGllc0NoYW5nZUxpc3RlbmVyKCBjb25zdCBTZXF1ZW5jZTwgT1VTdHJpbmcgPiYgUHJvcGVydHlOYW1lcywgY29uc3QgUmVmZXJlbmNlPCBYUHJvcGVydGllc0NoYW5nZUxpc3RlbmVyID4mIExpc3RlbmVyICkKCQl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKTsKICAgIHZpcnR1YWwgdm9pZCBTQUxfQ0FMTCByZW1vdmVQcm9wZXJ0aWVzQ2hhbmdlTGlzdGVuZXIoIGNvbnN0IFJlZmVyZW5jZTwgWFByb3BlcnRpZXNDaGFuZ2VMaXN0ZW5lciA+JiBMaXN0ZW5lciApCgkJdGhyb3coUnVudGltZUV4Y2VwdGlvbik7CgoKICAgIC8vIE1ldGhvZHMgb2YgWEVsZW1lbnRBY2Nlc3MKICAgIHZpcnR1YWwgVHlwZSBTQUxfQ0FMTCBnZXRFbGVtZW50VHlwZSggICkKCQl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKTsKICAgIHZpcnR1YWwgc2FsX0Jvb2wgU0FMX0NBTEwgaGFzRWxlbWVudHMoICApCgkJdGhyb3coUnVudGltZUV4Y2VwdGlvbik7CiAgICAvL3ZpcnR1YWwgWElkbENsYXNzUmVmIGdldEVsZW1lbnRUeXBlKHZvaWQpIGNvbnN0VEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApOwogICAgLy92aXJ0dWFsIEJPT0wgaGFzRWxlbWVudHModm9pZCkgY29uc3QgVEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApOwoKCS8vIFhOYW1lQWNjZXNzLU1ldGhvZGVuCiAgICAvLyBNZXRob2RzCiAgICB2aXJ0dWFsIEFueSBTQUxfQ0FMTCBnZXRCeU5hbWUoIGNvbnN0IE9VU3RyaW5nJiBhTmFtZSApCgkJdGhyb3coTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiwgV3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbik7CiAgICB2aXJ0dWFsIFNlcXVlbmNlPCBPVVN0cmluZyA+IFNBTF9DQUxMIGdldEVsZW1lbnROYW1lcyggICkKCQl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKTsKICAgIHZpcnR1YWwgc2FsX0Jvb2wgU0FMX0NBTEwgaGFzQnlOYW1lKCBjb25zdCBPVVN0cmluZyYgYU5hbWUgKQoJCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pOwogICAgLy92aXJ0dWFsIEFueSBnZXRCeU5hbWUoY29uc3QgVVN0cmluZyYgTmFtZSkgY29uc3QKCQkvL1RIUk9XUyggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24sIFdyYXBwZWRUYXJnZXRFeGNlcHRpb24sIFVzclN5c3RlbUV4Y2VwdGlvbikgKTsKICAgIC8vdmlydHVhbCBTZXF1ZW5jZTxVU3RyaW5nPiBnZXRFbGVtZW50TmFtZXModm9pZCkgY29uc3QgVEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApOwogICAgLy92aXJ0dWFsIEJPT0wgaGFzQnlOYW1lKGNvbnN0IFVTdHJpbmcmIE5hbWUpIGNvbnN0IFRIUk9XUyggKFVzclN5c3RlbUV4Y2VwdGlvbikgKTsKCgkvLyBYSW5kZXhBY2Nlc3MtTWV0aG9kZW4KICAgIC8vIE1ldGhvZHMKICAgIHZpcnR1YWwgc2FsX0ludDMyIFNBTF9DQUxMIGdldENvdW50KCAgKQoJCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pOwogICAgdmlydHVhbCBBbnkgU0FMX0NBTEwgZ2V0QnlJbmRleCggc2FsX0ludDMyIEluZGV4ICkKCQl0aHJvdyhJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKTsKICAgIC8vdmlydHVhbCBJTlQzMiBnZXRDb3VudCh2b2lkKSBjb25zdCBUSFJPV1MoIChVc3JTeXN0ZW1FeGNlcHRpb24pICk7CiAgICAvL3ZpcnR1YWwgQW55IGdldEJ5SW5kZXgoSU5UMzIgSW5kZXgpIGNvbnN0CgkJLy9USFJPV1MoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICk7Cn07CgovL1NNQVJUX1VOT19JTVBMRU1FTlRBVElPTihJbXBsSW50cm9UZXN0LFVzck9iamVjdCkKCnZvaWQgSW1wbEludHJvVGVzdDo6SW5pdCggdm9pZCApCnsKCS8vIEVpbmRldXRpZ2VuIE5hbWVuIHZlcnBhc3NlbgoJc3RhdGljIHNhbF9JbnQzMiBuT2JqQ291bnQgPSAwOwoJT1VTdHJpbmcgYU5hbWUoIE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIkludHJvVGVzdC1PYmogTnIuICIpICk7CglhTmFtZSArPSBPVVN0cmluZzo6dmFsdWVPZiggbk9iakNvdW50ICk7CglzZXRPYmplY3ROYW1lKCBhTmFtZSApOwoKCS8vIFByb3BlcnRpZXMgaW5pdGlhbGlzaWVyZW4KCWFBbnlBcnJheVswXSA8PD0gMy4xNDsKCWFBbnlBcnJheVsxXSA8PD0gKHNhbF9JbnQzMik0MjsKCWFBbnlBcnJheVsyXSA8PD0gT1VTdHJpbmcoIE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIkhhbGxvIikgKTsKCgkvLyBPdXRwdXQtSW50ZXJmYWNlCgkvL21fcE91dHB1dCA9IE5VTEw7CgoJLy8gRWlubWFsIGZ1ZXIgZGVuIGludGVybmVuIEdlYnJhdWNoIGRpZSBQcm9wZXJ0eVNldEluZm8gYWJob2xlbgoJbV94TXlJbmZvID0gZ2V0UHJvcGVydHlTZXRJbmZvKCk7CgltX3hNeUluZm8tPmFjcXVpcmUoKTsJCS8vIHNvbnN0IHJhdWNodCBlcyBhbSBQcm9ncmFtbS1FbmRlIGFiCgoJbV9uTWFya3VzQWdlID0gMzM7CgltX25NYXJrdXNDaGlsZHJlbkNvdW50ID0gMjsKCgltX2xEcm9lbmsgPSAzMTQ7CgltX25CbGEgPSA0MjsKCW1fbkJsdWIgPSAxMTE7CgltX25HdWxwID0gOTk7CgltX25MYWJlciA9IDE7CgllVHlwZUNsYXNzID0gVHlwZUNsYXNzX0lOVEVSRkFDRTsKCgkvLyBTdHJpbmctU2VxdWVuY2UgaW50aXRpYWxpc2llcmVuCglhU3RyaW5nU2VxLnJlYWxsb2MoIDMgKTsKCU9VU3RyaW5nKiBwU3RyID0gYVN0cmluZ1NlcS5nZXRBcnJheSgpOwoJcFN0clsgMCBdID0gT1VTdHJpbmcoIE9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIlN0cmluZyAwIikgKTsKCXBTdHJbIDEgXSA9IE9VU3RyaW5nKCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTdHJpbmcgMSIpICk7CglwU3RyWyAyIF0gPSBPVVN0cmluZyggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU3RyaW5nIDIiKSApOwoKICAgIC8vIHN0cnVjdHMgaW5pdGlhbGlzaWVyZW4KICAgIG1fYUZpcnN0U3RydWN0Lk5hbWUgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJGaXJzdFN0cnVjdC1OYW1lIik7CiAgICBtX2FGaXJzdFN0cnVjdC5IYW5kbGUgPSA3Nzc3NzsKICAgIC8vWElkbENsYXNzUmVmIFR5cGU7CiAgICBtX2FGaXJzdFN0cnVjdC5BdHRyaWJ1dGVzID0gLTIyMjsKCiAgICAvL1hJbnRlcmZhY2VSZWYgU291cmNlOwoJQW55IFZhbHVlOwoJVmFsdWUgPDw9IDIuNzE4MjgxODI4NDU5OwogICAgbV9hU2Vjb25kU3RydWN0LlZhbHVlID0gVmFsdWU7CiAgICAvL1hJZGxDbGFzc1JlZiBMaXN0ZW5lclR5cGU7CiAgICBtX2FTZWNvbmRTdHJ1Y3QuU3RhdGUgPSBQcm9wZXJ0eVN0YXRlX0RJUkVDVF9WQUxVRTsKCgkvLyBJbmRleEFjY2VzcwoJaUluZGV4QWNjZXNzQ291bnQgPSBERUZBVUxUX0lOREVYX0FDQ0VTU19DT1VOVDsKCXBJbmRleEFjY2Vzc1RhYiA9IE5VTEw7CglwTmFtZUFjY2Vzc1RhYiA9IE5VTEw7Cn0KCi8qCkJPT0wgSW1wbEludHJvVGVzdDo6cXVlcnlJbnRlcmZhY2UoIFVpayBhVWlrLCBYSW50ZXJmYWNlUmVmICYgck91dCApCnsKCWlmKCBhVWlrID09IFhJbnRyb1Rlc3Q6OmdldFNtYXJ0VWlrKCkgKQoJCXJPdXQgPSAoWEludHJvVGVzdCopdGhpczsKCWVsc2UgaWYoIGFVaWsgPT0gWFByb3BlcnR5U2V0OjpnZXRTbWFydFVpaygpICkKCQlyT3V0ID0gKFhQcm9wZXJ0eVNldCopdGhpczsKCWVsc2UgaWYoIGFVaWsgPT0gWE5hbWVBY2Nlc3M6OmdldFNtYXJ0VWlrKCkgKQoJCXJPdXQgPSAoWE5hbWVBY2Nlc3MqKXRoaXM7CgllbHNlIGlmKCBhVWlrID09IFhJbmRleEFjY2Vzczo6Z2V0U21hcnRVaWsoKSApCgkJck91dCA9IChYSW5kZXhBY2Nlc3MqKXRoaXM7CgllbHNlIGlmKCBhVWlrID09ICgoWEVsZW1lbnRBY2Nlc3MqKU5VTEwpLT5nZXRTbWFydFVpaygpICkKCQlyT3V0ID0gKFhFbGVtZW50QWNjZXNzKikoWEluZGV4QWNjZXNzICopdGhpczsKCWVsc2UKCQlVc3JPYmplY3Q6OnF1ZXJ5SW50ZXJmYWNlKCBhVWlrLCByT3V0ICk7CglyZXR1cm4gck91dC5pcygpOwp9CgpYSWRsQ2xhc3NSZWYgSW1wbEludHJvVGVzdDo6Z2V0SWRsQ2xhc3MoKQp7CglzdGF0aWMgWElkbENsYXNzUmVmIHhDbGFzcyA9IGNyZWF0ZVN0YW5kYXJkQ2xhc3MoIEwiSW1wbEludHJvVGVzdCIsCgkJVXNyT2JqZWN0OjpnZXRVc3JPYmplY3RJZGxDbGFzcygpLCA0LAoJCQlYSW50cm9UZXN0X2dldFJlZmxlY3Rpb24oKSwKCQkJWFByb3BlcnR5U2V0X2dldFJlZmxlY3Rpb24oKSwKCQkJWE5hbWVBY2Nlc3NfZ2V0UmVmbGVjdGlvbigpLAoJCQlYSW5kZXhBY2Nlc3NfZ2V0UmVmbGVjdGlvbigpICk7CglyZXR1cm4geENsYXNzOwp9CiovCgpSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiBJbXBsSW50cm9UZXN0OjpnZXRQcm9wZXJ0eVNldEluZm8oKQoJdGhyb3coUnVudGltZUV4Y2VwdGlvbikKewoJc3RhdGljIEltcGxQcm9wZXJ0eVNldEluZm8gYUluZm8oIG14TWdyICk7CgkvLyBBbGxlIE9iamVrdCBoYWJlbiBkaWUgZ2xlaWNoZW4gUHJvcGVydGllcywgZGVzaGFsYiBrYW5uCgkvLyBkaWUgSW5mbyBm/HIgYWxsZSBnbGVpY2ggc2VpbgoJcmV0dXJuICZhSW5mbzsKCgkvL2lmKCBtX3hNeUluZm8gPT0gTlVMTCApCgkvLwkoKEltcGxJbnRyb1Rlc3QqKXRoaXMpLT5tX3hNeUluZm8gPSBuZXcgSW1wbFByb3BlcnR5U2V0SW5mbyggdGhpcyApOwoJLy9yZXR1cm4gbV94TXlJbmZvOwp9Cgp2b2lkIEltcGxJbnRyb1Rlc3Q6OnNldFByb3BlcnR5VmFsdWUoIGNvbnN0IE9VU3RyaW5nJiBhUHJvcGVydHlOYW1lLCBjb25zdCBBbnkmIGFWYWx1ZSApCgl0aHJvdyhVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIFByb3BlcnR5VmV0b0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQovL3ZvaWQgSW1wbEludHJvVGVzdDo6c2V0UHJvcGVydHlWYWx1ZSggY29uc3QgVVN0cmluZyYgYVByb3BlcnR5TmFtZSwgY29uc3QgQW55JiBhVmFsdWUgKQovLwlUSFJPV1MoIChVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIFByb3BlcnR5VmV0b0V4Y2VwdGlvbiwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICkKewoJaWYoIGFQcm9wQ2hhbmdlTGlzdGVuZXIuaXMoKSAmJiBhUHJvcGVydHlOYW1lID09IGFQcm9wQ2hhbmdlTGlzdGVuZXJTdHIgKQoJewoJCVByb3BlcnR5Q2hhbmdlRXZlbnQgYUV2dDsKCQlhRXZ0LlNvdXJjZSA9IChPV2Vha09iamVjdCopdGhpczsKCQlhRXZ0LlByb3BlcnR5TmFtZSA9IGFQcm9wZXJ0eU5hbWU7CgkJYUV2dC5Qcm9wZXJ0eUhhbmRsZSA9IDBMOwoJCS8vYUV2dC5PbGRWYWx1ZTsKCQkvL2FFdnQuTmV3VmFsdWU7CgkJLy9hRXZ0LlByb3BhZ2F0aW9uSWQ7CgkJYVByb3BDaGFuZ2VMaXN0ZW5lci0+cHJvcGVydHlDaGFuZ2UoIGFFdnQgKTsKCX0KCWlmKCBhVmV0b1Byb3BDaGFuZ2VMaXN0ZW5lci5pcygpICYmIGFQcm9wZXJ0eU5hbWUgPT0gYVZldG9Qcm9wQ2hhbmdlTGlzdGVuZXJTdHIgKQoJewoJCVByb3BlcnR5Q2hhbmdlRXZlbnQgYUV2dDsKCQlhRXZ0LlNvdXJjZSA9IChPV2Vha09iamVjdCopdGhpczsKCQlhRXZ0LlByb3BlcnR5TmFtZSA9IGFWZXRvUHJvcENoYW5nZUxpc3RlbmVyU3RyOwoJCWFFdnQuUHJvcGVydHlIYW5kbGUgPSAwTDsKCQkvL2FFdnQuT2xkVmFsdWU7CgkJLy9hRXZ0Lk5ld1ZhbHVlOwoJCS8vYUV2dC5Qcm9wYWdhdGlvbklkOwoJCWFWZXRvUHJvcENoYW5nZUxpc3RlbmVyLT52ZXRvYWJsZUNoYW5nZSggYUV2dCApOwoJfQoKCVNlcXVlbmNlPFByb3BlcnR5PiBhUHJvcFNlcSA9IG1feE15SW5mby0+Z2V0UHJvcGVydGllcygpOwoJc2FsX0ludDMyIG5MZW4gPSBhUHJvcFNlcS5nZXRMZW5ndGgoKTsKCWZvciggc2FsX0ludDMyIGkgPSAwIDsgaSA8IG5MZW4gOyBpKysgKQoJewoJCVByb3BlcnR5IGFQcm9wID0gYVByb3BTZXEuZ2V0QXJyYXkoKVsgaSBdOwoJCWlmKCBhUHJvcC5OYW1lID09IGFQcm9wZXJ0eU5hbWUgKQoJCQlhQW55QXJyYXlbaV0gPSBhVmFsdWU7Cgl9Cn0KCkFueSBJbXBsSW50cm9UZXN0OjpnZXRQcm9wZXJ0eVZhbHVlKCBjb25zdCBPVVN0cmluZyYgUHJvcGVydHlOYW1lICkKCXRocm93KFVua25vd25Qcm9wZXJ0eUV4Y2VwdGlvbiwgV3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKLy9BbnkgSW1wbEludHJvVGVzdDo6Z2V0UHJvcGVydHlWYWx1ZShjb25zdCBVU3RyaW5nJiBhUHJvcGVydHlOYW1lKSBjb25zdAoJLy9USFJPV1MoIChVbmtub3duUHJvcGVydHlFeGNlcHRpb24sIFdyYXBwZWRUYXJnZXRFeGNlcHRpb24sIFVzclN5c3RlbUV4Y2VwdGlvbikgKQp7CglTZXF1ZW5jZTxQcm9wZXJ0eT4gYVByb3BTZXEgPSBtX3hNeUluZm8tPmdldFByb3BlcnRpZXMoKTsKCXNhbF9JbnQzMiBuTGVuID0gYVByb3BTZXEuZ2V0TGVuZ3RoKCk7Cglmb3IoIHNhbF9JbnQzMiBpID0gMCA7IGkgPCBuTGVuIDsgaSsrICkKCXsKCQlQcm9wZXJ0eSBhUHJvcCA9IGFQcm9wU2VxLmdldEFycmF5KClbIGkgXTsKCQlpZiggYVByb3AuTmFtZSA9PSBQcm9wZXJ0eU5hbWUgKQoJCQlyZXR1cm4gYUFueUFycmF5W2ldOwoJfQoJcmV0dXJuIEFueSgpOwp9CgpPVVN0cmluZyBJbXBsSW50cm9UZXN0OjpnZXRGaXJzdE5hbWUodm9pZCkKCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pCnsKCXJldHVybiBPVVN0cmluZyggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiTWFya3VzIikgKTsKfQoKdm9pZCBJbXBsSW50cm9UZXN0Ojp3cml0ZWxuKCBjb25zdCBPVVN0cmluZyYgVGV4dCApCgl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQp7CglPU3RyaW5nIGFTdHIoIFRleHQuZ2V0U3RyKCksIFRleHQuZ2V0TGVuZ3RoKCksIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCgkvLyBIYWJlbiB3aXIgZWluIE91dHB1dD8KCS8vaWYoIG1fcE91dHB1dCApCgkvL3sKCQkvL21fcE91dHB1dC0+ZG9Xcml0ZWxuKCBUZXh0U3RyICk7CgkvL30KCS8vIFNvbnN0IGVpbmZhY2ggcmF1c2JyYXRlbgoJLy9lbHNlCgl7CgkJcHJpbnRmKCAiJXMiLCBhU3RyLmdldFN0cigpICk7Cgl9Cn0KClJlZmVyZW5jZTwgWEludHJvVGVzdCA+IEltcGxJbnRyb1Rlc3Q6OmdldEludHJvVGVzdCgpCgl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQovL1hJbnRyb1Rlc3RSZWYgSW1wbEludHJvVGVzdDo6Z2V0SW50cm9UZXN0KHZvaWQpIFRIUk9XUyggKFVzclN5c3RlbUV4Y2VwdGlvbikgKQp7CglpZiggIW1feEludHJvVGVzdC5pcygpICkKCQltX3hJbnRyb1Rlc3QgPSBuZXcgSW1wbEludHJvVGVzdCggbXhNZ3IgKTsKCXJldHVybiBtX3hJbnRyb1Rlc3Q7Cn0KCi8vIE1ldGhvZGVuIHZvbiBYRWxlbWVudEFjY2VzcwpUeXBlIEltcGxJbnRyb1Rlc3Q6OmdldEVsZW1lbnRUeXBlKCAgKQoJdGhyb3coUnVudGltZUV4Y2VwdGlvbikKLy9YSWRsQ2xhc3NSZWYgSW1wbEludHJvVGVzdDo6Z2V0RWxlbWVudFR5cGUodm9pZCkgY29uc3QgVEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApCnsKCS8vIFRPRE8KCVR5cGUgYVJldFR5cGU7CglyZXR1cm4gYVJldFR5cGU7CgkvL3JldHVybiBSZWZlcmVuY2U8IFhJZGxDbGFzcyA+KCk7CgkvL3JldHVybiBWb2lkX2dldFJlZmxlY3Rpb24oKS0+Z2V0SWRsQ2xhc3MoKTsKfQoKc2FsX0Jvb2wgSW1wbEludHJvVGVzdDo6aGFzRWxlbWVudHMoICApCgl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQovL0JPT0wgSW1wbEludHJvVGVzdDo6aGFzRWxlbWVudHModm9pZCkgY29uc3QgVEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApCnsKCXJldHVybiBzYWxfVHJ1ZTsKfQoKLy8gWE5hbWVBY2Nlc3MtTWV0aG9kZW4Kc2FsX0ludDMyIGdldEluZGV4Rm9yTmFtZSggY29uc3QgT1VTdHJpbmcmIEl0ZW1OYW1lICkKewoJT1VTdHJpbmcgYUxlZnRTdHIgPSBJdGVtTmFtZS5jb3B5KCAwLCA0ICk7CglpZiggYUxlZnRTdHIgPT0gT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiSXRlbSIpICkKCXsKCQkvLyBUT0RPCgkJT1VTdHJpbmcgYU51bVN0ciA9IEl0ZW1OYW1lLmNvcHkoIDQgKTsKCQkvL3NhbF9JbnQzMiBpSW5kZXggPSAoSU5UMzIpVVN0cmluZ1RvU3RyaW5nKCBhTnVtU3RyLCBDSEFSU0VUX1NZU1RFTSApOwoJCS8vaWYoIGlJbmRleCA8IERFRkFVTFRfTkFNRV9BQ0NFU1NfQ09VTlQgKQoJCQkvL3JldHVybiBpSW5kZXg7Cgl9CglyZXR1cm4gLTE7Cn0KCgpBbnkgSW1wbEludHJvVGVzdDo6Z2V0QnlOYW1lKCBjb25zdCBPVVN0cmluZyYgYU5hbWUgKQoJdGhyb3coTm9TdWNoRWxlbWVudEV4Y2VwdGlvbiwgV3JhcHBlZFRhcmdldEV4Y2VwdGlvbiwgUnVudGltZUV4Y2VwdGlvbikKLy9BbnkgSW1wbEludHJvVGVzdDo6Z2V0QnlOYW1lKGNvbnN0IFVTdHJpbmcmIE5hbWUpIGNvbnN0CgkvL1RIUk9XUyggKE5vU3VjaEVsZW1lbnRFeGNlcHRpb24sIFdyYXBwZWRUYXJnZXRFeGNlcHRpb24sIFVzclN5c3RlbUV4Y2VwdGlvbikgKQp7CglBbnkgYVJldEFueTsKCglpZiggIXBOYW1lQWNjZXNzVGFiICApCgkJKChJbXBsSW50cm9UZXN0Kil0aGlzKS0+cE5hbWVBY2Nlc3NUYWIgID0gbmV3IFJlZmVyZW5jZTwgWEludHJvVGVzdCA+WyBERUZBVUxUX05BTUVfQUNDRVNTX0NPVU5UIF07CgoJc2FsX0ludDMyIGlJbmRleCA9IGdldEluZGV4Rm9yTmFtZSggYU5hbWUgKTsKCWlmKCBpSW5kZXggIT0gLTEgKQoJewoJCWlmKCAhcE5hbWVBY2Nlc3NUYWJbaUluZGV4XS5pcygpICkKCQl7CgkJCUltcGxJbnRyb1Rlc3QqIHAgPSBuZXcgSW1wbEludHJvVGVzdCggbXhNZ3IgKTsKCQkJT1VTdHJpbmcgYU5hbWUyKCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJJbnRyb1Rlc3QgYnkgTmFtZS1BY2Nlc3MsIEluZGV4ID0gIikgKTsKCQkJYU5hbWUyICs9IE9VU3RyaW5nOjp2YWx1ZU9mKCBpSW5kZXggKTsKCQkJLy9hTmFtZTIgPSBhTmFtZTIgKyBTdHJpbmdUb1VTdHJpbmcoIFN0cmluZyggaUluZGV4ICksIENIQVJTRVRfU1lTVEVNICk7CgkJCXAtPnNldE9iamVjdE5hbWUoIGFOYW1lMiApOwoJCQlwTmFtZUFjY2Vzc1RhYltpSW5kZXhdID0gcDsKCQl9CgoJCVJlZmVyZW5jZTwgWEludHJvVGVzdCA+IHhSZXQgPSBwTmFtZUFjY2Vzc1RhYltpSW5kZXhdOwoJCWFSZXRBbnkgPSBtYWtlQW55KCB4UmV0ICk7CgoJCS8vYVJldEFueS5zZXQoICZ4UmV0LCBYSW50cm9UZXN0X2dldFJlZmxlY3Rpb24oKSApOwoJCS8vcmV0dXJuIChVc3JPYmplY3QqKShYSW50cm9UZXN0KilwTmFtZUFjY2Vzc1RhYltpSW5kZXhdOwoJfQoJcmV0dXJuIGFSZXRBbnk7Cn0KClNlcXVlbmNlPCBPVVN0cmluZyA+IEltcGxJbnRyb1Rlc3Q6OmdldEVsZW1lbnROYW1lcyggICkKCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pCi8vU2VxdWVuY2U8VVN0cmluZz4gSW1wbEludHJvVGVzdDo6Z2V0RWxlbWVudE5hbWVzKHZvaWQpIGNvbnN0IFRIUk9XUyggKFVzclN5c3RlbUV4Y2VwdGlvbikgKQp7CglTZXF1ZW5jZTxPVVN0cmluZz4gYVN0clNlcSggREVGQVVMVF9OQU1FX0FDQ0VTU19DT1VOVCApOwoJT1VTdHJpbmcqIHBTdHIgPSBhU3RyU2VxLmdldEFycmF5KCk7Cglmb3IoIHNhbF9JbnQzMiBpID0gMCA7IGkgPCBERUZBVUxUX05BTUVfQUNDRVNTX0NPVU5UIDsgaSsrICkKCXsKCQlPVVN0cmluZyBhTmFtZSggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiSXRlbSIpICk7CgkJYU5hbWUgKz0gT1VTdHJpbmc6OnZhbHVlT2YoIGkgKTsKCQkvL2FOYW1lID0gYU5hbWUgKyBTdHJpbmdUb1VTdHJpbmcoIGksIENIQVJTRVRfU1lTVEVNICk7CgkJcFN0cltpXSA9IGFOYW1lOwoJfQoJcmV0dXJuIGFTdHJTZXE7Cn0KCnNhbF9Cb29sIEltcGxJbnRyb1Rlc3Q6Omhhc0J5TmFtZSggY29uc3QgT1VTdHJpbmcmIGFOYW1lICkKCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pCi8vQk9PTCBJbXBsSW50cm9UZXN0OjpoYXNCeU5hbWUoY29uc3QgVVN0cmluZyYgTmFtZSkgY29uc3QgVEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApCnsKCXJldHVybiAoIGdldEluZGV4Rm9yTmFtZSggYU5hbWUgKSAhPSAtMSApOwp9CgovLyBYSW5kZXhBY2Nlc3MtTWV0aG9kZW4Kc2FsX0ludDMyIEltcGxJbnRyb1Rlc3Q6OmdldENvdW50KCAgKQoJdGhyb3coUnVudGltZUV4Y2VwdGlvbikKLy9zYWxfSW50MzIgSW1wbEludHJvVGVzdDo6Z2V0Q291bnQodm9pZCkgY29uc3QgVEhST1dTKCAoVXNyU3lzdGVtRXhjZXB0aW9uKSApCnsKCXJldHVybiBpSW5kZXhBY2Nlc3NDb3VudDsKfQoKQW55IEltcGxJbnRyb1Rlc3Q6OmdldEJ5SW5kZXgoIHNhbF9JbnQzMiBJbmRleCApCgl0aHJvdyhJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBSdW50aW1lRXhjZXB0aW9uKQovL0FueSBJbXBsSW50cm9UZXN0OjpnZXRCeUluZGV4KCBzYWxfSW50MzIgSW5kZXggKSBjb25zdAoJLy9USFJPV1MoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uLCBXcmFwcGVkVGFyZ2V0RXhjZXB0aW9uLCBVc3JTeXN0ZW1FeGNlcHRpb24pICkKewoJQW55IGFSZXRBbnk7CgoJaWYoICFwSW5kZXhBY2Nlc3NUYWIgKQoJCSgoSW1wbEludHJvVGVzdCopdGhpcyktPnBJbmRleEFjY2Vzc1RhYiA9IG5ldyBSZWZlcmVuY2U8IFhJbnRyb1Rlc3QgPlsgaUluZGV4QWNjZXNzQ291bnQgXTsKCglpZiggSW5kZXggPCBpSW5kZXhBY2Nlc3NDb3VudCApCgl7CgkJaWYoICFwTmFtZUFjY2Vzc1RhYltJbmRleF0uaXMoKSApCgkJewoJCQlJbXBsSW50cm9UZXN0KiBwID0gbmV3IEltcGxJbnRyb1Rlc3QoIG14TWdyICk7CgkJCU9VU3RyaW5nIGFOYW1lKCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJJbnRyb1Rlc3QgYnkgSW5kZXgtQWNjZXNzLCBJbmRleCA9ICIpICk7CgkJCWFOYW1lICs9IE9VU3RyaW5nOjp2YWx1ZU9mKCBJbmRleCApOwoJCQkvL2FOYW1lID0gYU5hbWUgKyBTdHJpbmdUb1VTdHJpbmcoIFN0cmluZyggaUluZGV4ICksIENIQVJTRVRfU1lTVEVNICk7CgkJCXAtPnNldE9iamVjdE5hbWUoIGFOYW1lICk7CgkJCXBJbmRleEFjY2Vzc1RhYltJbmRleF0gPSBwOwoJCX0KCQlSZWZlcmVuY2U8IFhJbnRyb1Rlc3QgPiB4UmV0ID0gcEluZGV4QWNjZXNzVGFiW0luZGV4XTsKCQlhUmV0QW55ID0gbWFrZUFueSggeFJldCApOwoJfQoJcmV0dXJuIGFSZXRBbnk7Cn0KCnZvaWQgSW1wbEludHJvVGVzdDo6YWRkUHJvcGVydGllc0NoYW5nZUxpc3RlbmVyKCBjb25zdCBTZXF1ZW5jZTwgT1VTdHJpbmcgPiYgLypQcm9wZXJ0eU5hbWVzKi8sCgkJCQkJCQkJCQkJCSBjb25zdCBSZWZlcmVuY2U8IFhQcm9wZXJ0aWVzQ2hhbmdlTGlzdGVuZXIgPiYgLypMaXN0ZW5lciovICkKCQl0aHJvdyhSdW50aW1lRXhjZXB0aW9uKQovL3ZvaWQgSW1wbEludHJvVGVzdDo6YWRkUHJvcGVydGllc0NoYW5nZUxpc3RlbmVyCi8vKGNvbnN0IFNlcXVlbmNlPCBVU3RyaW5nID4mIFByb3BlcnR5TmFtZXMsIGNvbnN0IFhQcm9wZXJ0aWVzQ2hhbmdlTGlzdGVuZXJSZWYmIExpc3RlbmVyKQoJLy9USFJPV1MoIChVc3JTeXN0ZW1FeGNlcHRpb24pICkKewp9Cgp2b2lkIEltcGxJbnRyb1Rlc3Q6OnJlbW92ZVByb3BlcnRpZXNDaGFuZ2VMaXN0ZW5lcgooIGNvbnN0IFJlZmVyZW5jZTwgWFByb3BlcnRpZXNDaGFuZ2VMaXN0ZW5lciA+JiAvKkxpc3RlbmVyKi8gKQoJCXRocm93KFJ1bnRpbWVFeGNlcHRpb24pCi8vdm9pZCBJbXBsSW50cm9UZXN0OjpyZW1vdmVQcm9wZXJ0aWVzQ2hhbmdlTGlzdGVuZXIoY29uc3QgWFByb3BlcnRpZXNDaGFuZ2VMaXN0ZW5lclJlZiYgTGlzdGVuZXIpCgkvL1RIUk9XUyggKFVzclN5c3RlbUV4Y2VwdGlvbikgKQp7Cn0KCgoKc3RydWN0IERlZkl0ZW0KewoJY2hhciBjb25zdCAqIHBOYW1lOwoJc2FsX0ludDMyIG5Db25jZXB0Owp9OwoKLy8gU3BlemlhbC1XZXJ0IGZ1ZXIgTWV0aG9kLUNvbmNlcHQsIHVtICJub3JtYWxlIiBGdW5rdGlvbmVuIGtlbm56ZWljaG5lbiB6dSBrb2VubmVuCiNkZWZpbmUgIE1ldGhvZENvbmNlcHRfTk9STUFMX0lNUEwJCTB4ODAwMDAwMDAKCgovLyBUZXN0LU9iamVrdCBsaWVmZXJuCkFueSBnZXRJbnRyb3NwZWN0aW9uVGVzdE9iamVjdCggY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+ICYgeE1nciApCnsKCUFueSBhT2JqQW55OwoJUmVmZXJlbmNlPCBYSW50cm9UZXN0ID4geFRlc3RPYmogPSBuZXcgSW1wbEludHJvVGVzdCggeE1nciApOwoJYU9iakFueS5zZXRWYWx1ZSggJnhUZXN0T2JqLCA6OmdldENwcHVUeXBlKCAoY29uc3QgUmVmZXJlbmNlPCBYSW50cm9UZXN0ID4gKikwICkgKTsKCXJldHVybiBhT2JqQW55Owp9CgpzdGF0aWMgc2FsX0Jvb2wgdGVzdF9pbnRyb3NwKCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4geE1nciwKCQkJCQkJCSAgUmVmZXJlbmNlPCBYSWRsUmVmbGVjdGlvbiA+IC8qeFJlZmwqLywgUmVmZXJlbmNlPCBYSW50cm9zcGVjdGlvbiA+IHhJbnRyb3NwZWN0aW9uICkKewoJRGVmSXRlbSBwUHJvcGVydHlEZWZzW10gPQoJewoJCXsgIkZhY3RvciIsIFByb3BlcnR5Q29uY2VwdDo6UFJPUEVSVFlTRVQgfSwKCQl7ICJNeUNvdW50IiwgUHJvcGVydHlDb25jZXB0OjpQUk9QRVJUWVNFVCB9LAoJCXsgIkluZm8iLCBQcm9wZXJ0eUNvbmNlcHQ6OlBST1BFUlRZU0VUIH0sCgkJeyAiT2JqZWN0TmFtZSIsIFByb3BlcnR5Q29uY2VwdDo6QVRUUklCVVRFUyB9LAoJCXsgIkZpcnN0TmFtZSIsIFByb3BlcnR5Q29uY2VwdDo6QVRUUklCVVRFUyB9LAoJCXsgIkxhc3ROYW1lIiwgUHJvcGVydHlDb25jZXB0OjpBVFRSSUJVVEVTIH0sCgkJeyAiQWdlIiwgUHJvcGVydHlDb25jZXB0OjpBVFRSSUJVVEVTIH0sCgkJeyAiQ2hpbGRyZW5Db3VudCIsIFByb3BlcnR5Q29uY2VwdDo6QVRUUklCVVRFUyB9LAoJCXsgIkZpcnN0U3RydWN0IiwgUHJvcGVydHlDb25jZXB0OjpBVFRSSUJVVEVTIH0sCgkJeyAiU2Vjb25kU3RydWN0IiwgUHJvcGVydHlDb25jZXB0OjpBVFRSSUJVVEVTIH0sCgkJeyAiRHJvZW5rIiwgUHJvcGVydHlDb25jZXB0OjpNRVRIT0RTIH0sCgkJeyAiSW50cm9UZXN0IiwgUHJvcGVydHlDb25jZXB0OjpNRVRIT0RTIH0sCgkJeyAiQmxhIiwgUHJvcGVydHlDb25jZXB0OjpNRVRIT0RTIH0sCgkJeyAiQmx1YiIsIFByb3BlcnR5Q29uY2VwdDo6TUVUSE9EUyB9LAoJCXsgIkd1bHAiLCBQcm9wZXJ0eUNvbmNlcHQ6Ok1FVEhPRFMgfSwKCQl7ICJTdHJpbmdzIiwgUHJvcGVydHlDb25jZXB0OjpNRVRIT0RTIH0sCgkJeyAiTXVsdGlTZXF1ZW5jZSIsIFByb3BlcnR5Q29uY2VwdDo6TUVUSE9EUyB9LAoJCXsgIlByb3BlcnR5U2V0SW5mbyIsIFByb3BlcnR5Q29uY2VwdDo6TUVUSE9EUyB9LAoJCXsgIkVsZW1lbnRUeXBlIiwgUHJvcGVydHlDb25jZXB0OjpNRVRIT0RTIH0sCgkJeyAiRWxlbWVudE5hbWVzIiwgUHJvcGVydHlDb25jZXB0OjpNRVRIT0RTIH0sCgkJeyAiQ291bnQiLCBQcm9wZXJ0eUNvbmNlcHQ6Ok1FVEhPRFMgfSwKCQl7ICJUeXBlcyIsIFByb3BlcnR5Q29uY2VwdDo6TUVUSE9EUyB9LAoJCXsgIkltcGxlbWVudGF0aW9uSWQiLCBQcm9wZXJ0eUNvbmNlcHQ6Ok1FVEhPRFMgfSwKCQl7IE5VTEwsIDAgfQoJfTsKCgkvLyBUYWJlbGxlIGRlciBQcm9wZXJ0eS1OYW1lbiwgZGllIGdlZnVuZGVuIHdlcmRlbiBtdWVzc2VuCi8vIAljaGFyKiBwRGVtYW5kZWRQcm9wTmFtZXNbXSA9Ci8vIAl7Ci8vIAkJIkZhY3RvciIsCi8vIAkJIk15Q291bnQiLAovLyAJCSJJbmZvIiwKLy8gCQkiT2JqZWN0TmFtZSIsCi8vIAkJIkZpcnN0TmFtZSIsCi8vIAkJIkxhc3ROYW1lIiwKLy8gCQkiQWdlIiwKLy8gCQkiQ2hpbGRyZW5Db3VudCIsCi8vIAkJIkZpcnN0U3RydWN0IiwKLy8gCQkiU2Vjb25kU3RydWN0IiwKLy8gCQkiRHJvZW5rIiwKLy8gCQkiSW50cm9UZXN0IiwKLy8gCQkiQmxhIiwKLy8gCQkiQmx1YiIsCi8vIAkJIkd1bHAiLAovLyAJCSJTdHJpbmdzIiwKLy8gCQkiTXVsdGlTZXF1ZW5jZSIsCi8vIAkJIlByb3BlcnR5U2V0SW5mbyIsCi8vIAkJIkVsZW1lbnRUeXBlIiwKLy8gCQkiRWxlbWVudE5hbWVzIiwKLy8gCQkiQ291bnQiLAovLyAJCSJUeXBlcyIKLy8gCQkiSW1wbGVtZW50YXRpb25JZCIKLy8gCX07CgoJY2hhciBjb25zdCAqIHBEZW1hbmRlZFByb3BWYWxzW10gPQoJewoJCSIzLjE0MDAwMCIsCgkJIjQyIiwKCQkiSGFsbG8iLAoJCSJJbnRyb1Rlc3QtT2JqIE5yLiAwIiwKCQkiTWFya3VzIiwKCQkiTWV5ZXIiLAoJCSIzMyIsCgkJIjIiLAoJCSJUWVBFIFNUUlVDVCIsCgkJIlRZUEUgU1RSVUNUIiwKCQkiMzE0IiwKCQkiVFlQRSBJTlRFUkZBQ0UiLAoJCSI0MiIsCgkJIjExMSIsCgkJIjk5IiwKCQkiVFlQRSBTRVFVRU5DRSIsCgkJIlRZUEUgU0VRVUVOQ0UiLAoJCSJUWVBFIElOVEVSRkFDRSIsCgkJIlRZUEUgVFlQRSIsCgkJIlRZUEUgU0VRVUVOQ0UiLAoJCSIxMCIsCgkJIlRZUEUgU0VRVUVOQ0UiLAoJCSJUWVBFIFNFUVVFTkNFIiwKCX07CgoJY2hhciBjb25zdCAqIHBEZW1hbmRlZE1vZGlmaWVkUHJvcFZhbHNbXSA9Cgl7CgkJIjQuMTQwMDAwIiwKCQkiNDMiLAoJCSJIYWxsbyAoTW9kaWZpZWQhKSIsCgkJIkludHJvVGVzdC1PYmogTnIuIDAgKE1vZGlmaWVkISkiLAoJCSJNYXJrdXMiLAoJCSJNZXllciIsCgkJIjMzIiwKCQkiMyIsCgkJIldlcnQgd3VyZGUgbmljaHQgbW9kaWZpemllcnQiLAoJCSJXZXJ0IHd1cmRlIG5pY2h0IG1vZGlmaXppZXJ0IiwKCQkiMzE1IiwKCQkiV2VydCB3dXJkZSBuaWNodCBtb2RpZml6aWVydCIsCgkJIjQyIiwKCQkiMTEyIiwKCQkiOTkiLAoJCSJXZXJ0IHd1cmRlIG5pY2h0IG1vZGlmaXppZXJ0IiwKCQkiV2VydCB3dXJkZSBuaWNodCBtb2RpZml6aWVydCIsCgkJIldlcnQgd3VyZGUgbmljaHQgbW9kaWZpemllcnQiLAoJCSJXZXJ0IHd1cmRlIG5pY2h0IG1vZGlmaXppZXJ0IiwKCQkiV2VydCB3dXJkZSBuaWNodCBtb2RpZml6aWVydCIsCgkJIjEwIiwKCQkiV2VydCB3dXJkZSBuaWNodCBtb2RpZml6aWVydCIKCQkiV2VydCB3dXJkZSBuaWNodCBtb2RpZml6aWVydCIKCX07CgoJY2hhciBjb25zdCAqIHBEZW1hbmRlZFByb3BUeXBlc1tdID0KCXsKCQkiZG91YmxlIiwKCQkibG9uZyIsCgkJInN0cmluZyIsCgkJInN0cmluZyIsCgkJInN0cmluZyIsCgkJInN0cmluZyIsCgkJInNob3J0IiwKCQkic2hvcnQiLAoJCSJjb20uc3VuLnN0YXIuYmVhbnMuUHJvcGVydHkiLAoJCSJjb20uc3VuLnN0YXIuYmVhbnMuUHJvcGVydHlWYWx1ZSIsCgkJImxvbmciLAoJCSJNb2R1bGVBLlhJbnRyb1Rlc3QiLAoJCSJzaG9ydCIsCgkJInNob3J0IiwKCQkic2hvcnQiLAoJCSJbXXN0cmluZyIsCgkJIltdW11bXXNob3J0IiwKCQkiY29tLnN1bi5zdGFyLmJlYW5zLlhQcm9wZXJ0eVNldEluZm8iLAoJCSJ0eXBlIiwKCQkiW11zdHJpbmciLAoJCSJsb25nIiwKCQkiW110eXBlIiwKCQkiW11ieXRlIiwKCX07CgkvL2lzKCkgbkRlbWFuZGVkUHJvcENvdW50ID0gMjI7CgoKCURlZkl0ZW0gcE1ldGhvZERlZnNbXSA9Cgl7CgkJeyAicXVlcnlJbnRlcmZhY2UiLCBNZXRob2RDb25jZXB0X05PUk1BTF9JTVBMIH0sCgkJeyAiYWNxdWlyZSIsIE1ldGhvZENvbmNlcHQ6OkRBTkdFUk9VUyB9LAoJCXsgInJlbGVhc2UiLCBNZXRob2RDb25jZXB0OjpEQU5HRVJPVVMgfSwKCQl7ICJ3cml0ZWxuIiwgTWV0aG9kQ29uY2VwdF9OT1JNQUxfSU1QTCB9LAoJCXsgImdldERyb2VuayIsIE1ldGhvZENvbmNlcHQ6OlBST1BFUlRZIH0sCgkJeyAiZ2V0SW50cm9UZXN0IiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJnZXRVcHMiLCBNZXRob2RDb25jZXB0X05PUk1BTF9JTVBMIH0sCgkJeyAic2V0RHJvZW5rIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJnZXRCbGEiLCBNZXRob2RDb25jZXB0OjpQUk9QRVJUWSB9LAoJCXsgInNldEJsYSIsIE1ldGhvZENvbmNlcHRfTk9STUFMX0lNUEwgfSwKCQl7ICJnZXRCbHViIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJzZXRCbHViIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJnZXRHdWxwIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJzZXRHdWxwIiwgTWV0aG9kQ29uY2VwdF9OT1JNQUxfSU1QTCB9LAoJCXsgImdldFR5cGVDbGFzcyIsIE1ldGhvZENvbmNlcHRfTk9STUFMX0lNUEwgfSwKCQl7ICJzZXRUeXBlQ2xhc3MiLCBNZXRob2RDb25jZXB0X05PUk1BTF9JTVBMIH0sCgkJeyAiZ2V0U3RyaW5ncyIsIE1ldGhvZENvbmNlcHQ6OlBST1BFUlRZIH0sCgkJeyAic2V0U3RyaW5ncyIsIE1ldGhvZENvbmNlcHQ6OlBST1BFUlRZIH0sCgkJeyAic2V0U3RyaW5nc1Blck1ldGhvZCIsIE1ldGhvZENvbmNlcHRfTk9STUFMX0lNUEwgfSwKCQl7ICJnZXRNdWx0aVNlcXVlbmNlIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJzZXRNdWx0aVNlcXVlbmNlIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJhZGRQcm9wZXJ0aWVzQ2hhbmdlTGlzdGVuZXIiLCBNZXRob2RDb25jZXB0OjpMSVNURU5FUiB9LAoJCXsgInJlbW92ZVByb3BlcnRpZXNDaGFuZ2VMaXN0ZW5lciIsIE1ldGhvZENvbmNlcHQ6OkxJU1RFTkVSIH0sCgkJeyAiZ2V0UHJvcGVydHlTZXRJbmZvIiwgTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgfSwKCQl7ICJzZXRQcm9wZXJ0eVZhbHVlIiwgTWV0aG9kQ29uY2VwdF9OT1JNQUxfSU1QTCB9LAoJCXsgImdldFByb3BlcnR5VmFsdWUiLCBNZXRob2RDb25jZXB0X05PUk1BTF9JTVBMIH0sCgkJeyAiYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciIsIE1ldGhvZENvbmNlcHQ6OkxJU1RFTkVSIH0sCgkJeyAicmVtb3ZlUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciIsIE1ldGhvZENvbmNlcHQ6OkxJU1RFTkVSIH0sCgkJeyAiYWRkVmV0b2FibGVDaGFuZ2VMaXN0ZW5lciIsIE1ldGhvZENvbmNlcHQ6OkxJU1RFTkVSIH0sCgkJeyAicmVtb3ZlVmV0b2FibGVDaGFuZ2VMaXN0ZW5lciIsIE1ldGhvZENvbmNlcHQ6OkxJU1RFTkVSIH0sCgkJeyAiZ2V0RWxlbWVudFR5cGUiLCBNZXRob2RDb25jZXB0OjpQUk9QRVJUWSB8IE1ldGhvZENvbmNlcHQ6Ok5BTUVDT05UQUlORVJ8IE1ldGhvZENvbmNlcHQ6OklOREVYQ09OVEFJTkVSIHwgTWV0aG9kQ29uY2VwdDo6RU5VTUVSQVRJT04gIH0sCgkJeyAiaGFzRWxlbWVudHMiLCBNZXRob2RDb25jZXB0OjpOQU1FQ09OVEFJTkVSIHwgTWV0aG9kQ29uY2VwdDo6SU5ERVhDT05UQUlORVIgfCBNZXRob2RDb25jZXB0OjpFTlVNRVJBVElPTiB9LAoJCXsgImdldEJ5TmFtZSIsIE1ldGhvZENvbmNlcHQ6Ok5BTUVDT05UQUlORVIgfSwKCQl7ICJnZXRFbGVtZW50TmFtZXMiLCBNZXRob2RDb25jZXB0OjpQUk9QRVJUWSB8IE1ldGhvZENvbmNlcHQ6Ok5BTUVDT05UQUlORVIgfSwKCQl7ICJoYXNCeU5hbWUiLCBNZXRob2RDb25jZXB0OjpOQU1FQ09OVEFJTkVSIH0sCgkJeyAiZ2V0Q291bnQiLCBNZXRob2RDb25jZXB0OjpQUk9QRVJUWSB8IE1ldGhvZENvbmNlcHQ6OklOREVYQ09OVEFJTkVSIH0sCgkJeyAiZ2V0QnlJbmRleCIsIE1ldGhvZENvbmNlcHQ6OklOREVYQ09OVEFJTkVSIH0sCgkJeyAiZ2V0VHlwZXMiLCBNZXRob2RDb25jZXB0OjpQUk9QRVJUWSB9LAoJCXsgImdldEltcGxlbWVudGF0aW9uSWQiLCBNZXRob2RDb25jZXB0OjpQUk9QRVJUWSB9LAoJCXsgInF1ZXJ5QWRhcHRlciIsIE1ldGhvZENvbmNlcHRfTk9STUFMX0lNUEwgfSwKCQl7IE5VTEwsIDAgfQoJfTsKCglPU3RyaW5nIGFFcnJvclN0cjsKCgkvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKCS8vIFRlc3QtT2JqZWt0IGFubGVnZW4KCUFueSBhT2JqQW55ID0gZ2V0SW50cm9zcGVjdGlvblRlc3RPYmplY3QoIHhNZ3IgKTsKCgkvLyBJbnRyb3NwZWN0aW9uLVNlcnZpY2UgaG9sZW4KCS8vUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+IHhTZXJ2aWNlTWFuYWdlcihnZXRQcm9jZXNzU2VydmljZU1hbmFnZXIoKSwgVVNSX1FVRVJZKTsKCS8vUmVmZXJlbmNlPCBYSW50cm9zcGVjdGlvbiA+IHhJbnRyb3NwZWN0aW9uKCB4TWdyLT5jcmVhdGVJbnN0YW5jZShMImNvbS5zdW4uc3Rhci5iZWFucy5JbnRyb3NwZWN0aW9uIiksIFVOT19RVUVSWSApOwoJLy9URVNUX0VOU0hVUkUoIHhJbnRyb3NwZWN0aW9uLmlzKCksICJDcmVhdGlvbiBvZiBpbnRyb3NwZWN0aW9uIGluc3RhbmNlIGZhaWxlZCIgKTsKCS8vaWYoICF4SW50cm9zcGVjdGlvbi5pcygpICkKCQkvL3JldHVybiBzYWxfRmFsc2U7CgoJLy8gdW5kIHVuc3BlY3RlbgoJUmVmZXJlbmNlPCBYSW50cm9zcGVjdGlvbkFjY2VzcyA+IHhBY2Nlc3MgPSB4SW50cm9zcGVjdGlvbi0+aW5zcGVjdCggYU9iakFueSApOwoJeEFjY2VzcyA9IHhJbnRyb3NwZWN0aW9uLT5pbnNwZWN0KCBhT2JqQW55ICk7Cgl4QWNjZXNzID0geEludHJvc3BlY3Rpb24tPmluc3BlY3QoIGFPYmpBbnkgKTsKCVRFU1RfRU5TSFVSRSggeEFjY2Vzcy5pcygpLCAiaW50cm9zcGVjdGlvbiBmYWlsZWQsIG5vIFhJbnRyb3NwZWN0aW9uQWNjZXNzIHJldHVybmVkIiApOwoJaWYoICF4QWNjZXNzLmlzKCkgKQoJCXJldHVybiBzYWxfRmFsc2U7CgoJLy8gRXJnZWJuaXMgZGVyIEludHJvc3BlY3Rpb24gcHJ1ZWZlbgoKCS8vIFhQcm9wZXJ0eVNldC1VSUsgZXJtaXR0ZWxuCglUeXBlIGFUeXBlID0gZ2V0Q3BwdVR5cGUoIChSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldCA+KikgTlVMTCApOwoJLy90eXBlbGliX0ludGVyZmFjZVR5cGVEZXNjcmlwdGlvbiogcFR5cGVEZXNjID0gTlVMTDsKCS8vYVR5cGUuZ2V0RGVzY3JpcHRpb24oICh0eXBlbGliX1R5cGVEZXNjcmlwdGlvbioqKSZwVHlwZURlc2MgKTsKCS8vVWlrIGFQcm9wZXJ0eVNldFVpayA9ICooVWlrKikmcFR5cGVEZXNjLT5hVWlrOwoJLy90eXBlbGliX3R5cGVkZXNjcmlwdGlvbl9yZWxlYXNlKCAodHlwZWxpYl9UeXBlRGVzY3JpcHRpb24qKXBUeXBlRGVzYyApOwoKCVJlZmVyZW5jZTwgWEludGVyZmFjZSA+IHhQcm9wU2V0SWZhY2UgPSB4QWNjZXNzLT5xdWVyeUFkYXB0ZXIoIGFUeXBlICk7CgkvL1JlZmVyZW5jZTwgWEludGVyZmFjZSA+IHhQcm9wU2V0SWZhY2UgPSB4QWNjZXNzLT5xdWVyeUFkYXB0ZXIoIGFQcm9wZXJ0eVNldFVpayApOwoJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4UHJvcFNldCggeFByb3BTZXRJZmFjZSwgVU5PX1FVRVJZICk7CgkvL1hQcm9wZXJ0eVNldFJlZiB4UHJvcFNldCA9IChYUHJvcGVydHlTZXQqKXhQcm9wU2V0SWZhY2UtPgoJLy8JcXVlcnlJbnRlcmZhY2UoIFhQcm9wZXJ0eVNldDo6Z2V0U21hcnRVaWsoKSApOwoJVEVTVF9FTlNIVVJFKCB4UHJvcFNldC5pcygpLCAiQ291bGQgbm90IGdldCBYUHJvcGVydHlTZXQgYnkgcXVlcnlBZGFwdGVyKCkiICk7CgoJLy8gWEV4YWN0TmFtZQoJUmVmZXJlbmNlPCBYRXhhY3ROYW1lID4geEV4YWN0TmFtZSggeEFjY2VzcywgVU5PX1FVRVJZICk7CglURVNUX0VOU0hVUkUoIHhFeGFjdE5hbWUuaXMoKSwgIkludHJvc3BlY3Rpb24gdW50ZXJzdHVldHp0IGtlaW4gRXhhY3ROYW1lIiApOwoKCS8vIFNjaGxlaWZlIHVlYmVyIGFsbGUgS29tYmluYXRpb25lbiB2b24gQ29uY2VwdHMKCWZvciggc2FsX0ludDMyIG5Db25jZXB0cyA9IDAgOyBuQ29uY2VwdHMgPCAxNiA7IG5Db25jZXB0cysrICkKCXsKLy9wcmludGYoICIqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4iICk7Ci8vcHJpbnRmKCAibkNvbmNlcHRzID0gJWxkXG4iLCBuQ29uY2VwdHMgKTsKCgkJLy8gV2lldmllbGUgUHJvcGVydGllcyBzb2xsdGVuIGVzIHNlaW4KCQlzYWxfSW50MzIgbkRlbWFuZGVkUHJvcENvdW50ID0gMDsKCQlzYWxfSW50MzIgaUxpc3QgPSAwOwoJCXdoaWxlKCBwUHJvcGVydHlEZWZzWyBpTGlzdCBdLnBOYW1lICkKCQl7CgkJCWlmKCBwUHJvcGVydHlEZWZzWyBpTGlzdCBdLm5Db25jZXB0ICYgbkNvbmNlcHRzICkKCQkJCW5EZW1hbmRlZFByb3BDb3VudCsrOwoJCQlpTGlzdCsrOwoJCX0KCgkJaWYoIHhQcm9wU2V0LmlzKCkgKQoJCXsKCQkJUmVmZXJlbmNlPCBYUHJvcGVydHlTZXRJbmZvID4geFByb3BTZXRJbmZvID0geFByb3BTZXQtPmdldFByb3BlcnR5U2V0SW5mbygpOwoJCQkvL1NlcXVlbmNlPFByb3BlcnR5PiBhUmV0U2VxID0geFByb3BTZXRJbmZvLT5nZXRQcm9wZXJ0aWVzKCk7CgkJCVNlcXVlbmNlPFByb3BlcnR5PiBhUmV0U2VxID0geEFjY2Vzcy0+Z2V0UHJvcGVydGllcyggbkNvbmNlcHRzICk7CgoJCQlzYWxfSW50MzIgbkxlbiA9IGFSZXRTZXEuZ2V0TGVuZ3RoKCk7CgoJCQlhRXJyb3JTdHIgID0gIkV4cGVjdGVkIHRvIGZpbmQgIjsKCQkJYUVycm9yU3RyICs9IE9TdHJpbmc6OnZhbHVlT2YoIG5EZW1hbmRlZFByb3BDb3VudCApOwoJCQlhRXJyb3JTdHIgKz0gIiBwcm9wZXJ0aWVzIGJ1dCBmb3VuZCAiOwoJCQlhRXJyb3JTdHIgKz0gT1N0cmluZzo6dmFsdWVPZiggbkxlbiApOwoJCQlURVNUX0VOU0hVUkUoIG5MZW4gPT0gbkRlbWFuZGVkUHJvcENvdW50LCBhRXJyb3JTdHIuZ2V0U3RyKCkgKTsKCgkJCS8vIGNvdXQgPDwgIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiI7CgkJCS8vIGNvdXQgPDwgIioqKiBFcmdlYm5pcyBkZXIgSW50cm9zcGVjdGlvbiAqKipcbiI7CgkJCS8vIGNvdXQgPDwgIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiI7CgkJCS8vIGNvdXQgPDwgIlxuSW50cm9zcGVjdGlvbiBoYXQgIiA8PCBuTGVuIDw8ICIgUHJvcGVydGllcyBnZWZ1bmRlbjpcbiI7CgoJCQljb25zdCBQcm9wZXJ0eSogcFByb3BzID0gYVJldFNlcS5nZXRDb25zdEFycmF5KCk7CgkJCUFueSBhUHJvcFZhbDsKCQkJc2FsX0ludDMyIGk7CgkJCWlMaXN0ID0gMDsKCQkJZm9yKCBpID0gMCA7IGkgPCBuTGVuIDsgaSsrICkKCQkJewoJCQkJY29uc3QgUHJvcGVydHkgYVByb3AgPSBwUHJvcHNbIGkgXTsKCgkJCQkvLyBOYWVjaHN0ZSBQYXNzZW5kZSBNZXRob2RlIGluIGRlciBMaXN0ZSBzdWNoZW4KCQkJCXdoaWxlKCBwUHJvcGVydHlEZWZzWyBpTGlzdCBdLnBOYW1lICkKCQkJCXsKCQkJCQlpZiggcFByb3BlcnR5RGVmc1sgaUxpc3QgXS5uQ29uY2VwdCAmIG5Db25jZXB0cyApCgkJCQkJCWJyZWFrOwoJCQkJCWlMaXN0Kys7CgkJCQl9CgkJCQlzYWxfSW50MzIgaURlbWFuZGVkID0gaUxpc3Q7CgkJCQlpTGlzdCsrOwoKCQkJCU9VU3RyaW5nIGFQcm9wTmFtZSA9IGFQcm9wLk5hbWU7CgkJCQlPU3RyaW5nIGFOYW1lU3RyKCBhUHJvcE5hbWUuZ2V0U3RyKCksIGFQcm9wTmFtZS5nZXRMZW5ndGgoKSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJCQkJCS8vVVN0cmluZ1RvU3RyaW5nKGFQcm9wTmFtZSwgQ0hBUlNFVF9TWVNURU0pOwoKLy9wcmludGYoICJQcm9wZXJ0eSA9ICVzXG4iLCBhTmFtZVN0ci5nZXRTdHIoKSApOwoKCQkJCU9TdHJpbmcgYURlbWFuZGVkTmFtZSA9IHBQcm9wZXJ0eURlZnNbIGlEZW1hbmRlZCBdLnBOYW1lOwoJCQkJLy9PU3RyaW5nIGFEZW1hbmRlZE5hbWUgPSBwRGVtYW5kZWRQcm9wTmFtZXNbIGkgXTsKCQkJCWFFcnJvclN0ciAgPSAiRXhwZWN0ZWQgcHJvcGVydHkgXCIiOwoJCQkJYUVycm9yU3RyICs9IGFEZW1hbmRlZE5hbWU7CgkJCQlhRXJyb3JTdHIgKz0gIlwiLCBmb3VuZCBcIiI7CgkJCQlhRXJyb3JTdHIgKz0gYU5hbWVTdHI7CgkJCQlhRXJyb3JTdHIgKz0gIlwiIjsKCQkJCVRFU1RfRU5TSFVSRSggYU5hbWVTdHIgPT0gYURlbWFuZGVkTmFtZSwgYUVycm9yU3RyLmdldFN0cigpICk7CgkJCQkvLyBjb3V0IDw8ICJQcm9wZXJ0eSAiIDw8IChpKzEpIDw8ICI6IFwiIiA8PCAoY29uc3QgY2hhciopVVN0cmluZ1RvU3RyaW5nKGFQcm9wTmFtZSwgQ0hBUlNFVF9TWVNURU0pIDw8ICJcIiI7CgoKCQkJCVR5cGUgYVByb3BUeXBlID0gYVByb3AuVHlwZTsKCQkJCU9TdHJpbmcgYVR5cGVOYW1lU3RyKCBPVVN0cmluZ1RvT1N0cmluZyhhUHJvcFR5cGUuZ2V0VHlwZU5hbWUoKSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUykgKTsKCQkJCS8vUmVmZXJlbmNlPCBYSWRsQ2xhc3MgPiB4UHJvcFR5cGUgPSBhUHJvcC5UeXBlOwoJCQkJLy9PU3RyaW5nIGFUeXBlTmFtZVN0ciggeFByb3BUeXBlLT5nZXROYW1lKCksIHhQcm9wVHlwZS0+Z2V0TmFtZSgpLmdldExlbmd0aCgpLCBSVExfVEVYVEVOQ09ESU5HX0FTQ0lJX1VTICk7CgkJCQlPU3RyaW5nIGFEZW1hbmRlZFR5cGVOYW1lU3RyID0gcERlbWFuZGVkUHJvcFR5cGVzWyBpRGVtYW5kZWQgXTsKCQkJCS8vT1N0cmluZyBhRGVtYW5kZWRUeXBlTmFtZVN0ciA9IHBEZW1hbmRlZFByb3BUeXBlc1sgaSBdOwoJCQkJYUVycm9yU3RyICA9ICJQcm9wZXJ0eSBcIiI7CgkJCQlhRXJyb3JTdHIgKz0gYURlbWFuZGVkTmFtZTsKCQkJCWFFcnJvclN0ciArPSAiXCIsIGV4cGVjdGVkIHR5cGUgPiI7CgkJCQlhRXJyb3JTdHIgKz0gYURlbWFuZGVkVHlwZU5hbWVTdHI7CgkJCQlhRXJyb3JTdHIgKz0gIjwgZm91bmQgdHlwZSA+IjsKCQkJCWFFcnJvclN0ciArPSBhVHlwZU5hbWVTdHI7CgkJCQlhRXJyb3JTdHIgKz0gIjwiOwoJCQkJVEVTVF9FTlNIVVJFKCBhVHlwZU5hbWVTdHIgPT0gYURlbWFuZGVkVHlwZU5hbWVTdHIsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoJCQkJLy8gY291dCA8PCAiIChQcm9wLVR5cDogIiA8PCAoY29uc3QgY2hhciopVVN0cmluZ1RvU3RyaW5nKHhQcm9wVHlwZS0+Z2V0TmFtZSgpLCBDSEFSU0VUX1NZU1RFTSkgPDwgIikiOwoKCQkJCS8vIFdlcnQgZGVzIFByb3BlcnR5IGxlc2VuIHVuZCBhdXNnZWJlbgoJCQkJYVByb3BWYWwgPSB4UHJvcFNldC0+Z2V0UHJvcGVydHlWYWx1ZSggYVByb3BOYW1lICk7CgkJCQkvLyBjb3V0IDw8ICJcblx0V2VydCA9ICIgPDwgKGNvbnN0IGNoYXIqKVVTdHJpbmdUb1N0cmluZyhBbnlUb1N0cmluZyggYVByb3BWYWwsIHNhbF9UcnVlICksIENIQVJTRVRfU1lTVEVNKTsKCgkJCQlPU3RyaW5nIGFWYWxTdHIgPSBPVVN0cmluZ1RvT1N0cmluZyggQW55VG9TdHJpbmcoIGFQcm9wVmFsLCBzYWxfRmFsc2UsIHhNZ3IgKSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJCQkJT1N0cmluZyBhRGVtYW5kZWRWYWxTdHIgPSBwRGVtYW5kZWRQcm9wVmFsc1sgaURlbWFuZGVkIF07CgkJCQkvL09TdHJpbmcgYURlbWFuZGVkVmFsU3RyID0gcERlbWFuZGVkUHJvcFZhbHNbIGkgXTsKCQkJCWFFcnJvclN0ciAgPSAiUHJvcGVydHkgXCIiOwoJCQkJYUVycm9yU3RyICs9IGFEZW1hbmRlZE5hbWU7CgkJCQlhRXJyb3JTdHIgKz0gIlwiLCBleHBlY3RlZCB2YWwgPiI7CgkJCQlhRXJyb3JTdHIgKz0gYURlbWFuZGVkVmFsU3RyOwoJCQkJYUVycm9yU3RyICs9ICI8IGZvdW5kIHZhbCA+IjsKCQkJCWFFcnJvclN0ciArPSBhVmFsU3RyOwoJCQkJYUVycm9yU3RyICs9ICI8IjsKCQkJCVRFU1RfRU5TSFVSRSggYVZhbFN0ciA9PSBhRGVtYW5kZWRWYWxTdHIsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoKCQkJCS8vIFdlcnQgcHJ1ZWZlbiB1bmQgdHlwZ2VyZWNodCBtb2RpZml6aWVyZW4KCQkJCVR5cGVDbGFzcyBlVHlwZSA9IGFQcm9wVmFsLmdldFZhbHVlVHlwZSgpLmdldFR5cGVDbGFzcygpOwoJCQkJLy9SZWZlcmVuY2U8IFhJZGxDbGFzcyA+IHhJZGxDbGFzcyA9IGFQcm9wVmFsLmdldFJlZmxlY3Rpb24oKS0+Z2V0SWRsQ2xhc3MoKTsKCQkJCS8vVHlwZUNsYXNzIGVUeXBlID0geElkbENsYXNzLT5nZXRUeXBlQ2xhc3MoKTsKCQkJCUFueSBhTmV3VmFsOwoJCQkJc2FsX0Jvb2wgYk1vZGlmeSA9IHNhbF9UcnVlOwoJCQkJc3dpdGNoKCBlVHlwZSApCgkJCQl7CgkJCQkJY2FzZSBUeXBlQ2xhc3NfU1RSSU5HOgoJCQkJCXsKCQkJCQkJT1VTdHJpbmcgYVN0cjsKCQkJCQkJYVByb3BWYWwgPj49IGFTdHI7CgkJCQkJCS8vT1N0cmluZyBhU3RyID0gYVByb3BWYWwuZ2V0U3RyaW5nKCk7CgkJCQkJCWFTdHIgPSBhU3RyICsgT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIChNb2RpZmllZCEpIik7CgkJCQkJCWFOZXdWYWwgPDw9IGFTdHI7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQljYXNlIFR5cGVDbGFzc19ET1VCTEU6CgkJCQkJewoJCQkJCQlkb3VibGUgZCgwLjApOwoJCQkJCQlhUHJvcFZhbCA+Pj0gZDsKCQkJCQkJYU5ld1ZhbCA8PD0gZCArIDEuMDsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWNhc2UgVHlwZUNsYXNzX1NIT1JUOgoJCQkJCXsKCQkJCQkJc2FsX0ludDE2IG4oMCk7CgkJCQkJCWFQcm9wVmFsID4+PSBuOwoJCQkJCQlhTmV3VmFsIDw8PSBzYWxfSW50MTYoIG4gKyAxICk7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQljYXNlIFR5cGVDbGFzc19MT05HOgoJCQkJCXsKCQkJCQkJc2FsX0ludDMyIG4oMCk7CgkJCQkJCWFQcm9wVmFsID4+PSBuOwoJCQkJCQlhTmV3VmFsIDw8PSBzYWxfSW50MzIoIG4gKyAxICk7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQlkZWZhdWx0OgoJCQkJCQliTW9kaWZ5ID0gc2FsX0ZhbHNlOwoJCQkJCQlicmVhazsKCQkJCX0KCgkJCQkvLyBNb2RpZml6aWVyZW4gbnVyIGJlaW0gbGV0enRlbiBEdXJjaGxhdWYKCQkJCWlmKCBuQ29uY2VwdHMgPT0gMTUgKQoJCQkJewoJCQkJCS8vIFhFeGFjdE5hbWUgcHJ1ZWZlbiwgZGFmdWVyIGFsbGVzIGdyb3NzIG1hY2hlbgoJCQkJCS8vIChJbnRyb3NwZWN0aW9uIGlzdCBtaXQgTG93ZXJDYXNlIGltcGxlbWVudGllcnQsIGFsc28gYW5kZXJzIG1hY2hlbikKCQkJCQlPVVN0cmluZyBhVXBwZXJVU3RyID0gYVByb3BOYW1lLnRvQXNjaWlVcHBlckNhc2UoKTsKCQkJCQlPVVN0cmluZyBhRXhhY3ROYW1lID0geEV4YWN0TmFtZS0+Z2V0RXhhY3ROYW1lKCBhVXBwZXJVU3RyICk7CgkJCQkJaWYoIGFFeGFjdE5hbWUgIT0gYVByb3BOYW1lICkKCQkJCQl7CgkJCQkJCWFFcnJvclN0ciAgPSAiUHJvcGVydHkgXCIiOwoJCQkJCQlhRXJyb3JTdHIgKz0gT1VTdHJpbmdUb09TdHJpbmcoIGFQcm9wTmFtZSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJCQkJCQlhRXJyb3JTdHIgKz0gIlwiLCBub3QgZm91bmQgYXMgXCIiOwoJCQkJCQlhRXJyb3JTdHIgKz0gT1VTdHJpbmdUb09TdHJpbmcoYVVwcGVyVVN0ciwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJCQkJCQlhRXJyb3JTdHIgKz0gIlwiIHVzaW5nIFhFeGFjdE5hbWUiOwoJCQkJCQlURVNUX0VOU0hVUkUoIHNhbF9GYWxzZSwgYUVycm9yU3RyLmdldFN0cigpICk7CgkJCQkJfQoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWJNb2RpZnkgPSBzYWxfRmFsc2U7CgkJCQl9CgoJCQkJLy8gTmV1ZW4gV2VydCBzZXR6ZW4sIHdpZWRlciBsZXNlbiB1bmQgYXVzZ2ViZW4KCQkJCWlmKCBiTW9kaWZ5ICkKCQkJCXsKCQkJCQkvLyBjb3V0LmZsdXNoKCk7CgoJCQkJCS8vIDEuNy4xOTk5LCBVbmtub3duUHJvcGVydHlFeGNlcHRpb24gYmVpIFJlYWRPbmx5LVByb3BlcnRpZXMgYWJmYW5nZW4KCQkJCQl0cnkKCQkJCQl7CgkJCQkJCXhQcm9wU2V0LT5zZXRQcm9wZXJ0eVZhbHVlKCBhUHJvcE5hbWUsIGFOZXdWYWwgKTsKCQkJCQl9CgkJCQkJY2F0Y2goVW5rbm93blByb3BlcnR5RXhjZXB0aW9uIGUxKQoJCQkJCXsKCQkJCQl9CgoJCQkJCWFQcm9wVmFsID0geFByb3BTZXQtPmdldFByb3BlcnR5VmFsdWUoIGFQcm9wTmFtZSApOwoJCQkJCS8vIGNvdXQgPDwgIlxuXHRNb2RpZml6aWVydGVyIFdlcnQgPSAiIDw8IChjb25zdCBjaGFyKikgVVN0cmluZ1RvU3RyaW5nKEFueVRvU3RyaW5nKCBhUHJvcFZhbCwgc2FsX1RydWUgKSwgQ0hBUlNFVF9TWVNURU0pIDw8ICJcbiI7CgoJCQkJCU9VU3RyaW5nIGFTdHIgPSBBbnlUb1N0cmluZyggYVByb3BWYWwsIHNhbF9GYWxzZSwgeE1nciApOwoJCQkJCU9TdHJpbmcgYU1vZGlmaWVkVmFsU3RyID0gT1VTdHJpbmdUb09TdHJpbmcoIGFTdHIsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCQkJCQlPU3RyaW5nIGFEZW1hbmRlZE1vZGlmaWVkVmFsU3RyID0gcERlbWFuZGVkTW9kaWZpZWRQcm9wVmFsc1sgaSBdOwoJCQkJCWFFcnJvclN0ciAgPSAiUHJvcGVydHkgXCIiOwoJCQkJCWFFcnJvclN0ciArPSBhRGVtYW5kZWROYW1lOwoJCQkJCWFFcnJvclN0ciArPSAiXCIsIGV4cGVjdGVkIG1vZGlmaWVkIHZhbCA+IjsKCQkJCQlhRXJyb3JTdHIgKz0gYURlbWFuZGVkTW9kaWZpZWRWYWxTdHI7CgkJCQkJYUVycm9yU3RyICs9ICI8IGZvdW5kIHZhbCA+IjsKCQkJCQlhRXJyb3JTdHIgKz0gYU1vZGlmaWVkVmFsU3RyOwoJCQkJCWFFcnJvclN0ciArPSAiPCI7CgkJCQkJVEVTVF9FTlNIVVJFKCBhTW9kaWZpZWRWYWxTdHIgPT0gYURlbWFuZGVkTW9kaWZpZWRWYWxTdHIsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCS8vIGNvdXQgPDwgIlxuXHRXZXJ0IHd1cmRlIG5pY2h0IG1vZGlmaXppZXJ0XG4iOwoJCQkJfQoKCQkJCS8vIENoZWNrZW4sIG9iIGFsbGUgUHJvcGVydGllcyBhdWNoIGVpbnplbG4gZ2VmdW5kZW4gd2VyZGVuCgkJCQlhRXJyb3JTdHIgID0gInByb3BlcnR5IFwiIjsKCQkJCWFFcnJvclN0ciArPSBhRGVtYW5kZWROYW1lOwoJCQkJYUVycm9yU3RyICs9ICJcIiBub3QgZm91bmQgd2l0aCBoYXNQcm9wZXJ0eSgpIjsKCQkJCU9VU3RyaW5nIGFXRGVtYW5kZWROYW1lID0gT1N0cmluZ1RvT1VTdHJpbmcoYURlbWFuZGVkTmFtZSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJCQkJc2FsX0Jvb2wgYlByb3BlcnR5ID0geEFjY2Vzcy0+aGFzUHJvcGVydHkoIGFXRGVtYW5kZWROYW1lLCBuQ29uY2VwdHMgKTsKCQkJCS8vc2FsX0Jvb2wgYlByb3BlcnR5ID0geEFjY2Vzcy0+aGFzUHJvcGVydHkoIGFXRGVtYW5kZWROYW1lLCBQcm9wZXJ0eUNvbmNlcHQ6OkFMTCAtIFByb3BlcnR5Q29uY2VwdDo6REFOR0VST1VTICk7CgkJCQlURVNUX0VOU0hVUkUoIGJQcm9wZXJ0eSwgYUVycm9yU3RyLmdldFN0cigpICk7CgoJCQkJYUVycm9yU3RyICA9ICJwcm9wZXJ0eSBcIiI7CgkJCQlhRXJyb3JTdHIgKz0gYURlbWFuZGVkTmFtZTsKCQkJCWFFcnJvclN0ciArPSAiXCIgbm90IGVxdWFsIHRvIHNhbWUgUHJvcGVydHkgaW4gc2VxdWVuY2UgcmV0dXJuZWQgYnkgZ2V0UHJvcGVydGllcygpIjsKCQkJCXRyeQoJCQkJewoJCQkJCVByb3BlcnR5IGFHZXRQcm9wID0geEFjY2Vzcy0+Z2V0UHJvcGVydHkoIGFXRGVtYW5kZWROYW1lLCBuQ29uY2VwdHMgKTsKCQkJCQkvL1Byb3BlcnR5IGFHZXRQcm9wID0geEFjY2Vzcy0+Z2V0UHJvcGVydHkoIGFXRGVtYW5kZWROYW1lLCBQcm9wZXJ0eUNvbmNlcHQ6OkFMTCApOwoJCQkJCS8vVEVTVF9FTlNIVVJFKCBhR2V0UHJvcCA9PSBhUHJvcCAsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoJCQkJfQoJCQkJY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZTEpCgkJCQl7CgkJCQkJYUVycm9yU3RyICA9ICJwcm9wZXJ0eSBcIiI7CgkJCQkJYUVycm9yU3RyICs9IGFEZW1hbmRlZE5hbWU7CgkJCQkJYUVycm9yU3RyICs9ICJcIiwgZXhjZXB0aW9uIHdhcyB0aHJvd24gd2hlbiB0cnlpbmcgZ2V0UHJvcGVydHkoKSI7CgkJCQkJVEVTVF9FTlNIVVJFKCBzYWxfRmFsc2UsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoJCQkJfQoKCQkJfQoJCX0KCX0KCgkvLyBTY2hsZWlmZSB1ZWJlciBhbGxlIEtvbWJpbmF0aW9uZW4gdm9uIENvbmNlcHRzCglmb3IoIHNhbF9JbnQzMiBuQ29uY2VwdHMgPSAwIDsgbkNvbmNlcHRzIDwgMTI4IDsgbkNvbmNlcHRzKysgKQoJewovL3ByaW50ZiggIioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiIgKTsKLy9wcmludGYoICJuQ29uY2VwdHMgPSAlbGRcbiIsIG5Db25jZXB0cyApOwoKCQkvLyBEYXMgMl42LUJpdCBzdGVodCBmdWVyICJkZW4gUmVzdCIKCQlzYWxfSW50MzIgblJlYWxDb25jZXB0cyA9IG5Db25jZXB0czsKCQlpZiggbkNvbmNlcHRzICYgMHg0MCApCgkJCW5SZWFsQ29uY2VwdHMgfD0gKDB4RkZGRkZGRkYgLSAweDNGKTsKCgkJLy8gV2lldmllbGUgTWV0aG9kZW4gc29sbHRlbiBlcyBzZWluCgkJc2FsX0ludDMyIG5EZW1hbmRlZE1ldGhDb3VudCA9IDA7CgkJc2FsX0ludDMyIGlMaXN0ID0gMDsKCQl3aGlsZSggcE1ldGhvZERlZnNbIGlMaXN0IF0ucE5hbWUgKQoJCXsKCQkJaWYoIHBNZXRob2REZWZzWyBpTGlzdCBdLm5Db25jZXB0ICYgblJlYWxDb25jZXB0cyApCgkJCQluRGVtYW5kZWRNZXRoQ291bnQrKzsKCQkJaUxpc3QrKzsKCQl9CgoJCS8vIE1ldGhvZGVuLUFycmF5IGF1c2dlYmVuCgkJLy9hTWV0aG9kU2VxID0geEFjY2Vzcy0+Z2V0TWV0aG9kcwoJCVNlcXVlbmNlPCBSZWZlcmVuY2U8IFhJZGxNZXRob2QgPiA+IGFNZXRob2RTZXEgPSB4QWNjZXNzLT5nZXRNZXRob2RzKCBuUmVhbENvbmNlcHRzICk7CgkJLy9TZXF1ZW5jZTxYSWRsTWV0aG9kUmVmPiBhTWV0aG9kU2VxID0geEFjY2Vzcy0+Z2V0TWV0aG9kcwoJCS8vCSggTWV0aG9kQ29uY2VwdDo6QUxMIC0gTWV0aG9kQ29uY2VwdDo6REFOR0VST1VTIC0gTWV0aG9kQ29uY2VwdDo6UFJPUEVSVFkgKTsKCQlzYWxfSW50MzIgbkxlbiA9IGFNZXRob2RTZXEuZ2V0TGVuZ3RoKCk7CgkJLy8gY291dCA8PCAiXG5cbioqKiBNZXRob2RlbiAqKipcbiI7CgkJLy8gY291dCA8PCAiSW50cm9zcGVjdGlvbiBoYXQgIiA8PCBuTGVuIDw8ICIgTWV0aG9kZW4gZ2VmdW5kZW46XG4iOwoKCQlhRXJyb3JTdHIgID0gIkV4cGVjdGVkIHRvIGZpbmQgIjsKCQlhRXJyb3JTdHIgKz0gT1N0cmluZzo6dmFsdWVPZiggbkRlbWFuZGVkTWV0aENvdW50ICk7CgkJYUVycm9yU3RyICs9ICIgbWV0aG9kcyBidXQgZm91bmQgIjsKCQlhRXJyb3JTdHIgKz0gT1N0cmluZzo6dmFsdWVPZiggbkxlbiApOwoJCVRFU1RfRU5TSFVSRSggbkxlbiA9PSBuRGVtYW5kZWRNZXRoQ291bnQsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoKCQljb25zdCBSZWZlcmVuY2U8IFhJZGxNZXRob2QgPiogcE1ldGhvZHMgPSBhTWV0aG9kU2VxLmdldENvbnN0QXJyYXkoKTsKCQlzYWxfSW50MzIgaTsKCQlpTGlzdCA9IDA7CgoJCWZvciggaSA9IDAgOyBpIDwgbkxlbiA7IGkrKyApCgkJewoJCQkvLyBNZXRob2RlIGFuc3ByZWNoZW4KCQkJY29uc3QgUmVmZXJlbmNlPCBYSWRsTWV0aG9kID4mIHJ4TWV0aG9kID0gcE1ldGhvZHNbaV07CgoJCQkvLyBNZXRob2RlIGF1c2dlYmVuCgkJCU9VU3RyaW5nIGFNZXRoTmFtZSA9IHJ4TWV0aG9kLT5nZXROYW1lKCk7CgkJCU9TdHJpbmcgYU5hbWVTdHIgPSBPVVN0cmluZ1RvT1N0cmluZyhhTWV0aE5hbWUsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCi8vcHJpbnRmKCAiTWV0aG9kID0gJXNcbiIsIGFOYW1lU3RyLmdldFN0cigpICk7CgoJCQkvLyBOYWVjaHN0ZSBQYXNzZW5kZSBNZXRob2RlIGluIGRlciBMaXN0ZSBzdWNoZW4KCQkJd2hpbGUoIHBNZXRob2REZWZzWyBpTGlzdCBdLnBOYW1lICkKCQkJewoJCQkJaWYoIHBNZXRob2REZWZzWyBpTGlzdCBdLm5Db25jZXB0ICYgblJlYWxDb25jZXB0cyApCgkJCQkJYnJlYWs7CgkJCQlpTGlzdCsrOwoJCQl9CgkJCU9TdHJpbmcgYURlbWFuZGVkTmFtZSA9IHBNZXRob2REZWZzWyBpTGlzdCBdLnBOYW1lOwoJCQlpTGlzdCsrOwoKCQkJLy9PU3RyaW5nIGFEZW1hbmRlZE5hbWUgPSBwRGVtYW5kZWRNZXRoTmFtZXNbIGkgXTsKCQkJYUVycm9yU3RyICA9ICJFeHBlY3RlZCBtZXRob2QgXCIiOwoJCQlhRXJyb3JTdHIgKz0gYURlbWFuZGVkTmFtZTsKCQkJYUVycm9yU3RyICs9ICJcIiwgZm91bmQgXCIiOwoJCQlhRXJyb3JTdHIgKz0gYU5hbWVTdHI7CgkJCWFFcnJvclN0ciArPSAiXCIiOwoJCQlURVNUX0VOU0hVUkUoIGFOYW1lU3RyID09IGFEZW1hbmRlZE5hbWUsIGFFcnJvclN0ci5nZXRTdHIoKSApOwoJCQkvLyBjb3V0IDw8ICJNZXRob2RlICIgPDwgKGkrMSkgPDwgIjogIiA8PCAoY29uc3QgY2hhciopIFVTdHJpbmdUb1N0cmluZyhyeE1ldGhvZC0+Z2V0UmV0dXJuVHlwZSgpLT5nZXROYW1lKCksIENIQVJTRVRfU1lTVEVNKQoJCQkvLwkgPDwgIiAiIDw8IChjb25zdCBjaGFyKikgVVN0cmluZ1RvU3RyaW5nKHJ4TWV0aG9kLT5nZXROYW1lKCksIENIQVJTRVRfU1lTVEVNKSA8PCAiKCAiOwoKCQkJLy8gQ2hlY2tlbiwgb2IgYWxsZSBNZXRob2RlbiBhdWNoIGVpbnplbG4gZ2VmdW5kZW4gd2VyZGVuCgkJCWFFcnJvclN0ciAgPSAibWV0aG9kIFwiIjsKCQkJYUVycm9yU3RyICs9IGFEZW1hbmRlZE5hbWU7CgkJCWFFcnJvclN0ciArPSAiXCIgbm90IGZvdW5kIHdpdGggaGFzTWV0aG9kKCkiOwoJCQlPVVN0cmluZyBhV0RlbWFuZGVkTmFtZSA9IE9TdHJpbmdUb09VU3RyaW5nKGFEZW1hbmRlZE5hbWUsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCQkJc2FsX0Jvb2wgYk1ldGhvZCA9IHhBY2Nlc3MtPmhhc01ldGhvZCggYVdEZW1hbmRlZE5hbWUsIG5SZWFsQ29uY2VwdHMgKTsKCQkJLy9zYWxfQm9vbCBiTWV0aG9kID0geEFjY2Vzcy0+aGFzTWV0aG9kKCBhV0RlbWFuZGVkTmFtZSwgTWV0aG9kQ29uY2VwdDo6QUxMICk7CgkJCVRFU1RfRU5TSFVSRSggYk1ldGhvZCwgYUVycm9yU3RyLmdldFN0cigpICk7CgoJCQlhRXJyb3JTdHIgID0gIm1ldGhvZCBcIiI7CgkJCWFFcnJvclN0ciArPSBhRGVtYW5kZWROYW1lOwoJCQlhRXJyb3JTdHIgKz0gIlwiIG5vdCBlcXVhbCB0byBzYW1lIG1ldGhvZCBpbiBzZXF1ZW5jZSByZXR1cm5lZCBieSBnZXRNZXRob2RzKCkiOwoJCQl0cnkKCQkJewoJCQkJUmVmZXJlbmNlPCBYSWRsTWV0aG9kID4geEdldE1ldGhvZCA9IHhBY2Nlc3MtPmdldE1ldGhvZCggYVdEZW1hbmRlZE5hbWUsIG5SZWFsQ29uY2VwdHMgKTsKCQkJCS8vWElkbE1ldGhvZFJlZiB4R2V0TWV0aG9kID0geEFjY2Vzcy0+Z2V0TWV0aG9kKCBhV0RlbWFuZGVkTmFtZSwgTWV0aG9kQ29uY2VwdDo6QUxMICk7CgkJCQlURVNUX0VOU0hVUkUoIHhHZXRNZXRob2QgPT0gcnhNZXRob2QgLCBhRXJyb3JTdHIuZ2V0U3RyKCkgKTsKCQkJfQoJCQljYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlMSkKCQkJewoJCQkJYUVycm9yU3RyICA9ICJtZXRob2QgXCIiOwoJCQkJYUVycm9yU3RyICs9IGFEZW1hbmRlZE5hbWU7CgkJCQlhRXJyb3JTdHIgKz0gIlwiLCBleGNlcHRpb24gd2FzIHRocm93biB3aGVuIHRyeWluZyBnZXRNZXRob2QoKSI7CgkJCQlURVNUX0VOU0hVUkUoIHNhbF9GYWxzZSwgYUVycm9yU3RyLmdldFN0cigpICk7CgkJCX0KCQl9Cgl9CgoJLy8gTGlzdGVuZXItS2xhc3NlbiBhdXNnZWJlbgoJU2VxdWVuY2U8IFR5cGUgPiBhQ2xhc3NTZXEgPSB4QWNjZXNzLT5nZXRTdXBwb3J0ZWRMaXN0ZW5lcnMoKTsKCXNhbF9JbnQzMiBuTGVuID0gYUNsYXNzU2VxLmdldExlbmd0aCgpOwoJLy8gY291dCA8PCAiXG5cbioqKiBBbm1lbGRiYXJlIExpc3RlbmVyICoqKlxuIjsKCS8vIGNvdXQgPDwgIkludHJvc3BlY3Rpb24gaGF0ICIgPDwgbkxlbiA8PCAiIExpc3RlbmVyIGdlZnVuZGVuOlxuIjsKCgljb25zdCBUeXBlKiBwTGlzdGVuZXJzID0gYUNsYXNzU2VxLmdldENvbnN0QXJyYXkoKTsKCWZvciggc2FsX0ludDMyIGkgPSAwIDsgaSA8IG5MZW4gOyBpKysgKQoJewoJCS8vIE1ldGhvZGUgYW5zcHJlY2hlbgoJCWNvbnN0IFR5cGUmIGFMaXN0ZW5lclR5cGUgPSBwTGlzdGVuZXJzW2ldOwoKCQkvLyBOYW1lbiBiZXNvcmdlbgoJCU9VU3RyaW5nIGFMaXN0ZW5lckNsYXNzTmFtZSA9IGFMaXN0ZW5lclR5cGUuZ2V0VHlwZU5hbWUoKTsKCQkvLyBjb3V0IDw8ICJMaXN0ZW5lciAiIDw8IChpKzEpIDw8ICI6ICIgPDwgKGNvbnN0IGNoYXIqKVVTdHJpbmdUb1N0cmluZyhhTGlzdGVuZXJDbGFzc05hbWUsIENIQVJTRVRfU1lTVEVNKSA8PCAiXG4iOwoJfQoKCgkvLyBQZXJmb3JtYW5jZSBiZWkgaGFzTWV0aG9kIHRlc3Rlbi4KCS8vQ2hlY2tNZXRob2RQZXJmb3JtYW5jZSggeEFjY2VzcywgInF1ZXJ5SW50ZXJmYWNlIiwgMTAwMDAwICk7CgkvL0NoZWNrTWV0aG9kUGVyZm9ybWFuY2UoIHhBY2Nlc3MsICJnZXRJZGxDbGFzc2VzIiwgMTAwMDAwICk7CgoJLy8gY291dC5mbHVzaCgpOwoKCgoKCXJldHVybiBzYWxfVHJ1ZTsKfQoKClNBTF9JTVBMRU1FTlRfTUFJTigpCnsKCVJlZmVyZW5jZTwgWE11bHRpU2VydmljZUZhY3RvcnkgPiB4TWdyKCBjcmVhdGVSZWdpc3RyeVNlcnZpY2VGYWN0b3J5KCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJzdG9jdGVzdC5yZGIiKSApICk7CgoJc2FsX0Jvb2wgYlN1Y2MgPSBzYWxfRmFsc2U7Cgl0cnkKCXsKCQlSZWZlcmVuY2U8IFhJbXBsZW1lbnRhdGlvblJlZ2lzdHJhdGlvbiA+IHhJbXBsUmVnKAoJCQl4TWdyLT5jcmVhdGVJbnN0YW5jZSggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiY29tLnN1bi5zdGFyLnJlZ2lzdHJ5LkltcGxlbWVudGF0aW9uUmVnaXN0cmF0aW9uIikgKSwgVU5PX1FVRVJZICk7CgkJT1NMX0VOU1VSRSggeEltcGxSZWcuaXMoKSwgIiMjIyBubyBpbXBsIHJlZyEiICk7CgoJCS8vIFJlZ2lzdGVyIHNlcnZpY2VzCgkJT1VTdHJpbmcgbGliTmFtZSggUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVmbGVjdGlvbi51bm8iIFNBTF9ETExFWFRFTlNJT04pICk7Ci8vICAJCU9SZWFsRHluYW1pY0xvYWRlcjo6Y29tcHV0ZUxpYnJhcnlOYW1lKCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb3JlZmwiKSwgbGliTmFtZSk7CgkJZnByaW50ZihzdGRlcnIsICIxXG4iICk7CgkJeEltcGxSZWctPnJlZ2lzdGVySW1wbGVtZW50YXRpb24oT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiY29tLnN1bi5zdGFyLmxvYWRlci5TaGFyZWRMaWJyYXJ5IiksCgkJCQkJCQkJCQkgbGliTmFtZSwgUmVmZXJlbmNlPCBYU2ltcGxlUmVnaXN0cnkgPigpICk7CgkJZnByaW50ZihzdGRlcnIsICIyXG4iICk7CgkJUmVmZXJlbmNlPCBYSWRsUmVmbGVjdGlvbiA+IHhSZWZsKCB4TWdyLT5jcmVhdGVJbnN0YW5jZSggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiY29tLnN1bi5zdGFyLnJlZmxlY3Rpb24uQ29yZVJlZmxlY3Rpb24iKSApLCBVTk9fUVVFUlkgKTsKCQlPU0xfRU5TVVJFKCB4UmVmbC5pcygpLCAiIyMjIG5vIGNvcmVyZWZsZWN0aW9uISIgKTsKCgkJLy8gSW50cm9zcGVjdGlvbgoJCWxpYk5hbWUgPSBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKAogICAgICAgICAgICAiaW50cm9zcGVjdGlvbi51bm8iIFNBTF9ETExFWFRFTlNJT04pOwovLyAgCQlPUmVhbER5bmFtaWNMb2FkZXI6OmNvbXB1dGVMaWJyYXJ5TmFtZSggT1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiaW5zcCIpLCBsaWJOYW1lKTsKCQlmcHJpbnRmKHN0ZGVyciwgIjNcbiIgKTsKCQl4SW1wbFJlZy0+cmVnaXN0ZXJJbXBsZW1lbnRhdGlvbihPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIubG9hZGVyLlNoYXJlZExpYnJhcnkiKSwKCQkJCQkJCQkJCSBsaWJOYW1lLCBSZWZlcmVuY2U8IFhTaW1wbGVSZWdpc3RyeSA+KCkgKTsKCQlmcHJpbnRmKHN0ZGVyciwgIjRcbiIgKTsKCQlSZWZlcmVuY2U8IFhJbnRyb3NwZWN0aW9uID4geEludHJvc3AoIHhNZ3ItPmNyZWF0ZUluc3RhbmNlKCBPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIuYmVhbnMuSW50cm9zcGVjdGlvbiIpICksIFVOT19RVUVSWSApOwoJCU9TTF9FTlNVUkUoIHhSZWZsLmlzKCksICIjIyMgbm8gY29yZXJlZmxlY3Rpb24hIiApOwoKCQlmcHJpbnRmKHN0ZGVyciwgImJlZm9yZSB0ZXN0X2ludHJvc3BcbiIgKTsKCQliU3VjYyA9IHRlc3RfaW50cm9zcCggeE1nciwgeFJlZmwsIHhJbnRyb3NwICk7CgkJZnByaW50ZihzdGRlcnIsICJhZnRlciB0ZXN0X2ludHJvc3BcbiIgKTsKCQkvL2JTdWNjID0gdGVzdF9jb3JlZmwoIHhSZWZsICk7Cgl9CgljYXRjaCAoRXhjZXB0aW9uICYgckV4YykKCXsKCQlPU0xfRU5TVVJFKCBzYWxfRmFsc2UsICIjIyMgZXhjZXB0aW9uIG9jY3VyZWQhIiApOwoJCU9TdHJpbmcgYU1zZyggT1VTdHJpbmdUb09TdHJpbmcoIHJFeGMuTWVzc2FnZSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApICk7CgkJT1NMX1RSQUNFKCAiIyMjIGV4Y2VwdGlvbiBvY2N1cmVkOiAiICk7CgkJT1NMX1RSQUNFKCBhTXNnLmdldFN0cigpICk7CgkJT1NMX1RSQUNFKCAiXG4iICk7Cgl9CgoJUmVmZXJlbmNlPCBYQ29tcG9uZW50ID4oIHhNZ3IsIFVOT19RVUVSWSApLT5kaXNwb3NlKCk7CgoJcHJpbnRmKCAidGVzdGludHJvc3AgJXMgIVxuIiwgKGJTdWNjID8gInN1Y2NlZWRlZCIgOiAiZmFpbGVkIikgKTsKCXJldHVybiAoYlN1Y2MgPyAwIDogLTEpOwp9CgoKCgoKCgovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi8vKioqIFRFU1QtSW1wbGVtZW50YXRpb25lbiAqKioKLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLyBCbGVpYnQgYXVmIERhdWVyIG5pY2h0IGRyaW4sIGRpZW50IGFscyBleHBvcnRpZXJiYXJlIFRlc3QtS2xhc3NlCi8vIHouQi4gZnVlciBCYXNpYy1BbmJpbmR1bmcKCgoKCgoK