LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYmFzaWMuaHh4IgoKI2luY2x1ZGUgInNiY29tcC5oeHgiCgovLyBTaW5nbGUtbGluZSBJRiB1bmQgTXVsdGlsaW5lIElGCgp2b2lkIFNiaVBhcnNlcjo6SWYoKQp7CglzYWxfdUludDMyIG5FbmRMYmw7CglTYmlUb2tlbiBlVG9rID0gTklMOwoJLy8gRW5kZS1Ub2tlbnMgaWdub3JpZXJlbjoKCVNiaUV4cHJlc3Npb24gYUNvbmQoIHRoaXMgKTsKCWFDb25kLkdlbigpOwoJVGVzdFRva2VuKCBUSEVOICk7CglpZiggSXNFb2xuKCBOZXh0KCkgKSApCgl7CgkJLy8gQUIgMTMuNS4xOTk2OiAjMjc3MjAjIEFtIEVuZGUgamVkZW4gQmxvY2tzIG11c3MgZWluIEp1bXAgenUgRU5ESUYKCQkvLyBlaW5nZWZ1ZWd0IHdlcmRlbiwgZGFtaXQgYmVpIEVMU0VJRiBuaWNodCBlcm5ldXQgZGllIEJlZGluZ3VuZwoJCS8vIGF1c2dld2VydGV0IHdpcmQuIERpZSBUYWJlbGxlIG5pbW10IGFsbGUgQWJzcHJ1bmdzdGVsbGVuIGF1Zi4KI2RlZmluZSBKTVBfVEFCTEVfU0laRSAxMDAKCQlzYWxfdUludDMyIHBuSm1wVG9FbmRMYmxbSk1QX1RBQkxFX1NJWkVdOwkvLyAxMDAgRUxTRUlGcyB6dWxhZXNzaWcKCQlzYWxfdUludDE2IGlKbXAgPSAwOwkJCQkJCS8vIGFrdHVlbGxlciBUYWJlbGxlbi1JbmRleAoKCQkvLyBtdWx0aWxpbmUgSUYKCQluRW5kTGJsID0gYUdlbi5HZW4oIF9KVU1QRiwgMCApOwoJCWVUb2sgPSBQZWVrKCk7CgkJd2hpbGUoICEoIGVUb2sgPT0gRUxTRUlGIHx8IGVUb2sgPT0gRUxTRSB8fCBlVG9rID09IEVORElGICkgJiYKCQkJCSFiQWJvcnQgJiYgUGFyc2UoKSApCgkJewoJCQllVG9rID0gUGVlaygpOwoJCQlpZiggSXNFb2YoKSApCgkJCXsKCQkJCUVycm9yKCBTYkVSUl9CQURfQkxPQ0ssIElGICk7IGJBYm9ydCA9IHNhbF9UcnVlOyByZXR1cm47CgkJCX0KCQl9CgkJLy8gRUxTRUlGPwoJCXdoaWxlKCBlVG9rID09IEVMU0VJRiApCgkJewoJCQkvLyAjMjc3MjAjIEJlaSBlcmZvbGdyZWljaGVtIElGL0VMU0VJRiBhdWYgRU5ESUYgc3ByaW5nZW4KCQkJaWYoIGlKbXAgPj0JSk1QX1RBQkxFX1NJWkUgKQoJCQl7CgkJCQlFcnJvciggU2JFUlJfUFJPR19UT09fTEFSR0UgKTsJYkFib3J0ID0gc2FsX1RydWU7IAlyZXR1cm47CgkJCX0KCQkJcG5KbXBUb0VuZExibFtpSm1wKytdID0gYUdlbi5HZW4oIF9KVU1QLCAwICk7CgoJCQlOZXh0KCk7CgkJCWFHZW4uQmFja0NoYWluKCBuRW5kTGJsICk7CgoJCQlhR2VuLlN0YXRlbWVudCgpOwoJCQlTYmlFeHByZXNzaW9uKiBwQ29uZCA9IG5ldyBTYmlFeHByZXNzaW9uKCB0aGlzICk7CgkJCXBDb25kLT5HZW4oKTsKCQkJbkVuZExibCA9IGFHZW4uR2VuKCBfSlVNUEYsIDAgKTsKCQkJZGVsZXRlIHBDb25kOwoJCQlUZXN0VG9rZW4oIFRIRU4gKTsKCQkJZVRvayA9IFBlZWsoKTsKCQkJd2hpbGUoICEoIGVUb2sgPT0gRUxTRUlGIHx8IGVUb2sgPT0gRUxTRSB8fCBlVG9rID09IEVORElGICkgJiYKCQkJCQkhYkFib3J0ICYmIFBhcnNlKCkgKQoJCQl7CgkJCQllVG9rID0gUGVlaygpOwoJCQkJaWYoIElzRW9mKCkgKQoJCQkJewoJCQkJCUVycm9yKCBTYkVSUl9CQURfQkxPQ0ssIEVMU0VJRiApOyAgYkFib3J0ID0gc2FsX1RydWU7IHJldHVybjsKCQkJCX0KCQkJfQoJCX0KCQlpZiggZVRvayA9PSBFTFNFICkKCQl7CgkJCU5leHQoKTsKCQkJc2FsX3VJbnQzMiBuRWxzZUxibCA9IG5FbmRMYmw7CgkJCW5FbmRMYmwgPSBhR2VuLkdlbiggX0pVTVAsIDAgKTsKCQkJYUdlbi5CYWNrQ2hhaW4oIG5FbHNlTGJsICk7CgoJCQlhR2VuLlN0YXRlbWVudCgpOwoJCQlTdG1udEJsb2NrKCBFTkRJRiApOwoJCX0KCQllbHNlIGlmKCBlVG9rID09IEVORElGICkKCQkJTmV4dCgpOwoKCQkvLyAjMjc3MjAjIEptcC1UYWJlbGxlIGFiYXJiZWl0ZW4KCQl3aGlsZSggaUptcCA+IDAgKQoJCXsKCQkJaUptcC0tOwoJCQlhR2VuLkJhY2tDaGFpbiggcG5KbXBUb0VuZExibFtpSm1wXSApOwoJCX0KCX0KCWVsc2UKCXsKCQkvLyBzaW5nbGUgbGluZSBJRgoJCWJTaW5nbGVMaW5lSWYgPSBzYWxfVHJ1ZTsKCQluRW5kTGJsID0gYUdlbi5HZW4oIF9KVU1QRiwgMCApOwoJCVB1c2goIGVDdXJUb2sgKTsKCQl3aGlsZSggIWJBYm9ydCApCgkJewoJCQlpZiggIVBhcnNlKCkgKSBicmVhazsKCQkJZVRvayA9IFBlZWsoKTsKCQkJaWYoIGVUb2sgPT0gRUxTRSB8fCBlVG9rID09IEVPTE4gfHwgZVRvayA9PSBSRU0gKQoJCQkJYnJlYWs7CgkJfQoJCWlmKCBlVG9rID09IEVMU0UgKQoJCXsKCQkJTmV4dCgpOwoJCQlzYWxfdUludDMyIG5FbHNlTGJsID0gbkVuZExibDsKCQkJbkVuZExibCA9IGFHZW4uR2VuKCBfSlVNUCwgMCApOwoJCQlhR2VuLkJhY2tDaGFpbiggbkVsc2VMYmwgKTsKCQkJd2hpbGUoICFiQWJvcnQgKQoJCQl7CgkJCQlpZiggIVBhcnNlKCkgKSBicmVhazsKCQkJCWVUb2sgPSBQZWVrKCk7CgkJCQlpZiggZVRvayA9PSBFT0xOICkKCQkJCQlicmVhazsKCQkJfQoJCX0KCQliU2luZ2xlTGluZUlmID0gc2FsX0ZhbHNlOwoJfQoJYUdlbi5CYWNrQ2hhaW4oIG5FbmRMYmwgKTsKfQoKLy8gRUxTRS9FTFNFSUYvRU5ESUYgb2huZSBJRgoKdm9pZCBTYmlQYXJzZXI6Ok5vSWYoKQp7CglFcnJvciggU2JFUlJfTk9fSUYgKTsKCVN0bW50QmxvY2soIEVORElGICk7Cn0KCi8vIERPIFdISUxFLi4uTE9PUAovLyBETyAuLi4gTE9PUCBXSElMRQoKdm9pZCBTYmlQYXJzZXI6OkRvTG9vcCgpCnsKCXNhbF91SW50MzIgblN0YXJ0TGJsID0gYUdlbi5HZXRQQygpOwoJT3BlbkJsb2NrKCBETyApOwoJU2JpVG9rZW4gZVRvayA9IE5leHQoKTsKCWlmKCBJc0VvbG4oIGVUb2sgKSApCgl7CgkJLy8gRE8gLi4uIExPT1AgW1dISUxFfFVOVElMIGV4cHJdCgkJU3RtbnRCbG9jayggTE9PUCApOwoJCWVUb2sgPSBOZXh0KCk7CgkJaWYoIGVUb2sgPT0gVU5USUwgfHwgZVRvayA9PSBXSElMRSApCgkJewoJCQlTYmlFeHByZXNzaW9uIGFFeHByKCB0aGlzICk7CgkJCWFFeHByLkdlbigpOwoJCQlhR2VuLkdlbiggZVRvayA9PSBVTlRJTCA/IF9KVU1QRiA6IF9KVU1QVCwgblN0YXJ0TGJsICk7CgkJfSBlbHNlCgkJCWlmIChlVG9rID09IEVPTE4gfHwgZVRvayA9PSBSRU0pCgkJCQlhR2VuLkdlbiAoX0pVTVAsIG5TdGFydExibCk7CgkJCWVsc2UKCQkJCUVycm9yKCBTYkVSUl9FWFBFQ1RFRCwgV0hJTEUgKTsKCX0KCWVsc2UKCXsKCQkvLyBETyBbV0hJTEV8VU5USUwgZXhwcl0gLi4uIExPT1AKCQlpZiggZVRvayA9PSBVTlRJTCB8fCBlVG9rID09IFdISUxFICkKCQl7CgkJCVNiaUV4cHJlc3Npb24gYUNvbmQoIHRoaXMgKTsKCQkJYUNvbmQuR2VuKCk7CgkJfQoJCXNhbF91SW50MzIgbkVuZExibCA9IGFHZW4uR2VuKCBlVG9rID09IFVOVElMID8gX0pVTVBUIDogX0pVTVBGLCAwICk7CgkJU3RtbnRCbG9jayggTE9PUCApOwoJCVRlc3RFb2xuKCk7CgkJYUdlbi5HZW4oIF9KVU1QLCBuU3RhcnRMYmwgKTsKCQlhR2VuLkJhY2tDaGFpbiggbkVuZExibCApOwoJfQoJQ2xvc2VCbG9jaygpOwp9CgovLyBXSElMRSAuLi4gV0VORAoKdm9pZCBTYmlQYXJzZXI6OldoaWxlKCkKewoJU2JpRXhwcmVzc2lvbiBhQ29uZCggdGhpcyApOwoJc2FsX3VJbnQzMiBuU3RhcnRMYmwgPSBhR2VuLkdldFBDKCk7CglhQ29uZC5HZW4oKTsKCXNhbF91SW50MzIgbkVuZExibCA9IGFHZW4uR2VuKCBfSlVNUEYsIDAgKTsKCVN0bW50QmxvY2soIFdFTkQgKTsKCWFHZW4uR2VuKCBfSlVNUCwgblN0YXJ0TGJsICk7CglhR2VuLkJhY2tDaGFpbiggbkVuZExibCApOwp9CgovLyBGT1IgdmFyID0gZXhwciBUTyBleHByIFNURVAKCnZvaWQgU2JpUGFyc2VyOjpGb3IoKQp7Cglib29sIGJGb3JFYWNoID0gKCBQZWVrKCkgPT0gRUFDSCApOwoJaWYoIGJGb3JFYWNoICkKCQlOZXh0KCk7CglTYmlFeHByZXNzaW9uIGFMdmFsdWUoIHRoaXMsIFNiT1BFUkFORCApOwoJYUx2YWx1ZS5HZW4oKTsJCS8vIFZhcmlhYmxlIGF1ZiBkZW0gU3RhY2sKCglpZiggYkZvckVhY2ggKQoJewoJCVRlc3RUb2tlbiggX0lOXyApOwoJCVNiaUV4cHJlc3Npb24gYUNvbGxFeHByKCB0aGlzLCBTYk9QRVJBTkQgKTsKCQlhQ29sbEV4cHIuR2VuKCk7CS8vIENvbGxldGlvbiB2YXIgdG8gZm9yIHN0YWNrCgkJVGVzdEVvbG4oKTsJCgkJYUdlbi5HZW4oIF9JTklURk9SRUFDSCApOwoJfQoJZWxzZQoJewoJCVRlc3RUb2tlbiggRVEgKTsKCQlTYmlFeHByZXNzaW9uIGFTdGFydEV4cHIoIHRoaXMgKTsKCQlhU3RhcnRFeHByLkdlbigpOwkvLyBTdGFydGF1c2RydWNrIGF1ZiBkZW0gU3RhY2sKCQlUZXN0VG9rZW4oIFRPICk7CgkJU2JpRXhwcmVzc2lvbiBhU3RvcEV4cHIoIHRoaXMgKTsKCQlhU3RvcEV4cHIuR2VuKCk7CS8vIEVuZGF1c2RydWNrIGF1ZiBkZW0gU3RhY2sKCQlpZiggUGVlaygpID09IFNURVAgKQoJCXsKCQkJTmV4dCgpOwoJCQlTYmlFeHByZXNzaW9uIGFTdGVwRXhwciggdGhpcyApOwoJCQlhU3RlcEV4cHIuR2VuKCk7CgkJfQoJCWVsc2UKCQl7CgkJCVNiaUV4cHJlc3Npb24gYU9uZSggdGhpcywgMSwgU2J4SU5URUdFUiApOwoJCQlhT25lLkdlbigpOwoJCX0KCQlUZXN0RW9sbigpOwoJCS8vIERlciBTdGFjayBoYXQgamV0enQgNCBFbGVtZW50ZTogVmFyaWFibGUsIFN0YXJ0LCBFbmRlLCBJbmtyZW1lbnQKCQkvLyBTdGFydHdlcnQgYmluZGVuCgkJYUdlbi5HZW4oIF9JTklURk9SICk7Cgl9CgoJc2FsX3VJbnQzMiBuTG9vcCA9IGFHZW4uR2V0UEMoKTsKCS8vIFRlc3QgZHVyY2hmdWVocmVuLCBldnRsLiBTdGFjayBmcmVpZ2ViZW4KCXNhbF91SW50MzIgbkVuZFRhcmdldCA9IGFHZW4uR2VuKCBfVEVTVEZPUiwgMCApOwoJT3BlbkJsb2NrKCBGT1IgKTsKCVN0bW50QmxvY2soIE5FWFQgKTsKCWFHZW4uR2VuKCBfTkVYVCApOwoJYUdlbi5HZW4oIF9KVU1QLCBuTG9vcCApOwoJLy8gS29tbWVuIFZhcmlhYmxlIG5hY2ggTkVYVD8KCWlmKCBQZWVrKCkgPT0gU1lNQk9MICkKCXsKCQlTYmlFeHByZXNzaW9uIGFWYXIoIHRoaXMsIFNiT1BFUkFORCApOwoJCWlmKCBhVmFyLkdldFJlYWxWYXIoKSAhPSBhTHZhbHVlLkdldFJlYWxWYXIoKSApCgkJCUVycm9yKCBTYkVSUl9FWFBFQ1RFRCwgYUx2YWx1ZS5HZXRSZWFsVmFyKCktPkdldE5hbWUoKSApOwoJfQoJYUdlbi5CYWNrQ2hhaW4oIG5FbmRUYXJnZXQgKTsKCUNsb3NlQmxvY2soKTsKfQoKLy8gV0lUSCAuLiBFTkQgV0lUSAoKdm9pZCBTYmlQYXJzZXI6OldpdGgoKQp7CglTYmlFeHByZXNzaW9uIGFWYXIoIHRoaXMsIFNiT1BFUkFORCApOwoKCS8vIExldHp0ZW4gS25vdGVuIGluIGRlciBPYmpla3QtS2V0dGUgdWViZXJwcnVlZmVuCglTYmlFeHByTm9kZSAqcE5vZGUgPSBhVmFyLkdldEV4cHJOb2RlKCktPkdldFJlYWxOb2RlKCk7CglTYmlTeW1EZWYqIHBEZWYgPSBwTm9kZS0+R2V0VmFyKCk7CgkvLyBWYXJpYW50LCBBQiAyNy42LjE5OTcsICM0MTA5MDogYnp3LiBlbXB0eSAtPiBtdd8gT2JqZWN0IHNlaW4KCWlmKCBwRGVmLT5HZXRUeXBlKCkgPT0gU2J4VkFSSUFOVCB8fCBwRGVmLT5HZXRUeXBlKCkgPT0gU2J4RU1QVFkgKQoJCXBEZWYtPlNldFR5cGUoIFNieE9CSkVDVCApOwoJZWxzZSBpZiggcERlZi0+R2V0VHlwZSgpICE9IFNieE9CSkVDVCApCgkJRXJyb3IoIFNiRVJSX05FRURTX09CSkVDVCApOwoKCS8vIEtub3RlbiBhdWNoIGF1ZiBTYnhPQkpFQ1Qgc2V0emVuLCBkYW1pdCBzcGFldGVyIEdlbigpIGtsYXBwdAoJcE5vZGUtPlNldFR5cGUoIFNieE9CSkVDVCApOwoKCU9wZW5CbG9jayggTklMLCBhVmFyLkdldEV4cHJOb2RlKCkgKTsKCVN0bW50QmxvY2soIEVORFdJVEggKTsKCUNsb3NlQmxvY2soKTsKfQoKLy8gTE9PUC9ORVhUL1dFTkQgb2huZSBLb25zdHJ1a3QKCnZvaWQgU2JpUGFyc2VyOjpCYWRCbG9jaygpCnsKCWlmKCBlRW5kVG9rICkKCQlFcnJvciggU2JFUlJfQkFEX0JMT0NLLCBlRW5kVG9rICk7CgllbHNlCgkJRXJyb3IoIFNiRVJSX0JBRF9CTE9DSywgIkxvb3AvTmV4dC9XZW5kIiApOwp9CgovLyBPbiBleHByIEdvdG8vR29zdWIgbixuLG4uLi4KCnZvaWQgU2JpUGFyc2VyOjpPbkdvdG8oKQp7CglTYmlFeHByZXNzaW9uIGFDb25kKCB0aGlzICk7CglhQ29uZC5HZW4oKTsKCXNhbF91SW50MzIgbkxhYmVsc1RhcmdldCA9IGFHZW4uR2VuKCBfT05KVU1QLCAwICk7CglTYmlUb2tlbiBlVG9rID0gTmV4dCgpOwoJaWYoIGVUb2sgIT0gR09UTyAmJiBlVG9rICE9IEdPU1VCICkKCXsKCQlFcnJvciggU2JFUlJfRVhQRUNURUQsICJHb1RvL0dvU3ViIiApOwoJCWVUb2sgPSBHT1RPOwoJfQoJLy8gTGFiZWwtVGFiZWxsZSBlaW5sZXNlbjoKCXNhbF91SW50MzIgbkxibCA9IDA7CglkbwoJewoJCVNiaVRva2VuIGVUb2syID0gTklMOwoJCWVUb2syID0gTmV4dCgpOwkvLyBMYWJlbCBob2xlbgoJCWlmKCBNYXlCZUxhYmVsKCkgKQoJCXsKCQkJc2FsX3VJbnQzMiBuT2ZmID0gcFByb2MtPkdldExhYmVscygpLlJlZmVyZW5jZSggYVN5bSApOwoJCQlhR2VuLkdlbiggX0pVTVAsIG5PZmYgKTsKCQkJbkxibCsrOwoJCX0KCQllbHNlIEVycm9yKCBTYkVSUl9MQUJFTF9FWFBFQ1RFRCApOwoJfQoJd2hpbGUoICFiQWJvcnQgJiYgVGVzdENvbW1hKCkgKTsKCWlmKCBlVG9rID09IEdPU1VCICkKCQluTGJsIHw9IDB4ODAwMDsKCWFHZW4uUGF0Y2goIG5MYWJlbHNUYXJnZXQsIG5MYmwgKTsKfQoKLy8gR09UTy9HT1NVQgoKdm9pZCBTYmlQYXJzZXI6OkdvdG8oKQp7CglTYmlPcGNvZGUgZU9wID0gZUN1clRvayA9PSBHT1RPID8gX0pVTVAgOiBfR09TVUI7CglOZXh0KCk7CglpZiggTWF5QmVMYWJlbCgpICkKCXsKCQlzYWxfdUludDMyIG5PZmYgPSBwUHJvYy0+R2V0TGFiZWxzKCkuUmVmZXJlbmNlKCBhU3ltICk7CgkJYUdlbi5HZW4oIGVPcCwgbk9mZiApOwoJfQoJZWxzZSBFcnJvciggU2JFUlJfTEFCRUxfRVhQRUNURUQgKTsKfQoKLy8gUkVUVVJOIFtsYWJlbF0KCnZvaWQgU2JpUGFyc2VyOjpSZXR1cm4oKQp7CglOZXh0KCk7CglpZiggTWF5QmVMYWJlbCgpICkKCXsKCQlzYWxfdUludDMyIG5PZmYgPSBwUHJvYy0+R2V0TGFiZWxzKCkuUmVmZXJlbmNlKCBhU3ltICk7CgkJYUdlbi5HZW4oIF9SRVRVUk4sIG5PZmYgKTsKCX0KCWVsc2UgYUdlbi5HZW4oIF9SRVRVUk4sIDAgKTsKfQoKLy8gU0VMRUNUIENBU0UKCnZvaWQgU2JpUGFyc2VyOjpTZWxlY3QoKQp7CglUZXN0VG9rZW4oIENBU0UgKTsKCVNiaUV4cHJlc3Npb24gYUNhc2UoIHRoaXMgKTsKCVNiaVRva2VuIGVUb2sgPSBOSUw7CglhQ2FzZS5HZW4oKTsKCWFHZW4uR2VuKCBfQ0FTRSApOwoJVGVzdEVvbG4oKTsKCXNhbF91SW50MzIgbk5leHRUYXJnZXQgPSAwOwoJc2FsX3VJbnQzMiBuRG9uZVRhcmdldCA9IDA7CglzYWxfQm9vbCBiRWxzZSA9IHNhbF9GYWxzZTsKCS8vIERpZSBDYXNlcyBlaW5sZXNlbjoKCXdoaWxlKCAhYkFib3J0ICkKCXsKCQllVG9rID0gTmV4dCgpOwoJCWlmKCBlVG9rID09IENBU0UgKQoJCXsKCQkJaWYoIG5OZXh0VGFyZ2V0ICkKCQkJCWFHZW4uQmFja0NoYWluKCBuTmV4dFRhcmdldCApLCBuTmV4dFRhcmdldCA9IDA7CgkJCWFHZW4uU3RhdGVtZW50KCk7CgkJCS8vIEplZGVuIENhc2UgZWlubGVzZW4KCQkJc2FsX0Jvb2wgYkRvbmUgPSBzYWxfRmFsc2U7CgkJCXNhbF91SW50MzIgblRydWVUYXJnZXQgPSAwOwoJCQlpZiggUGVlaygpID09IEVMU0UgKQoJCQl7CgkJCQkvLyBDQVNFIEVMU0UKCQkJCU5leHQoKTsKCQkJCWJFbHNlID0gc2FsX1RydWU7CgkJCX0KCQkJZWxzZSB3aGlsZSggIWJEb25lICkKCQkJewoJCQkJaWYoIGJFbHNlICkKCQkJCQlFcnJvciggU2JFUlJfU1lOVEFYICk7CgkJCQlTYmlUb2tlbiBlVG9rMiA9IFBlZWsoKTsKCQkJCWlmKCBlVG9rMiA9PSBJUyB8fCAoIGVUb2syID49IEVRICYmIGVUb2syIDw9IEdFICkgKQoJCQkJewkvLyBDQVNFIFtJU10gb3BlcmF0b3IgZXhwcgoJCQkJCWlmKCBlVG9rMiA9PSBJUyApCgkJCQkJCU5leHQoKTsKCQkJCQllVG9rMiA9IFBlZWsoKTsKCQkJCQlpZiggZVRvazIgPCBFUSB8fCBlVG9rMiA+IEdFICkKCQkJCQkJRXJyb3IoIFNiRVJSX1NZTlRBWCApOwoJCQkJCWVsc2UgTmV4dCgpOwoJCQkJCVNiaUV4cHJlc3Npb24gYUNvbXBhcmUoIHRoaXMgKTsKCQkJCQlhQ29tcGFyZS5HZW4oKTsKCQkJCQluVHJ1ZVRhcmdldCA9IGFHZW4uR2VuKAogICAgICAgICAgICAgICAgICAgICAgICBfQ0FTRUlTLCBuVHJ1ZVRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgc2FsOjpzdGF0aWNfaW50X2Nhc3Q8IHNhbF91SW50MTYgPigKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNieEVRICsgKCBlVG9rMiAtIEVRICkgKSApOwoJCQkJfQoJCQkJZWxzZQoJCQkJewkvLyBDQVNFIGV4cHIgfCBleHByIFRPIGV4cHIKCQkJCQlTYmlFeHByZXNzaW9uIGFDYXNlMSggdGhpcyApOwoJCQkJCWFDYXNlMS5HZW4oKTsKCQkJCQlpZiggUGVlaygpID09IFRPICkKCQkJCQl7CgkJCQkJCS8vIENBU0UgYSBUTyBiCgkJCQkJCU5leHQoKTsKCQkJCQkJU2JpRXhwcmVzc2lvbiBhQ2FzZTIoIHRoaXMgKTsKCQkJCQkJYUNhc2UyLkdlbigpOwoJCQkJCQluVHJ1ZVRhcmdldCA9IGFHZW4uR2VuKCBfQ0FTRVRPLCBuVHJ1ZVRhcmdldCApOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJCS8vIENBU0UgYQoJCQkJCQluVHJ1ZVRhcmdldCA9IGFHZW4uR2VuKCBfQ0FTRUlTLCBuVHJ1ZVRhcmdldCwgU2J4RVEgKTsKCgkJCQl9CgkJCQlpZiggUGVlaygpID09IENPTU1BICkgTmV4dCgpOwoJCQkJZWxzZSBUZXN0RW9sbigpLCBiRG9uZSA9IHNhbF9UcnVlOwoJCQl9CgkJCS8vIEFsbGUgQ2FzZXMgYWJnZWFyYmVpdGV0CgkJCWlmKCAhYkVsc2UgKQoJCQl7CgkJCQluTmV4dFRhcmdldCA9IGFHZW4uR2VuKCBfSlVNUCwgbk5leHRUYXJnZXQgKTsKCQkJCWFHZW4uQmFja0NoYWluKCBuVHJ1ZVRhcmdldCApOwoJCQl9CgkJCS8vIGRlbiBTdGF0ZW1lbnQtUnVtcGYgYmF1ZW4KCQkJd2hpbGUoICFiQWJvcnQgKQoJCQl7CgkJCQllVG9rID0gUGVlaygpOwoJCQkJaWYoIGVUb2sgPT0gQ0FTRSB8fCBlVG9rID09IEVORFNFTEVDVCApCgkJCQkJYnJlYWs7CgkJCQlpZiggIVBhcnNlKCkgKSBnb3RvIGRvbmU7CgkJCQllVG9rID0gUGVlaygpOwoJCQkJaWYoIGVUb2sgPT0gQ0FTRSB8fCBlVG9rID09IEVORFNFTEVDVCApCgkJCQkJYnJlYWs7CgkJCX0KCQkJaWYoICFiRWxzZSApCgkJCQluRG9uZVRhcmdldCA9IGFHZW4uR2VuKCBfSlVNUCwgbkRvbmVUYXJnZXQgKTsKCQl9CgkJZWxzZSBpZiggIUlzRW9sbiggZVRvayApICkKCQkJYnJlYWs7Cgl9CmRvbmU6CglpZiggZVRvayAhPSBFTkRTRUxFQ1QgKQoJCUVycm9yKCBTYkVSUl9FWFBFQ1RFRCwgRU5EU0VMRUNUICk7CglpZiggbk5leHRUYXJnZXQgKQoJCWFHZW4uQmFja0NoYWluKCBuTmV4dFRhcmdldCApOwoJYUdlbi5CYWNrQ2hhaW4oIG5Eb25lVGFyZ2V0ICk7CglhR2VuLkdlbiggX0VORENBU0UgKTsKfQoKLy8gT04gRXJyb3IvVmFyaWFibGUKCiNpZmRlZiBfTVNDX1ZFUgojcHJhZ21hIG9wdGltaXplKCIiLG9mZikKI2VuZGlmCgp2b2lkIFNiaVBhcnNlcjo6T24oKQp7CglTYmlUb2tlbiBlVG9rID0gUGVlaygpOwoJU3RyaW5nIGFTdHJpbmcgPSBTYmlUb2tlbml6ZXI6OlN5bWJvbChlVG9rKTsKCWlmIChhU3RyaW5nLkVxdWFsc0lnbm9yZUNhc2VBc2NpaSgiRVJST1IiKSkKCS8vaWYgKCFhU3RyaW5nLklDb21wYXJlKCJFUlJPUiIpKQoJCWVUb2sgPSBfRVJST1JfOwkvLyBFcnJvciBrb21tdCBhbHMgU1lNQk9MCglpZiggZVRvayAhPSBfRVJST1JfICYmIGVUb2sgIT0gTE9DQUwgKSBPbkdvdG8oKTsKCWVsc2UKCXsKCQlpZiggZVRvayA9PSBMT0NBTCApIE5leHQoKTsKCQlOZXh0ICgpOyAvLyBLZWluIFRlc3RUb2tlbiBtZWhyLCBkYSBlcyBzb25zdCBlaW5lbiBGZWhsZXIgZ2lidAoKCQlOZXh0KCk7CS8vIFRva2VuIG5hY2ggRXJyb3IgaG9sZW4KCQlpZiggZUN1clRvayA9PSBHT1RPICkKCQl7CgkJCS8vIE9OIEVSUk9SIEdPVE8gbGFiZWx8MAoJCQlOZXh0KCk7CgkJCWJvb2wgYkVycm9yXyA9IGZhbHNlOwoJCQlpZiggTWF5QmVMYWJlbCgpICkKCQkJewoJCQkJaWYoIGVDdXJUb2sgPT0gTlVNQkVSICYmICFuVmFsICkKCQkJCQlhR2VuLkdlbiggX1NUREVSUk9SICk7CgkJCQllbHNlCgkJCQl7CgkJCQkJc2FsX3VJbnQzMiBuT2ZmID0gcFByb2MtPkdldExhYmVscygpLlJlZmVyZW5jZSggYVN5bSApOwoJCQkJCWFHZW4uR2VuKCBfRVJSSERMLCBuT2ZmICk7CgkJCQl9CgkJCX0KCQkJZWxzZSBpZiggZUN1clRvayA9PSBNSU5VUyApCgkJCXsKCQkJCU5leHQoKTsKCQkJCWlmKCBlQ3VyVG9rID09IE5VTUJFUiAmJiBuVmFsID09IDEgKQoJCQkJCWFHZW4uR2VuKCBfU1RERVJST1IgKTsKCQkJCWVsc2UKCQkJCQliRXJyb3JfID0gdHJ1ZTsKCQkJfQoJCQlpZiggYkVycm9yXyApCgkJCQlFcnJvciggU2JFUlJfTEFCRUxfRVhQRUNURUQgKTsJCQkKCQl9CgkJZWxzZSBpZiggZUN1clRvayA9PSBSRVNVTUUgKQoJCXsKCQkJVGVzdFRva2VuKCBORVhUICk7CgkJCWFHZW4uR2VuKCBfTk9FUlJPUiApOwoJCX0KCQllbHNlIEVycm9yKCBTYkVSUl9FWFBFQ1RFRCwgIkdvVG8vUmVzdW1lIiApOwoJfQp9CgojaWZkZWYgX01TQ19WRVIKI3ByYWdtYSBvcHRpbWl6ZSgiIixvZmYpCiNlbmRpZgoKLy8gUkVTVU1FIFswXXxORVhUfGxhYmVsCgp2b2lkIFNiaVBhcnNlcjo6UmVzdW1lKCkKewoJc2FsX3VJbnQzMiBuTGJsOwoKCXN3aXRjaCggTmV4dCgpICkKCXsKCQljYXNlIEVPUzoKCQljYXNlIEVPTE46CgkJCWFHZW4uR2VuKCBfUkVTVU1FLCAwICk7CgkJCWJyZWFrOwoJCWNhc2UgTkVYVDoKCQkJYUdlbi5HZW4oIF9SRVNVTUUsIDEgKTsKCQkJTmV4dCgpOwoJCQlicmVhazsKCQljYXNlIE5VTUJFUjoKCQkJaWYoICFuVmFsICkKCQkJewoJCQkJYUdlbi5HZW4oIF9SRVNVTUUsIDAgKTsKCQkJCWJyZWFrOwoJCQl9IC8vIGZhbGwgdGhydQoJCWNhc2UgU1lNQk9MOgoJCQlpZiggTWF5QmVMYWJlbCgpICkKCQkJewoJCQkJbkxibCA9IHBQcm9jLT5HZXRMYWJlbHMoKS5SZWZlcmVuY2UoIGFTeW0gKTsKCQkJCWFHZW4uR2VuKCBfUkVTVU1FLCBuTGJsICk7CgkJCQlOZXh0KCk7CgkJCQlicmVhazsKCQkJfSAvLyBmYWxsIHRocnUKCQlkZWZhdWx0OgoJCQlFcnJvciggU2JFUlJfTEFCRUxfRVhQRUNURUQgKTsKCX0KfQoK