LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxNSBNaWEtU29mdHdhcmUuDQogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzDQogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjANCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0DQogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbA0KICoNCiAqIENvbnRyaWJ1dG9yczoNCiAqICAgIEZyZWRlcmljIE1hZGlvdCAoTWlhLVNvZnR3YXJlKSAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbg0KICogICAgTmljb2xhcyBCcm9zIChNaWEtU29mdHdhcmUpIC0gQnVnIDMzNTAwMyAtIFtEaXNjb3ZlcmVyXSA6IEV4aXN0aW5nIERpc2NvdmVyZXJzIFJlZmFjdG9yaW5nIGJhc2VkIG9uIG5ldyBmcmFtZXdvcmsNCiAqICAgIEdy6WdvaXJlIER1cOkgKE1pYS1Tb2Z0d2FyZSkgLSBCdWcgNDgwMTgzIC0gVGhlIG1hbmlmZXN0Lm1mIGRpc2NvdmVyZXIgc2hvdWxkIG1hbmFnZSAnRXhwb3J0LVBhY2thZ2UnIA0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQpwYWNrYWdlIG9yZy5lY2xpcHNlLm1vZGlzY28ubWFuaWZlc3QuZGlzY292ZXJlcjsNCg0KaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247DQppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsNCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0Ow0KaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOw0KaW1wb3J0IGphdmEudXRpbC5MaXN0Ow0KaW1wb3J0IGphdmEudXRpbC5NYXA7DQoNCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuVVJJOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5yZXNvdXJjZS5SZXNvdXJjZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZmFjZXQudXRpbC5jb3JlLkxvZ2dlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLmluZnJhLmRpc2NvdmVyeS5jb3JlLkFic3RyYWN0TW9kZWxEaXNjb3ZlcmVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm1vZGlzY28uaW5mcmEuZGlzY292ZXJ5LmNvcmUuZXhjZXB0aW9uLkRpc2NvdmVyeUV4Y2VwdGlvbjsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0LkJ1bmRsZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0LkV4cG9ydGVkUGFja2FnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0LkltcG9ydGVkUGFja2FnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0Lk1hbmlmZXN0RmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5tb2Rpc2NvLm1hbmlmZXN0LlJlcXVpcmVkQnVuZGxlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm1vZGlzY28ubWFuaWZlc3QuVmVyc2lvbjsNCmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTWFuaWZlc3RFbGVtZW50Ow0KaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVFeGNlcHRpb247DQoNCnB1YmxpYyBjbGFzcyBNYW5pZmVzdE1vZGVsRGlzY292ZXJlcjIgZXh0ZW5kcyBBYnN0cmFjdE1vZGVsRGlzY292ZXJlcjxJRmlsZT4gew0KDQoJcHVibGljIGJvb2xlYW4gaXNBcHBsaWNhYmxlVG8oZmluYWwgSUZpbGUgc291cmNlKSB7DQoJCXJldHVybiBzb3VyY2UuaXNBY2Nlc3NpYmxlKCkgJiYgIk1BTklGRVNULk1GIi5lcXVhbHMoc291cmNlLmdldE5hbWUoKSk7IC8vJE5PTi1OTFMtMSQNCgl9DQoNCglAT3ZlcnJpZGUNCglwcm90ZWN0ZWQgdm9pZCBiYXNpY0Rpc2NvdmVyRWxlbWVudChmaW5hbCBJRmlsZSBmaWxlLA0KCQkJZmluYWwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgRGlzY292ZXJ5RXhjZXB0aW9uIHsNCgkJZmluYWwgU3RyaW5nIHBhdGhOYW1lID0gZmlsZS5nZXRGdWxsUGF0aCgpICsgIi54bWkiOyAvLyROT04tTkxTLTEkDQoJCWZpbmFsIFVSSSB1cmkgPSBVUkkuY3JlYXRlUGxhdGZvcm1SZXNvdXJjZVVSSShwYXRoTmFtZSwgdHJ1ZSk7DQoJCXNldERlZmF1bHRUYXJnZXRVUkkodXJpKTsNCgkJZmluYWwgUmVzb3VyY2UgcmVzb3VyY2UgPSBkaXNjb3Zlck1hbmlmZXN0TW9kZWwoZmlsZSk7DQoJCXNldFRhcmdldE1vZGVsKHJlc291cmNlKTsNCgl9DQoNCglwcml2YXRlIHN0YXRpYyB2b2lkIGRpc2NvdmVyQnVuZGxlU3ltYm9saWNOYW1lKGZpbmFsIEJ1bmRsZSBidW5kbGUsDQoJCQlmaW5hbCBTdHJpbmcgc3ltYm9saWNOYW1lVmFsdWUpIHRocm93cyBEaXNjb3ZlcnlFeGNlcHRpb24gew0KCQl0cnkgew0KCQkJZmluYWwgTWFuaWZlc3RFbGVtZW50W10gZWxlbWVudHMgPSBNYW5pZmVzdEVsZW1lbnQucGFyc2VIZWFkZXIoDQoJCQkJCSJCdW5kbGUtU3ltYm9saWNOYW1lIiwgc3ltYm9saWNOYW1lVmFsdWUpOyAvLyROT04tTkxTLTEkDQoJCQlpZiAoZWxlbWVudHMgIT0gbnVsbCAmJiBlbGVtZW50cy5sZW5ndGggPiAwKSB7DQoJCQkJZmluYWwgTWFuaWZlc3RFbGVtZW50IG1hbmlmZXN0RWxlbWVudCA9IGVsZW1lbnRzWzBdOw0KCQkJCWJ1bmRsZS5zZXRTeW1ib2xpY05hbWUobWFuaWZlc3RFbGVtZW50LmdldFZhbHVlKCkpOw0KCQkJCWZpbmFsIFN0cmluZyBzaW5nbGV0b25BdHRyID0NCgkJCQkJCW1hbmlmZXN0RWxlbWVudC5nZXREaXJlY3RpdmUoInNpbmdsZXRvbiIpOyAvLyROT04tTkxTLTEkDQoJCQkJaWYgKCJ0cnVlIi5lcXVhbHMoc2luZ2xldG9uQXR0cikpIHsgLy8kTk9OLU5MUy0xJA0KCQkJCQlidW5kbGUuc2V0U2luZ2xldG9uKHRydWUpOw0KCQkJCX0NCgkJCX0NCgkJfSBjYXRjaCAoQnVuZGxlRXhjZXB0aW9uIGUpIHsNCgkJCXRocm93IG5ldyBEaXNjb3ZlcnlFeGNlcHRpb24oZSk7DQoJCX0NCgl9DQoNCglwcml2YXRlIFJlc291cmNlIGRpc2NvdmVyTWFuaWZlc3RNb2RlbChmaW5hbCBJRmlsZSBtYW5pZmVzdEZpbGUpDQoJCQl0aHJvd3MgRGlzY292ZXJ5RXhjZXB0aW9uIHsNCgkJZmluYWwgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4gbWFuaWZlc3RWYWx1ZXMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsNCgkJZmluYWwgUmVzb3VyY2UgbWFuaWZlc3RSZXNvdXJjZSA9IGNyZWF0ZVRhcmdldE1vZGVsKCk7DQoJCUlucHV0U3RyZWFtIG1hbmlmZXN0Q29udGVudCA9IG51bGw7DQoJCXRyeSB7DQoJCQltYW5pZmVzdENvbnRlbnQgPSBtYW5pZmVzdEZpbGUuZ2V0Q29udGVudHMoKTsNCgkJCU1hbmlmZXN0RWxlbWVudC5wYXJzZUJ1bmRsZU1hbmlmZXN0KG1hbmlmZXN0Q29udGVudCwgbWFuaWZlc3RWYWx1ZXMpOw0KCQkJZmluYWwgQnVuZGxlIGJ1bmRsZSA9IE1hbmlmZXN0RmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQnVuZGxlKCk7DQoJCQltYW5pZmVzdFJlc291cmNlLmdldENvbnRlbnRzKCkuYWRkKGJ1bmRsZSk7DQoJCQlidW5kbGUuc2V0VmVyc2lvbihtYW5pZmVzdFZhbHVlcy5nZXQoIkJ1bmRsZS1WZXJzaW9uIikpOyAvLyROT04tTkxTLTEkDQoJCQlkaXNjb3ZlckJ1bmRsZVN5bWJvbGljTmFtZShidW5kbGUsIG1hbmlmZXN0VmFsdWVzLmdldCgiQnVuZGxlLVN5bWJvbGljTmFtZSIpKTsgLy8kTk9OLU5MUy0xJA0KCQkJYnVuZGxlLnNldE5hbWUobWFuaWZlc3RWYWx1ZXMuZ2V0KCJCdW5kbGUtTmFtZSIpKTsgLy8kTk9OLU5MUy0xJA0KCQkJYnVuZGxlLnNldEFjdGl2YXRvcihtYW5pZmVzdFZhbHVlcy5nZXQoIkJ1bmRsZS1BY3RpdmF0b3IiKSk7IC8vJE5PTi1OTFMtMSQNCgkJCWJ1bmRsZS5zZXRWZW5kb3IobWFuaWZlc3RWYWx1ZXMuZ2V0KCJCdW5kbGUtVmVuZG9yIikpOyAvLyROT04tTkxTLTEkDQoJCQlidW5kbGUuc2V0QWN0aXZhdGlvblBvbGljeShtYW5pZmVzdFZhbHVlcy5nZXQoIkJ1bmRsZS1BY3RpdmF0aW9uUG9saWN5IikpOyAvLyROT04tTkxTLTEkDQoJCQlidW5kbGUuc2V0UmVxdWlyZWRFeGVjdXRpb25FbnZpcm9ubWVudChtYW5pZmVzdFZhbHVlcw0KCQkJCQkuZ2V0KCJCdW5kbGUtUmVxdWlyZWRFeGVjdXRpb25FbnZpcm9ubWVudCIpKTsgLy8kTk9OLU5MUy0xJA0KCQkJZmluYWwgTWFuaWZlc3RFbGVtZW50W10gckJ1bmRsZU1FbHRzID0gDQoJCQkJCXBhcnNlSGVhZGVyKG1hbmlmZXN0VmFsdWVzLCAiUmVxdWlyZS1CdW5kbGUiKTsgLy8kTk9OLU5MUy0xJA0KCQkJaWYgKHJCdW5kbGVNRWx0cyAhPSBudWxsKSB7DQoJCQkJZmluYWwgTGlzdDxSZXF1aXJlZEJ1bmRsZT4gcmVxdWlyZWRCdW5kbGVzID0gDQoJCQkJCQlkaXNjb3ZlclJlcXVpcmVkQnVuZGxlKHJCdW5kbGVNRWx0cyk7DQoJCQkJYnVuZGxlLmdldFJlcXVpcmVkQnVuZGxlcygpLmFkZEFsbChyZXF1aXJlZEJ1bmRsZXMpOw0KCQkJfQ0KCQkJZGlzY292ZXJJbXBvcnRQYWNrYWdlKG1hbmlmZXN0VmFsdWVzLCBidW5kbGUpOw0KCQkJZGlzY292ZXJFeHBvcnRQYWNrYWdlKG1hbmlmZXN0VmFsdWVzLCBidW5kbGUpOw0KCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgew0KCQkJdGhyb3cgbmV3IERpc2NvdmVyeUV4Y2VwdGlvbihlKTsNCgkJfSBmaW5hbGx5IHsNCgkJCXRyeSB7DQoJCQkJaWYgKG1hbmlmZXN0Q29udGVudCAhPSBudWxsKSB7DQoJCQkJCW1hbmlmZXN0Q29udGVudC5jbG9zZSgpOw0KCQkJCX0NCgkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsNCgkJCQlmaW5hbCBTdHJpbmcgc3RyaW5nID0gU3RyaW5nLmZvcm1hdCgNCgkJCQkJCSJNYW5pZmVzdCBpbnB1dCBzdHJlYW0gY2xvc2luZyBmYWllZCAoJXMpIiwgLy8kTk9OLU5MUy0xJA0KCQkJCQkJbWFuaWZlc3RGaWxlLmdldExvY2F0aW9uKCkudG9PU1N0cmluZygpDQoJCQkJCSk7DQoJCQkJTG9nZ2VyLmxvZ0Vycm9yKGUsIHN0cmluZywgQWN0aXZhdG9yLmdldERlZmF1bHQoKSk7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIG1hbmlmZXN0UmVzb3VyY2U7DQoJfQ0KDQoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBkaXNjb3ZlckV4cG9ydFBhY2thZ2UoDQoJCQlmaW5hbCBNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0VmFsdWVzLCBmaW5hbCBCdW5kbGUgYnVuZGxlKQ0KCQkJCQl0aHJvd3MgQnVuZGxlRXhjZXB0aW9uIHsNCgkJZmluYWwgTWFuaWZlc3RFbGVtZW50W10gZXhwb3J0UGFja2FnZXMgPSANCgkJCQlwYXJzZUhlYWRlcihtYW5pZmVzdFZhbHVlcywgIkV4cG9ydC1QYWNrYWdlIik7IC8vJE5PTi1OTFMtMSQNCgkJaWYgKGV4cG9ydFBhY2thZ2VzICE9IG51bGwpIHsNCgkJCWZvciAoTWFuaWZlc3RFbGVtZW50IGV4cG9ydFBhY2thZ2UgOiBleHBvcnRQYWNrYWdlcykgew0KCQkJCWZpbmFsIEV4cG9ydGVkUGFja2FnZSBleHBvcnRlZFBhY2thZ2UgPSBNYW5pZmVzdEZhY3RvcnkuZUlOU1RBTkNFDQoJCQkJCQkuY3JlYXRlRXhwb3J0ZWRQYWNrYWdlKCk7DQoJCQkJZXhwb3J0ZWRQYWNrYWdlLnNldE5hbWUoZXhwb3J0UGFja2FnZS5nZXRWYWx1ZSgpKTsNCgkJCQlpZiAoZXhwb3J0UGFja2FnZS5nZXREaXJlY3RpdmUoIngtaW50ZXJuYWwiKSA9PSBudWxsKSB7IC8vJE5PTi1OTFMtMSQNCgkJCQkJZmluYWwgU3RyaW5nIGRpcmVjdGl2ZSA9IGV4cG9ydFBhY2thZ2UuZ2V0RGlyZWN0aXZlKCJ4LWZyaWVuZHMiKTsgLy8kTk9OLU5MUy0xJA0KCQkJCQlpZiAoZGlyZWN0aXZlID09IG51bGwpIHsNCgkJCQkJCWV4cG9ydGVkUGFja2FnZS5zZXRYSW50ZXJuYWwoZmFsc2UpOw0KCQkJCQl9IGVsc2Ugew0KCQkJCQkJZXhwb3J0ZWRQYWNrYWdlLnNldFhJbnRlcm5hbCh0cnVlKTsNCgkJCQkJCWZpbmFsIFN0cmluZ1tdIHhGcmllbmRzID0gZGlyZWN0aXZlLnNwbGl0KCIsIik7IC8vJE5PTi1OTFMtMSQNCgkJCQkJCWZvciAoU3RyaW5nIHhGcmllbmQgOiB4RnJpZW5kcykgew0KCQkJCQkJCWZpbmFsIEJ1bmRsZSB4ZkJ1bmRsZSA9IE1hbmlmZXN0RmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlQnVuZGxlKCk7DQoJCQkJCQkJeGZCdW5kbGUuc2V0TmFtZSh4RnJpZW5kKTsNCgkJCQkJCQlleHBvcnRlZFBhY2thZ2UuZ2V0WEZyaWVuZHMoKS5hZGQoeGZCdW5kbGUpOw0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJfSBlbHNlIHsNCgkJCQkJZXhwb3J0ZWRQYWNrYWdlLnNldFhJbnRlcm5hbCh0cnVlKTsNCgkJCQl9DQoJCQkJYnVuZGxlLmdldEV4cG9ydFBhY2thZ2VzKCkuYWRkKGV4cG9ydGVkUGFja2FnZSk7DQoJCQl9DQoJCX0NCgl9DQoNCglwcml2YXRlIHN0YXRpYyB2b2lkIGRpc2NvdmVySW1wb3J0UGFja2FnZSgNCgkJCWZpbmFsIE1hcDxTdHJpbmcsIFN0cmluZz4gbWFuaWZlc3RWYWx1ZXMsIGZpbmFsIEJ1bmRsZSBidW5kbGUpDQoJCQkJCXRocm93cyBCdW5kbGVFeGNlcHRpb24gew0KCQlmaW5hbCBNYW5pZmVzdEVsZW1lbnRbXSBpbXBvcnRlZFBhY2thZ2VzID0gDQoJCQkJcGFyc2VIZWFkZXIobWFuaWZlc3RWYWx1ZXMsICJJbXBvcnQtUGFja2FnZSIpOyAvLyROT04tTkxTLTEkDQoJCWlmIChpbXBvcnRlZFBhY2thZ2VzICE9IG51bGwpIHsNCgkJCWZvciAoTWFuaWZlc3RFbGVtZW50IGVsZW1lbnQgOiBpbXBvcnRlZFBhY2thZ2VzKSB7DQoJCQkJZmluYWwgSW1wb3J0ZWRQYWNrYWdlIGltcG9ydGVkUGFja2FnZSA9IE1hbmlmZXN0RmFjdG9yeS5lSU5TVEFOQ0UNCgkJCQkJCS5jcmVhdGVJbXBvcnRlZFBhY2thZ2UoKTsNCgkJCQlpbXBvcnRlZFBhY2thZ2Uuc2V0TmFtZShlbGVtZW50LmdldFZhbHVlKCkpOw0KCQkJCWZpbmFsIFN0cmluZyBidW5kbGVWZXJzaW9uID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoInZlcnNpb24iKTsgLy8kTk9OLU5MUy0xJA0KCQkJCWlmIChidW5kbGVWZXJzaW9uICE9IG51bGwpIHsNCgkJCQkJaW1wb3J0ZWRQYWNrYWdlLnNldFZlcnNpb24oZGlzY292ZXJWZXJzaW9uKGJ1bmRsZVZlcnNpb24pKTsNCgkJCQl9DQoJCQkJYnVuZGxlLmdldEltcG9ydGVkUGFja2FnZXMoKS5hZGQoaW1wb3J0ZWRQYWNrYWdlKTsNCgkJCX0NCgkJfQ0KCX0NCg0KCXByaXZhdGUgc3RhdGljIE1hbmlmZXN0RWxlbWVudFtdIHBhcnNlSGVhZGVyKA0KCQkJZmluYWwgTWFwPFN0cmluZywgU3RyaW5nPiBtYW5pZmVzdFZhbHVlcywgZmluYWwgU3RyaW5nIGtleSkNCgkJCQkJdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiB7DQoJCXJldHVybiBNYW5pZmVzdEVsZW1lbnQucGFyc2VIZWFkZXIoa2V5LCBtYW5pZmVzdFZhbHVlcy5nZXQoa2V5KSk7DQoJfQ0KDQoJcHJpdmF0ZSBzdGF0aWMgVmVyc2lvbiBkaXNjb3ZlclZlcnNpb24oZmluYWwgU3RyaW5nIGJ1bmRsZVZlcnNpb24pIHsNCgkJZmluYWwgVmVyc2lvbiB2ZXJzaW9uID0gTWFuaWZlc3RGYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVWZXJzaW9uKCk7DQoJCWZpbmFsIFN0cmluZyBmaXJzdENoYXIgPSBidW5kbGVWZXJzaW9uLnN1YnN0cmluZygwLCAxKTsNCgkJaWYgKCIoIi5lcXVhbHMoZmlyc3RDaGFyKSB8fCAiWyIuZXF1YWxzKGZpcnN0Q2hhcikpIHsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkDQoJCQlpZiAoIlsiLmVxdWFscyhmaXJzdENoYXIpKSB7IC8vJE5PTi1OTFMtMSQNCgkJCQl2ZXJzaW9uLnNldE1pbmltdW1Jc0luY2x1c2l2ZSh0cnVlKTsNCgkJCX0gZWxzZSB7DQoJCQkJdmVyc2lvbi5zZXRNaW5pbXVtSXNJbmNsdXNpdmUoZmFsc2UpOw0KCQkJfQ0KCQkJZmluYWwgaW50IGluZGV4T2ZTZXBhcmF0b3IgPSBidW5kbGVWZXJzaW9uLmluZGV4T2YoJywnKTsNCgkJCWZpbmFsIFN0cmluZyBtaW5pbXVtVmVyc2lvbiA9IGJ1bmRsZVZlcnNpb24uc3Vic3RyaW5nKA0KCQkJCQkxLCBpbmRleE9mU2VwYXJhdG9yKTsNCgkJCXZlcnNpb24uc2V0TWluaW11bShtaW5pbXVtVmVyc2lvbik7DQoJCQlmaW5hbCBTdHJpbmcgbWF4aW11bVZlcnNpb24gPSBidW5kbGVWZXJzaW9uLnN1YnN0cmluZygNCgkJCQkJaW5kZXhPZlNlcGFyYXRvciArIDEsIGJ1bmRsZVZlcnNpb24ubGVuZ3RoKCkgLSAxKTsNCgkJCXZlcnNpb24uc2V0TWF4aW11bShtYXhpbXVtVmVyc2lvbik7DQoJCQlpZiAoYnVuZGxlVmVyc2lvbi5zdWJzdHJpbmcoYnVuZGxlVmVyc2lvbi5sZW5ndGgoKSAtIDEpLmVxdWFscygiXSIpKSB7IC8vJE5PTi1OTFMtMSQNCgkJCQl2ZXJzaW9uLnNldE1heGltdW1Jc0luY2x1c2l2ZSh0cnVlKTsNCgkJCX0gZWxzZSB7DQoJCQkJdmVyc2lvbi5zZXRNYXhpbXVtSXNJbmNsdXNpdmUoZmFsc2UpOw0KCQkJfQ0KCQl9IGVsc2Ugew0KCQkJdmVyc2lvbi5zZXRNaW5pbXVtKGJ1bmRsZVZlcnNpb24pOw0KCQl9DQoJCXJldHVybiB2ZXJzaW9uOw0KCX0NCg0KCXByaXZhdGUgc3RhdGljIExpc3Q8UmVxdWlyZWRCdW5kbGU+IGRpc2NvdmVyUmVxdWlyZWRCdW5kbGUoDQoJCQlmaW5hbCBNYW5pZmVzdEVsZW1lbnRbXSByZXF1aXJlZEJ1bmRsZXMpIHsNCgkJZmluYWwgTGlzdDxSZXF1aXJlZEJ1bmRsZT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxSZXF1aXJlZEJ1bmRsZT4oKTsNCgkJZm9yIChNYW5pZmVzdEVsZW1lbnQgZWxlbWVudCA6IHJlcXVpcmVkQnVuZGxlcykgew0KCQkJZmluYWwgUmVxdWlyZWRCdW5kbGUgcmVxdWlyZWRCdW5kbGUgPQ0KCQkJCQlNYW5pZmVzdEZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZVJlcXVpcmVkQnVuZGxlKCk7DQoJCQlyZXF1aXJlZEJ1bmRsZS5zZXRTeW1ib2xpY05hbWUoZWxlbWVudC5nZXRWYWx1ZSgpKTsNCgkJCWZpbmFsIFN0cmluZyBidW5kbGVWZXJzaW9uID0NCgkJCQkJZWxlbWVudC5nZXRBdHRyaWJ1dGUoImJ1bmRsZS12ZXJzaW9uIik7IC8vJE5PTi1OTFMtMSQNCgkJCWlmIChidW5kbGVWZXJzaW9uICE9IG51bGwpIHsNCgkJCQlyZXF1aXJlZEJ1bmRsZS5zZXRWZXJzaW9uKGRpc2NvdmVyVmVyc2lvbihidW5kbGVWZXJzaW9uKSk7DQoJCQl9DQoJCQlyZXN1bHQuYWRkKHJlcXVpcmVkQnVuZGxlKTsNCgkJfQ0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCn0NCg==