LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA3IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuYWN0aW9uczsKCmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuam9icy5Kb2I7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS5kZWJ1Zy51aS5JRGVidWdVSUNvbnN0YW50czsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5JQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5FcnJvckRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVN0cnVjdHVyZWRTZWxlY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS53aW5kb3cuV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uud2l6YXJkLldpemFyZERpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLklDbGllbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuSUxhdW5jaGFibGVBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlB1Ymxpc2hTZXJ2ZXJKb2I7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuUmVzdGFydFNlcnZlckpvYjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TdGFydFNlcnZlckpvYjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5UcmFjZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5Nb2R1bGVBcnRpZmFjdERlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC52aWV3ZXJzLk1vZHVsZUFydGlmYWN0Q29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5EaXNwbGF5OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JV29ya2JlbmNoV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFdpbmRvd0FjdGlvbkRlbGVnYXRlOwovKioKICogU3VwcG9ydCBmb3Igc3RhcnRpbmcvc3RvcHBpbmcgc2VydmVyIGFuZCBjbGllbnRzIGZvciByZXNvdXJjZXMgcnVubmluZyBvbiBhIHNlcnZlci4KICovCnB1YmxpYyBjbGFzcyBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlIGltcGxlbWVudHMgSVdvcmtiZW5jaFdpbmRvd0FjdGlvbkRlbGVnYXRlIHsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nW10gbGF1bmNoTW9kZXMgPSB7CgkJSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUsIElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSB9OwoKCXByb3RlY3RlZCBPYmplY3Qgc2VsZWN0aW9uOwoKCXByb3RlY3RlZCBJV29ya2JlbmNoV2luZG93IHdpbmRvdzsKCglwcm90ZWN0ZWQgc3RhdGljIE9iamVjdCBnbG9iYWxTZWxlY3Rpb247CgoJcHJvdGVjdGVkIHN0YXRpYyBNYXAgZ2xvYmFsTGF1bmNoTW9kZTsKCXByb3RlY3RlZCBTdHJpbmcgbGF1bmNoTW9kZSA9IElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFOwoKCXByb3RlY3RlZCBib29sZWFuIHRhc2tzQW5kQ2xpZW50U2hvd247CgoJcHJvdGVjdGVkIElMYXVuY2hhYmxlQWRhcHRlciBsYXVuY2hhYmxlQWRhcHRlcjsKCXByb3RlY3RlZCBJQ2xpZW50IGNsaWVudDsKCgkvKioKCSAqIFJ1bk9uU2VydmVyQWN0aW9uRGVsZWdhdGUgY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHVibGljIFJ1bk9uU2VydmVyQWN0aW9uRGVsZWdhdGUoKSB7CgkJc3VwZXIoKTsKCX0KCgkvKioKCSAqIERpc3Bvc2VzIHRoaXMgYWN0aW9uIGRlbGVnYXRlLiAgVGhlIGltcGxlbWVudG9yIHNob3VsZCB1bmhvb2sgYW55IHJlZmVyZW5jZXMKCSAqIHRvIGl0c2VsZiBzbyB0aGF0IGdhcmJhZ2UgY29sbGVjdGlvbiBjYW4gb2NjdXIuCgkgKi8KCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJd2luZG93ID0gbnVsbDsKCX0KCgkvKioKCSAqIEluaXRpYWxpemVzIHRoaXMgYWN0aW9uIGRlbGVnYXRlIHdpdGggdGhlIHdvcmtiZW5jaCB3aW5kb3cgaXQgd2lsbCB3b3JrIGluLgoJICoKCSAqIEBwYXJhbSBuZXdXaW5kb3cgdGhlIHdpbmRvdyB0aGF0IHByb3ZpZGVzIHRoZSBjb250ZXh0IGZvciB0aGlzIGRlbGVnYXRlCgkgKi8KCXB1YmxpYyB2b2lkIGluaXQoSVdvcmtiZW5jaFdpbmRvdyBuZXdXaW5kb3cpIHsKCQl3aW5kb3cgPSBuZXdXaW5kb3c7Cgl9CgoJcHVibGljIElTZXJ2ZXIgZ2V0U2VydmVyKElNb2R1bGUgbW9kdWxlLCBJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlQXJ0aWZhY3QsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCUlTZXJ2ZXIgc2VydmVyID0gU2VydmVyQ29yZS5nZXREZWZhdWx0U2VydmVyKG1vZHVsZSk7CgkJCgkJLy8gaWdub3JlIHByZWZlcmVuY2UgaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhpcyBtb2RlLgoJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiAhU2VydmVyVUlQbHVnaW4uaXNDb21wYXRpYmxlV2l0aExhdW5jaE1vZGUoc2VydmVyLCBsYXVuY2hNb2RlKSkKCQkJc2VydmVyID0gbnVsbDsKCQkKCQlpZiAoc2VydmVyICE9IG51bGwgJiYgIVNlcnZlclV0aWwuY29udGFpbnNNb2R1bGUoc2VydmVyLCBtb2R1bGUsIG1vbml0b3IpKSB7CgkJCUlTZXJ2ZXJXb3JraW5nQ29weSB3YyA9IHNlcnZlci5jcmVhdGVXb3JraW5nQ29weSgpOwoJCQl0cnkgewoJCQkJU2VydmVyVXRpbC5tb2RpZnlNb2R1bGVzKHdjLCBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG5ldyBJTW9kdWxlWzBdLCBtb25pdG9yKTsKCQkJCXdjLnNhdmUoZmFsc2UsIG1vbml0b3IpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3QgYWRkIG1vZHVsZSB0byBzZXJ2ZXIiLCBjZSk7CgkJCQlzZXJ2ZXIgPSBudWxsOwoJCQl9CgkJfQoJCQoJCVNoZWxsIHNoZWxsOwoJCWlmICh3aW5kb3cgIT0gbnVsbCkKCQkJc2hlbGwgPSB3aW5kb3cuZ2V0U2hlbGwoKTsKCQllbHNlCgkJCXNoZWxsID0gU2VydmVyVUlQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRXb3JrYmVuY2goKS5nZXRBY3RpdmVXb3JrYmVuY2hXaW5kb3coKS5nZXRTaGVsbCgpOwoJCQoJCWlmIChzZXJ2ZXIgPT0gbnVsbCkgewoJCQkvLyB0cnkgdGhlIGZ1bGwgd2l6YXJkCgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkxhdW5jaGluZyB3aXphcmQiKTsKCQkJUnVuT25TZXJ2ZXJXaXphcmQgd2l6YXJkID0gbmV3IFJ1bk9uU2VydmVyV2l6YXJkKG1vZHVsZSwgbGF1bmNoTW9kZSwgbW9kdWxlQXJ0aWZhY3QpOwoJCQlDbG9zYWJsZVdpemFyZERpYWxvZyBkaWFsb2cgPSBuZXcgQ2xvc2FibGVXaXphcmREaWFsb2coc2hlbGwsIHdpemFyZCk7CgkJCWlmIChkaWFsb2cub3BlbigpID09IFdpbmRvdy5DQU5DRUwpIHsKCQkJCWlmIChtb25pdG9yICE9IG51bGwpCgkJCQkJbW9uaXRvci5zZXRDYW5jZWxlZCh0cnVlKTsKCQkJCXJldHVybiBudWxsOwoJCQl9CgkJCQoJCQl0cnkgewoJCQkJSm9iLmdldEpvYk1hbmFnZXIoKS5qb2luKCJvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmZhbWlseSIsIG51bGwpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkVycm9yIHdhaXRpbmcgZm9yIGpvYiIsIGUpOwoJCQl9CgkJCXNlcnZlciA9IHdpemFyZC5nZXRTZXJ2ZXIoKTsKCQkJYm9vbGVhbiBwcmVmZXJyZWQgPSB3aXphcmQuaXNQcmVmZXJyZWRTZXJ2ZXIoKTsKCQkJdGFza3NBbmRDbGllbnRTaG93biA9IHRydWU7CgkJCWNsaWVudCA9IHdpemFyZC5nZXRTZWxlY3RlZENsaWVudCgpOwoJCQlsYXVuY2hhYmxlQWRhcHRlciA9IHdpemFyZC5nZXRMYXVuY2hhYmxlQWRhcHRlcigpOwoJCQkKCQkJLy8gc2V0IHByZWZlcnJlZCBzZXJ2ZXIgaWYgcmVxdWVzdGVkCgkJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiBwcmVmZXJyZWQpIHsKCQkJCXRyeSB7CgkJCQkJU2VydmVyQ29yZS5zZXREZWZhdWx0U2VydmVyKG1vZHVsZSwgc2VydmVyLCBtb25pdG9yKTsKCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCQlTdHJpbmcgbWVzc2FnZSA9IE1lc3NhZ2VzLmVycm9yQ291bGROb3RTYXZlUHJlZmVyZW5jZTsKCQkJCQlFcnJvckRpYWxvZy5vcGVuRXJyb3Ioc2hlbGwsIE1lc3NhZ2VzLmVycm9yRGlhbG9nVGl0bGUsIG1lc3NhZ2UsIGNlLmdldFN0YXR1cygpKTsKCQkJCX0KCQkJfQoJCX0KCQkKCQl0cnkgewoJCQlKb2IuZ2V0Sm9iTWFuYWdlcigpLmpvaW4oIm9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuZmFtaWx5IiwgbmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkVycm9yIHdhaXRpbmcgZm9yIGpvYiIsIGUpOwoJCX0KCQkKCQlyZXR1cm4gc2VydmVyOwoJfQoKCS8qKgoJICogUnVuIHRoZSByZXNvdXJjZSBvbiBhIHNlcnZlci4KCSAqLwoJcHJvdGVjdGVkIHZvaWQgcnVuKCkgewoJCWZpbmFsIElNb2R1bGVBcnRpZmFjdFtdIG1vZHVsZUFydGlmYWN0cyA9IFNlcnZlclBsdWdpbi5nZXRNb2R1bGVBcnRpZmFjdHMoc2VsZWN0aW9uKTsKCQlpZiAobW9kdWxlQXJ0aWZhY3RzID09IG51bGwgfHwgbW9kdWxlQXJ0aWZhY3RzLmxlbmd0aCA9PSAwIHx8IG1vZHVsZUFydGlmYWN0c1swXSA9PSBudWxsKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihNZXNzYWdlcy5lcnJvck5vQXJ0aWZhY3QpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJObyBtb2R1bGUgYXJ0aWZhY3QgZm91bmQiKTsKCQkJcmV0dXJuOwoJCX0KCQkJCgkJCgkJU2hlbGwgc2hlbGwyID0gbnVsbDsKCQlpZiAod2luZG93ICE9IG51bGwpCgkJCXNoZWxsMiA9IHdpbmRvdy5nZXRTaGVsbCgpOwoJCWVsc2UgewoJCQl0cnkgewoJCQkJc2hlbGwyID0gU2VydmVyVUlQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRXb3JrYmVuY2goKS5nZXRBY3RpdmVXb3JrYmVuY2hXaW5kb3coKS5nZXRTaGVsbCgpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJLy8gaWdub3JlCgkJCX0KCQkJaWYgKHNoZWxsMiA9PSBudWxsKQoJCQkJc2hlbGwyID0gRGlzcGxheS5nZXREZWZhdWx0KCkuZ2V0QWN0aXZlU2hlbGwoKTsKCQl9CgkJZmluYWwgU2hlbGwgc2hlbGwgPSBzaGVsbDI7CgkJCgkJLy8gZ2V0IGEgdmFsaWQgTW9kdWxlQXJ0aWZhY3QgdGhhdCB3ZSBjYW4gdXNlIGZvciBsYXVuY2hpbmcKCQkvLyBUT0RPIFRoZSBNb2R1bGVBcnRpZmFjdENvbXBvc2l0ZSBzaG91bGQgYmUgcGFydCBvZiB0aGUgUnVuT25TZXJ2ZXJXaXphcmQKCQlmaW5hbCBJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlQXJ0aWZhY3Q7CgkJaWYgKG1vZHVsZUFydGlmYWN0cy5sZW5ndGggPiAxKSB7CgkJCU1vZHVsZUFydGlmYWN0Q29tcG9zaXRlIGFydGlmYWN0Q29tcG9zaXRlID0gbmV3IE1vZHVsZUFydGlmYWN0Q29tcG9zaXRlKHNoZWxsLCBtb2R1bGVBcnRpZmFjdHMsIGxhdW5jaE1vZGUpOwoJCQlpZiAoYXJ0aWZhY3RDb21wb3NpdGUub3BlbigpID09IFdpbmRvdy5DQU5DRUwpCgkJCQlyZXR1cm47CgkJCQoJCQltb2R1bGVBcnRpZmFjdCA9IGFydGlmYWN0Q29tcG9zaXRlLmdldFNlbGVjdGlvbigpOwoJCX0gZWxzZQoJCQltb2R1bGVBcnRpZmFjdCA9IG1vZHVsZUFydGlmYWN0c1swXTsKCQkKCQlpZiAobW9kdWxlQXJ0aWZhY3QuZ2V0TW9kdWxlKCkgPT0gbnVsbCkgeyAvLyAxNDk0MjUKCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKE1lc3NhZ2VzLmVycm9yTm9Nb2R1bGVzKTsKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTW9kdWxlIGFydGlmYWN0IG5vdCBjb250YWluZWQgaW4gYSBtb2R1bGUiKTsKCQkJcmV0dXJuOwoJCX0KCQlmaW5hbCBJTW9kdWxlIG1vZHVsZSA9IG1vZHVsZUFydGlmYWN0LmdldE1vZHVsZSgpOwoJCQoJCS8vIGNoZWNrIGZvciBzZXJ2ZXJzIHdpdGggdGhlIGdpdmVuIHN0YXJ0IG1vZGUKCQlJU2VydmVyW10gc2VydmVycyA9IFNlcnZlckNvcmUuZ2V0U2VydmVycygpOwoJCWJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZSAmJiAhZm91bmQ7IGkrKykgewoJCQkJaWYgKFNlcnZlclVJUGx1Z2luLmlzQ29tcGF0aWJsZVdpdGhMYXVuY2hNb2RlKHNlcnZlcnNbaV0sIGxhdW5jaE1vZGUpKSB7CgkJCQkJdHJ5IHsKCQkJCQkJSU1vZHVsZVtdIHBhcmVudHMgPSBzZXJ2ZXJzW2ldLmdldFJvb3RNb2R1bGVzKG1vZHVsZSwgbnVsbCk7CgkJCQkJCWlmIChwYXJlbnRzICE9IG51bGwgJiYgcGFyZW50cy5sZW5ndGggPiAwKQoJCQkJCQkJZm91bmQgPSB0cnVlOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCS8vIGlnbm9yZQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQkKCQlpZiAoIWZvdW5kKSB7CgkJCS8vIG5vIGV4aXN0aW5nIHNlcnZlciBzdXBwb3J0cyB0aGUgcHJvamVjdCBhbmQgc3RhcnQgbW9kZSEKCQkJLy8gY2hlY2sgaWYgdGhlcmUgbWlnaHQgYmUgYW5vdGhlciBvbmUgdGhhdCBjYW4gYmUgY3JlYXRlZAoJCQlJU2VydmVyVHlwZVtdIHNlcnZlclR5cGVzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJUeXBlcygpOwoJCQlpZiAoc2VydmVyVHlwZXMgIT0gbnVsbCkgewoJCQkJaW50IHNpemUgPSBzZXJ2ZXJUeXBlcy5sZW5ndGg7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemUgJiYgIWZvdW5kOyBpKyspIHsKCQkJCQlJU2VydmVyVHlwZSB0eXBlID0gc2VydmVyVHlwZXNbaV07CgkJCQkJSU1vZHVsZVR5cGVbXSBtb2R1bGVUeXBlcyA9IHR5cGUuZ2V0UnVudGltZVR5cGUoKS5nZXRNb2R1bGVUeXBlcygpOwoJCQkJCWlmICh0eXBlLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2RlKSAmJiBTZXJ2ZXJVdGlsLmlzU3VwcG9ydGVkTW9kdWxlKG1vZHVsZVR5cGVzLCBtb2R1bGUuZ2V0TW9kdWxlVHlwZSgpKSkgewoJCQkJCQlmb3VuZCA9IHRydWU7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWlmICghZm91bmQpIHsKCQkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihNZXNzYWdlcy5lcnJvck5vU2VydmVyKTsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIk5vIHNlcnZlciBmb3Igc3RhcnQgbW9kZSIpOwoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJCQoJCWlmICghU2VydmVyVUlQbHVnaW4uc2F2ZUVkaXRvcnMoKSkKCQkJcmV0dXJuOwoJCQoJCXRhc2tzQW5kQ2xpZW50U2hvd24gPSBmYWxzZTsKCQlJU2VydmVyIHNlcnZlcjIgPSBudWxsOwoJCWNsaWVudCA9IG51bGw7CgkJbGF1bmNoYWJsZUFkYXB0ZXIgPSBudWxsOwoJCXRyeSB7CgkJCUlQcm9ncmVzc01vbml0b3IgbW9uaXRvciA9IG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCk7CgkJCXNlcnZlcjIgPSBnZXRTZXJ2ZXIobW9kdWxlLCBtb2R1bGVBcnRpZmFjdCwgbW9uaXRvcik7CgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybjsKCQkJCgkJCWlmIChzZXJ2ZXIyICE9IG51bGwpIHsKCQkJCUlGb2xkZXIgZm9sZGVyID0gc2VydmVyMi5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKCk7CgkJCQlpZiAoZm9sZGVyICE9IG51bGwgJiYgZm9sZGVyLmdldFByb2plY3QoKSAhPSBudWxsICYmICFmb2xkZXIuZ2V0UHJvamVjdCgpLmlzT3BlbigpKQoJCQkJCWZvbGRlci5nZXRQcm9qZWN0KCkub3Blbihtb25pdG9yKTsKCQkJfQoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKHNoZWxsLCBjZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOwoJCQlyZXR1cm47CgkJfQoJCWZpbmFsIElTZXJ2ZXIgc2VydmVyID0gc2VydmVyMjsKCQkvL2lmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkvLwlyZXR1cm47CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiU2VydmVyOiAiICsgc2VydmVyKTsKCQkKCQlpZiAoc2VydmVyID09IG51bGwpIHsKCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKE1lc3NhZ2VzLmVycm9yTm9TZXJ2ZXIpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJObyBzZXJ2ZXIgZm91bmQiKTsKCQkJcmV0dXJuOwoJCX0KCQkKCQlpZiAoIVNlcnZlclVJUGx1Z2luLnByb21wdElmRGlydHkoc2hlbGwsIHNlcnZlcikpCgkJCXJldHVybjsKCQkKCQlpZiAoIXRhc2tzQW5kQ2xpZW50U2hvd24pIHsKCQkJUnVuT25TZXJ2ZXJXaXphcmQgd2l6YXJkID0gbmV3IFJ1bk9uU2VydmVyV2l6YXJkKHNlcnZlciwgbGF1bmNoTW9kZSwgbW9kdWxlQXJ0aWZhY3QpOwoJCQlpZiAod2l6YXJkLnNob3VsZEFwcGVhcigpKSB7CgkJCQlXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IFdpemFyZERpYWxvZyhzaGVsbCwgd2l6YXJkKTsKCQkJCWlmIChkaWFsb2cub3BlbigpID09IFdpbmRvdy5DQU5DRUwpCgkJCQkJcmV0dXJuOwoJCQl9IGVsc2UKCQkJCXdpemFyZC5wZXJmb3JtRmluaXNoKCk7CgkJCWNsaWVudCA9IHdpemFyZC5nZXRTZWxlY3RlZENsaWVudCgpOwoJCQlsYXVuY2hhYmxlQWRhcHRlciA9IHdpemFyZC5nZXRMYXVuY2hhYmxlQWRhcHRlcigpOwoJCX0KCQkKCQlpZiAobW9kdWxlQXJ0aWZhY3QgaW5zdGFuY2VvZiBNb2R1bGVBcnRpZmFjdERlbGVnYXRlKSB7CgkJCWJvb2xlYW4gY2FuTG9hZCA9IGZhbHNlOwoJCQl0cnkgewoJCQkJQ2xhc3MgYyA9IENsYXNzLmZvck5hbWUobW9kdWxlQXJ0aWZhY3QuZ2V0Q2xhc3MoKS5nZXROYW1lKCkpOwoJCQkJaWYgKGMubmV3SW5zdGFuY2UoKSAhPSBudWxsKQoJCQkJCWNhbkxvYWQgPSB0cnVlOwoJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkNvdWxkIG5vdCBsb2FkIG1vZHVsZSBhcnRpZmFjdCBkZWxlZ2F0ZSBjbGFzcywgc3dpdGNoaW5nIHRvIGJhY2t1cCIpOwoJCQl9CgkJCWlmIChjYW5Mb2FkKSB7CgkJCQl0cnkgewoJCQkJCUlQcm9ncmVzc01vbml0b3IgbW9uaXRvciA9IG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCk7CgkJCQkJSUxhdW5jaENvbmZpZ3VyYXRpb24gY29uZmlnID0gZ2V0TGF1bmNoQ29uZmlndXJhdGlvbihzZXJ2ZXIsIChNb2R1bGVBcnRpZmFjdERlbGVnYXRlKSBtb2R1bGVBcnRpZmFjdCwgbGF1bmNoYWJsZUFkYXB0ZXIsIGNsaWVudCwgbW9uaXRvcik7CgkJCQkJY29uZmlnLmxhdW5jaChsYXVuY2hNb2RlLCBtb25pdG9yKTsKCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3QgbGF1bmNoIFJ1biBvbiBTZXJ2ZXIiLCBjZSk7CgkJCQl9CgkJCQlyZXR1cm47CgkJCX0KCQl9CgkJCgkJVGhyZWFkIHRocmVhZCA9IG5ldyBUaHJlYWQoIlJ1biBvbiBTZXJ2ZXIiKSB7CgkJCXB1YmxpYyB2b2lkIHJ1bigpIHsKCQkJCWlmIChjbGllbnQgPT0gbnVsbCkgewoJCQkJCS8vIGlmIHRoZXJlIGlzIG5vIGNsaWVudCwgdXNlIGEgZHVtbXkKCQkJCQljbGllbnQgPSBuZXcgSUNsaWVudCgpIHsKCQkJCQkJcHVibGljIFN0cmluZyBnZXREZXNjcmlwdGlvbigpIHsKCQkJCQkJCXJldHVybiBNZXNzYWdlcy5jbGllbnREZWZhdWx0RGVzY3JpcHRpb247CgkJCQkJCX0KCgkJCQkJCXB1YmxpYyBTdHJpbmcgZ2V0SWQoKSB7CgkJCQkJCQlyZXR1cm4gIm9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuY2xpZW50LmRlZmF1bHQiOwoJCQkJCQl9CgoJCQkJCQlwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CgkJCQkJCQlyZXR1cm4gTWVzc2FnZXMuY2xpZW50RGVmYXVsdE5hbWU7CgkJCQkJCX0KCgkJCQkJCXB1YmxpYyBJU3RhdHVzIGxhdW5jaChJU2VydmVyIHNlcnZlcjMsIE9iamVjdCBsYXVuY2hhYmxlMiwgU3RyaW5nIGxhdW5jaE1vZGUzLCBJTGF1bmNoIGxhdW5jaCkgewoJCQkJCQkJcmV0dXJuIFN0YXR1cy5PS19TVEFUVVM7CgkJCQkJCX0KCgkJCQkJCXB1YmxpYyBib29sZWFuIHN1cHBvcnRzKElTZXJ2ZXIgc2VydmVyMywgT2JqZWN0IGxhdW5jaGFibGUyLCBTdHJpbmcgbGF1bmNoTW9kZTMpIHsKCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQl9CgkJCQkJfTsKCQkJCX0KCQkJCQoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiUmVhZHkgdG8gbGF1bmNoIik7CgkJCQkKCQkJCS8vIHN0YXJ0IHNlcnZlciBpZiBpdCdzIG5vdCBhbHJlYWR5IHN0YXJ0ZWQKCQkJCS8vIGFuZCBjdWUgdGhlIGNsaWVudCB0byBzdGFydAoJCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH07IC8vIFRPRE86IGdldCBwYXJlbnQgaGVpcmFyY2h5IGNvcnJlY3QKCQkJCWludCBzdGF0ZSA9IHNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpOwoJCQkJaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RBUlRJTkcpIHsKCQkJCQlMYXVuY2hDbGllbnRKb2IgY2xpZW50Sm9iID0gbmV3IExhdW5jaENsaWVudEpvYihzZXJ2ZXIsIG1vZHVsZXMsIGxhdW5jaE1vZGUsIG1vZHVsZUFydGlmYWN0LCBsYXVuY2hhYmxlQWRhcHRlciwgY2xpZW50KTsKCQkJCQljbGllbnRKb2Iuc2NoZWR1bGUoKTsKCQkJCX0gZWxzZSBpZiAoc3RhdGUgPT0gSVNlcnZlci5TVEFURV9TVEFSVEVEKSB7CgkJCQkJYm9vbGVhbiByZXN0YXJ0ID0gZmFsc2U7CgkJCQkJU3RyaW5nIG1vZGUgPSBzZXJ2ZXIuZ2V0TW9kZSgpOwoJCQkJCUlCcmVha3BvaW50TWFuYWdlciBicmVha3BvaW50TWFuYWdlciA9IERlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5nZXRCcmVha3BvaW50TWFuYWdlcigpOwoJCQkJCWJvb2xlYW4gZGlzYWJsZWRCcmVha3BvaW50cyA9IGZhbHNlOwoJCQkJCQoJCQkJCWlmIChzZXJ2ZXIuZ2V0U2VydmVyUmVzdGFydFN0YXRlKCkpIHsKCQkJCQkJaW50IHJlc3VsdCA9IG9wZW5SZXN0YXJ0RGlhbG9nKHNoZWxsKTsKCQkJCQkJaWYgKHJlc3VsdCA9PSAwKSB7CgkJCQkJCQlsYXVuY2hNb2RlID0gbW9kZTsKCQkJCQkJCXJlc3RhcnQgPSB0cnVlOwoJCQkJCQl9IGVsc2UgaWYgKHJlc3VsdCA9PSA5KSAvLyBjYW5jZWwKCQkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQkJaWYgKCFyZXN0YXJ0KSB7CgkJCQkJCWlmICghSUxhdW5jaE1hbmFnZXIuUlVOX01PREUuZXF1YWxzKG1vZGUpICYmIElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJCQkJYm9vbGVhbiBicmVha3BvaW50c09wdGlvbiA9IGZhbHNlOwoJCQkJCQkJaWYgKGJyZWFrcG9pbnRNYW5hZ2VyLmlzRW5hYmxlZCgpICYmIElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUuZXF1YWxzKG1vZGUpKQoJCQkJCQkJCWJyZWFrcG9pbnRzT3B0aW9uID0gdHJ1ZTsKCQkJCQkJCWludCByZXN1bHQgPSBvcGVuT3B0aW9uc0RpYWxvZyhzaGVsbCwgTWVzc2FnZXMud2l6UnVuT25TZXJ2ZXJUaXRsZSwgTWVzc2FnZXMuZGlhbG9nTW9kZVdhcm5pbmdSdW4sIGJyZWFrcG9pbnRzT3B0aW9uKTsKCQkJCQkJCWlmIChyZXN1bHQgPT0gMCkKCQkJCQkJCQlyZXN0YXJ0ID0gdHJ1ZTsKCQkJCQkJCWVsc2UgaWYgKHJlc3VsdCA9PSAxKSB7CgkJCQkJCQkJYnJlYWtwb2ludE1hbmFnZXIuc2V0RW5hYmxlZChmYWxzZSk7CgkJCQkJCQkJZGlzYWJsZWRCcmVha3BvaW50cyA9IHRydWU7CgkJCQkJCQkJbGF1bmNoTW9kZSA9IG1vZGU7CgkJCQkJCQl9IGVsc2UgaWYgKHJlc3VsdCA9PSAyKQoJCQkJCQkJCWxhdW5jaE1vZGUgPSBtb2RlOwoJCQkJCQkJZWxzZSAvLyByZXN1bHQgPT0gOSAvLyBjYW5jZWwKCQkJCQkJCQlyZXR1cm47CgkJCQkJCX0gZWxzZSBpZiAoIUlMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUuZXF1YWxzKG1vZGUpICYmIElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUuZXF1YWxzKGxhdW5jaE1vZGUpKSB7CgkJCQkJCQlpbnQgcmVzdWx0ID0gb3Blbk9wdGlvbnNEaWFsb2coc2hlbGwsIE1lc3NhZ2VzLndpekRlYnVnT25TZXJ2ZXJUaXRsZSwgTWVzc2FnZXMuZGlhbG9nTW9kZVdhcm5pbmdEZWJ1ZywgZmFsc2UpOwoJCQkJCQkJaWYgKHJlc3VsdCA9PSAwKQoJCQkJCQkJCXJlc3RhcnQgPSB0cnVlOwoJCQkJCQkJZWxzZSBpZiAocmVzdWx0ID09IDEpCgkJCQkJCQkJbGF1bmNoTW9kZSA9IG1vZGU7CgkJCQkJCQllbHNlIC8vIHJlc3VsdCA9PSA5IC8vIGNhbmNlbAoJCQkJCQkJCXJldHVybjsKCQkJCQkJfSBlbHNlIGlmICghSUxhdW5jaE1hbmFnZXIuUFJPRklMRV9NT0RFLmVxdWFscyhtb2RlKSAmJiBJTGF1bmNoTWFuYWdlci5QUk9GSUxFX01PREUuZXF1YWxzKGxhdW5jaE1vZGUpKSB7CgkJCQkJCQlib29sZWFuIGJyZWFrcG9pbnRzT3B0aW9uID0gZmFsc2U7CgkJCQkJCQlpZiAoYnJlYWtwb2ludE1hbmFnZXIuaXNFbmFibGVkKCkgJiYgSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERS5lcXVhbHMobW9kZSkpCgkJCQkJCQkJYnJlYWtwb2ludHNPcHRpb24gPSB0cnVlOwoJCQkJCQkJaW50IHJlc3VsdCA9IG9wZW5PcHRpb25zRGlhbG9nKHNoZWxsLCBNZXNzYWdlcy53aXpQcm9maWxlT25TZXJ2ZXJUaXRsZSwgTWVzc2FnZXMuZGlhbG9nTW9kZVdhcm5pbmdQcm9maWxlLCBicmVha3BvaW50c09wdGlvbik7CgkJCQkJCQlpZiAocmVzdWx0ID09IDApCgkJCQkJCQkJcmVzdGFydCA9IHRydWU7CgkJCQkJCQllbHNlIGlmIChyZXN1bHQgPT0gMSkgewoJCQkJCQkJCWJyZWFrcG9pbnRNYW5hZ2VyLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJCQkJCWRpc2FibGVkQnJlYWtwb2ludHMgPSB0cnVlOwoJCQkJCQkJCWxhdW5jaE1vZGUgPSBtb2RlOwoJCQkJCQkJfSBlbHNlIGlmIChyZXN1bHQgPT0gMikKCQkJCQkJCQlsYXVuY2hNb2RlID0gbW9kZTsKCQkJCQkJCWVsc2UgLy8gcmVzdWx0ID09IDkgLy8gY2FuY2VsCgkJCQkJCQkJcmV0dXJuOwoJCQkJCQl9CgkJCQkJCQoJCQkJCQlpZiAoSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERS5lcXVhbHMobGF1bmNoTW9kZSkpIHsKCQkJCQkJCWlmICghYnJlYWtwb2ludE1hbmFnZXIuaXNFbmFibGVkKCkgJiYgIWRpc2FibGVkQnJlYWtwb2ludHMpIHsKCQkJCQkJCQlpbnQgcmVzdWx0ID0gb3BlbkJyZWFrcG9pbnREaWFsb2coc2hlbGwpOwoJCQkJCQkJCWlmIChyZXN1bHQgPT0gMCkKCQkJCQkJCQkJYnJlYWtwb2ludE1hbmFnZXIuc2V0RW5hYmxlZCh0cnVlKTsKCQkJCQkJCQllbHNlIGlmIChyZXN1bHQgPT0gMSkgewoJCQkJCQkJCQkvLyBpZ25vcmUKCQkJCQkJCQl9IGVsc2UgLy8gcmVzdWx0ID09IDIKCQkJCQkJCQkJcmV0dXJuOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCQoJCQkJCVB1Ymxpc2hTZXJ2ZXJKb2IgcHVibGlzaEpvYiA9IG5ldyBQdWJsaXNoU2VydmVySm9iKHNlcnZlciwgSVNlcnZlci5QVUJMSVNIX0lOQ1JFTUVOVEFMLCBmYWxzZSk7CgkJCQkJTGF1bmNoQ2xpZW50Sm9iIGNsaWVudEpvYiA9IG5ldyBMYXVuY2hDbGllbnRKb2Ioc2VydmVyLCBtb2R1bGVzLCBsYXVuY2hNb2RlLCBtb2R1bGVBcnRpZmFjdCwgbGF1bmNoYWJsZUFkYXB0ZXIsIGNsaWVudCk7CgkJCQkJcHVibGlzaEpvYi5zZXROZXh0Sm9iKGNsaWVudEpvYik7CgkJCQkJCgkJCQkJaWYgKHJlc3RhcnQpIHsKCQkJCQkJUmVzdGFydFNlcnZlckpvYiByZXN0YXJ0Sm9iID0gbmV3IFJlc3RhcnRTZXJ2ZXJKb2Ioc2VydmVyLCBsYXVuY2hNb2RlKTsKCQkJCQkJcmVzdGFydEpvYi5zZXROZXh0Sm9iKHB1Ymxpc2hKb2IpOwoJCQkJCQlyZXN0YXJ0Sm9iLnNjaGVkdWxlKCk7CgkJCQkJfSBlbHNlCgkJCQkJCXB1Ymxpc2hKb2Iuc2NoZWR1bGUoKTsKCQkJCX0gZWxzZSBpZiAoc3RhdGUgIT0gSVNlcnZlci5TVEFURV9TVE9QUElORykgewoJCQkJCVB1Ymxpc2hTZXJ2ZXJKb2IgcHVibGlzaEpvYiA9IG5ldyBQdWJsaXNoU2VydmVySm9iKHNlcnZlcik7CgkJCQkJU3RhcnRTZXJ2ZXJKb2Igc3RhcnRTZXJ2ZXJKb2IgPSBuZXcgU3RhcnRTZXJ2ZXJKb2Ioc2VydmVyLCBsYXVuY2hNb2RlKTsKCQkJCQlMYXVuY2hDbGllbnRKb2IgY2xpZW50Sm9iID0gbmV3IExhdW5jaENsaWVudEpvYihzZXJ2ZXIsIG1vZHVsZXMsIGxhdW5jaE1vZGUsIG1vZHVsZUFydGlmYWN0LCBsYXVuY2hhYmxlQWRhcHRlciwgY2xpZW50KTsKCQkJCQkKCQkJCQlpZiAoKChTZXJ2ZXJUeXBlKXNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkpLnN0YXJ0QmVmb3JlUHVibGlzaCgpKSB7CgkJCQkJCXN0YXJ0U2VydmVySm9iLnNldE5leHRKb2IocHVibGlzaEpvYik7CgkJCQkJCXB1Ymxpc2hKb2Iuc2V0TmV4dEpvYihjbGllbnRKb2IpOwoJCQkJCQlzdGFydFNlcnZlckpvYi5zY2hlZHVsZSgpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXB1Ymxpc2hKb2Iuc2V0TmV4dEpvYihzdGFydFNlcnZlckpvYik7CgkJCQkJCXN0YXJ0U2VydmVySm9iLnNldE5leHRKb2IoY2xpZW50Sm9iKTsKCQkJCQkJcHVibGlzaEpvYi5zY2hlZHVsZSgpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX07CgkJdGhyZWFkLnNldERhZW1vbih0cnVlKTsKCQl0aHJlYWQuc3RhcnQoKTsKCX0KCglwcm90ZWN0ZWQgdm9pZCBzZXR1cExhdW5jaENvbmZpZ3VyYXRpb24oSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSBjb25maWcsIElTZXJ2ZXIgc2VydmVyLCBNb2R1bGVBcnRpZmFjdERlbGVnYXRlIG1vZHVsZUFydGlmYWN0LCBJTGF1bmNoYWJsZUFkYXB0ZXIgbGF1bmNoYWJsZUFkYXB0ZXIsIElDbGllbnQgY2xpZW50KSB7CgkJY29uZmlnLnNldEF0dHJpYnV0ZShSdW5PblNlcnZlckxhdW5jaENvbmZpZ3VyYXRpb25EZWxlZ2F0ZS5BVFRSX1NFUlZFUl9JRCwgc2VydmVyLmdldElkKCkpOwoJCWNvbmZpZy5zZXRBdHRyaWJ1dGUoUnVuT25TZXJ2ZXJMYXVuY2hDb25maWd1cmF0aW9uRGVsZWdhdGUuQVRUUl9NT0RVTEVfQVJUSUZBQ1QsIG1vZHVsZUFydGlmYWN0LnNlcmlhbGl6ZSgpKTsKCQljb25maWcuc2V0QXR0cmlidXRlKFJ1bk9uU2VydmVyTGF1bmNoQ29uZmlndXJhdGlvbkRlbGVnYXRlLkFUVFJfTU9EVUxFX0FSVElGQUNUX0NMQVNTLCBtb2R1bGVBcnRpZmFjdC5nZXRDbGFzcygpLmdldE5hbWUoKSk7CgkJY29uZmlnLnNldEF0dHJpYnV0ZShSdW5PblNlcnZlckxhdW5jaENvbmZpZ3VyYXRpb25EZWxlZ2F0ZS5BVFRSX0xBVU5DSEFCTEVfQURBUFRFUl9JRCwgbGF1bmNoYWJsZUFkYXB0ZXIuZ2V0SWQoKSk7CgkJY29uZmlnLnNldEF0dHJpYnV0ZShSdW5PblNlcnZlckxhdW5jaENvbmZpZ3VyYXRpb25EZWxlZ2F0ZS5BVFRSX0NMSUVOVF9JRCwgY2xpZW50LmdldElkKCkpOwoJfQoKCXByb3RlY3RlZCBJTGF1bmNoQ29uZmlndXJhdGlvbiBnZXRMYXVuY2hDb25maWd1cmF0aW9uKElTZXJ2ZXIgc2VydmVyLCBNb2R1bGVBcnRpZmFjdERlbGVnYXRlIG1vZHVsZUFydGlmYWN0LCBJTGF1bmNoYWJsZUFkYXB0ZXIgbGF1bmNoYWJsZUFkYXB0ZXIyLCBJQ2xpZW50IGNsaWVudDIsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCVN0cmluZyBzZXJ2ZXJJZCA9IHNlcnZlci5nZXRJZCgpOwoJCUlMYXVuY2hNYW5hZ2VyIGxhdW5jaE1hbmFnZXIgPSBEZWJ1Z1BsdWdpbi5nZXREZWZhdWx0KCkuZ2V0TGF1bmNoTWFuYWdlcigpOwoJCUlMYXVuY2hDb25maWd1cmF0aW9uVHlwZSBsYXVuY2hDb25maWdUeXBlID0gbGF1bmNoTWFuYWdlci5nZXRMYXVuY2hDb25maWd1cmF0aW9uVHlwZSgib3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5sYXVuY2hDb25maWd1cmF0aW9uVHlwZSIpOwoJCUlMYXVuY2hDb25maWd1cmF0aW9uW10gbGF1bmNoQ29uZmlncyA9IG51bGw7CgkJdHJ5IHsKCQkJbGF1bmNoQ29uZmlncyA9IGxhdW5jaE1hbmFnZXIuZ2V0TGF1bmNoQ29uZmlndXJhdGlvbnMobGF1bmNoQ29uZmlnVHlwZSk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQkKCQlpZiAobGF1bmNoQ29uZmlncyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gbGF1bmNoQ29uZmlncy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlMaXN0IGxpc3QgPSBsYXVuY2hDb25maWdzW2ldLmdldEF0dHJpYnV0ZShJRGVidWdVSUNvbnN0YW50cy5BVFRSX0ZBVk9SSVRFX0dST1VQUywgKExpc3QpbnVsbCk7CgkJCQlpZiAobGlzdCA9PSBudWxsIHx8IGxpc3QuaXNFbXB0eSgpKSB7CgkJCQkJdHJ5IHsKCQkJCQkJU3RyaW5nIHNlcnZlcklkMiA9IGxhdW5jaENvbmZpZ3NbaV0uZ2V0QXR0cmlidXRlKFJ1bk9uU2VydmVyTGF1bmNoQ29uZmlndXJhdGlvbkRlbGVnYXRlLkFUVFJfU0VSVkVSX0lELCAoU3RyaW5nKSBudWxsKTsKCQkJCQkJaWYgKHNlcnZlcklkLmVxdWFscyhzZXJ2ZXJJZDIpKSB7CgkJCQkJCQlmaW5hbCBJTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5IHdjID0gbGF1bmNoQ29uZmlnc1tpXS5nZXRXb3JraW5nQ29weSgpOwoJCQkJCQkJc2V0dXBMYXVuY2hDb25maWd1cmF0aW9uKHdjLCBzZXJ2ZXIsIG1vZHVsZUFydGlmYWN0LCBsYXVuY2hhYmxlQWRhcHRlcjIsIGNsaWVudDIpOwoJCQkJCQkJaWYgKHdjLmlzRGlydHkoKSkgewoJCQkJCQkJCXRyeSB7CgkJCQkJCQkJCXJldHVybiB3Yy5kb1NhdmUoKTsKCQkJCQkJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQkJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIGNvbmZpZ3VyaW5nIGxhdW5jaCIsIGNlKTsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCQlyZXR1cm4gbGF1bmNoQ29uZmlnc1tpXTsKCQkJCQkJfQoJCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBjb25maWd1cmluZyBsYXVuY2giLCBlKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJCgkJLy8gY3JlYXRlIGEgbmV3IGxhdW5jaCBjb25maWd1cmF0aW9uCgkJU3RyaW5nIGxhdW5jaE5hbWUgPSBOTFMuYmluZChNZXNzYWdlcy5ydW5PblNlcnZlckxhdW5jaENvbmZpZ05hbWUsIG1vZHVsZUFydGlmYWN0LmdldE5hbWUoKSk7CgkJbGF1bmNoTmFtZSA9IGdldFZhbGlkTGF1bmNoQ29uZmlndXJhdGlvbk5hbWUobGF1bmNoTmFtZSk7CgkJbGF1bmNoTmFtZSA9IGxhdW5jaE1hbmFnZXIuZ2VuZXJhdGVVbmlxdWVMYXVuY2hDb25maWd1cmF0aW9uTmFtZUZyb20obGF1bmNoTmFtZSk7IAoJCUlMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd2MgPSBsYXVuY2hDb25maWdUeXBlLm5ld0luc3RhbmNlKG51bGwsIGxhdW5jaE5hbWUpOwoJCXdjLnNldEF0dHJpYnV0ZShSdW5PblNlcnZlckxhdW5jaENvbmZpZ3VyYXRpb25EZWxlZ2F0ZS5BVFRSX1NFUlZFUl9JRCwgc2VydmVySWQpOwoJCXNldHVwTGF1bmNoQ29uZmlndXJhdGlvbih3Yywgc2VydmVyLCBtb2R1bGVBcnRpZmFjdCwgbGF1bmNoYWJsZUFkYXB0ZXIyLCBjbGllbnQyKTsKCQlyZXR1cm4gd2MuZG9TYXZlKCk7Cgl9CgoJLy9wcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGNoYXJbXSBJTlZBTElEX0NIQVJTID0gbmV3IGNoYXJbXSB7J1xcJywgJy8nLCAnOicsICcqJywgJz8nLCAnIicsICc8JywgJz4nLCAnfCcsICdcMCcsICdAJywgJyYnfTsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhcltdIElOVkFMSURfQ0hBUlMgPSBuZXcgY2hhcltdIHsnXFwnLCAnOicsICcqJywgJz8nLCAnIicsICc8JywgJz4nLCAnfCcsICdcMCcsICdAJywgJyYnfTsKCXByb3RlY3RlZCBTdHJpbmcgZ2V0VmFsaWRMYXVuY2hDb25maWd1cmF0aW9uTmFtZShTdHJpbmcgcykgewoJCWlmIChzID09IG51bGwgfHwgcy5sZW5ndGgoKSA9PSAwKQoJCQlyZXR1cm4gIjEiOwoJCWludCBzaXplID0gSU5WQUxJRF9DSEFSUy5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJcyA9IHMucmVwbGFjZShJTlZBTElEX0NIQVJTW2ldLCAnXycpOwoJCX0KCQlyZXR1cm4gczsKCX0KCgkvKioKCSAqIE9wZW4gYW4gb3B0aW9ucyBkaWFsb2cuCgkgKiAKCSAqIEBwYXJhbSBzaGVsbAoJICogQHBhcmFtIHRpdGxlCgkgKiBAcGFyYW0gbWVzc2FnZQoJICogQHBhcmFtIGJyZWFrcG9pbnRzT3B0aW9uCgkgKiBAcmV0dXJuIGEgZGlhbG9nIHJldHVybiBjb25zdGFudAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGludCBvcGVuT3B0aW9uc0RpYWxvZyhmaW5hbCBTaGVsbCBzaGVsbCwgZmluYWwgU3RyaW5nIHRpdGxlLCBmaW5hbCBTdHJpbmcgbWVzc2FnZSwgZmluYWwgYm9vbGVhbiBicmVha3BvaW50c09wdGlvbikgewoJCWlmIChicmVha3BvaW50c09wdGlvbikgewoJCQlpbnQgY3VycmVudCA9IFNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuZ2V0TGF1bmNoTW9kZTIoKTsKCQkJaWYgKGN1cnJlbnQgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERTJfUkVTVEFSVCkKCQkJCXJldHVybiAwOwoJCQllbHNlIGlmIChjdXJyZW50ID09IFNlcnZlclVJUHJlZmVyZW5jZXMuTEFVTkNIX01PREUyX0RJU0FCTEVfQlJFQUtQT0lOVFMpCgkJCQlyZXR1cm4gMTsKCQkJZWxzZSBpZiAoY3VycmVudCA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLkxBVU5DSF9NT0RFMl9DT05USU5VRSkKCQkJCXJldHVybiAyOwoJCX0gZWxzZSB7CgkJCWludCBjdXJyZW50ID0gU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5nZXRMYXVuY2hNb2RlKCk7CgkJCWlmIChjdXJyZW50ID09IFNlcnZlclVJUHJlZmVyZW5jZXMuTEFVTkNIX01PREVfUkVTVEFSVCkKCQkJCXJldHVybiAwOwoJCQllbHNlIGlmIChjdXJyZW50ID09IFNlcnZlclVJUHJlZmVyZW5jZXMuTEFVTkNIX01PREVfQ09OVElOVUUpCgkJCQlyZXR1cm4gMTsKCQl9CgkJZmluYWwgaW50W10gaSA9IG5ldyBpbnRbMV07CgkJc2hlbGwuZ2V0RGlzcGxheSgpLnN5bmNFeGVjKG5ldyBSdW5uYWJsZSgpIHsKCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJT3B0aW9uc01lc3NhZ2VEaWFsb2cgZGlhbG9nID0gbnVsbDsKCQkJCVN0cmluZ1tdIGl0ZW1zID0gbnVsbDsKCQkJCWlmIChicmVha3BvaW50c09wdGlvbikgewoJCQkJCWl0ZW1zID0gbmV3IFN0cmluZ1tdIHsKCQkJCQkJTWVzc2FnZXMuZGlhbG9nTW9kZVdhcm5pbmdSZXN0YXJ0LAoJCQkJCQlNZXNzYWdlcy5kaWFsb2dNb2RlV2FybmluZ0JyZWFrcG9pbnRzLAoJCQkJCQlNZXNzYWdlcy5kaWFsb2dNb2RlV2FybmluZ0NvbnRpbnVlCgkJCQkJfTsKCQkJCX0gZWxzZSB7CgkJCQkJaXRlbXMgPSBuZXcgU3RyaW5nW10gewoJCQkJCQlNZXNzYWdlcy5kaWFsb2dNb2RlV2FybmluZ1Jlc3RhcnQsCgkJCQkJCU1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nQ29udGludWUKCQkJCQl9OwoJCQkJfQoJCQkJCgkJCQlkaWFsb2cgPSBuZXcgT3B0aW9uc01lc3NhZ2VEaWFsb2coc2hlbGwsIHRpdGxlLCBtZXNzYWdlLCBpdGVtcyk7CgkJCQlpWzBdID0gZGlhbG9nLm9wZW4oKTsKCQkJCQoJCQkJaWYgKGRpYWxvZy5pc1JlbWVtYmVyKCkpIHsKCQkJCQlpZiAoYnJlYWtwb2ludHNPcHRpb24pIHsKCQkJCQkJaWYgKGlbMF0gPT0gMCkKCQkJCQkJCVNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuc2V0TGF1bmNoTW9kZTIoU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERTJfUkVTVEFSVCk7CgkJCQkJCWVsc2UgaWYgKGlbMF0gPT0gMSkKCQkJCQkJCVNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuc2V0TGF1bmNoTW9kZTIoU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERTJfRElTQUJMRV9CUkVBS1BPSU5UUyk7CgkJCQkJCWVsc2UgaWYgKGlbMF0gPT0gMikKCQkJCQkJCVNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuc2V0TGF1bmNoTW9kZTIoU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERTJfQ09OVElOVUUpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChpWzBdID09IDApCgkJCQkJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLnNldExhdW5jaE1vZGUoU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERV9SRVNUQVJUKTsKCQkJCQkJZWxzZSBpZiAoaVswXSA9PSAxKQoJCQkJCQkJU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5zZXRMYXVuY2hNb2RlKFNlcnZlclVJUHJlZmVyZW5jZXMuTEFVTkNIX01PREVfQ09OVElOVUUpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0pOwoJCXJldHVybiBpWzBdOwoJfQoKCS8qKgoJICogT3BlbiBhbiBvcHRpb25zIGRpYWxvZy4KCSAqIAoJICogQHBhcmFtIHNoZWxsCgkgKiBAcmV0dXJuIGEgZGlhbG9nIHJldHVybiBjb25zdGFudAoJICovCglwcm90ZWN0ZWQgc3RhdGljIGludCBvcGVuQnJlYWtwb2ludERpYWxvZyhmaW5hbCBTaGVsbCBzaGVsbCkgewoJCWludCBjdXJyZW50ID0gU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5nZXRFbmFibGVCcmVha3BvaW50cygpOwoJCWlmIChjdXJyZW50ID09IFNlcnZlclVJUHJlZmVyZW5jZXMuRU5BQkxFX0JSRUFLUE9JTlRTX0FMV0FZUykKCQkJcmV0dXJuIDA7CgkJZWxzZSBpZiAoY3VycmVudCA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLkVOQUJMRV9CUkVBS1BPSU5UU19ORVZFUikKCQkJcmV0dXJuIDE7CgkJCgkJZmluYWwgaW50W10gaSA9IG5ldyBpbnRbMV07CgkJc2hlbGwuZ2V0RGlzcGxheSgpLnN5bmNFeGVjKG5ldyBSdW5uYWJsZSgpIHsKCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJT3B0aW9uc01lc3NhZ2VEaWFsb2cgZGlhbG9nID0gbmV3IE9wdGlvbnNNZXNzYWdlRGlhbG9nKHNoZWxsLAoJCQkJCQlNZXNzYWdlcy53aXpEZWJ1Z09uU2VydmVyVGl0bGUsIE1lc3NhZ2VzLmRpYWxvZ0JyZWFrcG9pbnRzLCBuZXcgU3RyaW5nW10gewoJCQkJCQlNZXNzYWdlcy5kaWFsb2dCcmVha3BvaW50c1JlZW5hYmxlLCBNZXNzYWdlcy5kaWFsb2dNb2RlV2FybmluZ0NvbnRpbnVlfSk7CgkJCQlpWzBdID0gZGlhbG9nLm9wZW4oKTsKCQkJCWlmIChkaWFsb2cuaXNSZW1lbWJlcigpKSB7CgkJCQkJaWYgKGlbMF0gPT0gMCkKCQkJCQkJU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5zZXRFbmFibGVCcmVha3BvaW50cyhTZXJ2ZXJVSVByZWZlcmVuY2VzLkVOQUJMRV9CUkVBS1BPSU5UU19BTFdBWVMpOwoJCQkJCWVsc2UgaWYgKGlbMF0gPT0gMSkKCQkJCQkJU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5zZXRFbmFibGVCcmVha3BvaW50cyhTZXJ2ZXJVSVByZWZlcmVuY2VzLkVOQUJMRV9CUkVBS1BPSU5UU19ORVZFUik7CgkJCQl9CgkJCX0KCQl9KTsKCQlyZXR1cm4gaVswXTsKCX0KCgkvKioKCSAqIE9wZW4gYSByZXN0YXJ0IG9wdGlvbnMgZGlhbG9nLgoJICogCgkgKiBAcGFyYW0gc2hlbGwKCSAqIEByZXR1cm4gYSBkaWFsb2cgcmV0dXJuIGNvbnN0YW50CgkgKi8KCXByb3RlY3RlZCBzdGF0aWMgaW50IG9wZW5SZXN0YXJ0RGlhbG9nKGZpbmFsIFNoZWxsIHNoZWxsKSB7CgkJaW50IGN1cnJlbnQgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLmdldFJlc3RhcnQoKTsKCQlpZiAoY3VycmVudCA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLlJFU1RBUlRfQUxXQVlTKQoJCQlyZXR1cm4gMDsKCQllbHNlIGlmIChjdXJyZW50ID09IFNlcnZlclVJUHJlZmVyZW5jZXMuUkVTVEFSVF9ORVZFUikKCQkJcmV0dXJuIDE7CgkJCgkJZmluYWwgaW50W10gaSA9IG5ldyBpbnRbMV07CgkJc2hlbGwuZ2V0RGlzcGxheSgpLnN5bmNFeGVjKG5ldyBSdW5uYWJsZSgpIHsKCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJT3B0aW9uc01lc3NhZ2VEaWFsb2cgZGlhbG9nID0gbmV3IE9wdGlvbnNNZXNzYWdlRGlhbG9nKHNoZWxsLAoJCQkJCQlNZXNzYWdlcy5kZWZhdWx0RGlhbG9nVGl0bGUsIE1lc3NhZ2VzLmRpYWxvZ1Jlc3RhcnQsIG5ldyBTdHJpbmdbXSB7CgkJCQkJCU1lc3NhZ2VzLmRpYWxvZ1Jlc3RhcnRSZXN0YXJ0LCBNZXNzYWdlcy5kaWFsb2dSZXN0YXJ0Q29udGludWV9KTsKCQkJCWlbMF0gPSBkaWFsb2cub3BlbigpOwoJCQkJaWYgKGRpYWxvZy5pc1JlbWVtYmVyKCkpIHsKCQkJCQlpZiAoaVswXSA9PSAwKQoJCQkJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLnNldFJlc3RhcnQoU2VydmVyVUlQcmVmZXJlbmNlcy5SRVNUQVJUX0FMV0FZUyk7CgkJCQkJZWxzZSBpZiAoaVswXSA9PSAxKQoJCQkJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLnNldFJlc3RhcnQoU2VydmVyVUlQcmVmZXJlbmNlcy5SRVNUQVJUX05FVkVSKTsKCQkJCX0KCQkJfQoJCX0pOwoJCXJldHVybiBpWzBdOwoJfQoKCS8qKgoJICogVGhlIGRlbGVnYXRpbmcgYWN0aW9uIGhhcyBiZWVuIHBlcmZvcm1lZC4gSW1wbGVtZW50CgkgKiB0aGlzIG1ldGhvZCB0byBkbyB0aGUgYWN0dWFsIHdvcmsuCgkgKgoJICogQHBhcmFtIGFjdGlvbiBhY3Rpb24gcHJveHkgdGhhdCBoYW5kbGVzIHRoZSBwcmVzZW50YXRpb24KCSAqIHBvcnRpb24gb2YgdGhlIHBsdWdpbiBhY3Rpb24KCSAqLwoJcHVibGljIHZvaWQgcnVuKElBY3Rpb24gYWN0aW9uKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiUnVubmluZyBvbiBTZXJ2ZXIuLi4iKTsKCQl0cnkgewoJCQlydW4oKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJSdW4gb24gU2VydmVyIEVycm9yIiwgZSk7CgkJfQoJfQoKCXByb3RlY3RlZCBib29sZWFuIGlzRW5hYmxlZCgpIHsKCQl0cnkgewoJCQlCb29sZWFuIGIgPSAoQm9vbGVhbikgZ2xvYmFsTGF1bmNoTW9kZS5nZXQoZ2V0TGF1bmNoTW9kZSgpKTsKCQkJcmV0dXJuIGIuYm9vbGVhblZhbHVlKCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJLy8gaWdub3JlCgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHN0YXJ0IG1vZGUgdGhhdCB0aGUgc2VydmVyIHNob3VsZCB1c2UuCgkgKi8KCXByb3RlY3RlZCBTdHJpbmcgZ2V0TGF1bmNoTW9kZSgpIHsKCQlyZXR1cm4gbGF1bmNoTW9kZTsKCX0KCgkvKioKCSAqIFNldCB0aGUgbGF1bmNoIG1vZGUuCgkgKiAKCSAqIEBwYXJhbSBsYXVuY2hNb2RlIGEge0BsaW5rIElMYXVuY2hNYW5hZ2VyfSBsYXVuY2ggbW9kZQoJICovCglwdWJsaWMgdm9pZCBzZXRMYXVuY2hNb2RlKFN0cmluZyBsYXVuY2hNb2RlKSB7CgkJdGhpcy5sYXVuY2hNb2RlID0gbGF1bmNoTW9kZTsKCX0KCgkvKioKCSAqIERldGVybWluZSB3aGljaCBjbGllbnRzIGNhbiBhY3Qgb24gdGhlIGN1cnJlbnQgc2VsZWN0aW9uLgoJICoKCSAqIEBwYXJhbSBhY3Rpb24gYWN0aW9uIHByb3h5IHRoYXQgaGFuZGxlcyBwcmVzZW50YXRpb24KCSAqICAgIHBvcnRpb24gb2YgdGhlIHBsdWdpbiBhY3Rpb24KCSAqIEBwYXJhbSBzZWwgY3VycmVudCBzZWxlY3Rpb24gaW4gdGhlIGRlc2t0b3AKCSAqLwoJcHVibGljIHZvaWQgc2VsZWN0aW9uQ2hhbmdlZChJQWN0aW9uIGFjdGlvbiwgSVNlbGVjdGlvbiBzZWwpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICI+IHNlbGVjdGlvbkNoYW5nZWQiKTsKCQlzZWxlY3Rpb24gPSBudWxsOwoJCWxvbmcgdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoJCWlmIChzZWwgPT0gbnVsbCB8fCBzZWwuaXNFbXB0eSgpIHx8ICEoc2VsIGluc3RhbmNlb2YgSVN0cnVjdHVyZWRTZWxlY3Rpb24pKSB7CgkJCWFjdGlvbi5zZXRFbmFibGVkKGZhbHNlKTsKCQkJZ2xvYmFsU2VsZWN0aW9uID0gbnVsbDsKCQkJcmV0dXJuOwoJCX0KCQkKCQlJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWxlY3QgPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHNlbDsKCQlJdGVyYXRvciBpdGVyYXRvciA9IHNlbGVjdC5pdGVyYXRvcigpOwoJCWlmIChpdGVyYXRvci5oYXNOZXh0KCkpCgkJCXNlbGVjdGlvbiA9IGl0ZXJhdG9yLm5leHQoKTsKCQlpZiAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7IC8vIG1vcmUgdGhhbiBvbmUgc2VsZWN0aW9uIChzaG91bGQgbmV2ZXIgaGFwcGVuKQoJCQlhY3Rpb24uc2V0RW5hYmxlZChmYWxzZSk7CgkJCXNlbGVjdGlvbiA9IG51bGw7CgkJCWdsb2JhbFNlbGVjdGlvbiA9IG51bGw7CgkJCXJldHVybjsKCQl9CgkJCgkJaWYgKHNlbGVjdGlvbiAhPSBnbG9iYWxTZWxlY3Rpb24pIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiU2VsZWN0aW9uOiAiICsgc2VsZWN0aW9uKTsKCQkJaWYgKHNlbGVjdGlvbiAhPSBudWxsKQkKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlbGVjdGlvbiB0eXBlOiAiICsgc2VsZWN0aW9uLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKCQkJZ2xvYmFsU2VsZWN0aW9uID0gc2VsZWN0aW9uOwoJCQlnbG9iYWxMYXVuY2hNb2RlID0gbmV3IEhhc2hNYXAoKTsKCQkJaWYgKCFTZXJ2ZXJQbHVnaW4uaGFzTW9kdWxlQXJ0aWZhY3QoZ2xvYmFsU2VsZWN0aW9uKSkgewoJCQkJYWN0aW9uLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJcmV0dXJuOwoJCQl9CgkJCQoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJjaGVja2luZyBmb3IgbW9kdWxlIGFydGlmYWN0Iik7CgkJCUlNb2R1bGVBcnRpZmFjdFtdIG1vZHVsZUFydGlmYWN0cyA9IFNlcnZlclBsdWdpbi5nZXRNb2R1bGVBcnRpZmFjdHMoZ2xvYmFsU2VsZWN0aW9uKTsKCQkJSU1vZHVsZSBtb2R1bGUgPSBudWxsOwoJCQkvLyBUT0RPIC0gbXVsdGlwbGUgbW9kdWxlIGFydGlmYWN0cwoJCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlQXJ0aWZhY3QgPSBtb2R1bGVBcnRpZmFjdHNbMF07CgkJCWlmIChtb2R1bGVBcnRpZmFjdCAhPSBudWxsKQoJCQkJbW9kdWxlID0gbW9kdWxlQXJ0aWZhY3QuZ2V0TW9kdWxlKCk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIm1vZHVsZUFydGlmYWN0PSAiICsgbW9kdWxlQXJ0aWZhY3QgKyAiLCBtb2R1bGU9ICIgKyBtb2R1bGUpOwoJCQlpZiAobW9kdWxlICE9IG51bGwpCgkJCQlmaW5kR2xvYmFsTGF1bmNoTW9kZXMobW9kdWxlKTsKCQkJZWxzZSB7CgkJCQlnbG9iYWxMYXVuY2hNb2RlLnB1dChJTGF1bmNoTWFuYWdlci5SVU5fTU9ERSwgbmV3IEJvb2xlYW4odHJ1ZSkpOwoJCQkJZ2xvYmFsTGF1bmNoTW9kZS5wdXQoSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERSwgbmV3IEJvb2xlYW4odHJ1ZSkpOwoJCQkJZ2xvYmFsTGF1bmNoTW9kZS5wdXQoSUxhdW5jaE1hbmFnZXIuUFJPRklMRV9NT0RFLCBuZXcgQm9vbGVhbih0cnVlKSk7CgkJCX0KCQl9CgkJCgkJYWN0aW9uLnNldEVuYWJsZWQoaXNFbmFibGVkKCkpOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIjwgc2VsZWN0aW9uQ2hhbmdlZCAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gdGltZSkpOwoJfQoKCS8qKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZXJlIGlzIGEgc2VydmVyIGZhY3RvcnkgYXZhaWxhYmxlIGZvciB0aGUgZ2l2ZW4gbW9kdWxlCgkgKiBhbmQgdGhlIHZhcmlvdXMgc3RhcnQgbW9kZXMuCgkgKi8KCXByb3RlY3RlZCB2b2lkIGZpbmRHbG9iYWxMYXVuY2hNb2RlcyhJTW9kdWxlIG1vZHVsZSkgewoJCUlTZXJ2ZXJUeXBlW10gc2VydmVyVHlwZXMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlclR5cGVzKCk7CgkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJUeXBlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJU2VydmVyVHlwZSB0eXBlID0gc2VydmVyVHlwZXNbaV07CgkJCQlpZiAoaXNWYWxpZFNlcnZlclR5cGUodHlwZSwgbW9kdWxlKSkgewoJCQkJCWZvciAoYnl0ZSBiID0gMDsgYiA8IGxhdW5jaE1vZGVzLmxlbmd0aDsgYisrKSB7CgkJCQkJCWlmICh0eXBlLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2Rlc1tiXSkpIHsKCQkJCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KGxhdW5jaE1vZGVzW2JdLCBuZXcgQm9vbGVhbih0cnVlKSk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNlcnZlciB0eXBlIGNhbiBsYXVuY2ggdGhlIG1vZHVsZS4gCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIGlzVmFsaWRTZXJ2ZXJUeXBlKElTZXJ2ZXJUeXBlIHR5cGUsIElNb2R1bGUgbW9kdWxlKSB7CgkJdHJ5IHsKCQkJSVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gdHlwZS5nZXRSdW50aW1lVHlwZSgpOwoJCQlTZXJ2ZXJVdGlsLmlzU3VwcG9ydGVkTW9kdWxlKHJ1bnRpbWVUeXBlLmdldE1vZHVsZVR5cGVzKCksIG1vZHVsZS5nZXRNb2R1bGVUeXBlKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJcmV0dXJuIHRydWU7Cgl9Cn0=