LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5pbnRlcm5ldC5tb25pdG9yLnVpLmludGVybmFsOwoKaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5JRGlhbG9nQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWRMYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21ibzsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbnRyb2w7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UZXh0OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuaGVscC5Xb3JrYmVuY2hIZWxwOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmludGVybmV0Lm1vbml0b3IuY29yZS5JTW9uaXRvcldvcmtpbmdDb3B5OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmludGVybmV0Lm1vbml0b3IuY29yZS5JUHJvdG9jb2xBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmludGVybmV0Lm1vbml0b3IuY29yZS5Nb25pdG9yQ29yZTsKLyoqCiAqIAogKi8KcHVibGljIGNsYXNzIE1vbml0b3JEaWFsb2cgZXh0ZW5kcyBEaWFsb2cgewoJcHJvdGVjdGVkIElNb25pdG9yV29ya2luZ0NvcHkgbW9uaXRvcjsKCXByb3RlY3RlZCBib29sZWFuIGlzRWRpdDsKCQoJcHJpdmF0ZSBCdXR0b24gb2tCdXR0b247Cglwcml2YXRlIFRleHQgbW9uaXRvclBvcnQ7Cglwcml2YXRlIFRleHQgcmVtb3RlSG9zdG5hbWU7Cglwcml2YXRlIFRleHQgcmVtb3RlUG9ydDsKCQoJaW50ZXJmYWNlIFN0cmluZ01vZGlmeUxpc3RlbmVyIHsKCQlwdWJsaWMgdm9pZCB2YWx1ZUNoYW5nZWQoU3RyaW5nIHMpOwoJfQoJCglpbnRlcmZhY2UgQm9vbGVhbk1vZGlmeUxpc3RlbmVyIHsKCQlwdWJsaWMgdm9pZCB2YWx1ZUNoYW5nZWQoYm9vbGVhbiBiKTsKCX0KCQoJaW50ZXJmYWNlIFR5cGVNb2RpZnlMaXN0ZW5lciB7CgkJcHVibGljIHZvaWQgdmFsdWVDaGFuZ2VkKElQcm90b2NvbEFkYXB0ZXIgdHlwZSk7Cgl9CgoJLyoqCgkgKiBAcGFyYW0gcGFyZW50U2hlbGwKCSAqLwoJcHVibGljIE1vbml0b3JEaWFsb2coU2hlbGwgcGFyZW50U2hlbGwsIElNb25pdG9yV29ya2luZ0NvcHkgbW9uaXRvcikgewoJCXN1cGVyKHBhcmVudFNoZWxsKTsKCQl0aGlzLm1vbml0b3IgPSBtb25pdG9yOwoJCWlzRWRpdCA9IHRydWU7Cgl9CgkKCXB1YmxpYyBNb25pdG9yRGlhbG9nKFNoZWxsIHBhcmVudFNoZWxsKSB7CgkJc3VwZXIocGFyZW50U2hlbGwpOwoJCW1vbml0b3IgPSBNb25pdG9yQ29yZS5jcmVhdGVNb25pdG9yKCk7CgkJaXNFZGl0ID0gZmFsc2U7Cgl9CgkKCXByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVNoZWxsKFNoZWxsIHNoZWxsKSB7CgkJc3VwZXIuY29uZmlndXJlU2hlbGwoc2hlbGwpOwoJCWlmIChpc0VkaXQpCgkJCXNoZWxsLnNldFRleHQoTW9uaXRvclVJUGx1Z2luLmdldFJlc291cmNlKCIlZWRpdE1vbml0b3IiKSk7CgkJZWxzZQoJCQlzaGVsbC5zZXRUZXh0KE1vbml0b3JVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJW5ld01vbml0b3IiKSk7Cgl9CgkKCXByb3RlY3RlZCBMYWJlbCBjcmVhdGVMYWJlbChDb21wb3NpdGUgY29tcCwgU3RyaW5nIHR4dCkgewoJCUxhYmVsIGxhYmVsID0gbmV3IExhYmVsKGNvbXAsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KHR4dCk7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuSE9SSVpPTlRBTF9BTElHTl9CRUdJTk5JTkcgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9CRUdJTk5JTkcpKTsKCQlyZXR1cm4gbGFiZWw7Cgl9CgkKCXByb3RlY3RlZCBUZXh0IGNyZWF0ZVRleHQoQ29tcG9zaXRlIGNvbXAsIFN0cmluZyB0eHQsIGZpbmFsIFN0cmluZ01vZGlmeUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJZmluYWwgVGV4dCB0ZXh0ID0gbmV3IFRleHQoY29tcCwgU1dULkJPUkRFUik7CgkJaWYgKHR4dCAhPSBudWxsKQoJCQl0ZXh0LnNldFRleHQodHh0KTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCB8IEdyaWREYXRhLlZFUlRJQ0FMX0FMSUdOX0JFR0lOTklORyk7CgkJZGF0YS53aWR0aEhpbnQgPSAxNTA7CgkJdGV4dC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCWlmIChsaXN0ZW5lciAhPSBudWxsKQoJCQl0ZXh0LmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoTW9kaWZ5RXZlbnQgZSkgewkKCQkJCQlsaXN0ZW5lci52YWx1ZUNoYW5nZWQodGV4dC5nZXRUZXh0KCkpOwoJCQkJfQoJCQl9KTsKCQlyZXR1cm4gdGV4dDsKCX0KCQoJcHJvdGVjdGVkIENvbWJvIGNyZWF0ZVR5cGVDb21ibyhDb21wb3NpdGUgY29tcCwgZmluYWwgSVByb3RvY29sQWRhcHRlcltdIHR5cGVzLCBJUHJvdG9jb2xBZGFwdGVyIHNlbCwgZmluYWwgVHlwZU1vZGlmeUxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJZmluYWwgQ29tYm8gY29tYm8gPSBuZXcgQ29tYm8oY29tcCwgU1dULkRST1BfRE9XTiB8IFNXVC5SRUFEX09OTFkpOwoJCWludCBzaXplID0gdHlwZXMubGVuZ3RoOwoJCVN0cmluZ1tdIGl0ZW1zID0gbmV3IFN0cmluZ1tzaXplXTsKCQlpbnQgaW5kZXggPSAtMTsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlpdGVtc1tpXSA9IHR5cGVzW2ldLmdldE5hbWUoKTsKCQkJaWYgKHR5cGVzW2ldLmVxdWFscyhzZWwpKQoJCQkJaW5kZXggPSBpOwoJCX0KCQljb21iby5zZXRJdGVtcyhpdGVtcyk7CgkJaWYgKGluZGV4ID49IDApCgkJCWNvbWJvLnNlbGVjdChpbmRleCk7CgkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9CRUdJTk5JTkcpOwoJCWRhdGEud2lkdGhIaW50ID0gMTUwOwoJCWNvbWJvLnNldExheW91dERhdGEoZGF0YSk7CgkJaWYgKGxpc3RlbmVyICE9IG51bGwpCgkJCWNvbWJvLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsJCgkJCQkJbGlzdGVuZXIudmFsdWVDaGFuZ2VkKHR5cGVzW2NvbWJvLmdldFNlbGVjdGlvbkluZGV4KCldKTsKCQkJCX0KCQkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQkJd2lkZ2V0U2VsZWN0ZWQoZSk7CgkJCQl9CgkJCX0pOwoJCXJldHVybiBjb21ibzsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuRGlhbG9nI2NyZWF0ZURpYWxvZ0FyZWEob3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlKQoJICovCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlDb21wb3NpdGUgY29tcG9zaXRlID0gKENvbXBvc2l0ZSkgc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCSgoR3JpZExheW91dCljb21wb3NpdGUuZ2V0TGF5b3V0KCkpLm51bUNvbHVtbnMgPSAyOwoJCQoJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChjb21wb3NpdGUsIENvbnRleHRJZHMuUFJFRl9ESUFMT0cpOwoJCQoJCWNyZWF0ZUxhYmVsKGNvbXBvc2l0ZSwgTW9uaXRvclVJUGx1Z2luLmdldFJlc291cmNlKCIlbG9jYWxQb3J0IikpOwkJCgkJbW9uaXRvclBvcnQgPSBjcmVhdGVUZXh0KGNvbXBvc2l0ZSwgbW9uaXRvci5nZXRMb2NhbFBvcnQoKSArICIiLCBuZXcgU3RyaW5nTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHZhbHVlQ2hhbmdlZChTdHJpbmcgcykgewoJCQkJdHJ5IHsKCQkJCQltb25pdG9yLnNldExvY2FsUG9ydChJbnRlZ2VyLnBhcnNlSW50KHMpKTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJLy8gaWdub3JlCgkJCQl9CgkJCQl2YWxpZGF0ZUZpZWxkcygpOwoJCQl9CgkJfSk7CgkJCgkJR3JvdXAgZ3JvdXAgPSBuZXcgR3JvdXAoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgyLCBmYWxzZSk7CgkJZ3JvdXAuc2V0TGF5b3V0KGxheW91dCk7CgkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWdyb3VwLnNldExheW91dERhdGEoZGF0YSk7CgkJZ3JvdXAuc2V0VGV4dChNb25pdG9yVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVyZW1vdGVHcm91cCIpKTsKCQkKCQljcmVhdGVMYWJlbChncm91cCwgTW9uaXRvclVJUGx1Z2luLmdldFJlc291cmNlKCIlcmVtb3RlSG9zdCIpKTsJCQoJCXJlbW90ZUhvc3RuYW1lID0gY3JlYXRlVGV4dChncm91cCwgbW9uaXRvci5nZXRSZW1vdGVIb3N0KCksIG5ldyBTdHJpbmdNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgdmFsdWVDaGFuZ2VkKFN0cmluZyBzKSB7CgkJCQltb25pdG9yLnNldFJlbW90ZUhvc3Qocyk7CgkJCQl2YWxpZGF0ZUZpZWxkcygpOwoJCQl9CgkJfSk7CgkJCgkJY3JlYXRlTGFiZWwoZ3JvdXAsIE1vbml0b3JVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXJlbW90ZVBvcnQiKSk7CQkKCQlyZW1vdGVQb3J0ID0gY3JlYXRlVGV4dChncm91cCwgbW9uaXRvci5nZXRSZW1vdGVQb3J0KCkgKyAiIiwgbmV3IFN0cmluZ01vZGlmeUxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCB2YWx1ZUNoYW5nZWQoU3RyaW5nIHMpIHsKCQkJCXRyeSB7CgkJCQkJbW9uaXRvci5zZXRSZW1vdGVQb3J0KEludGVnZXIucGFyc2VJbnQocykpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkvLyBpZ25vcmUKCQkJCX0KCQkJCXZhbGlkYXRlRmllbGRzKCk7CgkJCX0KCQl9KTsKCQkKCQljcmVhdGVMYWJlbChncm91cCwgTW9uaXRvclVJUGx1Z2luLmdldFJlc291cmNlKCIlcGFyc2VUeXBlIikpOwkJCgkJY3JlYXRlVHlwZUNvbWJvKGdyb3VwLCBNb25pdG9yQ29yZS5nZXRQcm90b2NvbEFkYXB0ZXJzKCksIG1vbml0b3IuZ2V0UHJvdG9jb2xBZGFwdGVyKCksIG5ldyBUeXBlTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHZhbHVlQ2hhbmdlZChJUHJvdG9jb2xBZGFwdGVyIHR5cGUpIHsKCQkJCW1vbml0b3Iuc2V0UHJvdG9jb2xBZGFwdGVyKHR5cGUpOwoJCQl9CgkJfSk7CgkJCgkJcmV0dXJuIGNvbXBvc2l0ZTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuRGlhbG9nI29rUHJlc3NlZCgpCgkgKi8KCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQltb25pdG9yLnNhdmUoKTsKCQlzdXBlci5va1ByZXNzZWQoKTsKCX0KCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVCdXR0b25CYXIoQ29tcG9zaXRlIHBhcmVudCkgewoJCUNvbnRyb2wgYnV0dG9uQ29udHJvbCA9IHN1cGVyLmNyZWF0ZUJ1dHRvbkJhcihwYXJlbnQpOwoJCXZhbGlkYXRlRmllbGRzKCk7CgkJcmV0dXJuIGJ1dHRvbkNvbnRyb2w7Cgl9CgoJcHJpdmF0ZSB2b2lkIHNldE9LQnV0dG9uRW5hYmxlZChib29sZWFuIGN1cklzRW5hYmxlZCkgewoJCWlmIChva0J1dHRvbiA9PSBudWxsKQoJCQlva0J1dHRvbiA9IGdldEJ1dHRvbihJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKTsKCQkKCQlpZiAob2tCdXR0b24gIT0gbnVsbCkKCQkJb2tCdXR0b24uc2V0RW5hYmxlZChjdXJJc0VuYWJsZWQpOwoJfQoKCXByb3RlY3RlZCB2b2lkIHZhbGlkYXRlRmllbGRzKCkgewoJCWlmIChtb25pdG9yUG9ydCA9PSBudWxsKQoJCQlyZXR1cm47CgkJCgkJYm9vbGVhbiByZXN1bHQgPSB0cnVlOwoKCQlTdHJpbmcgY3Vyckhvc3RuYW1lID0gcmVtb3RlSG9zdG5hbWUuZ2V0VGV4dCgpOwoJCWlmICghaXNWYWxpZEhvc3RuYW1lKGN1cnJIb3N0bmFtZSkpCgkJCXJlc3VsdCA9IGZhbHNlOwoJCQoJCVN0cmluZyBjdXJySG9zdG5hbWVQb3J0ID0gcmVtb3RlUG9ydC5nZXRUZXh0KCk7CgkJdHJ5IHsKCQkJSW50ZWdlci5wYXJzZUludChjdXJySG9zdG5hbWVQb3J0KTsKCQl9IGNhdGNoIChFeGNlcHRpb24gYW55KSB7CgkJCXJlc3VsdCA9IGZhbHNlOwoJCX0KCQkKCQlTdHJpbmcgY3Vyck1vbml0b3JQb3J0ID0gbW9uaXRvclBvcnQuZ2V0VGV4dCgpOwoJCXRyeSB7CgkJCUludGVnZXIucGFyc2VJbnQoY3Vyck1vbml0b3JQb3J0KTsKCQl9IGNhdGNoIChFeGNlcHRpb24gYW55KSB7CgkJCXJlc3VsdCA9IGZhbHNlOwoJCX0KCQkKCQlpZiAocmVzdWx0ICYmIGlzTG9jYWxob3N0KGN1cnJIb3N0bmFtZSkpIHsKCQkJaWYgKGN1cnJIb3N0bmFtZVBvcnQuZXF1YWxzKGN1cnJNb25pdG9yUG9ydCkpCgkJCQlyZXN1bHQgPSBmYWxzZTsKCQl9CgkJc2V0T0tCdXR0b25FbmFibGVkKHJlc3VsdCk7Cgl9CgkKCXByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkSG9zdG5hbWUoU3RyaW5nIGhvc3QpIHsKCQlpZiAoaG9zdCA9PSBudWxsIHx8IGhvc3QudHJpbSgpLmxlbmd0aCgpIDwgMSkKCQkJcmV0dXJuIGZhbHNlOwoJCQoJCWludCBsZW5ndGggPSBob3N0Lmxlbmd0aCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCQkJY2hhciBjID0gaG9zdC5jaGFyQXQoaSk7CgkJCWlmICghQ2hhcmFjdGVyLmlzTGV0dGVyT3JEaWdpdChjKSAmJiBjICE9ICc6JyAmJiBjICE9ICcuJykKCQkJCXJldHVybiBmYWxzZTsKCQl9CgkJaWYgKGhvc3QuZW5kc1dpdGgoIjoiKSkKCQkJcmV0dXJuIGZhbHNlOwoJCXJldHVybiB0cnVlOwoJfQoKCXByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBpc0xvY2FsaG9zdChTdHJpbmcgaG9zdCkgewoJCWlmIChob3N0ID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQl0cnkgewoJCQlpZiAoImxvY2FsaG9zdCIuZXF1YWxzKGhvc3QpIHx8ICIxMjcuMC4wLjEiLmVxdWFscyhob3N0KSkKCQkJCXJldHVybiB0cnVlOwoJCQlJbmV0QWRkcmVzcyBsb2NhbEhvc3RhZGRyID0gSW5ldEFkZHJlc3MuZ2V0TG9jYWxIb3N0KCk7CgkJCWlmIChsb2NhbEhvc3RhZGRyLmdldEhvc3ROYW1lKCkuZXF1YWxzKGhvc3QpKQoJCQkJcmV0dXJuIHRydWU7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkVycm9yIGNoZWNraW5nIGZvciBsb2NhbGhvc3QiLCBlKTsKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQp9