LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuYWN0aW9uczsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLmpvYnMuSm9iOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5EZWJ1Z1BsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUJyZWFrcG9pbnRNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5JQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5FcnJvckRpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVN0cnVjdHVyZWRTZWxlY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS53aW5kb3cuV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uud2l6YXJkLldpemFyZERpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLklDbGllbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuSUxhdW5jaGFibGVBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlB1Ymxpc2hTZXJ2ZXJKb2I7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuUmVzdGFydFNlcnZlckpvYjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXJQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TdGFydFNlcnZlckpvYjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwud2l6YXJkLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5EaXNwbGF5OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5JV29ya2JlbmNoV2luZG93OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFdpbmRvd0FjdGlvbkRlbGVnYXRlOwovKioKICogU3VwcG9ydCBmb3Igc3RhcnRpbmcvc3RvcHBpbmcgc2VydmVyIGFuZCBjbGllbnRzIGZvciByZXNvdXJjZXMgcnVubmluZyBvbiBhIHNlcnZlci4KICovCnB1YmxpYyBjbGFzcyBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlIGltcGxlbWVudHMgSVdvcmtiZW5jaFdpbmRvd0FjdGlvbkRlbGVnYXRlIHsKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nW10gbGF1bmNoTW9kZXMgPSB7CgkJSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUsIElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSB9OwoKCXByb3RlY3RlZCBPYmplY3Qgc2VsZWN0aW9uOwoKCXByb3RlY3RlZCBJV29ya2JlbmNoV2luZG93IHdpbmRvdzsKCglwcm90ZWN0ZWQgc3RhdGljIE9iamVjdCBnbG9iYWxTZWxlY3Rpb247CgoJcHJvdGVjdGVkIHN0YXRpYyBNYXAgZ2xvYmFsTGF1bmNoTW9kZTsKCQoJcHJvdGVjdGVkIGJvb2xlYW4gdGFza3NSdW47CgoJLyoqCgkgKiBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlIGNvbnN0cnVjdG9yIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBSdW5PblNlcnZlckFjdGlvbkRlbGVnYXRlKCkgewoJCXN1cGVyKCk7Cgl9CgoJLyoqCgkgKiBEaXNwb3NlcyB0aGlzIGFjdGlvbiBkZWxlZ2F0ZS4gIFRoZSBpbXBsZW1lbnRvciBzaG91bGQgdW5ob29rIGFueSByZWZlcmVuY2VzCgkgKiB0byBpdHNlbGYgc28gdGhhdCBnYXJiYWdlIGNvbGxlY3Rpb24gY2FuIG9jY3VyLgoJICovCglwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewoJCXdpbmRvdyA9IG51bGw7Cgl9CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIGFjdGlvbiBkZWxlZ2F0ZSB3aXRoIHRoZSB3b3JrYmVuY2ggd2luZG93IGl0IHdpbGwgd29yayBpbi4KCSAqCgkgKiBAcGFyYW0gbmV3V2luZG93IHRoZSB3aW5kb3cgdGhhdCBwcm92aWRlcyB0aGUgY29udGV4dCBmb3IgdGhpcyBkZWxlZ2F0ZQoJICovCglwdWJsaWMgdm9pZCBpbml0KElXb3JrYmVuY2hXaW5kb3cgbmV3V2luZG93KSB7CgkJd2luZG93ID0gbmV3V2luZG93OwoJfQoKCXB1YmxpYyBJU2VydmVyIGdldFNlcnZlcihJTW9kdWxlIG1vZHVsZSwgU3RyaW5nIGxhdW5jaE1vZGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCUlTZXJ2ZXIgc2VydmVyID0gU2VydmVyQ29yZS5nZXREZWZhdWx0U2VydmVyKG1vZHVsZSk7CgkJCgkJLy8gaWdub3JlIHByZWZlcmVuY2UgaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhpcyBtb2RlLgoJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiAhU2VydmVyVUlQbHVnaW4uaXNDb21wYXRpYmxlV2l0aExhdW5jaE1vZGUoc2VydmVyLCBsYXVuY2hNb2RlKSkKCQkJc2VydmVyID0gbnVsbDsKCQkKCQlpZiAoc2VydmVyICE9IG51bGwgJiYgIVNlcnZlclV0aWwuY29udGFpbnNNb2R1bGUoc2VydmVyLCBtb2R1bGUsIG1vbml0b3IpKSB7CgkJCUlTZXJ2ZXJXb3JraW5nQ29weSB3YyA9IHNlcnZlci5jcmVhdGVXb3JraW5nQ29weSgpOwoJCQl0cnkgewoJCQkJU2VydmVyVXRpbC5tb2RpZnlNb2R1bGVzKHdjLCBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sIG5ldyBJTW9kdWxlWzBdLCBtb25pdG9yKTsKCQkJCXdjLnNhdmUoZmFsc2UsIG1vbml0b3IpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3QgYWRkIG1vZHVsZSB0byBzZXJ2ZXIiLCBjZSk7CgkJCQlzZXJ2ZXIgPSBudWxsOwoJCQl9CgkJfQoJCQoJCVNoZWxsIHNoZWxsOwoJCWlmICh3aW5kb3cgIT0gbnVsbCkKCQkJc2hlbGwgPSB3aW5kb3cuZ2V0U2hlbGwoKTsKCQllbHNlCgkJCXNoZWxsID0gU2VydmVyVUlQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRXb3JrYmVuY2goKS5nZXRBY3RpdmVXb3JrYmVuY2hXaW5kb3coKS5nZXRTaGVsbCgpOwoKCQlpZiAoc2VydmVyID09IG51bGwpIHsKCQkJLy8gdHJ5IHRoZSBmdWxsIHdpemFyZAoJCQlSdW5PblNlcnZlcldpemFyZCB3aXphcmQgPSBuZXcgUnVuT25TZXJ2ZXJXaXphcmQobW9kdWxlLCBsYXVuY2hNb2RlKTsKCQkJQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKHNoZWxsLCB3aXphcmQpOwoJCQlpZiAoZGlhbG9nLm9wZW4oKSA9PSBXaW5kb3cuQ0FOQ0VMKSB7CgkJCQlpZiAobW9uaXRvciAhPSBudWxsKQoJCQkJCW1vbml0b3Iuc2V0Q2FuY2VsZWQodHJ1ZSk7CgkJCQlyZXR1cm4gbnVsbDsKCQkJfQoKCQkJdHJ5IHsKCQkJCUpvYi5nZXRKb2JNYW5hZ2VyKCkuam9pbigib3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5mYW1pbHkiLCBudWxsKTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJFcnJvciB3YWl0aW5nIGZvciBqb2IiLCBlKTsKCQkJfQoJCQlzZXJ2ZXIgPSB3aXphcmQuZ2V0U2VydmVyKCk7CgkJCWJvb2xlYW4gcHJlZmVycmVkID0gd2l6YXJkLmlzUHJlZmVycmVkU2VydmVyKCk7CgkJCXRhc2tzUnVuID0gdHJ1ZTsKCgkJCS8vIHNldCBwcmVmZXJyZWQgc2VydmVyIGlmIHJlcXVlc3RlZAoJCQlpZiAoc2VydmVyICE9IG51bGwgJiYgcHJlZmVycmVkKSB7CgkJCQl0cnkgewoJCQkJCVNlcnZlckNvcmUuc2V0RGVmYXVsdFNlcnZlcihtb2R1bGUsIHNlcnZlciwgbW9uaXRvcik7CgkJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQkJU3RyaW5nIG1lc3NhZ2UgPSBNZXNzYWdlcy5lcnJvckNvdWxkTm90U2F2ZVByZWZlcmVuY2U7CgkJCQkJRXJyb3JEaWFsb2cub3BlbkVycm9yKHNoZWxsLCBNZXNzYWdlcy5lcnJvckRpYWxvZ1RpdGxlLCBtZXNzYWdlLCBjZS5nZXRTdGF0dXMoKSk7CgkJCQl9CgkJCX0KCQl9CgkJCgkJdHJ5IHsKCQkJSm9iLmdldEpvYk1hbmFnZXIoKS5qb2luKCJvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmZhbWlseSIsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJFcnJvciB3YWl0aW5nIGZvciBqb2IiLCBlKTsKCQl9CgkJCgkJcmV0dXJuIHNlcnZlcjsKCX0KCgkvKioKCSAqIFJ1biB0aGUgcmVzb3VyY2Ugb24gYSBzZXJ2ZXIuCgkgKi8KCXByb3RlY3RlZCB2b2lkIHJ1bigpIHsKCQlmaW5hbCBTdHJpbmcgbGF1bmNoTW9kZTIgPSBnZXRMYXVuY2hNb2RlKCk7CgkJZmluYWwgSU1vZHVsZUFydGlmYWN0IG1vZHVsZUFydGlmYWN0ID0gU2VydmVyUGx1Z2luLmxvYWRNb2R1bGVBcnRpZmFjdChzZWxlY3Rpb24pOwoJCQoJCVNoZWxsIHNoZWxsMiA9IG51bGw7CgkJaWYgKHdpbmRvdyAhPSBudWxsKQoJCQlzaGVsbDIgPSB3aW5kb3cuZ2V0U2hlbGwoKTsKCQllbHNlIHsKCQkJdHJ5IHsKCQkJCXNoZWxsMiA9IFNlcnZlclVJUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0V29ya2JlbmNoKCkuZ2V0QWN0aXZlV29ya2JlbmNoV2luZG93KCkuZ2V0U2hlbGwoKTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCS8vIGlnbm9yZQoJCQl9CgkJCWlmIChzaGVsbDIgPT0gbnVsbCkKCQkJCXNoZWxsMiA9IERpc3BsYXkuZ2V0RGVmYXVsdCgpLmdldEFjdGl2ZVNoZWxsKCk7CgkJfQoJCWZpbmFsIFNoZWxsIHNoZWxsID0gc2hlbGwyOwoJCQoJCWlmIChtb2R1bGVBcnRpZmFjdCA9PSBudWxsKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihNZXNzYWdlcy5lcnJvck5vQXJ0aWZhY3QpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJObyBtb2R1bGUgYXJ0aWZhY3QgZm91bmQiKTsKCQkJcmV0dXJuOwoJCX0KCQlpZiAobW9kdWxlQXJ0aWZhY3QuZ2V0TW9kdWxlKCkgPT0gbnVsbCkgeyAvLyAxNDk0MjUKCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKE1lc3NhZ2VzLmVycm9yTm9Nb2R1bGVzKTsKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTW9kdWxlIGFydGlmYWN0IG5vdCBjb250YWluZWQgaW4gYSBtb2R1bGUiKTsKCQkJcmV0dXJuOwoJCX0KCQlmaW5hbCBJTW9kdWxlIG1vZHVsZSA9IG1vZHVsZUFydGlmYWN0LmdldE1vZHVsZSgpOwoJCQoJCS8vIGNoZWNrIGZvciBzZXJ2ZXJzIHdpdGggdGhlIGdpdmVuIHN0YXJ0IG1vZGUKCQlJU2VydmVyW10gc2VydmVycyA9IFNlcnZlckNvcmUuZ2V0U2VydmVycygpOwoJCWJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZSAmJiAhZm91bmQ7IGkrKykgewoJCQkJaWYgKFNlcnZlclVJUGx1Z2luLmlzQ29tcGF0aWJsZVdpdGhMYXVuY2hNb2RlKHNlcnZlcnNbaV0sIGxhdW5jaE1vZGUyKSkgewoJCQkJCXRyeSB7CgkJCQkJCUlNb2R1bGVbXSBwYXJlbnRzID0gc2VydmVyc1tpXS5nZXRSb290TW9kdWxlcyhtb2R1bGUsIG51bGwpOwoJCQkJCQlpZiAocGFyZW50cyAhPSBudWxsICYmIHBhcmVudHMubGVuZ3RoID4gMCkKCQkJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCQkvLyBpZ25vcmUKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJCgkJaWYgKCFmb3VuZCkgewoJCQkvLyBubyBleGlzdGluZyBzZXJ2ZXIgc3VwcG9ydHMgdGhlIHByb2plY3QgYW5kIHN0YXJ0IG1vZGUhCgkJCS8vIGNoZWNrIGlmIHRoZXJlIG1pZ2h0IGJlIGFub3RoZXIgb25lIHRoYXQgY2FuIGJlIGNyZWF0ZWQKCQkJSVNlcnZlclR5cGVbXSBzZXJ2ZXJUeXBlcyA9IFNlcnZlckNvcmUuZ2V0U2VydmVyVHlwZXMoKTsKCQkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpIHsKCQkJCWludCBzaXplID0gc2VydmVyVHlwZXMubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplICYmICFmb3VuZDsgaSsrKSB7CgkJCQkJSVNlcnZlclR5cGUgdHlwZSA9IHNlcnZlclR5cGVzW2ldOwoJCQkJCUlNb2R1bGVUeXBlW10gbW9kdWxlVHlwZXMgPSB0eXBlLmdldFJ1bnRpbWVUeXBlKCkuZ2V0TW9kdWxlVHlwZXMoKTsKCQkJCQlpZiAodHlwZS5zdXBwb3J0c0xhdW5jaE1vZGUobGF1bmNoTW9kZTIpICYmIFNlcnZlclV0aWwuaXNTdXBwb3J0ZWRNb2R1bGUobW9kdWxlVHlwZXMsIG1vZHVsZS5nZXRNb2R1bGVUeXBlKCkpKSB7CgkJCQkJCWZvdW5kID0gdHJ1ZTsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJaWYgKCFmb3VuZCkgewoJCQkJRWNsaXBzZVV0aWwub3BlbkVycm9yKE1lc3NhZ2VzLmVycm9yTm9TZXJ2ZXIpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTm8gc2VydmVyIGZvciBzdGFydCBtb2RlIik7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgkJCgkJaWYgKCFTZXJ2ZXJVSVBsdWdpbi5zYXZlRWRpdG9ycygpKQoJCQlyZXR1cm47CgkJCgkJdGFza3NSdW4gPSBmYWxzZTsKCQlJU2VydmVyIHNlcnZlcjIgPSBudWxsOwoJCXRyeSB7CgkJCUlQcm9ncmVzc01vbml0b3IgbW9uaXRvciA9IG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCk7CgkJCXNlcnZlcjIgPSBnZXRTZXJ2ZXIobW9kdWxlLCBsYXVuY2hNb2RlMiwgbW9uaXRvcik7CgkJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJCXJldHVybjsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihzaGVsbCwgY2UuZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKCQkJcmV0dXJuOwoJCX0KCQlmaW5hbCBJU2VydmVyIHNlcnZlciA9IHNlcnZlcjI7CgkJLy9pZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJLy8JcmV0dXJuOwoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlcnZlcjogIiArIHNlcnZlcik7CgkJCgkJaWYgKHNlcnZlciA9PSBudWxsKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihNZXNzYWdlcy5lcnJvck5vU2VydmVyKTsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiTm8gc2VydmVyIGZvdW5kIik7CgkJCXJldHVybjsKCQl9CgkJCgkJaWYgKCFTZXJ2ZXJVSVBsdWdpbi5wcm9tcHRJZkRpcnR5KHNoZWxsLCBzZXJ2ZXIpKQoJCQlyZXR1cm47CgkJCgkJaWYgKCF0YXNrc1J1bikgewoJCQlTZWxlY3RUYXNrc1dpemFyZCB3aXphcmQgPSBuZXcgU2VsZWN0VGFza3NXaXphcmQoc2VydmVyKTsKCQkJd2l6YXJkLmFkZFBhZ2VzKCk7CgkJCWlmICh3aXphcmQuaGFzVGFza3MoKSAmJiB3aXphcmQuaGFzT3B0aW9uYWxUYXNrcygpKSB7CgkJCQlXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IFdpemFyZERpYWxvZyhzaGVsbCwgd2l6YXJkKTsKCQkJCWlmIChkaWFsb2cub3BlbigpID09IFdpbmRvdy5DQU5DRUwpCgkJCQkJcmV0dXJuOwoJCQl9IGVsc2UKCQkJCXdpemFyZC5wZXJmb3JtRmluaXNoKCk7CgkJfQoJCQoJCVRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKCJSdW4gb24gU2VydmVyIikgewoJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQlTdHJpbmcgbGF1bmNoTW9kZSA9IGxhdW5jaE1vZGUyOwoJCQkJCgkJCQkvLyBnZXQgdGhlIGxhdW5jaGFibGUgYWRhcHRlciBhbmQgbW9kdWxlIG9iamVjdAoJCQkJSUxhdW5jaGFibGVBZGFwdGVyIGxhdW5jaGFibGVBZGFwdGVyID0gbnVsbDsKCQkJCU9iamVjdCBsYXVuY2hhYmxlID0gbnVsbDsKCQkJCUlMYXVuY2hhYmxlQWRhcHRlcltdIGFkYXB0ZXJzID0gU2VydmVyUGx1Z2luLmdldExhdW5jaGFibGVBZGFwdGVycygpOwoJCQkJaWYgKGFkYXB0ZXJzICE9IG51bGwpIHsKCQkJCQlpbnQgc2l6ZTIgPSBhZGFwdGVycy5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMjsgaisrKSB7CgkJCQkJCUlMYXVuY2hhYmxlQWRhcHRlciBhZGFwdGVyID0gYWRhcHRlcnNbal07CgkJCQkJCXRyeSB7CgkJCQkJCQlPYmplY3QgbGF1bmNoYWJsZTIgPSBhZGFwdGVyLmdldExhdW5jaGFibGUoc2VydmVyLCBtb2R1bGVBcnRpZmFjdCk7CgkJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJhZGFwdGVyPSAiICsgYWRhcHRlciArICIsIGxhdW5jaGFibGU9ICIgKyBsYXVuY2hhYmxlMik7CgkJCQkJCQlpZiAobGF1bmNoYWJsZTIgIT0gbnVsbCkgewoJCQkJCQkJCWxhdW5jaGFibGVBZGFwdGVyID0gYWRhcHRlcjsKCQkJCQkJCQlsYXVuY2hhYmxlID0gbGF1bmNoYWJsZTI7CgkJCQkJCQl9CgkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBpbiBsYXVuY2hhYmxlIGFkYXB0ZXIiLCBlKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCQoJCQkJSUNsaWVudFtdIGNsaWVudHMgPSBuZXcgSUNsaWVudFswXTsKCQkJCWlmIChsYXVuY2hhYmxlICE9IG51bGwpCgkJCQkJY2xpZW50cyA9IGdldENsaWVudHMoc2VydmVyLCBsYXVuY2hhYmxlLCBsYXVuY2hNb2RlKTsKCQkJCQoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTGF1bmNoYWJsZSBjbGllbnRzOiAiICsgY2xpZW50cyk7CgkJCQkKCQkJCUlDbGllbnQgY2xpZW50ID0gbnVsbDsKCQkJCWlmIChjbGllbnRzID09IG51bGwgfHwgY2xpZW50cy5sZW5ndGggPT0gMCkgewoJCQkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihNZXNzYWdlcy5lcnJvck5vQ2xpZW50KTsKCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJObyBsYXVuY2hhYmxlIGNsaWVudHMhIik7CgkJCQkJcmV0dXJuOwoJCQkJfSBlbHNlIGlmIChjbGllbnRzLmxlbmd0aCA9PSAxKSB7CgkJCQkJY2xpZW50ID0gY2xpZW50c1swXTsKCQkJCX0gZWxzZSB7CgkJCQkJU2VsZWN0Q2xpZW50V2l6YXJkIHdpemFyZCA9IG5ldyBTZWxlY3RDbGllbnRXaXphcmQoY2xpZW50cyk7CgkJCQkJZmluYWwgQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKHNoZWxsLCB3aXphcmQpOwoJCQkJCXNoZWxsLmdldERpc3BsYXkoKS5zeW5jRXhlYyhuZXcgUnVubmFibGUoKSB7CgkJCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsKCQkJCQkJCWRpYWxvZy5vcGVuKCk7CgkJCQkJCX0KCQkJCQl9KTsKCQkJCQljbGllbnQgPSB3aXphcmQuZ2V0U2VsZWN0ZWRDbGllbnQoKTsKCQkJCQlpZiAoY2xpZW50ID09IG51bGwpCgkJCQkJCXJldHVybjsKCQkJCX0KCQkJCQoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiUmVhZHkgdG8gbGF1bmNoIik7CgkJCQkKCQkJCS8vIHN0YXJ0IHNlcnZlciBpZiBpdCdzIG5vdCBhbHJlYWR5IHN0YXJ0ZWQKCQkJCS8vIGFuZCBjdWUgdGhlIGNsaWVudCB0byBzdGFydAoJCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH07IC8vIFRPRE86IGdldCBwYXJlbnQgaGVpcmFyY2h5IGNvcnJlY3QKCQkJCWludCBzdGF0ZSA9IHNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpOwoJCQkJaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RBUlRJTkcpIHsKCQkJCQlMYXVuY2hDbGllbnRKb2IgY2xpZW50Sm9iID0gbmV3IExhdW5jaENsaWVudEpvYihzZXJ2ZXIsIG1vZHVsZXMsIGxhdW5jaE1vZGUsIG1vZHVsZUFydGlmYWN0LCBsYXVuY2hhYmxlQWRhcHRlciwgY2xpZW50KTsKCQkJCQljbGllbnRKb2Iuc2NoZWR1bGUoKTsKCQkJCX0gZWxzZSBpZiAoc3RhdGUgPT0gSVNlcnZlci5TVEFURV9TVEFSVEVEKSB7CgkJCQkJYm9vbGVhbiByZXN0YXJ0ID0gZmFsc2U7CgkJCQkJU3RyaW5nIG1vZGUgPSBzZXJ2ZXIuZ2V0TW9kZSgpOwoJCQkJCUlCcmVha3BvaW50TWFuYWdlciBicmVha3BvaW50TWFuYWdlciA9IERlYnVnUGx1Z2luLmdldERlZmF1bHQoKS5nZXRCcmVha3BvaW50TWFuYWdlcigpOwoJCQkJCWJvb2xlYW4gZGlzYWJsZWRCcmVha3BvaW50cyA9IGZhbHNlOwoJCQkJCQoJCQkJCWlmICghSUxhdW5jaE1hbmFnZXIuUlVOX01PREUuZXF1YWxzKG1vZGUpICYmIElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJCQlib29sZWFuIGJyZWFrcG9pbnRzT3B0aW9uID0gZmFsc2U7CgkJCQkJCWlmIChicmVha3BvaW50TWFuYWdlci5pc0VuYWJsZWQoKSAmJiBJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLmVxdWFscyhtb2RlKSkKCQkJCQkJCWJyZWFrcG9pbnRzT3B0aW9uID0gdHJ1ZTsKCQkJCQkJaW50IHJlc3VsdCA9IG9wZW5PcHRpb25zRGlhbG9nKHNoZWxsLCBNZXNzYWdlcy53aXpSdW5PblNlcnZlclRpdGxlLCBNZXNzYWdlcy5kaWFsb2dNb2RlV2FybmluZ1J1biwgYnJlYWtwb2ludHNPcHRpb24pOwoJCQkJCQlpZiAocmVzdWx0ID09IDApCgkJCQkJCQlyZXN0YXJ0ID0gdHJ1ZTsKCQkJCQkJZWxzZSBpZiAocmVzdWx0ID09IDEpIHsKCQkJCQkJCWJyZWFrcG9pbnRNYW5hZ2VyLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJCQkJZGlzYWJsZWRCcmVha3BvaW50cyA9IHRydWU7CgkJCQkJCQlsYXVuY2hNb2RlID0gbW9kZTsKCQkJCQkJfSBlbHNlIGlmIChyZXN1bHQgPT0gMikKCQkJCQkJCWxhdW5jaE1vZGUgPSBtb2RlOwoJCQkJCQllbHNlIC8vIHJlc3VsdCA9PSA5CgkJCQkJCQlyZXR1cm47CgkJCQkJfSBlbHNlIGlmICghSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERS5lcXVhbHMobW9kZSkgJiYgSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERS5lcXVhbHMobGF1bmNoTW9kZSkpIHsKCQkJCQkJaW50IHJlc3VsdCA9IG9wZW5PcHRpb25zRGlhbG9nKHNoZWxsLCBNZXNzYWdlcy53aXpEZWJ1Z09uU2VydmVyVGl0bGUsIE1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nRGVidWcsIGZhbHNlKTsKCQkJCQkJaWYgKHJlc3VsdCA9PSAwKQoJCQkJCQkJcmVzdGFydCA9IHRydWU7CgkJCQkJCWVsc2UgaWYgKHJlc3VsdCA9PSAxKQoJCQkJCQkJbGF1bmNoTW9kZSA9IG1vZGU7CgkJCQkJCWVsc2UgLy8gcmVzdWx0ID09IDkKCQkJCQkJCXJldHVybjsKCQkJCQl9IGVsc2UgaWYgKCFJTGF1bmNoTWFuYWdlci5QUk9GSUxFX01PREUuZXF1YWxzKG1vZGUpICYmIElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERS5lcXVhbHMobGF1bmNoTW9kZSkpIHsKCQkJCQkJYm9vbGVhbiBicmVha3BvaW50c09wdGlvbiA9IGZhbHNlOwoJCQkJCQlpZiAoYnJlYWtwb2ludE1hbmFnZXIuaXNFbmFibGVkKCkgJiYgSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERS5lcXVhbHMobW9kZSkpCgkJCQkJCQlicmVha3BvaW50c09wdGlvbiA9IHRydWU7CgkJCQkJCWludCByZXN1bHQgPSBvcGVuT3B0aW9uc0RpYWxvZyhzaGVsbCwgTWVzc2FnZXMud2l6UHJvZmlsZU9uU2VydmVyVGl0bGUsIE1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nUHJvZmlsZSwgYnJlYWtwb2ludHNPcHRpb24pOwoJCQkJCQlpZiAocmVzdWx0ID09IDApCgkJCQkJCQlyZXN0YXJ0ID0gdHJ1ZTsKCQkJCQkJZWxzZSBpZiAocmVzdWx0ID09IDEpIHsKCQkJCQkJCWJyZWFrcG9pbnRNYW5hZ2VyLnNldEVuYWJsZWQoZmFsc2UpOwoJCQkJCQkJZGlzYWJsZWRCcmVha3BvaW50cyA9IHRydWU7CgkJCQkJCQlsYXVuY2hNb2RlID0gbW9kZTsKCQkJCQkJfSBlbHNlIGlmIChyZXN1bHQgPT0gMikKCQkJCQkJCWxhdW5jaE1vZGUgPSBtb2RlOwoJCQkJCQllbHNlIC8vIHJlc3VsdCA9PSA5CgkJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJCQoJCQkJCWlmIChJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJCQlpZiAoIWJyZWFrcG9pbnRNYW5hZ2VyLmlzRW5hYmxlZCgpICYmICFkaXNhYmxlZEJyZWFrcG9pbnRzKSB7CgkJCQkJCQlpbnQgcmVzdWx0ID0gb3BlbkJyZWFrcG9pbnREaWFsb2coc2hlbGwpOwoJCQkJCQkJaWYgKHJlc3VsdCA9PSAwKQoJCQkJCQkJCWJyZWFrcG9pbnRNYW5hZ2VyLnNldEVuYWJsZWQodHJ1ZSk7CgkJCQkJCQllbHNlIGlmIChyZXN1bHQgPT0gMSkgewoJCQkJCQkJCS8vIGlnbm9yZQoJCQkJCQkJfSBlbHNlIC8vIHJlc3VsdCA9PSAyCgkJCQkJCQkJcmV0dXJuOwoJCQkJCQl9CgkJCQkJfQoJCQkJCQoJCQkJCVB1Ymxpc2hTZXJ2ZXJKb2IgcHVibGlzaEpvYiA9IG5ldyBQdWJsaXNoU2VydmVySm9iKHNlcnZlciwgSVNlcnZlci5QVUJMSVNIX0lOQ1JFTUVOVEFMLCBmYWxzZSk7CgkJCQkJTGF1bmNoQ2xpZW50Sm9iIGNsaWVudEpvYiA9IG5ldyBMYXVuY2hDbGllbnRKb2Ioc2VydmVyLCBtb2R1bGVzLCBsYXVuY2hNb2RlLCBtb2R1bGVBcnRpZmFjdCwgbGF1bmNoYWJsZUFkYXB0ZXIsIGNsaWVudCk7CgkJCQkJcHVibGlzaEpvYi5zZXROZXh0Sm9iKGNsaWVudEpvYik7CgkJCQkJCgkJCQkJaWYgKHJlc3RhcnQpIHsKCQkJCQkJUmVzdGFydFNlcnZlckpvYiByZXN0YXJ0Sm9iID0gbmV3IFJlc3RhcnRTZXJ2ZXJKb2Ioc2VydmVyLCBsYXVuY2hNb2RlKTsKCQkJCQkJcmVzdGFydEpvYi5zZXROZXh0Sm9iKHB1Ymxpc2hKb2IpOwoJCQkJCQlyZXN0YXJ0Sm9iLnNjaGVkdWxlKCk7CgkJCQkJfSBlbHNlCgkJCQkJCXB1Ymxpc2hKb2Iuc2NoZWR1bGUoKTsKCQkJCX0gZWxzZSBpZiAoc3RhdGUgIT0gSVNlcnZlci5TVEFURV9TVE9QUElORykgewoJCQkJCVB1Ymxpc2hTZXJ2ZXJKb2IgcHVibGlzaEpvYiA9IG5ldyBQdWJsaXNoU2VydmVySm9iKHNlcnZlcik7CgkJCQkJU3RhcnRTZXJ2ZXJKb2Igc3RhcnRTZXJ2ZXJKb2IgPSBuZXcgU3RhcnRTZXJ2ZXJKb2Ioc2VydmVyLCBsYXVuY2hNb2RlKTsKCQkJCQlMYXVuY2hDbGllbnRKb2IgY2xpZW50Sm9iID0gbmV3IExhdW5jaENsaWVudEpvYihzZXJ2ZXIsIG1vZHVsZXMsIGxhdW5jaE1vZGUsIG1vZHVsZUFydGlmYWN0LCBsYXVuY2hhYmxlQWRhcHRlciwgY2xpZW50KTsKCQkJCQkKCQkJCQlpZiAoKChTZXJ2ZXJUeXBlKXNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkpLnN0YXJ0QmVmb3JlUHVibGlzaCgpKSB7CgkJCQkJCXN0YXJ0U2VydmVySm9iLnNldE5leHRKb2IocHVibGlzaEpvYik7CgkJCQkJCXB1Ymxpc2hKb2Iuc2V0TmV4dEpvYihjbGllbnRKb2IpOwoJCQkJCQlzdGFydFNlcnZlckpvYi5zY2hlZHVsZSgpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXB1Ymxpc2hKb2Iuc2V0TmV4dEpvYihzdGFydFNlcnZlckpvYik7CgkJCQkJCXN0YXJ0U2VydmVySm9iLnNldE5leHRKb2IoY2xpZW50Sm9iKTsKCQkJCQkJcHVibGlzaEpvYi5zY2hlZHVsZSgpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX07CgkJdGhyZWFkLnNldERhZW1vbih0cnVlKTsKCQl0aHJlYWQuc3RhcnQoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGxhdW5jaGFibGUgY2xpZW50cyBmb3IgdGhlIGdpdmVuIHNlcnZlciBhbmQgbGF1bmNoYWJsZQoJICogb2JqZWN0LgoJICoKCSAqIEBwYXJhbSBzZXJ2ZXIgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXIKCSAqIEBwYXJhbSBsYXVuY2hhYmxlCgkgKiBAcGFyYW0gbGF1bmNoTW9kZSBTdHJpbmcKCSAqIEByZXR1cm4gYW4gYXJyYXkgb2YgY2xpZW50cwoJICovCglwdWJsaWMgc3RhdGljIElDbGllbnRbXSBnZXRDbGllbnRzKElTZXJ2ZXIgc2VydmVyLCBPYmplY3QgbGF1bmNoYWJsZSwgU3RyaW5nIGxhdW5jaE1vZGUpIHsKCQlBcnJheUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJQ2xpZW50W10gY2xpZW50cyA9IFNlcnZlclBsdWdpbi5nZXRDbGllbnRzKCk7CgkJaWYgKGNsaWVudHMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGNsaWVudHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiY2xpZW50PSAiICsgY2xpZW50c1tpXSk7CgkJCQlpZiAoY2xpZW50c1tpXS5zdXBwb3J0cyhzZXJ2ZXIsIGxhdW5jaGFibGUsIGxhdW5jaE1vZGUpKQoJCQkJCWxpc3QuYWRkKGNsaWVudHNbaV0pOwoJCQl9CgkJfQoJCQoJCUlDbGllbnRbXSBjbGllbnRzMiA9IG5ldyBJQ2xpZW50W2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkoY2xpZW50czIpOwoJCXJldHVybiBjbGllbnRzMjsKCX0KCgkvKioKCSAqIE9wZW4gYW4gb3B0aW9ucyBkaWFsb2cuCgkgKiAKCSAqIEBwYXJhbSBzaGVsbAoJICogQHBhcmFtIHRpdGxlCgkgKiBAcGFyYW0gbWVzc2FnZQoJICogQHBhcmFtIGJyZWFrcG9pbnRzT3B0aW9uCgkgKiBAcmV0dXJuIGEgZGlhbG9nIHJldHVybiBjb25zdGFudAoJICovCglwcm90ZWN0ZWQgaW50IG9wZW5PcHRpb25zRGlhbG9nKGZpbmFsIFNoZWxsIHNoZWxsLCBmaW5hbCBTdHJpbmcgdGl0bGUsIGZpbmFsIFN0cmluZyBtZXNzYWdlLCBmaW5hbCBib29sZWFuIGJyZWFrcG9pbnRzT3B0aW9uKSB7CgkJaWYgKGJyZWFrcG9pbnRzT3B0aW9uKSB7CgkJCWludCBjdXJyZW50ID0gU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5nZXRMYXVuY2hNb2RlMigpOwoJCQlpZiAoY3VycmVudCA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLkxBVU5DSF9NT0RFMl9SRVNUQVJUKQoJCQkJcmV0dXJuIDA7CgkJCWVsc2UgaWYgKGN1cnJlbnQgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERTJfRElTQUJMRV9CUkVBS1BPSU5UUykKCQkJCXJldHVybiAxOwoJCQllbHNlIGlmIChjdXJyZW50ID09IFNlcnZlclVJUHJlZmVyZW5jZXMuTEFVTkNIX01PREUyX0NPTlRJTlVFKQoJCQkJcmV0dXJuIDI7CgkJfSBlbHNlIHsKCQkJaW50IGN1cnJlbnQgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLmdldExhdW5jaE1vZGUoKTsKCQkJaWYgKGN1cnJlbnQgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERV9SRVNUQVJUKQoJCQkJcmV0dXJuIDA7CgkJCWVsc2UgaWYgKGN1cnJlbnQgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERV9DT05USU5VRSkKCQkJCXJldHVybiAxOwoJCX0KCQlmaW5hbCBpbnRbXSBpID0gbmV3IGludFsxXTsKCQlzaGVsbC5nZXREaXNwbGF5KCkuc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQlPcHRpb25zTWVzc2FnZURpYWxvZyBkaWFsb2cgPSBudWxsOwoJCQkJU3RyaW5nW10gaXRlbXMgPSBudWxsOwoJCQkJaWYgKGJyZWFrcG9pbnRzT3B0aW9uKSB7CgkJCQkJaXRlbXMgPSBuZXcgU3RyaW5nW10gewoJCQkJCQlNZXNzYWdlcy5kaWFsb2dNb2RlV2FybmluZ1Jlc3RhcnQsCgkJCQkJCU1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nQnJlYWtwb2ludHMsCgkJCQkJCU1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nQ29udGludWUKCQkJCQl9OwoJCQkJfSBlbHNlIHsKCQkJCQlpdGVtcyA9IG5ldyBTdHJpbmdbXSB7CgkJCQkJCU1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nUmVzdGFydCwKCQkJCQkJTWVzc2FnZXMuZGlhbG9nTW9kZVdhcm5pbmdDb250aW51ZQoJCQkJCX07CgkJCQl9CgkJCQkKCQkJCWRpYWxvZyA9IG5ldyBPcHRpb25zTWVzc2FnZURpYWxvZyhzaGVsbCwgdGl0bGUsIG1lc3NhZ2UsIGl0ZW1zKTsKCQkJCWlbMF0gPSBkaWFsb2cub3BlbigpOwoJCQkJCgkJCQlpZiAoZGlhbG9nLmlzUmVtZW1iZXIoKSkgewoJCQkJCWlmIChicmVha3BvaW50c09wdGlvbikgewoJCQkJCQlpZiAoaVswXSA9PSAwKQoJCQkJCQkJU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5zZXRMYXVuY2hNb2RlMihTZXJ2ZXJVSVByZWZlcmVuY2VzLkxBVU5DSF9NT0RFMl9SRVNUQVJUKTsKCQkJCQkJZWxzZSBpZiAoaVswXSA9PSAxKQoJCQkJCQkJU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5zZXRMYXVuY2hNb2RlMihTZXJ2ZXJVSVByZWZlcmVuY2VzLkxBVU5DSF9NT0RFMl9ESVNBQkxFX0JSRUFLUE9JTlRTKTsKCQkJCQkJZWxzZSBpZiAoaVswXSA9PSAyKQoJCQkJCQkJU2VydmVyVUlQbHVnaW4uZ2V0UHJlZmVyZW5jZXMoKS5zZXRMYXVuY2hNb2RlMihTZXJ2ZXJVSVByZWZlcmVuY2VzLkxBVU5DSF9NT0RFMl9DT05USU5VRSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJaWYgKGlbMF0gPT0gMCkKCQkJCQkJCVNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuc2V0TGF1bmNoTW9kZShTZXJ2ZXJVSVByZWZlcmVuY2VzLkxBVU5DSF9NT0RFX1JFU1RBUlQpOwoJCQkJCQllbHNlIGlmIChpWzBdID09IDEpCgkJCQkJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLnNldExhdW5jaE1vZGUoU2VydmVyVUlQcmVmZXJlbmNlcy5MQVVOQ0hfTU9ERV9DT05USU5VRSk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfSk7CgkJcmV0dXJuIGlbMF07Cgl9CgoJLyoqCgkgKiBPcGVuIGFuIG9wdGlvbnMgZGlhbG9nLgoJICogCgkgKiBAcGFyYW0gc2hlbGwKCSAqIEByZXR1cm4gYSBkaWFsb2cgcmV0dXJuIGNvbnN0YW50CgkgKi8KCXByb3RlY3RlZCBpbnQgb3BlbkJyZWFrcG9pbnREaWFsb2coZmluYWwgU2hlbGwgc2hlbGwpIHsKCQlpbnQgY3VycmVudCA9IFNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuZ2V0RW5hYmxlQnJlYWtwb2ludHMoKTsKCQlpZiAoY3VycmVudCA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLkVOQUJMRV9CUkVBS1BPSU5UU19BTFdBWVMpCgkJCXJldHVybiAwOwoJCWVsc2UgaWYgKGN1cnJlbnQgPT0gU2VydmVyVUlQcmVmZXJlbmNlcy5FTkFCTEVfQlJFQUtQT0lOVFNfTkVWRVIpCgkJCXJldHVybiAxOwoJCQoJCWZpbmFsIGludFtdIGkgPSBuZXcgaW50WzFdOwoJCXNoZWxsLmdldERpc3BsYXkoKS5zeW5jRXhlYyhuZXcgUnVubmFibGUoKSB7CgkJCXB1YmxpYyB2b2lkIHJ1bigpIHsKCQkJCS8vQnJlYWtwb2ludERpYWxvZyBkaWFsb2cgPSBuZXcgQnJlYWtwb2ludERpYWxvZyhzaGVsbCk7CgkJCQlPcHRpb25zTWVzc2FnZURpYWxvZyBkaWFsb2cgPSBuZXcgT3B0aW9uc01lc3NhZ2VEaWFsb2coc2hlbGwsCgkJCQkJCU1lc3NhZ2VzLndpekRlYnVnT25TZXJ2ZXJUaXRsZSwgTWVzc2FnZXMuZGlhbG9nQnJlYWtwb2ludHMsIG5ldyBTdHJpbmdbXSB7CgkJCQkJCU1lc3NhZ2VzLmRpYWxvZ0JyZWFrcG9pbnRzUmVlbmFibGUsCU1lc3NhZ2VzLmRpYWxvZ01vZGVXYXJuaW5nQ29udGludWV9KTsKCQkJCWlbMF0gPSBkaWFsb2cub3BlbigpOwoJCQkJaWYgKGRpYWxvZy5pc1JlbWVtYmVyKCkpIHsKCQkJCQlpZiAoaVswXSA9PSAwKQoJCQkJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLnNldEVuYWJsZUJyZWFrcG9pbnRzKFNlcnZlclVJUHJlZmVyZW5jZXMuRU5BQkxFX0JSRUFLUE9JTlRTX0FMV0FZUyk7CgkJCQkJZWxzZSBpZiAoaVswXSA9PSAxKQoJCQkJCQlTZXJ2ZXJVSVBsdWdpbi5nZXRQcmVmZXJlbmNlcygpLnNldEVuYWJsZUJyZWFrcG9pbnRzKFNlcnZlclVJUHJlZmVyZW5jZXMuRU5BQkxFX0JSRUFLUE9JTlRTX05FVkVSKTsKCQkJCX0KCQkJfQoJCX0pOwoJCXJldHVybiBpWzBdOwoJfQoKCS8qKgoJICogVGhlIGRlbGVnYXRpbmcgYWN0aW9uIGhhcyBiZWVuIHBlcmZvcm1lZC4gSW1wbGVtZW50CgkgKiB0aGlzIG1ldGhvZCB0byBkbyB0aGUgYWN0dWFsIHdvcmsuCgkgKgoJICogQHBhcmFtIGFjdGlvbiBhY3Rpb24gcHJveHkgdGhhdCBoYW5kbGVzIHRoZSBwcmVzZW50YXRpb24KCSAqIHBvcnRpb24gb2YgdGhlIHBsdWdpbiBhY3Rpb24KCSAqLwoJcHVibGljIHZvaWQgcnVuKElBY3Rpb24gYWN0aW9uKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiUnVubmluZyBvbiBTZXJ2ZXIuLi4iKTsKCQl0cnkgewoJCQlydW4oKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJSdW4gb24gU2VydmVyIEVycm9yIiwgZSk7CgkJfQoJfQoJCglwcm90ZWN0ZWQgYm9vbGVhbiBpc0VuYWJsZWQoKSB7CgkJdHJ5IHsKCQkJQm9vbGVhbiBiID0gKEJvb2xlYW4pIGdsb2JhbExhdW5jaE1vZGUuZ2V0KGdldExhdW5jaE1vZGUoKSk7CgkJCXJldHVybiBiLmJvb2xlYW5WYWx1ZSgpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzdGFydCBtb2RlIHRoYXQgdGhlIHNlcnZlciBzaG91bGQgdXNlLgoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGdldExhdW5jaE1vZGUoKSB7CgkJcmV0dXJuIElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFOwoJfQoKCS8qKgoJICogRGV0ZXJtaW5lIHdoaWNoIGNsaWVudHMgY2FuIGFjdCBvbiB0aGUgY3VycmVudCBzZWxlY3Rpb24uCgkgKgoJICogQHBhcmFtIGFjdGlvbiBhY3Rpb24gcHJveHkgdGhhdCBoYW5kbGVzIHByZXNlbnRhdGlvbgoJICogICAgcG9ydGlvbiBvZiB0aGUgcGx1Z2luIGFjdGlvbgoJICogQHBhcmFtIHNlbCBjdXJyZW50IHNlbGVjdGlvbiBpbiB0aGUgZGVza3RvcAoJICovCglwdWJsaWMgdm9pZCBzZWxlY3Rpb25DaGFuZ2VkKElBY3Rpb24gYWN0aW9uLCBJU2VsZWN0aW9uIHNlbCkgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIj4gc2VsZWN0aW9uQ2hhbmdlZCIpOwoJCXNlbGVjdGlvbiA9IG51bGw7CgkJbG9uZyB0aW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgkJaWYgKHNlbCA9PSBudWxsIHx8IHNlbC5pc0VtcHR5KCkgfHwgIShzZWwgaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikpIHsKCQkJYWN0aW9uLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlnbG9iYWxTZWxlY3Rpb24gPSBudWxsOwoJCQlyZXR1cm47CgkJfQoKCQlJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWxlY3QgPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHNlbDsKCQlJdGVyYXRvciBpdGVyYXRvciA9IHNlbGVjdC5pdGVyYXRvcigpOwoJCWlmIChpdGVyYXRvci5oYXNOZXh0KCkpCgkJCXNlbGVjdGlvbiA9IGl0ZXJhdG9yLm5leHQoKTsKCQlpZiAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7IC8vIG1vcmUgdGhhbiBvbmUgc2VsZWN0aW9uIChzaG91bGQgbmV2ZXIgaGFwcGVuKQoJCQlhY3Rpb24uc2V0RW5hYmxlZChmYWxzZSk7CgkJCXNlbGVjdGlvbiA9IG51bGw7CgkJCWdsb2JhbFNlbGVjdGlvbiA9IG51bGw7CgkJCXJldHVybjsKCQl9CgoJCWlmIChzZWxlY3Rpb24gIT0gZ2xvYmFsU2VsZWN0aW9uKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlbGVjdGlvbjogIiArIHNlbGVjdGlvbik7CgkJCWlmIChzZWxlY3Rpb24gIT0gbnVsbCkJCgkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJTZWxlY3Rpb24gdHlwZTogIiArIHNlbGVjdGlvbi5nZXRDbGFzcygpLmdldE5hbWUoKSk7CgkJCWdsb2JhbFNlbGVjdGlvbiA9IHNlbGVjdGlvbjsKCQkJZ2xvYmFsTGF1bmNoTW9kZSA9IG5ldyBIYXNoTWFwKCk7CgkJCWlmICghU2VydmVyUGx1Z2luLmhhc01vZHVsZUFydGlmYWN0KGdsb2JhbFNlbGVjdGlvbikpIHsKCQkJCWFjdGlvbi5zZXRFbmFibGVkKGZhbHNlKTsKCQkJCXJldHVybjsKCQkJfQoJCQkKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiY2hlY2tpbmcgZm9yIG1vZHVsZSBhcnRpZmFjdCIpOwoJCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlQXJ0aWZhY3QgPSBTZXJ2ZXJQbHVnaW4uZ2V0TW9kdWxlQXJ0aWZhY3QoZ2xvYmFsU2VsZWN0aW9uKTsKCQkJSU1vZHVsZSBtb2R1bGUgPSBudWxsOwoJCQlpZiAobW9kdWxlQXJ0aWZhY3QgIT0gbnVsbCkKCQkJCW1vZHVsZSA9IG1vZHVsZUFydGlmYWN0LmdldE1vZHVsZSgpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJtb2R1bGVBcnRpZmFjdD0gIiArIG1vZHVsZUFydGlmYWN0ICsgIiwgbW9kdWxlPSAiICsgbW9kdWxlKTsKCQkJaWYgKG1vZHVsZSAhPSBudWxsKQoJCQkJZmluZEdsb2JhbExhdW5jaE1vZGVzKG1vZHVsZSk7CgkJCWVsc2UgewoJCQkJZ2xvYmFsTGF1bmNoTW9kZS5wdXQoSUxhdW5jaE1hbmFnZXIuUlVOX01PREUsIG5ldyBCb29sZWFuKHRydWUpKTsKCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KElMYXVuY2hNYW5hZ2VyLkRFQlVHX01PREUsIG5ldyBCb29sZWFuKHRydWUpKTsKCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KElMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERSwgbmV3IEJvb2xlYW4odHJ1ZSkpOwoJCQl9CgkJfQoKCQlhY3Rpb24uc2V0RW5hYmxlZChpc0VuYWJsZWQoKSk7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiPCBzZWxlY3Rpb25DaGFuZ2VkICIgKyAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSB0aW1lKSk7Cgl9CgkKCS8qKgoJICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZXJlIGlzIGEgc2VydmVyIGZhY3RvcnkgYXZhaWxhYmxlIGZvciB0aGUgZ2l2ZW4gbW9kdWxlCgkgKiBhbmQgdGhlIHZhcmlvdXMgc3RhcnQgbW9kZXMuCgkgKi8KCXByb3RlY3RlZCB2b2lkIGZpbmRHbG9iYWxMYXVuY2hNb2RlcyhJTW9kdWxlIG1vZHVsZSkgewoJCUlTZXJ2ZXJUeXBlW10gc2VydmVyVHlwZXMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlclR5cGVzKCk7CgkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJUeXBlcy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlJU2VydmVyVHlwZSB0eXBlID0gc2VydmVyVHlwZXNbaV07CgkJCQlpZiAoaXNWYWxpZFNlcnZlclR5cGUodHlwZSwgbW9kdWxlKSkgewoJCQkJCWZvciAoYnl0ZSBiID0gMDsgYiA8IGxhdW5jaE1vZGVzLmxlbmd0aDsgYisrKSB7CgkJCQkJCWlmICh0eXBlLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2Rlc1tiXSkpIHsKCQkJCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KGxhdW5jaE1vZGVzW2JdLCBuZXcgQm9vbGVhbih0cnVlKSk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHNlcnZlciB0eXBlIGNhbiBsYXVuY2ggdGhlIG1vZHVsZS4gCgkgKi8KCXByb3RlY3RlZCBib29sZWFuIGlzVmFsaWRTZXJ2ZXJUeXBlKElTZXJ2ZXJUeXBlIHR5cGUsIElNb2R1bGUgbW9kdWxlKSB7CgkJdHJ5IHsKCQkJSVJ1bnRpbWVUeXBlIHJ1bnRpbWVUeXBlID0gdHlwZS5nZXRSdW50aW1lVHlwZSgpOwoJCQlTZXJ2ZXJVdGlsLmlzU3VwcG9ydGVkTW9kdWxlKHJ1bnRpbWVUeXBlLmdldE1vZHVsZVR5cGVzKCksIG1vZHVsZS5nZXRNb2R1bGVUeXBlKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJcmV0dXJuIHRydWU7Cgl9CgoJcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNMYXVuY2hNb2RlKElTZXJ2ZXIgc2VydmVyLCBTdHJpbmcgbGF1bmNoTW9kZSkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0U2VydmVyVHlwZSgpLnN1cHBvcnRzTGF1bmNoTW9kZShsYXVuY2hNb2RlKTsKCX0KfQ==