LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogCiAqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5wb2xpY2llczsKCmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLkVBbm5vdGF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZ2VmLmNvbW1hbmRzLkNvbW1hbmQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5jb21tb24uY29yZS5jb21tYW5kLklDb21wb3NpdGVDb21tYW5kOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS5jb3JlLmNvbW1hbmRzLkRlbGV0ZUNvbW1hbmQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5lbWYuY29tbWFuZHMuY29yZS5jb21tYW5kLkNvbXBvc2l0ZVRyYW5zYWN0aW9uYWxDb21tYW5kOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZW1mLnR5cGUuY29yZS5jb21tYW5kcy5EZXN0cm95RWxlbWVudENvbW1hbmQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5lbWYudHlwZS5jb3JlLmNvbW1hbmRzLkRlc3Ryb3lSZWZlcmVuY2VDb21tYW5kOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZW1mLnR5cGUuY29yZS5yZXF1ZXN0cy5DcmVhdGVSZWxhdGlvbnNoaXBSZXF1ZXN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZW1mLnR5cGUuY29yZS5yZXF1ZXN0cy5EZXN0cm95RWxlbWVudFJlcXVlc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5lbWYudHlwZS5jb3JlLnJlcXVlc3RzLkRlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZW1mLnR5cGUuY29yZS5yZXF1ZXN0cy5SZW9yaWVudFJlZmVyZW5jZVJlbGF0aW9uc2hpcFJlcXVlc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5FZGdlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uTm9kZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLm5vdGF0aW9uLlZpZXc7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQuY29tbWFuZHMuUmVmQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eUNyZWF0ZUNvbW1hbmQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQuY29tbWFuZHMuUmVmQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eVJlb3JpZW50Q29tbWFuZDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5jb21tYW5kcy5SZWZBY3Rpdml0eVByb2R1Y2VkQXJ0ZWZhY3RDcmVhdGVDb21tYW5kOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsuZGlhZ3JhbS5lZGl0LmNvbW1hbmRzLlJlZkFjdGl2aXR5UHJvZHVjZWRBcnRlZmFjdFJlb3JpZW50Q29tbWFuZDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5jb21tYW5kcy5SZWZBY3Rpdml0eVJlcXVpcmVkQXJ0ZWZhY3RDcmVhdGVDb21tYW5kOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsuZGlhZ3JhbS5lZGl0LmNvbW1hbmRzLlJlZkFjdGl2aXR5UmVxdWlyZWRBcnRlZmFjdFJlb3JpZW50Q29tbWFuZDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5jb21tYW5kcy5SZWZBY3Rpdml0eVJvbGVDcmVhdGVDb21tYW5kOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsuZGlhZ3JhbS5lZGl0LmNvbW1hbmRzLlJlZkFjdGl2aXR5Um9sZVJlb3JpZW50Q29tbWFuZDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5wYXJ0cy5SZWZBY3Rpdml0eTJFZGl0UGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5wYXJ0cy5SZWZBY3Rpdml0eVByZWNlZGluZ0FjdGl2aXR5RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQucGFydHMuUmVmQWN0aXZpdHlQcm9kdWNlZEFydGVmYWN0RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQucGFydHMuUmVmQWN0aXZpdHlSZWZBY3Rpdml0eVN1YkFjdGl2aXR5Q29tcGFydG1lbnQyRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQucGFydHMuUmVmQWN0aXZpdHlSZXF1aXJlZEFydGVmYWN0RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQucGFydHMuUmVmQWN0aXZpdHlSb2xlRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLnBhcnQuUmVmZnJhbWV3b3JrVmlzdWFsSURSZWdpc3RyeTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0ucHJvdmlkZXJzLlJlZmZyYW1ld29ya0VsZW1lbnRUeXBlczsKCi8qKgogKiBAZ2VuZXJhdGVkCiAqLwpwdWJsaWMgY2xhc3MgUmVmQWN0aXZpdHkySXRlbVNlbWFudGljRWRpdFBvbGljeSBleHRlbmRzCgkJUmVmZnJhbWV3b3JrQmFzZUl0ZW1TZW1hbnRpY0VkaXRQb2xpY3kgewoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgUmVmQWN0aXZpdHkySXRlbVNlbWFudGljRWRpdFBvbGljeSgpIHsKCQlzdXBlcihSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuUmVmQWN0aXZpdHlfMzAwMSk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCBDb21tYW5kIGdldERlc3Ryb3lFbGVtZW50Q29tbWFuZChEZXN0cm95RWxlbWVudFJlcXVlc3QgcmVxKSB7CgkJVmlldyB2aWV3ID0gKFZpZXcpIGdldEhvc3QoKS5nZXRNb2RlbCgpOwoJCUNvbXBvc2l0ZVRyYW5zYWN0aW9uYWxDb21tYW5kIGNtZCA9IG5ldyBDb21wb3NpdGVUcmFuc2FjdGlvbmFsQ29tbWFuZCgKCQkJCWdldEVkaXRpbmdEb21haW4oKSwgbnVsbCk7CgkJY21kLnNldFRyYW5zYWN0aW9uTmVzdGluZ0VuYWJsZWQoZmFsc2UpOwoJCWZvciAoSXRlcmF0b3I8Pz4gaXQgPSB2aWV3LmdldFRhcmdldEVkZ2VzKCkuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewoJCQlFZGdlIGluY29taW5nTGluayA9IChFZGdlKSBpdC5uZXh0KCk7CgkJCWlmIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5LmdldFZpc3VhbElEKGluY29taW5nTGluaykgPT0gUmVmQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eUVkaXRQYXJ0LlZJU1VBTF9JRCkgewoJCQkJRGVzdHJveVJlZmVyZW5jZVJlcXVlc3QgciA9IG5ldyBEZXN0cm95UmVmZXJlbmNlUmVxdWVzdCgKCQkJCQkJaW5jb21pbmdMaW5rLmdldFNvdXJjZSgpLmdldEVsZW1lbnQoKSwgbnVsbCwKCQkJCQkJaW5jb21pbmdMaW5rLmdldFRhcmdldCgpLmdldEVsZW1lbnQoKSwgZmFsc2UpOwoJCQkJY21kLmFkZChuZXcgRGVzdHJveVJlZmVyZW5jZUNvbW1hbmQocikpOwoJCQkJY21kLmFkZChuZXcgRGVsZXRlQ29tbWFuZChnZXRFZGl0aW5nRG9tYWluKCksIGluY29taW5nTGluaykpOwoJCQkJY29udGludWU7CgkJCX0KCQl9CgkJZm9yIChJdGVyYXRvcjw/PiBpdCA9IHZpZXcuZ2V0U291cmNlRWRnZXMoKS5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CgkJCUVkZ2Ugb3V0Z29pbmdMaW5rID0gKEVkZ2UpIGl0Lm5leHQoKTsKCQkJaWYgKFJlZmZyYW1ld29ya1Zpc3VhbElEUmVnaXN0cnkuZ2V0VmlzdWFsSUQob3V0Z29pbmdMaW5rKSA9PSBSZWZBY3Rpdml0eVJlcXVpcmVkQXJ0ZWZhY3RFZGl0UGFydC5WSVNVQUxfSUQpIHsKCQkJCURlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0IHIgPSBuZXcgRGVzdHJveVJlZmVyZW5jZVJlcXVlc3QoCgkJCQkJCW91dGdvaW5nTGluay5nZXRTb3VyY2UoKS5nZXRFbGVtZW50KCksIG51bGwsCgkJCQkJCW91dGdvaW5nTGluay5nZXRUYXJnZXQoKS5nZXRFbGVtZW50KCksIGZhbHNlKTsKCQkJCWNtZC5hZGQobmV3IERlc3Ryb3lSZWZlcmVuY2VDb21tYW5kKHIpKTsKCQkJCWNtZC5hZGQobmV3IERlbGV0ZUNvbW1hbmQoZ2V0RWRpdGluZ0RvbWFpbigpLCBvdXRnb2luZ0xpbmspKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5LmdldFZpc3VhbElEKG91dGdvaW5nTGluaykgPT0gUmVmQWN0aXZpdHlQcm9kdWNlZEFydGVmYWN0RWRpdFBhcnQuVklTVUFMX0lEKSB7CgkJCQlEZXN0cm95UmVmZXJlbmNlUmVxdWVzdCByID0gbmV3IERlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0KAoJCQkJCQlvdXRnb2luZ0xpbmsuZ2V0U291cmNlKCkuZ2V0RWxlbWVudCgpLCBudWxsLAoJCQkJCQlvdXRnb2luZ0xpbmsuZ2V0VGFyZ2V0KCkuZ2V0RWxlbWVudCgpLCBmYWxzZSk7CgkJCQljbWQuYWRkKG5ldyBEZXN0cm95UmVmZXJlbmNlQ29tbWFuZChyKSk7CgkJCQljbWQuYWRkKG5ldyBEZWxldGVDb21tYW5kKGdldEVkaXRpbmdEb21haW4oKSwgb3V0Z29pbmdMaW5rKSk7CgkJCQljb250aW51ZTsKCQkJfQoJCQlpZiAoUmVmZnJhbWV3b3JrVmlzdWFsSURSZWdpc3RyeS5nZXRWaXN1YWxJRChvdXRnb2luZ0xpbmspID09IFJlZkFjdGl2aXR5UHJlY2VkaW5nQWN0aXZpdHlFZGl0UGFydC5WSVNVQUxfSUQpIHsKCQkJCURlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0IHIgPSBuZXcgRGVzdHJveVJlZmVyZW5jZVJlcXVlc3QoCgkJCQkJCW91dGdvaW5nTGluay5nZXRTb3VyY2UoKS5nZXRFbGVtZW50KCksIG51bGwsCgkJCQkJCW91dGdvaW5nTGluay5nZXRUYXJnZXQoKS5nZXRFbGVtZW50KCksIGZhbHNlKTsKCQkJCWNtZC5hZGQobmV3IERlc3Ryb3lSZWZlcmVuY2VDb21tYW5kKHIpKTsKCQkJCWNtZC5hZGQobmV3IERlbGV0ZUNvbW1hbmQoZ2V0RWRpdGluZ0RvbWFpbigpLCBvdXRnb2luZ0xpbmspKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCWlmIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5LmdldFZpc3VhbElEKG91dGdvaW5nTGluaykgPT0gUmVmQWN0aXZpdHlSb2xlRWRpdFBhcnQuVklTVUFMX0lEKSB7CgkJCQlEZXN0cm95UmVmZXJlbmNlUmVxdWVzdCByID0gbmV3IERlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0KAoJCQkJCQlvdXRnb2luZ0xpbmsuZ2V0U291cmNlKCkuZ2V0RWxlbWVudCgpLCBudWxsLAoJCQkJCQlvdXRnb2luZ0xpbmsuZ2V0VGFyZ2V0KCkuZ2V0RWxlbWVudCgpLCBmYWxzZSk7CgkJCQljbWQuYWRkKG5ldyBEZXN0cm95UmVmZXJlbmNlQ29tbWFuZChyKSk7CgkJCQljbWQuYWRkKG5ldyBEZWxldGVDb21tYW5kKGdldEVkaXRpbmdEb21haW4oKSwgb3V0Z29pbmdMaW5rKSk7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQlFQW5ub3RhdGlvbiBhbm5vdGF0aW9uID0gdmlldy5nZXRFQW5ub3RhdGlvbigiU2hvcnRjdXQiKTsgLy8kTk9OLU5MUy0xJAoJCWlmIChhbm5vdGF0aW9uID09IG51bGwpIHsKCQkJLy8gdGhlcmUgYXJlIGluZGlyZWN0bHkgcmVmZXJlbmNlZCBjaGlsZHJlbiwgbmVlZCBleHRyYSBjb21tYW5kczogZmFsc2UKCQkJYWRkRGVzdHJveUNoaWxkTm9kZXNDb21tYW5kKGNtZCk7CgkJCWFkZERlc3Ryb3lTaG9ydGN1dHNDb21tYW5kKGNtZCwgdmlldyk7CgkJCS8vIGRlbGV0ZSBob3N0IGVsZW1lbnQKCQkJY21kLmFkZChuZXcgRGVzdHJveUVsZW1lbnRDb21tYW5kKHJlcSkpOwoJCX0gZWxzZSB7CgkJCWNtZC5hZGQobmV3IERlbGV0ZUNvbW1hbmQoZ2V0RWRpdGluZ0RvbWFpbigpLCB2aWV3KSk7CgkJfQoJCXJldHVybiBnZXRHRUZXcmFwcGVyKGNtZC5yZWR1Y2UoKSk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByaXZhdGUgdm9pZCBhZGREZXN0cm95Q2hpbGROb2Rlc0NvbW1hbmQoSUNvbXBvc2l0ZUNvbW1hbmQgY21kKSB7CgkJVmlldyB2aWV3ID0gKFZpZXcpIGdldEhvc3QoKS5nZXRNb2RlbCgpOwoJCWZvciAoSXRlcmF0b3I8Pz4gbml0ID0gdmlldy5nZXRDaGlsZHJlbigpLml0ZXJhdG9yKCk7IG5pdC5oYXNOZXh0KCk7KSB7CgkJCU5vZGUgbm9kZSA9IChOb2RlKSBuaXQubmV4dCgpOwoJCQlzd2l0Y2ggKFJlZmZyYW1ld29ya1Zpc3VhbElEUmVnaXN0cnkuZ2V0VmlzdWFsSUQobm9kZSkpIHsKCQkJY2FzZSBSZWZBY3Rpdml0eVJlZkFjdGl2aXR5U3ViQWN0aXZpdHlDb21wYXJ0bWVudDJFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCQlmb3IgKEl0ZXJhdG9yPD8+IGNpdCA9IG5vZGUuZ2V0Q2hpbGRyZW4oKS5pdGVyYXRvcigpOyBjaXQKCQkJCQkJLmhhc05leHQoKTspIHsKCQkJCQlOb2RlIGNub2RlID0gKE5vZGUpIGNpdC5uZXh0KCk7CgkJCQkJc3dpdGNoIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5LmdldFZpc3VhbElEKGNub2RlKSkgewoJCQkJCWNhc2UgUmVmQWN0aXZpdHkyRWRpdFBhcnQuVklTVUFMX0lEOgoJCQkJCQlmb3IgKEl0ZXJhdG9yPD8+IGl0ID0gY25vZGUuZ2V0VGFyZ2V0RWRnZXMoKS5pdGVyYXRvcigpOyBpdAoJCQkJCQkJCS5oYXNOZXh0KCk7KSB7CgkJCQkJCQlFZGdlIGluY29taW5nTGluayA9IChFZGdlKSBpdC5uZXh0KCk7CgkJCQkJCQlpZiAoUmVmZnJhbWV3b3JrVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkJCQkuZ2V0VmlzdWFsSUQoaW5jb21pbmdMaW5rKSA9PSBSZWZBY3Rpdml0eVByZWNlZGluZ0FjdGl2aXR5RWRpdFBhcnQuVklTVUFMX0lEKSB7CgkJCQkJCQkJRGVzdHJveVJlZmVyZW5jZVJlcXVlc3QgciA9IG5ldyBEZXN0cm95UmVmZXJlbmNlUmVxdWVzdCgKCQkJCQkJCQkJCWluY29taW5nTGluay5nZXRTb3VyY2UoKS5nZXRFbGVtZW50KCksCgkJCQkJCQkJCQludWxsLCBpbmNvbWluZ0xpbmsuZ2V0VGFyZ2V0KCkKCQkJCQkJCQkJCQkJLmdldEVsZW1lbnQoKSwgZmFsc2UpOwoJCQkJCQkJCWNtZC5hZGQobmV3IERlc3Ryb3lSZWZlcmVuY2VDb21tYW5kKHIpKTsKCQkJCQkJCQljbWQuYWRkKG5ldyBEZWxldGVDb21tYW5kKGdldEVkaXRpbmdEb21haW4oKSwKCQkJCQkJCQkJCWluY29taW5nTGluaykpOwoJCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWZvciAoSXRlcmF0b3I8Pz4gaXQgPSBjbm9kZS5nZXRTb3VyY2VFZGdlcygpLml0ZXJhdG9yKCk7IGl0CgkJCQkJCQkJLmhhc05leHQoKTspIHsKCQkJCQkJCUVkZ2Ugb3V0Z29pbmdMaW5rID0gKEVkZ2UpIGl0Lm5leHQoKTsKCQkJCQkJCWlmIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCQkJCS5nZXRWaXN1YWxJRChvdXRnb2luZ0xpbmspID09IFJlZkFjdGl2aXR5UmVxdWlyZWRBcnRlZmFjdEVkaXRQYXJ0LlZJU1VBTF9JRCkgewoJCQkJCQkJCURlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0IHIgPSBuZXcgRGVzdHJveVJlZmVyZW5jZVJlcXVlc3QoCgkJCQkJCQkJCQlvdXRnb2luZ0xpbmsuZ2V0U291cmNlKCkuZ2V0RWxlbWVudCgpLAoJCQkJCQkJCQkJbnVsbCwgb3V0Z29pbmdMaW5rLmdldFRhcmdldCgpCgkJCQkJCQkJCQkJCS5nZXRFbGVtZW50KCksIGZhbHNlKTsKCQkJCQkJCQljbWQuYWRkKG5ldyBEZXN0cm95UmVmZXJlbmNlQ29tbWFuZChyKSk7CgkJCQkJCQkJY21kLmFkZChuZXcgRGVsZXRlQ29tbWFuZChnZXRFZGl0aW5nRG9tYWluKCksCgkJCQkJCQkJCQlvdXRnb2luZ0xpbmspKTsKCQkJCQkJCQljb250aW51ZTsKCQkJCQkJCX0KCQkJCQkJCWlmIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCQkJCS5nZXRWaXN1YWxJRChvdXRnb2luZ0xpbmspID09IFJlZkFjdGl2aXR5UHJvZHVjZWRBcnRlZmFjdEVkaXRQYXJ0LlZJU1VBTF9JRCkgewoJCQkJCQkJCURlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0IHIgPSBuZXcgRGVzdHJveVJlZmVyZW5jZVJlcXVlc3QoCgkJCQkJCQkJCQlvdXRnb2luZ0xpbmsuZ2V0U291cmNlKCkuZ2V0RWxlbWVudCgpLAoJCQkJCQkJCQkJbnVsbCwgb3V0Z29pbmdMaW5rLmdldFRhcmdldCgpCgkJCQkJCQkJCQkJCS5nZXRFbGVtZW50KCksIGZhbHNlKTsKCQkJCQkJCQljbWQuYWRkKG5ldyBEZXN0cm95UmVmZXJlbmNlQ29tbWFuZChyKSk7CgkJCQkJCQkJY21kLmFkZChuZXcgRGVsZXRlQ29tbWFuZChnZXRFZGl0aW5nRG9tYWluKCksCgkJCQkJCQkJCQlvdXRnb2luZ0xpbmspKTsKCQkJCQkJCQljb250aW51ZTsKCQkJCQkJCX0KCQkJCQkJCWlmIChSZWZmcmFtZXdvcmtWaXN1YWxJRFJlZ2lzdHJ5CgkJCQkJCQkJCS5nZXRWaXN1YWxJRChvdXRnb2luZ0xpbmspID09IFJlZkFjdGl2aXR5UHJlY2VkaW5nQWN0aXZpdHlFZGl0UGFydC5WSVNVQUxfSUQpIHsKCQkJCQkJCQlEZXN0cm95UmVmZXJlbmNlUmVxdWVzdCByID0gbmV3IERlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0KAoJCQkJCQkJCQkJb3V0Z29pbmdMaW5rLmdldFNvdXJjZSgpLmdldEVsZW1lbnQoKSwKCQkJCQkJCQkJCW51bGwsIG91dGdvaW5nTGluay5nZXRUYXJnZXQoKQoJCQkJCQkJCQkJCQkuZ2V0RWxlbWVudCgpLCBmYWxzZSk7CgkJCQkJCQkJY21kLmFkZChuZXcgRGVzdHJveVJlZmVyZW5jZUNvbW1hbmQocikpOwoJCQkJCQkJCWNtZC5hZGQobmV3IERlbGV0ZUNvbW1hbmQoZ2V0RWRpdGluZ0RvbWFpbigpLAoJCQkJCQkJCQkJb3V0Z29pbmdMaW5rKSk7CgkJCQkJCQkJY29udGludWU7CgkJCQkJCQl9CgkJCQkJCQlpZiAoUmVmZnJhbWV3b3JrVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkJCQkuZ2V0VmlzdWFsSUQob3V0Z29pbmdMaW5rKSA9PSBSZWZBY3Rpdml0eVJvbGVFZGl0UGFydC5WSVNVQUxfSUQpIHsKCQkJCQkJCQlEZXN0cm95UmVmZXJlbmNlUmVxdWVzdCByID0gbmV3IERlc3Ryb3lSZWZlcmVuY2VSZXF1ZXN0KAoJCQkJCQkJCQkJb3V0Z29pbmdMaW5rLmdldFNvdXJjZSgpLmdldEVsZW1lbnQoKSwKCQkJCQkJCQkJCW51bGwsIG91dGdvaW5nTGluay5nZXRUYXJnZXQoKQoJCQkJCQkJCQkJCQkuZ2V0RWxlbWVudCgpLCBmYWxzZSk7CgkJCQkJCQkJY21kLmFkZChuZXcgRGVzdHJveVJlZmVyZW5jZUNvbW1hbmQocikpOwoJCQkJCQkJCWNtZC5hZGQobmV3IERlbGV0ZUNvbW1hbmQoZ2V0RWRpdGluZ0RvbWFpbigpLAoJCQkJCQkJCQkJb3V0Z29pbmdMaW5rKSk7CgkJCQkJCQkJY29udGludWU7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJY21kLmFkZChuZXcgRGVzdHJveUVsZW1lbnRDb21tYW5kKAoJCQkJCQkJCW5ldyBEZXN0cm95RWxlbWVudFJlcXVlc3QoZ2V0RWRpdGluZ0RvbWFpbigpLAoJCQkJCQkJCQkJY25vZGUuZ2V0RWxlbWVudCgpLCBmYWxzZSkpKTsgLy8gZGlyZWN0bHlPd25lZDogdHJ1ZQoJCQkJCQkvLyBkb24ndCBuZWVkIGV4cGxpY2l0IGRlbGV0aW9uIG9mIGNub2RlIGFzIHBhcmVudCdzIHZpZXcgZGVsZXRpb24gd291bGQgY2xlYW4gY2hpbGQgdmlld3MgYXMgd2VsbCAKCQkJCQkJLy8gY21kLmFkZChuZXcgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS5jb3JlLmNvbW1hbmRzLkRlbGV0ZUNvbW1hbmQoZ2V0RWRpdGluZ0RvbWFpbigpLCBjbm9kZSkpOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlicmVhazsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIENvbW1hbmQgZ2V0Q3JlYXRlUmVsYXRpb25zaGlwQ29tbWFuZChDcmVhdGVSZWxhdGlvbnNoaXBSZXF1ZXN0IHJlcSkgewoJCUNvbW1hbmQgY29tbWFuZCA9IHJlcS5nZXRUYXJnZXQoKSA9PSBudWxsID8gZ2V0U3RhcnRDcmVhdGVSZWxhdGlvbnNoaXBDb21tYW5kKHJlcSkKCQkJCTogZ2V0Q29tcGxldGVDcmVhdGVSZWxhdGlvbnNoaXBDb21tYW5kKHJlcSk7CgkJcmV0dXJuIGNvbW1hbmQgIT0gbnVsbCA/IGNvbW1hbmQgOiBzdXBlcgoJCQkJLmdldENyZWF0ZVJlbGF0aW9uc2hpcENvbW1hbmQocmVxKTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIENvbW1hbmQgZ2V0U3RhcnRDcmVhdGVSZWxhdGlvbnNoaXBDb21tYW5kKAoJCQlDcmVhdGVSZWxhdGlvbnNoaXBSZXF1ZXN0IHJlcSkgewoJCWlmIChSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuUmVmQWN0aXZpdHlSZXF1aXJlZEFydGVmYWN0XzQwMDEgPT0gcmVxCgkJCQkuZ2V0RWxlbWVudFR5cGUoKSkgewoJCQlyZXR1cm4gZ2V0R0VGV3JhcHBlcihuZXcgUmVmQWN0aXZpdHlSZXF1aXJlZEFydGVmYWN0Q3JlYXRlQ29tbWFuZCgKCQkJCQlyZXEsIHJlcS5nZXRTb3VyY2UoKSwgcmVxLmdldFRhcmdldCgpKSk7CgkJfQoJCWlmIChSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuUmVmQWN0aXZpdHlQcm9kdWNlZEFydGVmYWN0XzQwMDIgPT0gcmVxCgkJCQkuZ2V0RWxlbWVudFR5cGUoKSkgewoJCQlyZXR1cm4gZ2V0R0VGV3JhcHBlcihuZXcgUmVmQWN0aXZpdHlQcm9kdWNlZEFydGVmYWN0Q3JlYXRlQ29tbWFuZCgKCQkJCQlyZXEsIHJlcS5nZXRTb3VyY2UoKSwgcmVxLmdldFRhcmdldCgpKSk7CgkJfQoJCWlmIChSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuUmVmQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eV80MDAzID09IHJlcQoJCQkJLmdldEVsZW1lbnRUeXBlKCkpIHsKCQkJcmV0dXJuIGdldEdFRldyYXBwZXIobmV3IFJlZkFjdGl2aXR5UHJlY2VkaW5nQWN0aXZpdHlDcmVhdGVDb21tYW5kKAoJCQkJCXJlcSwgcmVxLmdldFNvdXJjZSgpLCByZXEuZ2V0VGFyZ2V0KCkpKTsKCQl9CgkJaWYgKFJlZmZyYW1ld29ya0VsZW1lbnRUeXBlcy5SZWZBY3Rpdml0eVJvbGVfNDAwNCA9PSByZXEKCQkJCS5nZXRFbGVtZW50VHlwZSgpKSB7CgkJCXJldHVybiBnZXRHRUZXcmFwcGVyKG5ldyBSZWZBY3Rpdml0eVJvbGVDcmVhdGVDb21tYW5kKHJlcSwKCQkJCQlyZXEuZ2V0U291cmNlKCksIHJlcS5nZXRUYXJnZXQoKSkpOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIENvbW1hbmQgZ2V0Q29tcGxldGVDcmVhdGVSZWxhdGlvbnNoaXBDb21tYW5kKAoJCQlDcmVhdGVSZWxhdGlvbnNoaXBSZXF1ZXN0IHJlcSkgewoJCWlmIChSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuUmVmQWN0aXZpdHlSZXF1aXJlZEFydGVmYWN0XzQwMDEgPT0gcmVxCgkJCQkuZ2V0RWxlbWVudFR5cGUoKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJaWYgKFJlZmZyYW1ld29ya0VsZW1lbnRUeXBlcy5SZWZBY3Rpdml0eVByb2R1Y2VkQXJ0ZWZhY3RfNDAwMiA9PSByZXEKCQkJCS5nZXRFbGVtZW50VHlwZSgpKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCQlpZiAoUmVmZnJhbWV3b3JrRWxlbWVudFR5cGVzLlJlZkFjdGl2aXR5UHJlY2VkaW5nQWN0aXZpdHlfNDAwMyA9PSByZXEKCQkJCS5nZXRFbGVtZW50VHlwZSgpKSB7CgkJCXJldHVybiBnZXRHRUZXcmFwcGVyKG5ldyBSZWZBY3Rpdml0eVByZWNlZGluZ0FjdGl2aXR5Q3JlYXRlQ29tbWFuZCgKCQkJCQlyZXEsIHJlcS5nZXRTb3VyY2UoKSwgcmVxLmdldFRhcmdldCgpKSk7CgkJfQoJCWlmIChSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuUmVmQWN0aXZpdHlSb2xlXzQwMDQgPT0gcmVxCgkJCQkuZ2V0RWxlbWVudFR5cGUoKSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGNvbW1hbmQgdG8gcmVvcmllbnQgRVJlZmVyZW5jZSBiYXNlZCBsaW5rLiBOZXcgbGluayB0YXJnZXQgb3Igc291cmNlCgkgKiBzaG91bGQgYmUgdGhlIGRvbWFpbiBtb2RlbCBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG5vZGUuCgkgKiAKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIENvbW1hbmQgZ2V0UmVvcmllbnRSZWZlcmVuY2VSZWxhdGlvbnNoaXBDb21tYW5kKAoJCQlSZW9yaWVudFJlZmVyZW5jZVJlbGF0aW9uc2hpcFJlcXVlc3QgcmVxKSB7CgkJc3dpdGNoIChnZXRWaXN1YWxJRChyZXEpKSB7CgkJY2FzZSBSZWZBY3Rpdml0eVJlcXVpcmVkQXJ0ZWZhY3RFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCXJldHVybiBnZXRHRUZXcmFwcGVyKG5ldyBSZWZBY3Rpdml0eVJlcXVpcmVkQXJ0ZWZhY3RSZW9yaWVudENvbW1hbmQoCgkJCQkJcmVxKSk7CgkJY2FzZSBSZWZBY3Rpdml0eVByb2R1Y2VkQXJ0ZWZhY3RFZGl0UGFydC5WSVNVQUxfSUQ6CgkJCXJldHVybiBnZXRHRUZXcmFwcGVyKG5ldyBSZWZBY3Rpdml0eVByb2R1Y2VkQXJ0ZWZhY3RSZW9yaWVudENvbW1hbmQoCgkJCQkJcmVxKSk7CgkJY2FzZSBSZWZBY3Rpdml0eVByZWNlZGluZ0FjdGl2aXR5RWRpdFBhcnQuVklTVUFMX0lEOgoJCQlyZXR1cm4gZ2V0R0VGV3JhcHBlcihuZXcgUmVmQWN0aXZpdHlQcmVjZWRpbmdBY3Rpdml0eVJlb3JpZW50Q29tbWFuZCgKCQkJCQlyZXEpKTsKCQljYXNlIFJlZkFjdGl2aXR5Um9sZUVkaXRQYXJ0LlZJU1VBTF9JRDoKCQkJcmV0dXJuIGdldEdFRldyYXBwZXIobmV3IFJlZkFjdGl2aXR5Um9sZVJlb3JpZW50Q29tbWFuZChyZXEpKTsKCQl9CgkJcmV0dXJuIHN1cGVyLmdldFJlb3JpZW50UmVmZXJlbmNlUmVsYXRpb25zaGlwQ29tbWFuZChyZXEpOwoJfQoKfQo=