LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYmFzaWMuaHh4IgoKI2luY2x1ZGUgInNiY29tcC5oeHgiCgovLyBTaW5nbGUtbGluZSBJRiB1bmQgTXVsdGlsaW5lIElGCgp2b2lkIFNiaVBhcnNlcjo6SWYoKQp7CglzYWxfdUludDMyIG5FbmRMYmw7CglTYmlUb2tlbiBlVG9rID0gTklMOwoJLy8gRW5kZS1Ub2tlbnMgaWdub3JpZXJlbjoKCVNiaUV4cHJlc3Npb24gYUNvbmQoIHRoaXMgKTsKCWFDb25kLkdlbigpOwoJVGVzdFRva2VuKCBUSEVOICk7CglpZiggSXNFb2xuKCBOZXh0KCkgKSApCgl7CgkJLy8gQUIgMTMuNS4xOTk2OiAjMjc3MjAjIEFtIEVuZGUgamVkZW4gQmxvY2tzIG11c3MgZWluIEp1bXAgenUgRU5ESUYKCQkvLyBlaW5nZWb8Z3Qgd2VyZGVuLCBkYW1pdCBiZWkgRUxTRUlGIG5pY2h0IGVybmV1dCBkaWUgQmVkaW5ndW5nCgkJLy8gYXVzZ2V3ZXJ0ZXQgd2lyZC4gRGllIFRhYmVsbGUgbmltbXQgYWxsZSBBYnNwcnVuZ3N0ZWxsZW4gYXVmLgojZGVmaW5lIEpNUF9UQUJMRV9TSVpFIDEwMAoJCXNhbF91SW50MzIgcG5KbXBUb0VuZExibFtKTVBfVEFCTEVfU0laRV07CS8vIDEwMCBFTFNFSUZzIHp1bGFlc3NpZwoJCXNhbF91SW50MTYgaUptcCA9IDA7CQkJCQkJLy8gYWt0dWVsbGVyIFRhYmVsbGVuLUluZGV4CgoJCS8vIG11bHRpbGluZSBJRgoJCW5FbmRMYmwgPSBhR2VuLkdlbiggX0pVTVBGLCAwICk7CgkJZVRvayA9IFBlZWsoKTsKCQl3aGlsZSggISggZVRvayA9PSBFTFNFSUYgfHwgZVRvayA9PSBFTFNFIHx8IGVUb2sgPT0gRU5ESUYgKSAmJgoJCQkJIWJBYm9ydCAmJiBQYXJzZSgpICkKCQl7CgkJCWVUb2sgPSBQZWVrKCk7CgkJCWlmKCBJc0VvZigpICkKCQkJewoJCQkJRXJyb3IoIFNiRVJSX0JBRF9CTE9DSywgSUYgKTsgYkFib3J0ID0gc2FsX1RydWU7IHJldHVybjsKCQkJfQoJCX0KCQkvLyBFTFNFSUY/CgkJd2hpbGUoIGVUb2sgPT0gRUxTRUlGICkKCQl7CgkJCS8vICMyNzcyMCMgQmVpIGVyZm9sZ3JlaWNoZW0gSUYvRUxTRUlGIGF1ZiBFTkRJRiBzcHJpbmdlbgoJCQlpZiggaUptcCA+PQlKTVBfVEFCTEVfU0laRSApCgkJCXsKCQkJCUVycm9yKCBTYkVSUl9QUk9HX1RPT19MQVJHRSApOwliQWJvcnQgPSBzYWxfVHJ1ZTsgCXJldHVybjsKCQkJfQoJCQlwbkptcFRvRW5kTGJsW2lKbXArK10gPSBhR2VuLkdlbiggX0pVTVAsIDAgKTsKCgkJCU5leHQoKTsKCQkJYUdlbi5CYWNrQ2hhaW4oIG5FbmRMYmwgKTsKCgkJCWFHZW4uU3RhdGVtZW50KCk7CgkJCVNiaUV4cHJlc3Npb24qIHBDb25kID0gbmV3IFNiaUV4cHJlc3Npb24oIHRoaXMgKTsKCQkJcENvbmQtPkdlbigpOwoJCQluRW5kTGJsID0gYUdlbi5HZW4oIF9KVU1QRiwgMCApOwoJCQlkZWxldGUgcENvbmQ7CgkJCVRlc3RUb2tlbiggVEhFTiApOwoJCQllVG9rID0gUGVlaygpOwoJCQl3aGlsZSggISggZVRvayA9PSBFTFNFSUYgfHwgZVRvayA9PSBFTFNFIHx8IGVUb2sgPT0gRU5ESUYgKSAmJgoJCQkJCSFiQWJvcnQgJiYgUGFyc2UoKSApCgkJCXsKCQkJCWVUb2sgPSBQZWVrKCk7CgkJCQlpZiggSXNFb2YoKSApCgkJCQl7CgkJCQkJRXJyb3IoIFNiRVJSX0JBRF9CTE9DSywgRUxTRUlGICk7IGJBYm9ydCA9IHNhbF9UcnVlOyByZXR1cm47CgkJCQl9CgkJCX0KCQl9CgkJaWYoIGVUb2sgPT0gRUxTRSApCgkJewoJCQlOZXh0KCk7CgkJCXNhbF91SW50MzIgbkVsc2VMYmwgPSBuRW5kTGJsOwoJCQluRW5kTGJsID0gYUdlbi5HZW4oIF9KVU1QLCAwICk7CgkJCWFHZW4uQmFja0NoYWluKCBuRWxzZUxibCApOwoKCQkJYUdlbi5TdGF0ZW1lbnQoKTsKCQkJU3RtbnRCbG9jayggRU5ESUYgKTsKCQl9CgkJZWxzZSBpZiggZVRvayA9PSBFTkRJRiApCgkJCU5leHQoKTsKCgkJLy8gIzI3NzIwIyBKbXAtVGFiZWxsZSBhYmFyYmVpdGVuCgkJd2hpbGUoIGlKbXAgPiAwICkKCQl7CgkJCWlKbXAtLTsKCQkJYUdlbi5CYWNrQ2hhaW4oIHBuSm1wVG9FbmRMYmxbaUptcF0gKTsKCQl9Cgl9CgllbHNlCgl7CgkJLy8gc2luZ2xlIGxpbmUgSUYKCQliU2luZ2xlTGluZUlmID0gc2FsX1RydWU7CgkJbkVuZExibCA9IGFHZW4uR2VuKCBfSlVNUEYsIDAgKTsKCQlQdXNoKCBlQ3VyVG9rICk7CgkJd2hpbGUoICFiQWJvcnQgKQoJCXsKCQkJaWYoICFQYXJzZSgpICkgYnJlYWs7CgkJCWVUb2sgPSBQZWVrKCk7CgkJCWlmKCBlVG9rID09IEVMU0UgfHwgZVRvayA9PSBFT0xOIHx8IGVUb2sgPT0gUkVNICkKCQkJCWJyZWFrOwoJCX0KCQlpZiggZVRvayA9PSBFTFNFICkKCQl7CgkJCU5leHQoKTsKCQkJc2FsX3VJbnQzMiBuRWxzZUxibCA9IG5FbmRMYmw7CgkJCW5FbmRMYmwgPSBhR2VuLkdlbiggX0pVTVAsIDAgKTsKCQkJYUdlbi5CYWNrQ2hhaW4oIG5FbHNlTGJsICk7CgkJCXdoaWxlKCAhYkFib3J0ICkKCQkJewoJCQkJaWYoICFQYXJzZSgpICkgYnJlYWs7CgkJCQllVG9rID0gUGVlaygpOwoJCQkJaWYoIGVUb2sgPT0gRU9MTiB8fCBlVG9rID09IFJFTSApCgkJCQkJYnJlYWs7CgkJCX0KCQl9CgkJYlNpbmdsZUxpbmVJZiA9IHNhbF9GYWxzZTsKCX0KCWFHZW4uQmFja0NoYWluKCBuRW5kTGJsICk7Cn0KCi8vIEVMU0UvRUxTRUlGL0VORElGIG9obmUgSUYKCnZvaWQgU2JpUGFyc2VyOjpOb0lmKCkKewoJRXJyb3IoIFNiRVJSX05PX0lGICk7CglTdG1udEJsb2NrKCBFTkRJRiApOwp9CgovLyBETyBXSElMRS4uLkxPT1AKLy8gRE8gLi4uIExPT1AgV0hJTEUKCnZvaWQgU2JpUGFyc2VyOjpEb0xvb3AoKQp7CglzYWxfdUludDMyIG5TdGFydExibCA9IGFHZW4uR2V0UEMoKTsKCU9wZW5CbG9jayggRE8gKTsKCVNiaVRva2VuIGVUb2sgPSBOZXh0KCk7CglpZiggSXNFb2xuKCBlVG9rICkgKQoJewoJCS8vIERPIC4uLiBMT09QIFtXSElMRXxVTlRJTCBleHByXQoJCVN0bW50QmxvY2soIExPT1AgKTsKCQllVG9rID0gTmV4dCgpOwoJCWlmKCBlVG9rID09IFVOVElMIHx8IGVUb2sgPT0gV0hJTEUgKQoJCXsKCQkJU2JpRXhwcmVzc2lvbiBhRXhwciggdGhpcyApOwoJCQlhRXhwci5HZW4oKTsKCQkJYUdlbi5HZW4oIGVUb2sgPT0gVU5USUwgPyBfSlVNUEYgOiBfSlVNUFQsIG5TdGFydExibCApOwoJCX0gZWxzZQoJCQlpZiAoZVRvayA9PSBFT0xOIHx8IGVUb2sgPT0gUkVNKQoJCQkJYUdlbi5HZW4gKF9KVU1QLCBuU3RhcnRMYmwpOwoJCQllbHNlCgkJCQlFcnJvciggU2JFUlJfRVhQRUNURUQsIFdISUxFICk7Cgl9CgllbHNlCgl7CgkJLy8gRE8gW1dISUxFfFVOVElMIGV4cHJdIC4uLiBMT09QCgkJaWYoIGVUb2sgPT0gVU5USUwgfHwgZVRvayA9PSBXSElMRSApCgkJewoJCQlTYmlFeHByZXNzaW9uIGFDb25kKCB0aGlzICk7CgkJCWFDb25kLkdlbigpOwoJCX0KCQlzYWxfdUludDMyIG5FbmRMYmwgPSBhR2VuLkdlbiggZVRvayA9PSBVTlRJTCA/IF9KVU1QVCA6IF9KVU1QRiwgMCApOwoJCVN0bW50QmxvY2soIExPT1AgKTsKCQlUZXN0RW9sbigpOwoJCWFHZW4uR2VuKCBfSlVNUCwgblN0YXJ0TGJsICk7CgkJYUdlbi5CYWNrQ2hhaW4oIG5FbmRMYmwgKTsKCX0KCUNsb3NlQmxvY2soKTsKfQoKLy8gV0hJTEUgLi4uIFdFTkQKCnZvaWQgU2JpUGFyc2VyOjpXaGlsZSgpCnsKCVNiaUV4cHJlc3Npb24gYUNvbmQoIHRoaXMgKTsKCXNhbF91SW50MzIgblN0YXJ0TGJsID0gYUdlbi5HZXRQQygpOwoJYUNvbmQuR2VuKCk7CglzYWxfdUludDMyIG5FbmRMYmwgPSBhR2VuLkdlbiggX0pVTVBGLCAwICk7CglTdG1udEJsb2NrKCBXRU5EICk7CglhR2VuLkdlbiggX0pVTVAsIG5TdGFydExibCApOwoJYUdlbi5CYWNrQ2hhaW4oIG5FbmRMYmwgKTsKfQoKLy8gRk9SIHZhciA9IGV4cHIgVE8gZXhwciBTVEVQCgp2b2lkIFNiaVBhcnNlcjo6Rm9yKCkKewoJYm9vbCBiRm9yRWFjaCA9ICggUGVlaygpID09IEVBQ0ggKTsKCWlmKCBiRm9yRWFjaCApCgkJTmV4dCgpOwoJU2JpRXhwcmVzc2lvbiBhTHZhbHVlKCB0aGlzLCBTYk9QRVJBTkQgKTsKCWFMdmFsdWUuR2VuKCk7CQkvLyBWYXJpYWJsZSBhdWYgZGVtIFN0YWNrCgoJaWYoIGJGb3JFYWNoICkKCXsKCQlUZXN0VG9rZW4oIF9JTl8gKTsKCQlTYmlFeHByZXNzaW9uIGFDb2xsRXhwciggdGhpcywgU2JPUEVSQU5EICk7CgkJYUNvbGxFeHByLkdlbigpOwkvLyBDb2xsZXRpb24gdmFyIHRvIGZvciBzdGFjawoJCVRlc3RFb2xuKCk7CgkJYUdlbi5HZW4oIF9JTklURk9SRUFDSCApOwoJfQoJZWxzZQoJewoJCVRlc3RUb2tlbiggRVEgKTsKCQlTYmlFeHByZXNzaW9uIGFTdGFydEV4cHIoIHRoaXMgKTsKCQlhU3RhcnRFeHByLkdlbigpOwkvLyBTdGFydGF1c2RydWNrIGF1ZiBkZW0gU3RhY2sKCQlUZXN0VG9rZW4oIFRPICk7CgkJU2JpRXhwcmVzc2lvbiBhU3RvcEV4cHIoIHRoaXMgKTsKCQlhU3RvcEV4cHIuR2VuKCk7CS8vIEVuZGF1c2RydWNrIGF1ZiBkZW0gU3RhY2sKCQlpZiggUGVlaygpID09IFNURVAgKQoJCXsKCQkJTmV4dCgpOwoJCQlTYmlFeHByZXNzaW9uIGFTdGVwRXhwciggdGhpcyApOwoJCQlhU3RlcEV4cHIuR2VuKCk7CgkJfQoJCWVsc2UKCQl7CgkJCVNiaUV4cHJlc3Npb24gYU9uZSggdGhpcywgMSwgU2J4SU5URUdFUiApOwoJCQlhT25lLkdlbigpOwoJCX0KCQlUZXN0RW9sbigpOwoJCS8vIERlciBTdGFjayBoYXQgamV0enQgNCBFbGVtZW50ZTogVmFyaWFibGUsIFN0YXJ0LCBFbmRlLCBJbmtyZW1lbnQKCQkvLyBTdGFydHdlcnQgYmluZGVuCgkJYUdlbi5HZW4oIF9JTklURk9SICk7Cgl9CgoJc2FsX3VJbnQzMiBuTG9vcCA9IGFHZW4uR2V0UEMoKTsKCS8vIFRlc3QgZHVyY2hm/GhyZW4sIGV2dGwuIFN0YWNrIGZyZWlnZWJlbgoJc2FsX3VJbnQzMiBuRW5kVGFyZ2V0ID0gYUdlbi5HZW4oIF9URVNURk9SLCAwICk7CglPcGVuQmxvY2soIEZPUiApOwoJU3RtbnRCbG9jayggTkVYVCApOwoJYUdlbi5HZW4oIF9ORVhUICk7CglhR2VuLkdlbiggX0pVTVAsIG5Mb29wICk7CgkvLyBLb21tZW4gVmFyaWFibGUgbmFjaCBORVhUPwoJaWYoIFBlZWsoKSA9PSBTWU1CT0wgKQoJewoJCVNiaUV4cHJlc3Npb24gYVZhciggdGhpcywgU2JPUEVSQU5EICk7CgkJaWYoIGFWYXIuR2V0UmVhbFZhcigpICE9IGFMdmFsdWUuR2V0UmVhbFZhcigpICkKCQkJRXJyb3IoIFNiRVJSX0VYUEVDVEVELCBhTHZhbHVlLkdldFJlYWxWYXIoKS0+R2V0TmFtZSgpICk7Cgl9CglhR2VuLkJhY2tDaGFpbiggbkVuZFRhcmdldCApOwoJQ2xvc2VCbG9jaygpOwp9CgovLyBXSVRIIC4uIEVORCBXSVRICgp2b2lkIFNiaVBhcnNlcjo6V2l0aCgpCnsKCVNiaUV4cHJlc3Npb24gYVZhciggdGhpcywgU2JPUEVSQU5EICk7CgoJLy8gTGV0enRlbiBLbm90ZW4gaW4gZGVyIE9iamVrdC1LZXR0ZSD8YmVycHL8ZmVuCglTYmlFeHByTm9kZSAqcE5vZGUgPSBhVmFyLkdldEV4cHJOb2RlKCktPkdldFJlYWxOb2RlKCk7CglTYmlTeW1EZWYqIHBEZWYgPSBwTm9kZS0+R2V0VmFyKCk7CgkvLyBWYXJpYW50LCBBQiAyNy42LjE5OTcsICM0MTA5MDogYnp3LiBlbXB0eSAtPiBtdd8gT2JqZWN0IHNlaW4KCWlmKCBwRGVmLT5HZXRUeXBlKCkgPT0gU2J4VkFSSUFOVCB8fCBwRGVmLT5HZXRUeXBlKCkgPT0gU2J4RU1QVFkgKQoJCXBEZWYtPlNldFR5cGUoIFNieE9CSkVDVCApOwoJZWxzZSBpZiggcERlZi0+R2V0VHlwZSgpICE9IFNieE9CSkVDVCApCgkJRXJyb3IoIFNiRVJSX05FRURTX09CSkVDVCApOwoKCS8vIEtub3RlbiBhdWNoIGF1ZiBTYnhPQkpFQ1Qgc2V0emVuLCBkYW1pdCBzcOR0ZXIgR2VuKCkga2xhcHB0CglwTm9kZS0+U2V0VHlwZSggU2J4T0JKRUNUICk7CgoJT3BlbkJsb2NrKCBOSUwsIGFWYXIuR2V0RXhwck5vZGUoKSApOwoJU3RtbnRCbG9jayggRU5EV0lUSCApOwoJQ2xvc2VCbG9jaygpOwp9CgovLyBMT09QL05FWFQvV0VORCBvaG5lIEtvbnN0cnVrdAoKdm9pZCBTYmlQYXJzZXI6OkJhZEJsb2NrKCkKewoJaWYoIGVFbmRUb2sgKQoJCUVycm9yKCBTYkVSUl9CQURfQkxPQ0ssIGVFbmRUb2sgKTsKCWVsc2UKCQlFcnJvciggU2JFUlJfQkFEX0JMT0NLLCAiTG9vcC9OZXh0L1dlbmQiICk7Cn0KCi8vIE9uIGV4cHIgR290by9Hb3N1YiBuLG4sbi4uLgoKdm9pZCBTYmlQYXJzZXI6Ok9uR290bygpCnsKCVNiaUV4cHJlc3Npb24gYUNvbmQoIHRoaXMgKTsKCWFDb25kLkdlbigpOwoJc2FsX3VJbnQzMiBuTGFiZWxzVGFyZ2V0ID0gYUdlbi5HZW4oIF9PTkpVTVAsIDAgKTsKCVNiaVRva2VuIGVUb2sgPSBOZXh0KCk7CglpZiggZVRvayAhPSBHT1RPICYmIGVUb2sgIT0gR09TVUIgKQoJewoJCUVycm9yKCBTYkVSUl9FWFBFQ1RFRCwgIkdvVG8vR29TdWIiICk7CgkJZVRvayA9IEdPVE87Cgl9CgkvLyBMYWJlbC1UYWJlbGxlIGVpbmxlc2VuOgoJc2FsX3VJbnQzMiBuTGJsID0gMDsKCWRvCgl7CgkJU2JpVG9rZW4gZVRvazIgPSBOSUw7CgkJZVRvazIgPSBOZXh0KCk7CS8vIExhYmVsIGhvbGVuCgkJaWYoIE1heUJlTGFiZWwoKSApCgkJewoJCQlzYWxfdUludDMyIG5PZmYgPSBwUHJvYy0+R2V0TGFiZWxzKCkuUmVmZXJlbmNlKCBhU3ltICk7CgkJCWFHZW4uR2VuKCBfSlVNUCwgbk9mZiApOwoJCQluTGJsKys7CgkJfQoJCWVsc2UgRXJyb3IoIFNiRVJSX0xBQkVMX0VYUEVDVEVEICk7Cgl9Cgl3aGlsZSggIWJBYm9ydCAmJiBUZXN0Q29tbWEoKSApOwoJaWYoIGVUb2sgPT0gR09TVUIgKQoJCW5MYmwgfD0gMHg4MDAwOwoJYUdlbi5QYXRjaCggbkxhYmVsc1RhcmdldCwgbkxibCApOwp9CgovLyBHT1RPL0dPU1VCCgp2b2lkIFNiaVBhcnNlcjo6R290bygpCnsKCVNiaU9wY29kZSBlT3AgPSBlQ3VyVG9rID09IEdPVE8gPyBfSlVNUCA6IF9HT1NVQjsKCU5leHQoKTsKCWlmKCBNYXlCZUxhYmVsKCkgKQoJewoJCXNhbF91SW50MzIgbk9mZiA9IHBQcm9jLT5HZXRMYWJlbHMoKS5SZWZlcmVuY2UoIGFTeW0gKTsKCQlhR2VuLkdlbiggZU9wLCBuT2ZmICk7Cgl9CgllbHNlIEVycm9yKCBTYkVSUl9MQUJFTF9FWFBFQ1RFRCApOwp9CgovLyBSRVRVUk4gW2xhYmVsXQoKdm9pZCBTYmlQYXJzZXI6OlJldHVybigpCnsKCU5leHQoKTsKCWlmKCBNYXlCZUxhYmVsKCkgKQoJewoJCXNhbF91SW50MzIgbk9mZiA9IHBQcm9jLT5HZXRMYWJlbHMoKS5SZWZlcmVuY2UoIGFTeW0gKTsKCQlhR2VuLkdlbiggX1JFVFVSTiwgbk9mZiApOwoJfQoJZWxzZSBhR2VuLkdlbiggX1JFVFVSTiwgMCApOwp9CgovLyBTRUxFQ1QgQ0FTRQoKdm9pZCBTYmlQYXJzZXI6OlNlbGVjdCgpCnsKCVRlc3RUb2tlbiggQ0FTRSApOwoJU2JpRXhwcmVzc2lvbiBhQ2FzZSggdGhpcyApOwoJU2JpVG9rZW4gZVRvayA9IE5JTDsKCWFDYXNlLkdlbigpOwoJYUdlbi5HZW4oIF9DQVNFICk7CglUZXN0RW9sbigpOwoJc2FsX3VJbnQzMiBuTmV4dFRhcmdldCA9IDA7CglzYWxfdUludDMyIG5Eb25lVGFyZ2V0ID0gMDsKCXNhbF9Cb29sIGJFbHNlID0gc2FsX0ZhbHNlOwoJLy8gRGllIENhc2VzIGVpbmxlc2VuOgoJd2hpbGUoICFiQWJvcnQgKQoJewoJCWVUb2sgPSBOZXh0KCk7CgkJaWYoIGVUb2sgPT0gQ0FTRSApCgkJewoJCQlpZiggbk5leHRUYXJnZXQgKQoJCQkJYUdlbi5CYWNrQ2hhaW4oIG5OZXh0VGFyZ2V0ICksIG5OZXh0VGFyZ2V0ID0gMDsKCQkJYUdlbi5TdGF0ZW1lbnQoKTsKCQkJLy8gSmVkZW4gQ2FzZSBlaW5sZXNlbgoJCQlzYWxfQm9vbCBiRG9uZSA9IHNhbF9GYWxzZTsKCQkJc2FsX3VJbnQzMiBuVHJ1ZVRhcmdldCA9IDA7CgkJCWlmKCBQZWVrKCkgPT0gRUxTRSApCgkJCXsKCQkJCS8vIENBU0UgRUxTRQoJCQkJTmV4dCgpOwoJCQkJYkVsc2UgPSBzYWxfVHJ1ZTsKCQkJfQoJCQllbHNlIHdoaWxlKCAhYkRvbmUgKQoJCQl7CgkJCQlpZiggYkVsc2UgKQoJCQkJCUVycm9yKCBTYkVSUl9TWU5UQVggKTsKCQkJCVNiaVRva2VuIGVUb2syID0gUGVlaygpOwoJCQkJaWYoIGVUb2syID09IElTIHx8ICggZVRvazIgPj0gRVEgJiYgZVRvazIgPD0gR0UgKSApCgkJCQl7CS8vIENBU0UgW0lTXSBvcGVyYXRvciBleHByCgkJCQkJaWYoIGVUb2syID09IElTICkKCQkJCQkJTmV4dCgpOwoJCQkJCWVUb2syID0gUGVlaygpOwoJCQkJCWlmKCBlVG9rMiA8IEVRIHx8IGVUb2syID4gR0UgKQoJCQkJCQlFcnJvciggU2JFUlJfU1lOVEFYICk7CgkJCQkJZWxzZSBOZXh0KCk7CgkJCQkJU2JpRXhwcmVzc2lvbiBhQ29tcGFyZSggdGhpcyApOwoJCQkJCWFDb21wYXJlLkdlbigpOwoJCQkJCW5UcnVlVGFyZ2V0ID0gYUdlbi5HZW4oCgkJCQkJCV9DQVNFSVMsIG5UcnVlVGFyZ2V0LAoJCQkJCQlzYWw6OnN0YXRpY19pbnRfY2FzdDwgc2FsX3VJbnQxNiA+KAoJCQkJCQkJU2J4RVEgKyAoIGVUb2syIC0gRVEgKSApICk7CgkJCQl9CgkJCQllbHNlCgkJCQl7CS8vIENBU0UgZXhwciB8IGV4cHIgVE8gZXhwcgoJCQkJCVNiaUV4cHJlc3Npb24gYUNhc2UxKCB0aGlzICk7CgkJCQkJYUNhc2UxLkdlbigpOwoJCQkJCWlmKCBQZWVrKCkgPT0gVE8gKQoJCQkJCXsKCQkJCQkJLy8gQ0FTRSBhIFRPIGIKCQkJCQkJTmV4dCgpOwoJCQkJCQlTYmlFeHByZXNzaW9uIGFDYXNlMiggdGhpcyApOwoJCQkJCQlhQ2FzZTIuR2VuKCk7CgkJCQkJCW5UcnVlVGFyZ2V0ID0gYUdlbi5HZW4oIF9DQVNFVE8sIG5UcnVlVGFyZ2V0ICk7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQkJLy8gQ0FTRSBhCgkJCQkJCW5UcnVlVGFyZ2V0ID0gYUdlbi5HZW4oIF9DQVNFSVMsIG5UcnVlVGFyZ2V0LCBTYnhFUSApOwoKCQkJCX0KCQkJCWlmKCBQZWVrKCkgPT0gQ09NTUEgKSBOZXh0KCk7CgkJCQllbHNlIFRlc3RFb2xuKCksIGJEb25lID0gc2FsX1RydWU7CgkJCX0KCQkJLy8gQWxsZSBDYXNlcyBhYmdlYXJiZWl0ZXQKCQkJaWYoICFiRWxzZSApCgkJCXsKCQkJCW5OZXh0VGFyZ2V0ID0gYUdlbi5HZW4oIF9KVU1QLCBuTmV4dFRhcmdldCApOwoJCQkJYUdlbi5CYWNrQ2hhaW4oIG5UcnVlVGFyZ2V0ICk7CgkJCX0KCQkJLy8gZGVuIFN0YXRlbWVudC1SdW1wZiBiYXVlbgoJCQl3aGlsZSggIWJBYm9ydCApCgkJCXsKCQkJCWVUb2sgPSBQZWVrKCk7CgkJCQlpZiggZVRvayA9PSBDQVNFIHx8IGVUb2sgPT0gRU5EU0VMRUNUICkKCQkJCQlicmVhazsKCQkJCWlmKCAhUGFyc2UoKSApIGdvdG8gZG9uZTsKCQkJCWVUb2sgPSBQZWVrKCk7CgkJCQlpZiggZVRvayA9PSBDQVNFIHx8IGVUb2sgPT0gRU5EU0VMRUNUICkKCQkJCQlicmVhazsKCQkJfQoJCQlpZiggIWJFbHNlICkKCQkJCW5Eb25lVGFyZ2V0ID0gYUdlbi5HZW4oIF9KVU1QLCBuRG9uZVRhcmdldCApOwoJCX0KCQllbHNlIGlmKCAhSXNFb2xuKCBlVG9rICkgKQoJCQlicmVhazsKCX0KZG9uZToKCWlmKCBlVG9rICE9IEVORFNFTEVDVCApCgkJRXJyb3IoIFNiRVJSX0VYUEVDVEVELCBFTkRTRUxFQ1QgKTsKCWlmKCBuTmV4dFRhcmdldCApCgkJYUdlbi5CYWNrQ2hhaW4oIG5OZXh0VGFyZ2V0ICk7CglhR2VuLkJhY2tDaGFpbiggbkRvbmVUYXJnZXQgKTsKCWFHZW4uR2VuKCBfRU5EQ0FTRSApOwp9CgovLyBPTiBFcnJvci9WYXJpYWJsZQoKI2lmZGVmIF9NU0NfVkVSCiNwcmFnbWEgb3B0aW1pemUoIiIsb2ZmKQojZW5kaWYKCnZvaWQgU2JpUGFyc2VyOjpPbigpCnsKCVNiaVRva2VuIGVUb2sgPSBQZWVrKCk7CglTdHJpbmcgYVN0cmluZyA9IFNiaVRva2VuaXplcjo6U3ltYm9sKGVUb2spOwoJaWYgKGFTdHJpbmcuRXF1YWxzSWdub3JlQ2FzZUFzY2lpKCJFUlJPUiIpKQoJLy9pZiAoIWFTdHJpbmcuSUNvbXBhcmUoIkVSUk9SIikpCgkJZVRvayA9IF9FUlJPUl87CS8vIEVycm9yIGtvbW10IGFscyBTWU1CT0wKCWlmKCBlVG9rICE9IF9FUlJPUl8gJiYgZVRvayAhPSBMT0NBTCApIE9uR290bygpOwoJZWxzZQoJewoJCWlmKCBlVG9rID09IExPQ0FMICkgTmV4dCgpOwoJCU5leHQgKCk7IC8vIEtlaW4gVGVzdFRva2VuIG1laHIsIGRhIGVzIHNvbnN0IGVpbmVuIEZlaGxlciBnaWJ0CgoJCU5leHQoKTsJLy8gVG9rZW4gbmFjaCBFcnJvciBob2xlbgoJCWlmKCBlQ3VyVG9rID09IEdPVE8gKQoJCXsKCQkJLy8gT04gRVJST1IgR09UTyBsYWJlbHwwCgkJCU5leHQoKTsKCQkJYm9vbCBiRXJyb3JfID0gZmFsc2U7CgkJCWlmKCBNYXlCZUxhYmVsKCkgKQoJCQl7CgkJCQlpZiggZUN1clRvayA9PSBOVU1CRVIgJiYgIW5WYWwgKQoJCQkJCWFHZW4uR2VuKCBfU1RERVJST1IgKTsKCQkJCWVsc2UKCQkJCXsKCQkJCQlzYWxfdUludDMyIG5PZmYgPSBwUHJvYy0+R2V0TGFiZWxzKCkuUmVmZXJlbmNlKCBhU3ltICk7CgkJCQkJYUdlbi5HZW4oIF9FUlJIREwsIG5PZmYgKTsKCQkJCX0KCQkJfQoJCQllbHNlIGlmKCBlQ3VyVG9rID09IE1JTlVTICkKCQkJewoJCQkJTmV4dCgpOwoJCQkJaWYoIGVDdXJUb2sgPT0gTlVNQkVSICYmIG5WYWwgPT0gMSApCgkJCQkJYUdlbi5HZW4oIF9TVERFUlJPUiApOwoJCQkJZWxzZQoJCQkJCWJFcnJvcl8gPSB0cnVlOwoJCQl9CgkJCWlmKCBiRXJyb3JfICkKCQkJCUVycm9yKCBTYkVSUl9MQUJFTF9FWFBFQ1RFRCApOwoJCX0KCQllbHNlIGlmKCBlQ3VyVG9rID09IFJFU1VNRSApCgkJewoJCQlUZXN0VG9rZW4oIE5FWFQgKTsKCQkJYUdlbi5HZW4oIF9OT0VSUk9SICk7CgkJfQoJCWVsc2UgRXJyb3IoIFNiRVJSX0VYUEVDVEVELCAiR29Uby9SZXN1bWUiICk7Cgl9Cn0KCiNpZmRlZiBfTVNDX1ZFUgojcHJhZ21hIG9wdGltaXplKCIiLG9mZikKI2VuZGlmCgovLyBSRVNVTUUgWzBdfE5FWFR8bGFiZWwKCnZvaWQgU2JpUGFyc2VyOjpSZXN1bWUoKQp7CglzYWxfdUludDMyIG5MYmw7CgoJc3dpdGNoKCBOZXh0KCkgKQoJewoJCWNhc2UgRU9TOgoJCWNhc2UgRU9MTjoKCQkJYUdlbi5HZW4oIF9SRVNVTUUsIDAgKTsKCQkJYnJlYWs7CgkJY2FzZSBORVhUOgoJCQlhR2VuLkdlbiggX1JFU1VNRSwgMSApOwoJCQlOZXh0KCk7CgkJCWJyZWFrOwoJCWNhc2UgTlVNQkVSOgoJCQlpZiggIW5WYWwgKQoJCQl7CgkJCQlhR2VuLkdlbiggX1JFU1VNRSwgMCApOwoJCQkJYnJlYWs7CgkJCX0gLy8gZmFsbCB0aHJvdWdoCgkJY2FzZSBTWU1CT0w6CgkJCWlmKCBNYXlCZUxhYmVsKCkgKQoJCQl7CgkJCQluTGJsID0gcFByb2MtPkdldExhYmVscygpLlJlZmVyZW5jZSggYVN5bSApOwoJCQkJYUdlbi5HZW4oIF9SRVNVTUUsIG5MYmwgKTsKCQkJCU5leHQoKTsKCQkJCWJyZWFrOwoJCQl9IC8vIGZhbGwgdGhyb3VnaAoJCWRlZmF1bHQ6CgkJCUVycm9yKCBTYkVSUl9MQUJFTF9FWFBFQ1RFRCApOwoJfQp9CgovKiB2aW06IHNldCBub2V0IHN3PTQgdHM9NDogKi8K