LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSBDb3Jwb3JhdGlvbiAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLmludGVybmFsOwoKaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5QcmVmZXJlbmNlczsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5TdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuaW50ZXJuZXQubW9uaXRvci5jb3JlLmludGVybmFsLmh0dHAuUmVzZW5kSFRUUFJlcXVlc3Q7Ci8qKgogKiAKICovCnB1YmxpYyBjbGFzcyBNb25pdG9yTWFuYWdlciB7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQUREID0gMDsKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBDSEFOR0UgPSAxOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFJFTU9WRSA9IDI7CgoJLy8gbW9uaXRvcnMKCXByb3RlY3RlZCBMaXN0IG1vbml0b3JzOwoJcHJvdGVjdGVkIE1hcCB0aHJlYWRzID0gbmV3IEhhc2hNYXAoKTsKCQoJcHJvdGVjdGVkIExpc3QgbW9uaXRvckxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCglwcml2YXRlIFByZWZlcmVuY2VzLklQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIHBjbDsKCXByb3RlY3RlZCBib29sZWFuIGlnbm9yZVByZWZlcmVuY2VDaGFuZ2VzID0gZmFsc2U7CgkKCXByb3RlY3RlZCBNYXAgcmVzZW5kTWFwID0gbmV3IEhhc2hNYXAoKTsKCQoJcHJvdGVjdGVkIHN0YXRpYyBNb25pdG9yTWFuYWdlciBpbnN0YW5jZTsKCQoJc3RhdGljIHsKCQlNb25pdG9yUGx1Z2luLmdldEluc3RhbmNlKCkuZXhlY3V0ZVN0YXJ0dXBzKCk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgTW9uaXRvck1hbmFnZXIgZ2V0SW5zdGFuY2UoKSB7CgkJaWYgKGluc3RhbmNlID09IG51bGwpCgkJCWluc3RhbmNlID0gbmV3IE1vbml0b3JNYW5hZ2VyKCk7CgkKCQlyZXR1cm4gaW5zdGFuY2U7Cgl9CgkKCXByaXZhdGUgTW9uaXRvck1hbmFnZXIoKSB7CgkJbG9hZE1vbml0b3JzKCk7CgkJCgkJcGNsID0gbmV3IFByZWZlcmVuY2VzLklQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBwcm9wZXJ0eUNoYW5nZShQcmVmZXJlbmNlcy5Qcm9wZXJ0eUNoYW5nZUV2ZW50IGV2ZW50KSB7CgkJCQlpZiAoaWdub3JlUHJlZmVyZW5jZUNoYW5nZXMpCgkJCQkJcmV0dXJuOwoJCQkJU3RyaW5nIHByb3BlcnR5ID0gZXZlbnQuZ2V0UHJvcGVydHkoKTsKCQkJCWlmIChwcm9wZXJ0eS5lcXVhbHMoIm1vbml0b3JzIikpIHsKCQkJCQlsb2FkTW9uaXRvcnMoKTsKCQkJCX0KCQkJfQoJCX07CgkJCgkJTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFBsdWdpblByZWZlcmVuY2VzKCkuYWRkUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcihwY2wpOwoJfQoJCglwcm90ZWN0ZWQgdm9pZCBkaXNwb3NlKCkgewoJCU1vbml0b3JQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRQbHVnaW5QcmVmZXJlbmNlcygpLnJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIocGNsKTsKCX0KCQoJcHVibGljIElNb25pdG9yV29ya2luZ0NvcHkgY3JlYXRlTW9uaXRvcigpIHsKCQlyZXR1cm4gbmV3IE1vbml0b3JXb3JraW5nQ29weSgpOwoJfQoJCglwdWJsaWMgTGlzdCBnZXRNb25pdG9ycygpIHsKCQlyZXR1cm4gbmV3IEFycmF5TGlzdChtb25pdG9ycyk7Cgl9CgoJcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIGFkZE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCW1vbml0b3JzLmFkZChtb25pdG9yKTsKCQlmaXJlTW9uaXRvckV2ZW50KG1vbml0b3IsIEFERCk7CgkJc2F2ZU1vbml0b3JzKCk7Cgl9CgkKCXByb3RlY3RlZCBib29sZWFuIGlzUnVubmluZyhJTW9uaXRvciBtb25pdG9yKSB7CgkJcmV0dXJuICh0aHJlYWRzLmdldChtb25pdG9yKSAhPSBudWxsKTsKCX0KCglwdWJsaWMgdm9pZCBzdGFydE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCXJldHVybjsKCQkKCQlpZiAoQWNjZXB0VGhyZWFkLmlzUG9ydEluVXNlKG1vbml0b3IuZ2V0TG9jYWxQb3J0KCkpKQoJCQl0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIE1vbml0b3JQbHVnaW4uUExVR0lOX0lELCAwLCBNb25pdG9yUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JQb3J0SW5Vc2UiLCBtb25pdG9yLmdldExvY2FsUG9ydCgpICsgIiIpLCBudWxsKSk7CgkJCgkJQWNjZXB0VGhyZWFkIHRocmVhZCA9IG5ldyBBY2NlcHRUaHJlYWQobW9uaXRvcik7CgkJdGhyZWFkLnN0YXJ0U2VydmVyKCk7CgkJdGhyZWFkcy5wdXQobW9uaXRvciwgdGhyZWFkKTsKCX0KCQoJcHVibGljIHZvaWQgc3RvcE1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmICghbW9uaXRvcnMuY29udGFpbnMobW9uaXRvcikpCgkJCXJldHVybjsKCQkKCQlBY2NlcHRUaHJlYWQgdGhyZWFkID0gKEFjY2VwdFRocmVhZCkgdGhyZWFkcy5nZXQobW9uaXRvcik7CgkJaWYgKHRocmVhZCAhPSBudWxsKSB7CgkJCXRocmVhZC5zdG9wU2VydmVyKCk7CgkJCXRocmVhZHMucmVtb3ZlKG1vbml0b3IpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZU1vbml0b3IoSU1vbml0b3IgbW9uaXRvcikgewoJCWlmIChtb25pdG9yLmlzUnVubmluZygpKQoJCQlzdG9wTW9uaXRvcihtb25pdG9yKTsKCQltb25pdG9ycy5yZW1vdmUobW9uaXRvcik7CgkJZmlyZU1vbml0b3JFdmVudChtb25pdG9yLCBSRU1PVkUpOwoJCXNhdmVNb25pdG9ycygpOwoJfQoJCglwcm90ZWN0ZWQgc3luY2hyb25pemVkIHZvaWQgbW9uaXRvckNoYW5nZWQoSU1vbml0b3IgbW9uaXRvcikgewoJCWZpcmVNb25pdG9yRXZlbnQobW9uaXRvciwgQ0hBTkdFKTsKCQlzYXZlTW9uaXRvcnMoKTsKCX0KCQoJcHJvdGVjdGVkIGJvb2xlYW4gZXhpc3RzKElNb25pdG9yIG1vbml0b3IpIHsKCQlyZXR1cm4gKG1vbml0b3JzLmNvbnRhaW5zKG1vbml0b3IpKTsKCX0KCQoJLyoqCgkgKiBBZGQgbW9uaXRvciBsaXN0ZW5lci4KCSAqIAoJICogQHBhcmFtIGxpc3RlbmVyCgkgKi8KCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRNb25pdG9yTGlzdGVuZXIoSU1vbml0b3JMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmICghbW9uaXRvckxpc3RlbmVycy5jb250YWlucyhsaXN0ZW5lcikpCgkJCW1vbml0b3JMaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIFJlbW92ZSBtb25pdG9yIGxpc3RlbmVyLgoJICogCgkgKiBAcGFyYW0gbGlzdGVuZXIKCSAqLwoJcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlbW92ZU1vbml0b3JMaXN0ZW5lcihJTW9uaXRvckxpc3RlbmVyIGxpc3RlbmVyKSB7CgkJaWYgKG1vbml0b3JMaXN0ZW5lcnMuY29udGFpbnMobGlzdGVuZXIpKQoJCQltb25pdG9yTGlzdGVuZXJzLnJlbW92ZShsaXN0ZW5lcik7Cgl9CgkKCS8qKgoJICogRmlyZSBhIG1vbml0b3IgZXZlbnQuCgkgKiAKCSAqIEBwYXJhbSBtb25pdG9yIHRoZSBtb25pdG9yCgkgKiBAcGFyYW0gdHlwZSB0aGUgdHlwZSBvZiBldmVudAoJICovCglwcm90ZWN0ZWQgdm9pZCBmaXJlTW9uaXRvckV2ZW50KElNb25pdG9yIG1vbml0b3IsIGludCB0eXBlKSB7CgkJT2JqZWN0W10gb2JqID0gbW9uaXRvckxpc3RlbmVycy50b0FycmF5KCk7CgkJCgkJaW50IHNpemUgPSBvYmoubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCUlNb25pdG9yTGlzdGVuZXIgbGlzdGVuZXIgPSAoSU1vbml0b3JMaXN0ZW5lcikgb2JqW2ldOwoJCQlpZiAodHlwZSA9PSBBREQpCgkJCQlsaXN0ZW5lci5tb25pdG9yQWRkZWQobW9uaXRvcik7CgkJCWVsc2UgaWYgKHR5cGUgPT0gQ0hBTkdFKQoJCQkJbGlzdGVuZXIubW9uaXRvckNoYW5nZWQobW9uaXRvcik7CgkJCWVsc2UgaWYgKHR5cGUgPT0gUkVNT1ZFKQoJCQkJbGlzdGVuZXIubW9uaXRvclJlbW92ZWQobW9uaXRvcik7CgkJfQoJfQoKCXByb3RlY3RlZCBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkTW9uaXRvcnMoKSB7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTG9hZGluZyBtb25pdG9ycyIpOwoJCQoJCW1vbml0b3JzID0gbmV3IEFycmF5TGlzdCgpOwoJCVByZWZlcmVuY2VzIHByZWZzID0gTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFBsdWdpblByZWZlcmVuY2VzKCk7CgkJU3RyaW5nIHhtbFN0cmluZyA9IHByZWZzLmdldFN0cmluZygibW9uaXRvcnMiKTsKCQlpZiAoeG1sU3RyaW5nICE9IG51bGwgJiYgeG1sU3RyaW5nLmxlbmd0aCgpID4gMCkgewoJCQl0cnkgewoJCQkJQnl0ZUFycmF5SW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oeG1sU3RyaW5nLmdldEJ5dGVzKCkpOwoJCQkJSU1lbWVudG8gbWVtZW50byA9IFhNTE1lbWVudG8ubG9hZE1lbWVudG8oaW4pOwoJCQoJCQkJSU1lbWVudG9bXSBjaGlsZHJlbiA9IG1lbWVudG8uZ2V0Q2hpbGRyZW4oIm1vbml0b3IiKTsKCQkJCWlmIChjaGlsZHJlbiAhPSBudWxsKSB7CgkJCQkJaW50IHNpemUgPSBjaGlsZHJlbi5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQkJTW9uaXRvciBtb25pdG9yID0gbmV3IE1vbml0b3IoKTsKCQkJCQkJbW9uaXRvci5sb2FkKGNoaWxkcmVuW2ldKTsKCQkJCQkJbW9uaXRvcnMuYWRkKG1vbml0b3IpOwoJCQkJCX0KCQkJCX0KCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLldBUk5JTkcsICJDb3VsZCBub3QgbG9hZCBtb25pdG9yczogIiArIGUuZ2V0TWVzc2FnZSgpKTsKCQkJfQoJCX0KCX0KCQoJcHJvdGVjdGVkIHN5bmNocm9uaXplZCB2b2lkIHNhdmVNb25pdG9ycygpIHsKCQl0cnkgewoJCQlpZ25vcmVQcmVmZXJlbmNlQ2hhbmdlcyA9IHRydWU7CgkJCVhNTE1lbWVudG8gbWVtZW50byA9IFhNTE1lbWVudG8uY3JlYXRlV3JpdGVSb290KCJtb25pdG9ycyIpOwoKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb25pdG9ycy5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlNb25pdG9yIG1vbml0b3IgPSAoTW9uaXRvcikgaXRlcmF0b3IubmV4dCgpOwoJCQkJSU1lbWVudG8gY2hpbGQgPSBtZW1lbnRvLmNyZWF0ZUNoaWxkKCJtb25pdG9yIik7CgkJCQltb25pdG9yLnNhdmUoY2hpbGQpOwoJCQl9CgkJCQoJCQlTdHJpbmcgeG1sU3RyaW5nID0gbWVtZW50by5zYXZlVG9TdHJpbmcoKTsKCQkJUHJlZmVyZW5jZXMgcHJlZnMgPSBNb25pdG9yUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0UGx1Z2luUHJlZmVyZW5jZXMoKTsKCQkJcHJlZnMuc2V0VmFsdWUoIm1vbml0b3JzIiwgeG1sU3RyaW5nKTsKCQkJTW9uaXRvclBsdWdpbi5nZXRJbnN0YW5jZSgpLnNhdmVQbHVnaW5QcmVmZXJlbmNlcygpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkNvdWxkIG5vdCBzYXZlIGJyb3dzZXJzIiwgZSk7CgkJfQoJCWlnbm9yZVByZWZlcmVuY2VDaGFuZ2VzID0gZmFsc2U7Cgl9CgkKCS8qKgoJICogQ3JlYXRlcyBhIG5ldyByZXNlbmQgcmVxdWVzdCBmcm9tIHRoZSBnaXZlbiByZXF1ZXN0LgoJICogCgkgKiBAcGFyYW0gcmVxdWVzdCB0aGUgcmVxdWVzdCB0aGF0IGlzIHRvIGJlIHJlc2VudDsgbWF5IG5vdCBiZSA8Y29kZT5udWxsPC9jb2RlPgoJICogQHJldHVybiBhIG5ldyByZXNlbmQgcmVxdWVzdAoJICovCglwdWJsaWMgc3RhdGljIFJlc2VuZEhUVFBSZXF1ZXN0IGNyZWF0ZVJlc2VuZFJlcXVlc3QoUmVxdWVzdCByZXF1ZXN0KSB7CgkJaWYgKHJlcXVlc3QgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoJCXJldHVybiBuZXcgUmVzZW5kSFRUUFJlcXVlc3QoKE1vbml0b3IpcmVxdWVzdC5nZXRNb25pdG9yKCksIHJlcXVlc3QpOwoJfQoKCS8qKgoJICogQWRkcyBhIHJlc2VuZCByZXF1ZXN0IHRvIHRoaXMgcmVxdWVzdC4KCSAqIAoJICogQHBhcmFtIHJlcXVlc3QgdGhlIHJlc2VuZCByZXF1ZXN0IHRvIGFkZAoJICovCglwdWJsaWMgdm9pZCBhZGRSZXNlbmRSZXF1ZXN0KFJlcXVlc3QgcmVxdWVzdCwgUmVzZW5kSFRUUFJlcXVlc3QgcmVzZW5kUmVxKSB7CgkJaWYgKHJlcXVlc3QgPT0gbnVsbCB8fCByZXNlbmRSZXEgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCQoJCUxpc3QgbGlzdCA9IG51bGw7CgkJdHJ5IHsKCQkJbGlzdCA9IChMaXN0KSByZXNlbmRNYXAuZ2V0KHJlcXVlc3QpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCS8vIGlnbm9yZQoJCX0KCQkKCQlpZiAobGlzdCA9PSBudWxsKSB7CgkJCWxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCXJlc2VuZE1hcC5wdXQocmVxdWVzdCwgbGlzdCk7CgkJfQoJCWxpc3QuYWRkKHJlc2VuZFJlcSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlc2VuZCByZXF1ZXN0cyBiYXNlZCBvbiB0aGlzIHJlcXVlc3QuIAoJICogCgkgKiBAcmV0dXJuIHRoZSBhcnJheSBvZiByZXNlbmQgcmVxdWVzdHMgYmFzZWQgb24gdGhpcyByZXF1ZXN0CgkgKi8KCXB1YmxpYyBSZXNlbmRIVFRQUmVxdWVzdFtdIGdldFJlc2VuZFJlcXVlc3RzKFJlcXVlc3QgcmVxdWVzdCkgewoJCXRyeSB7CgkJCUxpc3QgbGlzdCA9IChMaXN0KSByZXNlbmRNYXAuZ2V0KHJlcXVlc3QpOwoJCQlSZXNlbmRIVFRQUmVxdWVzdFtdIHJyID0gbmV3IFJlc2VuZEhUVFBSZXF1ZXN0W2xpc3Quc2l6ZSgpXTsKCQkJbGlzdC50b0FycmF5KHJyKTsKCQkJcmV0dXJuIHJyOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBuZXcgUmVzZW5kSFRUUFJlcXVlc3RbMF07CgkJfQoJfQp9