LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIENvcHlyaWdodCAoYykgMjAwMCwgMjAwNSBJQk0gQ29ycG9yYXRpb24gYW5kIG90aGVycy4NCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMNCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMA0KICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQNCiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sDQqgKg0KICogQ29udHJpYnV0b3JzOg0KICogICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCg0KIyBpbmNsdWRlIDx1cGRhdGUuaD4NCiMgaW5jbHVkZSA8d2luZG93cy5oPg0KIyBpbmNsdWRlIDx3aW5pb2N0bC5oPiAvLyBJT0NUTCBjb2RlczogTWVkaWFUeXBlDQoNCi8vIFdpbmRvd3MgVmVyc2lvbg0KaW50IFdJTjk4ID0gMDsNCmludCBXSU5OVCA9IDE7DQppbnQgV0lOTUUgPSAyOw0KaW50IFdJTjIwMDAgPSAzOw0KaW50IFdJTlhQID0gNDsNCg0KLy8gc2V0IHRvIDEgZm9yIERFQlVHDQppbnQgREVCVUcgPSAwOw0KDQovLyBzZXQgdG8gMCB0byBydW4gb24gV2luZG93cyA5NSAqVW5zdXBwb3J0ZWQqDQppbnQgTk9XSU45NSA9IDE7DQoNCg0KLy8gR0xPQkFMIE1FVEhPRFMNCi8vIC0tLS0tLS0tLS0tLS0tLQ0KDQovKg0KICoNCiAqLw0KanN0cmluZyBXaW5kb3dzVG9qc3RyaW5nKCBKTklFbnYqIGpuaWVudiwgY2hhciogYnVmICkNCnsNCiAganN0cmluZyBydG4gPSAwOw0KICB3Y2hhcl90KiBidWZmZXIgPSAwOw0KICBpbnQgYnVmZmVyTGVuID0gc3RybGVuKGJ1Zik7ICANCiAgaWYoIGJ1ZmZlckxlbiA9PSAwICl7DQogICAgcnRuID0gam5pZW52IC0+TmV3U3RyaW5nVVRGKGJ1Zik7DQoJaWYgKERFQlVHKQ0KCQlwcmludGYoIldpbmRvd3NUb0pTdHJpbmcgQnVmZmVyIGlzIGVtcHR5XG4iKTsgICAgDQogIH0gZWxzZSB7DQogICAgaW50IGxlbmd0aCA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoIENQX0FDUCwgMCwgKExQQ1NUUilidWYsIGJ1ZmZlckxlbiwgTlVMTCwgMCApOw0KICAgIGJ1ZmZlciA9ICh3Y2hhcl90KiltYWxsb2MoIGxlbmd0aCoyICsgMSApOw0KICAgIGlmKGludCBlcnI9TXVsdGlCeXRlVG9XaWRlQ2hhciggQ1BfQUNQLCAwLCAoTFBDU1RSKWJ1ZiwgYnVmZmVyTGVuLCAoTFBXU1RSKWJ1ZmZlciwgbGVuZ3RoICkgPjAgKXsNCiAgICAgIHJ0biA9IGpuaWVudi0+TmV3U3RyaW5nKChqY2hhciopYnVmZmVyLCBsZW5ndGggKTsNCiAgICB9IGVsc2Ugew0KCQlpZiAoREVCVUcpDQoJCQlwcmludGYoIk11bHRpQnl0ZVRvV2lkZUNoYXIgJWlcbiIsZXJyKTsgICAgDQogICAgfQ0KICB9DQogIGlmKCBidWZmZXIgKQ0KICAgZnJlZSggYnVmZmVyICk7DQogIHJldHVybiBydG47DQp9DQoNCg0KDQovKg0KICogY2FsbHMgR2V0Vm9sdW1lSW5mb3JtYXRpb24gdG8gcmV0cml2ZSB0aGUgbGFiZWwgb2YgdGhlIHZvbHVtZQ0KICogUmV0dXJucyBOVUxMIGlmIGFuIGVycm9yIG9jY3Vycw0KICogQHBhcmFtIGRyaXZlTGV0dGVyIHBhdGggdG8gdGhlIGRyaXZlICJjOlxcIg0KICogQHByYW1hIGpuaWVudiBKTklFbnZpcm9ubWVudA0KICovDQpqc3RyaW5nIGdldExhYmVsKFRDSEFSIGRyaXZlTGV0dGVyW10sSk5JRW52ICogam5pZW52KXsNCg0KCWpzdHJpbmcgcmVzdWx0ID0gTlVMTDsNCglUQ0hBUiBidWZbMTI4XTsJDQoJDQoJLy8gYWx3YXlzIHJldHVybiBudWxsIGFzIFVOSUNPREUgaXMgbm90IGltcGxlbWVudGVkDQoJLy8gaG93IGNhbiB3ZSBnZXQgdGhlIGxhYmVsIG9mIGEgdm9sdW1lIGFzIFVOSUNPREUgY2hhciA/DQoJcmV0dXJuIHJlc3VsdDsNCgkNCglpbnQgZXJyID0gR2V0Vm9sdW1lSW5mb3JtYXRpb24oDQoJCWRyaXZlTGV0dGVyLA0KCQlidWYsDQoJCXNpemVvZihidWYpIC0gMSwNCgkJTlVMTCwNCgkJTlVMTCwNCgkJTlVMTCwNCgkJTlVMTCwNCgkJMCk7DQoJaWYgKGVycil7DQoJCXJlc3VsdCA9IFdpbmRvd3NUb2pzdHJpbmcoam5pZW52LCBidWYpOw0KCX0gZWxzZSB7DQoJCWlmIChERUJVRykNCgkJCXByaW50ZigiRXJyb3IgR2V0Vm9sdW1lSW5mb3JtYXRpb24gJWlcbiIsZXJyKTsJCQkJDQogCX0NCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovKg0KICogcmV0dXJucyB0aGUgVmVyc2lvbiBvZiBXaW5kb3dzDQogKiBpbnQgMCBXSU45ODsNCiAqIGludCAxIFdJTk5UOw0KICogaW50IDIgV0lOTUU7DQogKiBpbnQgMyBXSU4yMDAwOw0KICogaW50IDQgV0lOWFA7DQogKiByZXR1cm5zIC0xIG90aGVyd2lzZQ0KICovDQppbnQgZ2V0V2luZG93c1ZlcnNpb24oKXsNCglPU1ZFUlNJT05JTkZPRVggb3N2aTsNCglpbnQgVU5LTk9XTiA9IC0xOw0KCQ0KCVplcm9NZW1vcnkoJm9zdmksIHNpemVvZihPU1ZFUlNJT05JTkZPRVgpKTsNCglvc3ZpLmR3T1NWZXJzaW9uSW5mb1NpemUgPSBzaXplb2YoT1NWRVJTSU9OSU5GT0VYKTsNCgkNCglpZighKEdldFZlcnNpb25FeCgoT1NWRVJTSU9OSU5GTyAqKSZvc3ZpKSkpew0KCQlpZiAoREVCVUcpDQoJCQlwcmludGYoIlVOS05PV04gVkVSU0lPTjogQ2Fubm90IGV4ZWN1dGUgR2V0VmVyc2lvbkV4XG4iKTsNCgkJLy8gaWYgT1NWRVJTSU9ORVggZG9lc24ndCB3b3JrLCB0cnkgT1NWRVJTSU9OSU5GTw0KCQlvc3ZpLmR3T1NWZXJzaW9uSW5mb1NpemUgPSBzaXplb2YoT1NWRVJTSU9OSU5GTyk7CQkJIAkNCgkJaWYoIShHZXRWZXJzaW9uRXgoKE9TVkVSU0lPTklORk8gKikmb3N2aSkpKXsNCgkJaWYgKERFQlVHKQ0KCQkJcHJpbnRmKCJVTktOT1dOIFZFUlNJT046IENhbm5vdCBleGVjdXRlIEdldFZlcnNpb25FeFxuIik7DQoJCQlyZXR1cm4gVU5LTk9XTjsNCgkJfQ0KCX0NCgkNCglzd2l0Y2gob3N2aS5kd1BsYXRmb3JtSWQpew0KCQljYXNlIFZFUl9QTEFURk9STV9XSU4zMl9OVDoNCgkJCWlmIChERUJVRykNCgkJCQlwcmludGYoIlZFUlNJT04gTlQ6IE1haiAlaSBNaW4gJWlcbiIsb3N2aS5kd01ham9yVmVyc2lvbixvc3ZpLmR3TWlub3JWZXJzaW9uKTsJCQkJIAkNCgkJCWlmKG9zdmkuZHdNYWpvclZlcnNpb248PTQpDQoJCQkJcmV0dXJuIFdJTk5UOw0KCQkJaWYob3N2aS5kd01ham9yVmVyc2lvbj09NSl7DQoJCQkJaWYgKG9zdmkuZHdNaW5vclZlcnNpb249PTApDQoJCQkJCXJldHVybiBXSU4yMDAwOw0KCQkJCWlmIChvc3ZpLmR3TWlub3JWZXJzaW9uPT0xKQ0KCQkJCQlyZXR1cm4gV0lOWFA7DQoJCQl9IGVsc2Ugew0KCQkJCXJldHVybiBVTktOT1dOOw0KCQkJfTsNCgkJCWJyZWFrOw0KCQljYXNlIFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTOg0KCQkJaWYgKERFQlVHKQ0KCQkJCXByaW50ZigiVkVSU0lPTiBOb24gTlQ6IE1haiAlaSBNaW4gJWlcbiIsb3N2aS5kd01ham9yVmVyc2lvbixvc3ZpLmR3TWlub3JWZXJzaW9uKTsJCQkJIAkNCgkJCWlmKG9zdmkuZHdNYWpvclZlcnNpb249PTQpew0KCQkJCWlmIChvc3ZpLmR3TWlub3JWZXJzaW9uPT0xMCkNCgkJCQkJcmV0dXJuIFdJTjk4Ow0KCQkJCWlmIChvc3ZpLmR3TWlub3JWZXJzaW9uPT05MCkNCgkJCQkJcmV0dXJuIFdJTk1FOw0KCQkJfSBlbHNlIHsNCgkJCQlyZXR1cm4gVU5LTk9XTjsNCgkJCX0NCgkJCWJyZWFrOw0KCQlkZWZhdWx0Og0KCQkJaWYgKERFQlVHKQ0KCQkJCXByaW50ZigiVkVSU0lPTiBVTktOT1dOOiBNYWogJWkgTWluICVpXG4iLG9zdmkuZHdNYWpvclZlcnNpb24sb3N2aS5kd01pbm9yVmVyc2lvbik7CQkJCSAJDQoJCQlyZXR1cm4gVU5LTk9XTjsNCgl9DQoJcmV0dXJuIFVOS05PV047DQp9IA0KDQovKg0KICogUmV0dXJucyB0aGUgdHlwZSBvZiBSZW1vdmFibGUgRHJpdmUgDQogKiBSZXR1cm5zIA0KICogb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvX1ZPTFVNRV9GTE9QUFlfMw0KICogb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvX1ZPTFVNRV9GTE9QUFlfNQ0KICogb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvX1ZPTFVNRV9SRU1PVkFCTEUNCiAqLw0KamxvbmcgZ2V0RmxvcHB5KFRDSEFSIGRyaXZlTGV0dGVyW10pew0KDQoJVENIQVIgZmxvcHB5UGF0aFs4XTsNCglIQU5ETEUgaGFuZGxlOw0KCURJU0tfR0VPTUVUUlkgZ2VvbWV0cnlbMjBdOw0KCURXT1JEIGR3Ow0KCWpsb25nIFVOS05PV04gPSBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fVk9MVU1FX1JFTU9WQUJMRTsNCg0KCXNwcmludGYoZmxvcHB5UGF0aCwgIlxcXFwuXFwlYzoiLCBkcml2ZUxldHRlclswXSk7DQoJaWYgKERFQlVHKQ0KCQlwcmludGYoIlBhdGggJXNcbiIsZmxvcHB5UGF0aCk7DQoJLy8gQlVHIDI1NzE5DQogICAgU2V0RXJyb3JNb2RlKCBTRU1fRkFJTENSSVRJQ0FMRVJST1JTICk7IAkJDQoJaGFuZGxlPUNyZWF0ZUZpbGUoZmxvcHB5UGF0aCwwLEZJTEVfU0hBUkVfUkVBRCxOVUxMLE9QRU5fQUxXQVlTLDAsTlVMTCk7DQoJaWYgKGhhbmRsZT09SU5WQUxJRF9IQU5ETEVfVkFMVUUpew0KCQlpZiAoREVCVUcpDQoJCQlwcmludGYoIkludmFsaWQgSGFuZGxlICVzXG4iLGZsb3BweVBhdGgpOw0KCQlyZXR1cm4gVU5LTk9XTjsNCgl9IGVsc2Ugew0KCQlpZihEZXZpY2VJb0NvbnRyb2woaGFuZGxlLA0KCQkJSU9DVExfRElTS19HRVRfTUVESUFfVFlQRVMsMCwwLA0KCQkJZ2VvbWV0cnksc2l6ZW9mKGdlb21ldHJ5KSwmZHcsMCkgDQoJCQkmJiBkdz4wKSB7DQoJCQlzd2l0Y2goZ2VvbWV0cnlbMF0uTWVkaWFUeXBlKXsNCgkJCSBjYXNlIEY1XzE2MF81MTI6DQoJCQkgY2FzZSBGNV8xODBfNTEyOg0KCQkJIGNhc2UgRjVfMzIwXzUxMjoNCgkJCSBjYXNlIEY1XzMyMF8xMDI0Og0KCQkJIGNhc2UgRjVfMzYwXzUxMjoNCgkJCSBjYXNlIEY1XzFQdDJfNTEyOg0KCQkJCWlmIChERUJVRykNCgkJCQkJcHJpbnRmKCJGb3VuZCA1IDEvNCBEcml2ZVxuIik7CQkJCSAJDQoJCQkgCXJldHVybiBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fVk9MVU1FX0ZMT1BQWV81Ow0KCQkJIGNhc2UgRjNfNzIwXzUxMjoJCQkgCQkJCSAJCQkJIAkJCQkgCQkJCSANCgkJCSBjYXNlIEYzXzFQdDQ0XzUxMjoNCgkJCSBjYXNlIEYzXzJQdDg4XzUxMjoNCgkJCSBjYXNlIEYzXzIwUHQ4XzUxMjoJCQkJIAkJCQkgCQkJCSANCgkJCQlpZiAoREVCVUcpDQoJCQkJCXByaW50ZigiRm91bmQgMyAxLzIgRHJpdmVcbiIpOwkJCQkgCQ0KCQkJIAlyZXR1cm4gb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvX1ZPTFVNRV9GTE9QUFlfMzsNCgkJCSBkZWZhdWx0Og0KCQkJIAlyZXR1cm4gVU5LTk9XTjsNCgkJCX0NCgkJfQ0KCX0NCglyZXR1cm4gVU5LTk9XTjsJDQp9DQoNCi8qDQogKiBSZXR1cm5zIHRoZSBVTkMgbmFtZSBvZiBhIHJlbW90ZSBkcml2ZQ0KICogKFxcTWFjaGluZVxwYXRoXHBhdGgxXHBhdGgyJCkNCiAqIHJldHVybnMgTlVMTCBpZiBhbiBlcnJvciBvY2N1cnMNCiAqLw0KIGpzdHJpbmcgZ2V0UmVtb3RlTmV0d29ya05hbWUoVENIQVIgZHJpdmVMZXR0ZXJbXSxKTklFbnYgKiBqbmllbnYpew0KIAkNCiAJdW5zaWduZWQgbG9uZyBzaXplID0yNTY7DQogCVRDSEFSIGJ1ZlsyNTZdOwkNCiAJVENIQVIgZHJpdmVQYXRoWzJdOw0KIAlEV09SRCBlcnI7DQogCWpzdHJpbmcgcmVzdWx0ID0gTlVMTDsNCiAJDQogCS8vIGFsd2F5cyByZXR1cm4gTlVMTCBhcyBVTklDT0RFIG5vdCBpbXBsZW1lbnRlZA0KCS8vIGhvdyBjYW4gd2UgZ2V0IHRoZSBsYWJlbCBvZiBhIHJlbW90ZSBuZXR3b3JrIG5hbWUgYXMgVU5JQ09ERSBjaGFyID8gCQ0KIAlyZXR1cm4gcmVzdWx0Ow0KIAkNCglzcHJpbnRmKGRyaXZlUGF0aCwgIiVjOiIsIGRyaXZlTGV0dGVyWzBdKTsgCQ0KIAllcnIgPSBXTmV0R2V0Q29ubmVjdGlvbihkcml2ZVBhdGgsYnVmLCZzaXplKTsNCiAJDQogCWlmIChlcnI9PVdOX1NVQ0NFU1Mpew0KCQlyZXN1bHQgPSBXaW5kb3dzVG9qc3RyaW5nKGpuaWVudixidWYpOw0KCX0gZWxzZSB7DQoJCWlmIChERUJVRykNCgkJCXByaW50ZigiRXJyb3IgV05FdEdldENvbm5lY3Rpb24gJWkiLGVycik7CQkJCQ0KIAl9DQoJcmV0dXJuIHJlc3VsdDsNCiB9DQoNCg0KLy8gSk5JIE1FVEhPRFMNCi8vIC0tLS0tLS0tLS0tLS0tLQ0KDQovKg0KICogQ2xhc3M6ICAgICBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm8NCiAqIE1ldGhvZDogICAgbmF0aXZlR2V0RnJlZVNwYWNlDQogKiBTaWduYXR1cmU6IChMamF2YS9pby9GaWxlOylKDQogKi8NCkpOSUVYUE9SVCBqbG9uZyBKTklDQUxMIEphdmFfb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvX25hdGl2ZUdldEZyZWVTcGFjZSgNCglKTklFbnYgKiBqbmllbnYsDQoJamNsYXNzIGphdmFDbGFzcywNCglqb2JqZWN0IGZpbGUpIHsNCg0KCS8vIHRvIHJldHJpdmUgdGhlIFN0cmluZw0KCWpjbGFzcyBjbHM7DQoJam1ldGhvZElEIGlkOw0KCWpvYmplY3Qgb2JqOw0KDQoJLy8gamF2YS5pby5GaWxlLmdldEFic29sdXRlUGF0aCgpDQoJY29uc3QgVENIQVIgKiBscERpcmVjdG9yeU5hbWU7DQoNCgkvLyBXaW5kb3dzIFBhcmFtZXRlcnMNCglfX2ludDY0IGk2NEZyZWVCeXRlc0F2YWlsYWJsZVRvQ2FsbGVyOw0KCV9faW50NjQgaTY0VG90YWxOdW1iZXJPZkJ5dGVzOw0KCV9faW50NjQgaTY0VG90YWxOdW1iZXJPZkZyZWVCeXRlczsNCg0KCS8vIHRoZSByZXN1bHQNCglqbG9uZyByZXN1bHQgPSBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fU0laRV9VTktOT1dOOw0KDQoJLy8gZmlyc3QsIG9idGFpbiB0aGUgUGF0aCBmcm9tIHRoZSBqYXZhLmlvLkZpbGUgcGFyYW1ldGVyDQoJY2xzID0gam5pZW52IC0+IEdldE9iamVjdENsYXNzKGZpbGUpOw0KCWlkID0gam5pZW52IC0+IEdldE1ldGhvZElEKGNscywgImdldEFic29sdXRlUGF0aCIsICIoKUxqYXZhL2xhbmcvU3RyaW5nOyIpOw0KCW9iaiA9IGpuaWVudiAtPiBDYWxsT2JqZWN0TWV0aG9kKGZpbGUsIGlkKTsNCglscERpcmVjdG9yeU5hbWUgPSBqbmllbnYgLT4gR2V0U3RyaW5nVVRGQ2hhcnMoKGpzdHJpbmcpIG9iaiwgMCk7DQoJaWYgKERFQlVHKQ0KCQlwcmludGYoIkRpcmVjdG9yeTogWyVzXVxuIixscERpcmVjdG9yeU5hbWUpOw0KDQoJaWYgKGludCB3aW4gPSAoaW50KWdldFdpbmRvd3NWZXJzaW9uKCk8MCAmJiBOT1dJTjk1KXsNCgkJLy8gd2luZG93cyA5NSBvciBvdGhlcg0KCQlpZiAoREVCVUcpDQoJCQlwcmludGYoIlVuc3VwcG9ydGVkIFdpbmRvd3M6ICVpXG4iLHdpbik7CQkNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoNCglpbnQgZXJyID0gR2V0RGlza0ZyZWVTcGFjZUV4KA0KCQkJCWxwRGlyZWN0b3J5TmFtZSwNCgkJCQkoUFVMQVJHRV9JTlRFR0VSKSAmIGk2NEZyZWVCeXRlc0F2YWlsYWJsZVRvQ2FsbGVyLA0KCQkJCShQVUxBUkdFX0lOVEVHRVIpICYgaTY0VG90YWxOdW1iZXJPZkJ5dGVzLA0KCQkJCShQVUxBUkdFX0lOVEVHRVIpICYgaTY0VG90YWxOdW1iZXJPZkZyZWVCeXRlcyk7DQoJCQkNCglpZiAoZXJyKSB7DQoJCXJlc3VsdCA9IChqbG9uZykgaTY0RnJlZUJ5dGVzQXZhaWxhYmxlVG9DYWxsZXI7DQoJfQ0KDQoJcmV0dXJuIHJlc3VsdDsNCn0NCg0KLyoNCiAqIENsYXNzOiAgICAgb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvDQogKiBNZXRob2Q6ICAgIG5hdGl2ZUdldExhYmVsDQogKiBTaWduYXR1cmU6IChMamF2YS9pby9GaWxlOylMamF2YS9sYW5nL1N0cmluZzsNCiAqLw0KSk5JRVhQT1JUIGpzdHJpbmcgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3VwZGF0ZV9jb25maWd1cmF0aW9uX0xvY2FsU3lzdGVtSW5mb19uYXRpdmVHZXRMYWJlbCgNCglKTklFbnYgKiBqbmllbnYsDQoJamNsYXNzIGphdmFDbGFzcywNCglqb2JqZWN0IGZpbGUpIHsNCg0KCS8vIHRvIHJldHJpdmUgdGhlIFN0cmluZw0KCWpjbGFzcyBjbHM7DQoJam1ldGhvZElEIGlkOw0KCWpvYmplY3Qgb2JqOw0KDQoJLy8gamF2YS5pby5GaWxlLmdldEFic29sdXRlUGF0aCgpDQoJY29uc3QgVENIQVIgKiBscERpcmVjdG9yeU5hbWU7DQoNCgkvLyBvYnRhaW4gdGhlIFN0cmluZyBmcm9tIHRoZSBwYXJhbWV0ZXINCgljbHMgPSBqbmllbnYgLT4gR2V0T2JqZWN0Q2xhc3MoZmlsZSk7DQoJaWQgPSBqbmllbnYgLT4gR2V0TWV0aG9kSUQoY2xzLCAiZ2V0QWJzb2x1dGVQYXRoIiwgIigpTGphdmEvbGFuZy9TdHJpbmc7Iik7DQoJb2JqID0gam5pZW52IC0+IENhbGxPYmplY3RNZXRob2QoZmlsZSwgaWQpOw0KCWxwRGlyZWN0b3J5TmFtZSA9IGpuaWVudiAtPiBHZXRTdHJpbmdVVEZDaGFycygoanN0cmluZykgb2JqLCAwKTsNCglpZiAoREVCVUcpDQoJCXByaW50ZigiRGlyZWN0b3J5OiBbJXNdXG4iLGxwRGlyZWN0b3J5TmFtZSk7DQoNCgkvLw0KCWpzdHJpbmcgcmVzdWx0ID0gTlVMTDsNCglpbnQgZmxvcHB5Ow0KCQ0KCWlmIChpbnQgd2luID0gKGludClnZXRXaW5kb3dzVmVyc2lvbigpPDAgJiYgTk9XSU45NSl7DQoJCS8vIHdpbmRvd3MgOTUgb3Igb3RoZXINCgkJaWYgKERFQlVHKQ0KCQkJcHJpbnRmKCJVbnN1cHBvcnRlZCBXaW5kb3dzOiAlaVxuIix3aW4pOwkJDQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KCQkNCgkvLyBNYWtlIHN1cmUgd2UgaGF2ZSBhIFN0cmluZyBvZiB0aGUgRm9ybTogPGxldHRlcj46DQoJaWYgKCc6JyA9PSBscERpcmVjdG9yeU5hbWVbMV0pIHsNCgkJVENIQVIgZHJpdmVMZXR0ZXJbNF07IC8vIGkuZS4gLT4gQzpcXA0KCQltZW1jcHkoZHJpdmVMZXR0ZXIsIGxwRGlyZWN0b3J5TmFtZSwgMik7DQoJCXN0cmNweShkcml2ZUxldHRlciArIDIsICJcXCIpOw0KCQlzd2l0Y2ggKEdldERyaXZlVHlwZShkcml2ZUxldHRlcikpIHsNCgkJCWNhc2UgRFJJVkVfUkVNT1RFIDoNCgkJCQkvLyBjaGVjayBuYW1lIG9mIG1hY2hpbmUgYW5kIHBhdGggb2YgcmVtb3RlDQoJCQkJaWYgKERFQlVHKQ0KCQkJCQlwcmludGYoIlJlbW90ZSBEcml2ZSIpOw0KCQkJCXJlc3VsdCA9IGdldFJlbW90ZU5ldHdvcmtOYW1lKGRyaXZlTGV0dGVyLGpuaWVudik7CQkJCQ0KCQkJCWJyZWFrOw0KCQkJZGVmYXVsdCA6DQoJCQkJaWYgKERFQlVHKQ0KCQkJCQlwcmludGYoIkFub3RoZXIgRHJpdmUgYXQgJXMiLCBkcml2ZUxldHRlcik7DQoJCQkJcmVzdWx0ID0gZ2V0TGFiZWwoZHJpdmVMZXR0ZXIsam5pZW52KTsNCgkJCQlicmVhazsNCgkJfSANCgl9IA0KDQoJcmV0dXJuIHJlc3VsdDsNCn0NCg0KLyoNCiAqIENsYXNzOiAgICAgb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvDQogKiBNZXRob2Q6ICAgIG5hdGl2ZUdldFR5cGUNCiAqIFNpZ25hdHVyZTogKExqYXZhL2lvL0ZpbGU7KUkNCiAqLw0KSk5JRVhQT1JUIGppbnQgSk5JQ0FMTCBKYXZhX29yZ19lY2xpcHNlX3VwZGF0ZV9jb25maWd1cmF0aW9uX0xvY2FsU3lzdGVtSW5mb19uYXRpdmVHZXRUeXBlKA0KCUpOSUVudiAqIGpuaWVudiwNCglqY2xhc3MgamF2YUNsYXNzLA0KCWpvYmplY3QgZmlsZSkgew0KDQoJLy8gdG8gcmV0cml2ZSB0aGUgU3RyaW5nDQoJamNsYXNzIGNsczsNCglqbWV0aG9kSUQgaWQ7DQoJam9iamVjdCBvYmo7DQoNCgkvLyBqYXZhLmlvLkZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkNCgljb25zdCBUQ0hBUiAqIGxwRGlyZWN0b3J5TmFtZTsNCg0KCS8vIG9idGFpbiB0aGUgU3RyaW5nIGZyb20gdGhlIHBhcmFtZXRlcg0KCWNscyA9IGpuaWVudiAtPiBHZXRPYmplY3RDbGFzcyhmaWxlKTsNCglpZCA9IGpuaWVudiAtPiBHZXRNZXRob2RJRChjbHMsICJnZXRBYnNvbHV0ZVBhdGgiLCAiKClMamF2YS9sYW5nL1N0cmluZzsiKTsNCglvYmogPSBqbmllbnYgLT4gQ2FsbE9iamVjdE1ldGhvZChmaWxlLCBpZCk7DQoJbHBEaXJlY3RvcnlOYW1lID0gam5pZW52IC0+IEdldFN0cmluZ1VURkNoYXJzKChqc3RyaW5nKSBvYmosIDApOw0KCWlmIChERUJVRykNCgkJcHJpbnRmKCJEaXJlY3Rvcnk6IFslc11cbiIsbHBEaXJlY3RvcnlOYW1lKTsNCg0KCWludCByZXN1bHQgPSBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fVk9MVU1FX1VOS05PV047DQoJaWYgKGludCB3aW4gPSAoaW50KWdldFdpbmRvd3NWZXJzaW9uKCk8MCAmJiBOT1dJTjk1KXsNCgkJLy8gd2luZG93cyA5NSBvciBvdGhlcg0KCQlpZiAoREVCVUcpDQoJCQlwcmludGYoIlVuc3VwcG9ydGVkIFdpbmRvd3M6ICVpXG4iLHdpbik7CQkNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJLy8gTWFrZSBzdXJlIHdlIGhhdmUgYSBTdHJpbmcgb2YgdGhlIEZvcm06IDxsZXR0ZXI+Og0KCWlmICgnOicgPT0gbHBEaXJlY3RvcnlOYW1lWzFdKSB7DQoJCVRDSEFSIGRyaXZlTGV0dGVyWzRdOyAvL0M6XFwNCgkJbWVtY3B5KGRyaXZlTGV0dGVyLCBscERpcmVjdG9yeU5hbWUsIDIpOw0KCQlzdHJjcHkoZHJpdmVMZXR0ZXIgKyAyLCAiXFwiKTsNCg0KCQlzd2l0Y2ggKEdldERyaXZlVHlwZShkcml2ZUxldHRlcikpIHsNCgkJCWNhc2UgRFJJVkVfUkVNT1ZBQkxFIDoNCgkJCQkvLyBjaGVjayBpZiBmbG9wcHkgMy41LCBmbG9wcHkgNS4yNQkNCgkJCQkvLyBvciBvdGhlciByZW1vdmFibGUgZGV2aWNlIChVU0IsUENNQ0lBIC4uLikNCgkJCQlpZiAoREVCVUcpDQoJCQkJCXByaW50ZigiUmVtb3ZhYmxlIERldmljZSIpOw0KCQkJCXJlc3VsdCA9IGdldEZsb3BweShkcml2ZUxldHRlcik7CQkJCQkNCgkJCQlicmVhazsNCgkJCWNhc2UgRFJJVkVfQ0RST00gOg0KCQkJCXJlc3VsdCA9IG9yZ19lY2xpcHNlX3VwZGF0ZV9jb25maWd1cmF0aW9uX0xvY2FsU3lzdGVtSW5mb19WT0xVTUVfQ0RST007DQoJCQkJYnJlYWs7DQoJCQljYXNlIERSSVZFX0ZJWEVEIDoNCgkJCQlyZXN1bHQgPSBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fVk9MVU1FX0ZJWEVEOw0KCQkJCWJyZWFrOw0KCQkJY2FzZSBEUklWRV9SRU1PVEUgOg0KCQkJCXJlc3VsdCA9IG9yZ19lY2xpcHNlX3VwZGF0ZV9jb25maWd1cmF0aW9uX0xvY2FsU3lzdGVtSW5mb19WT0xVTUVfUkVNT1RFOw0KCQkJCWJyZWFrOw0KCQkJY2FzZSBEUklWRV9OT19ST09UX0RJUiA6DQoJCQkJcmVzdWx0ID0gb3JnX2VjbGlwc2VfdXBkYXRlX2NvbmZpZ3VyYXRpb25fTG9jYWxTeXN0ZW1JbmZvX1ZPTFVNRV9JTlZBTElEX1BBVEg7DQoJCQkJYnJlYWs7DQoJCQljYXNlIERSSVZFX1JBTURJU0sgOg0KCQkJCXJlc3VsdCA9IG9yZ19lY2xpcHNlX3VwZGF0ZV9jb25maWd1cmF0aW9uX0xvY2FsU3lzdGVtSW5mb19WT0xVTUVfUkFNRElTSzsNCgkJCQlicmVhazsJCQkNCgkJCWNhc2UgRFJJVkVfVU5LTk9XTiA6DQoJCQlkZWZhdWx0IDoNCgkJCQlyZXN1bHQgPSBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fVk9MVU1FX1VOS05PV047DQoJCQkJYnJlYWs7DQoJCX0NCgl9IGVsc2Ugew0KCQlyZXN1bHQgPSBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fVk9MVU1FX0lOVkFMSURfUEFUSDsNCgl9DQoNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovKg0KICogQ2xhc3M6ICAgICBvcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm8NCiAqIE1ldGhvZDogICAgbmF0aXZlTGlzdE1vdW50UG9pbnRzDQogKiBTaWduYXR1cmU6ICgpW0xqYXZhL2xhbmcvU3RyaW5nOw0KICovDQpKTklFWFBPUlQgam9iamVjdEFycmF5IEpOSUNBTEwgSmF2YV9vcmdfZWNsaXBzZV91cGRhdGVfY29uZmlndXJhdGlvbl9Mb2NhbFN5c3RlbUluZm9fbmF0aXZlTGlzdE1vdW50UG9pbnRzKA0KCUpOSUVudiAqIGpuaWVudiwNCglqY2xhc3MgamF2YUNsYXNzKSB7DQoNCgkvLw0KCURXT1JEIGxvZ0RyaXZlczsNCglVSU5UIGRyaXZlOw0KCVRDSEFSIGRyaXZlTmFtZVsxMDBdOw0KCWpvYmplY3RBcnJheSByZXR1cm5BcnJheTsNCglpbnQgbkRyaXZlID0gMDsNCg0KCS8vIA0KCWpjbGFzcyBzdHJpbmdDbGFzczsNCglqb2JqZWN0IGVtcHR5Ow0KCWludCBpbmRleCA9IDA7DQoJam9iamVjdCBzdHI7DQoNCg0KCWxvZ0RyaXZlcyA9IEdldExvZ2ljYWxEcml2ZXMoKTsNCglmb3IgKGRyaXZlID0gMDsgZHJpdmUgPCAzMjsgZHJpdmUrKykgew0KCQlpZiAobG9nRHJpdmVzICYgKDEgPDwgZHJpdmUpKSB7DQoJCQluRHJpdmUrKzsNCgkJfQ0KCX0NCg0KCXN0cmluZ0NsYXNzID0gam5pZW52IC0+IEZpbmRDbGFzcygiamF2YS9sYW5nL1N0cmluZyIpOw0KCWVtcHR5ID0gam5pZW52IC0+IE5ld1N0cmluZ1VURigiIik7DQoJcmV0dXJuQXJyYXkgPSBqbmllbnYgLT4gTmV3T2JqZWN0QXJyYXkobkRyaXZlLCBzdHJpbmdDbGFzcywgZW1wdHkpOw0KDQoJaWYgKGludCB3aW4gPSAoaW50KWdldFdpbmRvd3NWZXJzaW9uKCk8MCAmJiBOT1dJTjk1KXsNCgkJLy8gd2luZG93cyA5NSBvciBvdGhlcg0KCQlpZiAoREVCVUcpDQoJCQlwcmludGYoIlVuc3VwcG9ydGVkIFdpbmRvd3M6ICVpXG4iLHdpbik7CQ0KCQlyZXR1cm4gTlVMTDsNCgl9DQoNCglmb3IgKGRyaXZlID0gMDsgZHJpdmUgPCAzMjsgZHJpdmUrKykgew0KCQlpZiAobG9nRHJpdmVzICYgKDEgPDwgZHJpdmUpKSB7DQoJCQlzcHJpbnRmKGRyaXZlTmFtZSwgIiVjOlxcIiwgZHJpdmUgKyAnQScpOw0KCQkJc3RyID0gam5pZW52IC0+IE5ld1N0cmluZ1VURihkcml2ZU5hbWUpOw0KCQkJam5pZW52IC0+IFNldE9iamVjdEFycmF5RWxlbWVudChyZXR1cm5BcnJheSwgaW5kZXgsIHN0cik7DQoJCQlpbmRleCsrOw0KCQl9DQoJfQ0KDQoJcmV0dXJuIHJldHVybkFycmF5Ow0KfQ0KDQo=