LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIudG9tY2F0LmNvcmUuaW50ZXJuYWwueG1sOwoKaW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC4qOwoKaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlcjsKaW1wb3J0IGphdmF4LnhtbC5wYXJzZXJzLkRvY3VtZW50QnVpbGRlckZhY3Rvcnk7CgppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci50b21jYXQuY29yZS5pbnRlcm5hbC5UcmFjZTsKaW1wb3J0IG9yZy53M2MuZG9tLio7CmltcG9ydCBvcmcueG1sLnNheC5FbnRpdHlSZXNvbHZlcjsKaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwppbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwovKioKICogVXRpbGl0eSBjbGFzcyB0byBjcmVhdGUgYW5kIHJlYWQgWE1MIGRvY3VtZW50cy4KICovCnB1YmxpYyBjbGFzcyBYTUxVdGlsIHsKCXByaXZhdGUgc3RhdGljIERvY3VtZW50QnVpbGRlciBkb2N1bWVudEJ1aWxkZXI7CgoJLyoqCgkgKiBYTUxVdGlsIGNvbnN0cnVjdG9yIGNvbW1lbnQuCgkgKi8KCXB1YmxpYyBYTUxVdGlsKCkgewoJCXN1cGVyKCk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgRG9jdW1lbnRCdWlsZGVyIGdldERvY3VtZW50QnVpbGRlcigpIHsKCQlpZiAoZG9jdW1lbnRCdWlsZGVyID09IG51bGwpCgkJCXRyeSB7CgkJCQlEb2N1bWVudEJ1aWxkZXJGYWN0b3J5IGZhY3RvcnkgPSBEb2N1bWVudEJ1aWxkZXJGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CgkJCQlmYWN0b3J5LnNldFZhbGlkYXRpbmcoZmFsc2UpOwoJCQkJZmFjdG9yeS5zZXROYW1lc3BhY2VBd2FyZShmYWxzZSk7CgkJCQlmYWN0b3J5LnNldEV4cGFuZEVudGl0eVJlZmVyZW5jZXMoZmFsc2UpOwoJCQkJLy9mYWN0b3J5LnNldEF0dHJpYnV0ZSgiaHR0cDovL2FwYWNoZS5vcmcveG1sL2ZlYXR1cmVzL25vbnZhbGlkYXRpbmcvbG9hZC1leHRlcm5hbC1kdGQiLCBuZXcgQm9vbGVhbihmYWxzZSkpOwoJCQkJZG9jdW1lbnRCdWlsZGVyID0gZmFjdG9yeS5uZXdEb2N1bWVudEJ1aWxkZXIoKTsKCQkJCWRvY3VtZW50QnVpbGRlci5zZXRFbnRpdHlSZXNvbHZlcihuZXcgRW50aXR5UmVzb2x2ZXIoKSB7CgkJCQkJcHVibGljIElucHV0U291cmNlIHJlc29sdmVFbnRpdHkoU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCQkJcmV0dXJuIG5ldyBJbnB1dFNvdXJjZShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbMF0pKTsKCQkJCQl9CgkJCQl9KTsKCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIlJycm9yIGNyZWF0aW5nIGRvY3VtZW50IGJ1aWxkZXIiKTsKCQkJfQoKCQlyZXR1cm4gZG9jdW1lbnRCdWlsZGVyOwoJfQoKCS8qKgoJICogQ3JlYXRlIGEgY2hpbGQgb2YgdGhlIGdpdmVuIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LgoJICogQHJldHVybiBvcmcudzNjLmRvbS5FbGVtZW50CgkgKiBAcGFyYW0gbm9kZU5hbWUgamF2YS5sYW5nLlN0cmluZwoJICovCglwdWJsaWMgc3RhdGljIEVsZW1lbnQgY3JlYXRlQ2hpbGRFbGVtZW50KERvY3VtZW50IGRvYywgRWxlbWVudCBlbGVtZW50LCBpbnQgaW5kZXgsIFN0cmluZyBub2RlTmFtZSkgewoJCUVsZW1lbnQgZWxlbWVudDIgPSBkb2MuY3JlYXRlRWxlbWVudChub2RlTmFtZSk7CgkJdHJ5IHsKCQkJTm9kZUxpc3QgY2hpbGRMaXN0ID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShub2RlTmFtZSk7CgkJCU5vZGUgY2hpbGQgPSBjaGlsZExpc3QuaXRlbShpbmRleCk7CgkJCWVsZW1lbnQuaW5zZXJ0QmVmb3JlKGVsZW1lbnQyLCBjaGlsZCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJZWxlbWVudC5hcHBlbmRDaGlsZChlbGVtZW50Mik7CgkJfQoJCXJldHVybiBlbGVtZW50MjsKCX0KCgkvKioKCSAqIENyZWF0ZSBhIGNoaWxkIG9mIHRoZSBnaXZlbiBub2RlLgoJICogQHJldHVybiBvcmcudzNjLmRvbS5FbGVtZW50CgkgKiBAcGFyYW0gbm9kZU5hbWUgamF2YS5sYW5nLlN0cmluZwoJICovCglwdWJsaWMgc3RhdGljIEVsZW1lbnQgY3JlYXRlQ2hpbGRFbGVtZW50KERvY3VtZW50IGRvYywgTm9kZSBub2RlLCBTdHJpbmcgbm9kZU5hbWUpIHsKCQlFbGVtZW50IGVsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudChub2RlTmFtZSk7CgkJbm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTsKCQlyZXR1cm4gZWxlbWVudDsKCX0KCgkvKioKCSAqIFNldCB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIG5vZGUgdG8gdGhlIGdpdmVuIHRleHQuCgkgKiBAcGFyYW0gbiBvcmcudzNjLmRvbS5Ob2RlCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBjcmVhdGVUZXh0Q2hpbGRFbGVtZW50KERvY3VtZW50IGRvYywgTm9kZSBub2RlLCBTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CgkJRWxlbWVudCBlbGVtZW50ID0gY3JlYXRlQ2hpbGRFbGVtZW50KGRvYywgbm9kZSwgbmFtZSk7CgkJZWxlbWVudC5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUodmFsdWUpKTsKCX0KCgkvKioKCSAqIFJldHVybiB0aGUgYXR0cmlidXRlIHZhbHVlLgoJICogQHJldHVybiBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gZWxlbWVudCBvcmcudzNjLmRvbS5FbGVtZW50CgkgKiBAcGFyYW0gYXR0ciBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKEVsZW1lbnQgZWxlbWVudCwgU3RyaW5nIGF0dHIpIHsKCQlyZXR1cm4gZWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKGF0dHIpLmdldFZhbHVlKCk7Cgl9CgoJcHVibGljIHN0YXRpYyBieXRlW10gZ2V0Q29udGVudHMoRG9jdW1lbnQgZG9jdW1lbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQl0cnkgewoJCQlwcmludChuZXcgUHJpbnRXcml0ZXIob3V0KSwgZG9jdW1lbnQpOwoJCQlyZXR1cm4gb3V0LnRvQnl0ZUFycmF5KCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJCXRocm93IG5ldyBJT0V4Y2VwdGlvbihleC5nZXRMb2NhbGl6ZWRNZXNzYWdlKCkpOwoJCX0gZmluYWxseSB7CgkJCWlmIChvdXQgIT0gbnVsbCkKCQkJCXRyeSB7CgkJCQkJb3V0LmNsb3NlKCk7CgkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCS8vIGlnbm9yZQoJCQkJfQoJCX0KCX0KCglwcm90ZWN0ZWQgc3RhdGljIFN0cmluZyBnZXREb2N1bWVudFR5cGVEYXRhKERvY3VtZW50VHlwZSBkb2N0eXBlKSB7CgkJU3RyaW5nIGRhdGEgPSBkb2N0eXBlLmdldE5hbWUoKTsKCQlpZiAoZG9jdHlwZS5nZXRQdWJsaWNJZCgpICE9IG51bGwpIHsKCQkJZGF0YSArPSAiIFBVQkxJQyBcIiIgKyBkb2N0eXBlLmdldFB1YmxpY0lkKCkgKyAiXCIiOwoJCQlTdHJpbmcgc3lzdGVtSWQgPSBkb2N0eXBlLmdldFN5c3RlbUlkKCk7CgkJCWlmIChzeXN0ZW1JZCA9PSBudWxsKQoJCQkJc3lzdGVtSWQgPSAiIjsKCQkJZGF0YSArPSAiIFwiIiArIHN5c3RlbUlkICsgIlwiIjsKCQl9IGVsc2UKCQkJZGF0YSArPSAiIFNZU1RFTSBcIiIgKyBkb2N0eXBlLmdldFN5c3RlbUlkKCkgKyAiXCIiOwoJCgkJcmV0dXJuIGRhdGE7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gYW4gaXRlcmF0b3IgZm9yIHRoZSBzdWJlbGVtZW50cy4KCSAqIEByZXR1cm4gamF2YS51dGlsLkl0ZXJhdG9yCgkgKiBAcGFyYW0gZWxlbWVudCBvcmcudzNjLmRvbS5FbGVtZW50CgkgKiBAcGFyYW0gbmFtZSBqYXZhLmxhbmcuU3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgSXRlcmF0b3IgZ2V0Tm9kZUl0ZXJhdG9yKEVsZW1lbnQgZWxlbWVudCwgU3RyaW5nIG5hbWUpIHsKCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJTm9kZUxpc3Qgbm9kZUxpc3QgPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKG5hbWUpOwoJCgkJaW50IGxlbmd0aCA9IG5vZGVMaXN0LmdldExlbmd0aCgpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspCgkJCWxpc3QuYWRkKG5vZGVMaXN0Lml0ZW0oaSkpOwoJCgkJcmV0dXJuIGxpc3QuaXRlcmF0b3IoKTsKCX0KCgkvKioKCSAqIEdldCB0aGUgdmFsdWUgb2YgdGhpcyBub2RlLiBXaWxsIHJldHVybiAiIiBpbnN0ZWFkIG9mIG51bGwuCgkgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSBub2RlIG9yZy53M2MuZG9tLk5vZGUKCSAqLwoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0Tm9kZVZhbHVlKE5vZGUgbm9kZSkgewoJCU5vZGVMaXN0IG5vZGVMaXN0ID0gbm9kZS5nZXRDaGlsZE5vZGVzKCk7CgkKCQlpbnQgbGVuZ3RoID0gbm9kZUxpc3QuZ2V0TGVuZ3RoKCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewoJCQlOb2RlIG4gPSBub2RlTGlzdC5pdGVtKGkpOwoJCQlpZiAobiBpbnN0YW5jZW9mIFRleHQpIHsKCQkJCVRleHQgdCA9IChUZXh0KSBuOwoJCQkJcmV0dXJuIHQuZ2V0Tm9kZVZhbHVlKCk7CgkJCX0KCQl9CgkJcmV0dXJuICIiOwoJfQoKCS8qKgoJICogR2V0IHRoZSB2YWx1ZSBvZiBhIHN1Ym5vZGUuCgkgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKCSAqIEBwYXJhbSBub2RlIG9yZy53M2MuZG9tLk5vZGUKCSAqLwoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U3ViTm9kZVZhbHVlKEVsZW1lbnQgZWxlbWVudCwgU3RyaW5nIG5hbWUpIHsKCQlOb2RlTGlzdCBub2RlTGlzdCA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUobmFtZSk7CgkJcmV0dXJuIGdldE5vZGVWYWx1ZShub2RlTGlzdC5pdGVtKDApKS50cmltKCk7Cgl9CgoJLyoqCgkgKiBJbnNlcnQgdGhlIGdpdmVuIHRleHQuCgkgKiBAcGFyYW0gbiBvcmcudzNjLmRvbS5Ob2RlCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBpbnNlcnRUZXh0KERvY3VtZW50IGRvYywgTm9kZSBub2RlLCBTdHJpbmcgdGV4dCkgewoJCW5vZGUuYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZUNEQVRBU2VjdGlvbih0ZXh0KSk7Cgl9CgoJcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgbm9ybWFsaXplKFN0cmluZyBzKSB7CgkJU3RyaW5nQnVmZmVyIHN0cmluZ2J1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCQlpbnQgaSA9IHMgPT0gbnVsbCA/IDAgOiBzLmxlbmd0aCgpOwoJCWZvciAoaW50IGogPSAwOyBqIDwgaTsgaisrKSB7CgkJCWNoYXIgYyA9IHMuY2hhckF0KGopOwoJCQlzd2l0Y2ggKGMpIHsKCQkJCWNhc2UgNjAgOiAvKiAnPCcgKi8KCQkJCQlzdHJpbmdidWZmZXIuYXBwZW5kKCImbHQ7Iik7CgkJCQkJYnJlYWs7CgkKCQkJCWNhc2UgNjIgOiAvKiAnPicgKi8KCQkJCQlzdHJpbmdidWZmZXIuYXBwZW5kKCImZ3Q7Iik7CgkJCQkJYnJlYWs7CgkKCQkJCWNhc2UgMzggOiAvKiAnJicgKi8KCQkJCQlzdHJpbmdidWZmZXIuYXBwZW5kKCImYW1wOyIpOwoJCQkJCWJyZWFrOwoJCgkJCQljYXNlIDM0IDogLyogJyInICovCgkJCQkJc3RyaW5nYnVmZmVyLmFwcGVuZCgiJnF1b3Q7Iik7CgkJCQkJYnJlYWs7CgkKCQkJCWNhc2UgMTAgOiAvKiAnXG4nICovCgkJCQljYXNlIDEzIDogLyogJ1xyJyAqLwoJCQkJZGVmYXVsdCA6CgkJCQkJc3RyaW5nYnVmZmVyLmFwcGVuZChjKTsKCQkJCQlicmVhazsKCQoJCQl9CgkJfQoJCgkJcmV0dXJuIHN0cmluZ2J1ZmZlci50b1N0cmluZygpOwoJfQoKCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBwcmludChQcmludFdyaXRlciBvdXQsIE5vZGUgbm9kZSkgewoJCWlmIChub2RlID09IG51bGwpCgkJCXJldHVybjsKCQlzaG9ydCB0eXBlID0gbm9kZS5nZXROb2RlVHlwZSgpOwoJCXN3aXRjaCAodHlwZSkgewoJCQljYXNlIE5vZGUuRE9DVU1FTlRfTk9ERTogewoJCQkJLy9vdXQucHJpbnRsbigiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+Iik7CgkJCQlvdXQucHJpbnRsbigiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiPz5cbiIpOwoJCQkJTm9kZUxpc3Qgbm9kZWxpc3QgPSBub2RlLmdldENoaWxkTm9kZXMoKTsKCQkJCWludCBzaXplID0gbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7CgkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykKCQkJCQlwcmludChvdXQsIG5vZGVsaXN0Lml0ZW0oaSkpOwoJCQkJYnJlYWs7CgkJCX0KCQoJCQljYXNlIE5vZGUuRE9DVU1FTlRfVFlQRV9OT0RFOiB7CgkJCQlEb2N1bWVudFR5cGUgZG9jVHlwZSA9IChEb2N1bWVudFR5cGUpIG5vZGU7CgkJCQlvdXQucHJpbnQoIjwhRE9DVFlQRSAiICsgZ2V0RG9jdW1lbnRUeXBlRGF0YShkb2NUeXBlKSArICI+XG4iKTsKCQkJCWJyZWFrOwoJCQl9CgkKCQkJY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTogewoJCQkJb3V0LnByaW50KCc8Jyk7CgkJCQlvdXQucHJpbnQobm9kZS5nZXROb2RlTmFtZSgpKTsKCQkJCU5hbWVkTm9kZU1hcCBtYXAgPSBub2RlLmdldEF0dHJpYnV0ZXMoKTsKCQkJCWlmIChtYXAgIT0gbnVsbCkgewoJCQkJCWludCBzaXplID0gbWFwLmdldExlbmd0aCgpOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQkJCUF0dHIgYXR0ciA9IChBdHRyKSBtYXAuaXRlbShpKTsKCQkJCQkJb3V0LnByaW50KCcgJyk7CgkJCQkJCW91dC5wcmludChhdHRyLmdldE5vZGVOYW1lKCkpOwoJCQkJCQlvdXQucHJpbnQoIj1cIiIpOwoJCQkJCQlvdXQucHJpbnQobm9ybWFsaXplKGF0dHIuZ2V0Tm9kZVZhbHVlKCkpKTsKCQkJCQkJb3V0LnByaW50KCciJyk7CgkJCQkJfQoJCQkJfQoJCgkJCQlpZiAoIW5vZGUuaGFzQ2hpbGROb2RlcygpKQoJCQkJCW91dC5wcmludCgiLz4iKTsKCQkJCWVsc2UgewoJCQkJCW91dC5wcmludCgnPicpOwoJCQkJCU5vZGVMaXN0IG5vZGVsaXN0ID0gbm9kZS5nZXRDaGlsZE5vZGVzKCk7CgkJCQkJaW50IG51bUNoaWxkcmVuID0gbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7CgkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBudW1DaGlsZHJlbjsgaSsrKQoJCQkJCQlwcmludChvdXQsIG5vZGVsaXN0Lml0ZW0oaSkpOwoJCgkJCQkJb3V0LnByaW50KCI8LyIpOwoJCQkJCW91dC5wcmludChub2RlLmdldE5vZGVOYW1lKCkpOwoJCQkJCW91dC5wcmludCgnPicpOwoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQoJCQljYXNlIE5vZGUuRU5USVRZX1JFRkVSRU5DRV9OT0RFOiB7CgkJCQlOb2RlTGlzdCBub2RlbGlzdCA9IG5vZGUuZ2V0Q2hpbGROb2RlcygpOwoJCQkJaWYgKG5vZGVsaXN0ICE9IG51bGwpIHsKCQkJCQlpbnQgc2l6ZSA9IG5vZGVsaXN0LmdldExlbmd0aCgpOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKQoJCQkJCQlwcmludChvdXQsIG5vZGVsaXN0Lml0ZW0oaSkpOwoJCgkJCQl9CgkJCQlicmVhazsKCQkJfQoJCgkJCWNhc2UgTm9kZS5DREFUQV9TRUNUSU9OX05PREU6IHsKCQkJCW91dC5wcmludChub3JtYWxpemUobm9kZS5nZXROb2RlVmFsdWUoKSkpOwoJCQkJYnJlYWs7CgkJCX0KCQoJCQljYXNlIE5vZGUuVEVYVF9OT0RFOiB7CgkJCQlvdXQucHJpbnQobm9ybWFsaXplKG5vZGUuZ2V0Tm9kZVZhbHVlKCkpKTsKCQkJCWJyZWFrOwoJCQl9CgkKCQkJY2FzZSBOb2RlLlBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERTogewoJCQkJb3V0LnByaW50KCI8PyIpOwoJCQkJb3V0LnByaW50KG5vZGUuZ2V0Tm9kZU5hbWUoKSk7CgkJCQlTdHJpbmcgcyA9IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7CgkJCQlpZiAocyAhPSBudWxsICYmIHMubGVuZ3RoKCkgPiAwKSB7CgkJCQkJb3V0LnByaW50KCcgJyk7CgkJCQkJb3V0LnByaW50KHMpOwoJCQkJfQoJCQkJb3V0LnByaW50KCI/PiIpOwoJCQkJYnJlYWs7CgkJCX0KCQoJCQljYXNlIE5vZGUuQ09NTUVOVF9OT0RFOiB7CgkJCQlvdXQucHJpbnQoIjwhLS0iKTsKCQkJCW91dC5wcmludChub2RlLmdldE5vZGVWYWx1ZSgpKTsKCQkJCW91dC5wcmludCgiLS0+Iik7CgkJCQlicmVhazsKCQkJfQoJCgkJCWRlZmF1bHQ6IHsKCQkJCW91dC5wcmludChub3JtYWxpemUobm9kZS5nZXROb2RlVmFsdWUoKSkpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJb3V0LmZsdXNoKCk7Cgl9CgoJcHVibGljIHN0YXRpYyB2b2lkIHNhdmUoU3RyaW5nIGZpbGVuYW1lLCBEb2N1bWVudCBkb2N1bWVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlQcmludFdyaXRlciBvdXQgPSBudWxsOwoJCXRyeSB7CgkJCW91dCA9IG5ldyBQcmludFdyaXRlcihuZXcgQnVmZmVyZWRXcml0ZXIobmV3IEZpbGVXcml0ZXIoZmlsZW5hbWUpKSk7CgkJCS8vdHJhY2VOb2RlKGRvY3VtZW50LCAiIik7CgkJCXByaW50KG91dCwgZG9jdW1lbnQpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgewoJCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXguZ2V0TG9jYWxpemVkTWVzc2FnZSgpKTsKCQl9IGZpbmFsbHkgewoJCQlpZiAob3V0ICE9IG51bGwpCgkJCQl0cnkgewoJCQkJCW91dC5jbG9zZSgpOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQkvLyBpZ25vcmUKCQkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBTZXQgdGhlIHZhbHVlIG9mIHRoZSBzdWJub2RlCgkgKgoJICogQHBhcmFtIGVsZW1lbnQgb3JnLnczYy5kb20uRWxlbWVudAoJICogQHBhcmFtIG5hbWUgamF2YS5sYW5nLlN0cmluZwoJICogQHBhcmFtIHZhbHVlIGphdmEubGFuZy5TdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHNldE5vZGVWYWx1ZShOb2RlIG5vZGUsIFN0cmluZyBuYW1lLCBTdHJpbmcgdmFsdWUpIHsKCQlTdHJpbmcgcyA9IG5vZGUuZ2V0Tm9kZVZhbHVlKCk7CgkJaWYgKHMgIT0gbnVsbCkgewoJCQlub2RlLnNldE5vZGVWYWx1ZSh2YWx1ZSk7CgkJCXJldHVybjsKCQl9CgkJTm9kZUxpc3Qgbm9kZWxpc3QgPSBub2RlLmdldENoaWxkTm9kZXMoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IG5vZGVsaXN0LmdldExlbmd0aCgpOyBpKyspIHsKCQkJaWYgKG5vZGVsaXN0Lml0ZW0oaSkgaW5zdGFuY2VvZiBUZXh0KSB7CgkJCQlUZXh0IHRleHQgPSAoVGV4dCkgbm9kZWxpc3QuaXRlbShpKTsKCQkJCXRleHQuc2V0RGF0YSh2YWx1ZSk7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgkJcmV0dXJuOwoJfQoKCXB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvU3RyaW5nKERvY3VtZW50IGRvY3VtZW50KSB7CgkJUHJpbnRXcml0ZXIgb3V0ID0gbnVsbDsKCQl0cnkgewoJCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oMTAyNCk7CgkJCW91dCA9IG5ldyBQcmludFdyaXRlcihiYW9zKTsKCQkJcHJpbnQob3V0LCBkb2N1bWVudCk7CgkJCXJldHVybiBuZXcgU3RyaW5nKGJhb3MudG9CeXRlQXJyYXkoKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CgkJCS8vIGlnbm9yZQoJCX0gZmluYWxseSB7CgkJCWlmIChvdXQgIT0gbnVsbCkKCQkJCXRyeSB7CgkJCQkJb3V0LmNsb3NlKCk7CgkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCS8vIGlnbm9yZQoJCQkJfQoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KfQ==