cGFja2FnZSBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLnRvbWNhdC5jb3JlLmludGVybmFsLnhtbDsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYxLjAKICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjEwLmh0bWwKoCoKICogQ29udHJpYnV0b3JzOgogKiAgICBJQk0gLSBJbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLmlvLlNlcmlhbGl6YWJsZTsKaW1wb3J0IG9yZy53M2MuZG9tLio7Ci8qKgogKiBBbiBYTUwgZWxlbWVudC4KICovCnB1YmxpYyBjbGFzcyBYTUxFbGVtZW50IGltcGxlbWVudHMgU2VyaWFsaXphYmxlIHsKCXByaXZhdGUgRWxlbWVudCB4bWxFbGVtZW50OwoJcHJvdGVjdGVkIEZhY3RvcnkgZmFjdG9yeTsKCglwdWJsaWMgWE1MRWxlbWVudCgpIHsgfQoKCXB1YmxpYyBBdHRyIGFkZEF0dHJpYnV0ZShTdHJpbmcgcywgU3RyaW5nIHMxKSB7CgkJQXR0ciBhdHRyID0gZmFjdG9yeS5jcmVhdGVBdHRyaWJ1dGUocywgeG1sRWxlbWVudCk7CgkJYXR0ci5zZXRWYWx1ZShzMSk7CgkJcmV0dXJuIGF0dHI7Cgl9CgoJcHVibGljIFhNTEVsZW1lbnQgY3JlYXRlRWxlbWVudChpbnQgaW5kZXgsIFN0cmluZyBzKSB7CgkJcmV0dXJuIGZhY3RvcnkuY3JlYXRlRWxlbWVudChpbmRleCwgcywgeG1sRWxlbWVudCk7Cgl9CgoJcHVibGljIFhNTEVsZW1lbnQgY3JlYXRlRWxlbWVudChTdHJpbmcgcykgewoJCXJldHVybiBmYWN0b3J5LmNyZWF0ZUVsZW1lbnQocywgeG1sRWxlbWVudCk7Cgl9CgoJcHVibGljIHZvaWQgY3JlYXRlRW1wdHlCb2R5KCkgewoJfQoKCXB1YmxpYyBYTUxFbGVtZW50IGZpbmRFbGVtZW50KFN0cmluZyBzKSB7CgkJTm9kZUxpc3Qgbm9kZWxpc3QgPSB4bWxFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKHMpOwoJCWludCBpID0gbm9kZWxpc3QgPT0gbnVsbCA/IDAgOiBub2RlbGlzdC5nZXRMZW5ndGgoKTsKCQlmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykgewoJCQlOb2RlIG5vZGUgPSBub2RlbGlzdC5pdGVtKGopOwoJCQlTdHJpbmcgczEgPSBub2RlLmdldE5vZGVOYW1lKCkudHJpbSgpOwoJCQlpZiAoczEuZXF1YWxzKHMpKQoJCQkJcmV0dXJuIGZhY3RvcnkubmV3SW5zdGFuY2UoKEVsZW1lbnQpIG5vZGUpOwoJCX0KCQoJCXJldHVybiBjcmVhdGVFbGVtZW50KHMpOwoJfQoKCXB1YmxpYyBYTUxFbGVtZW50IGZpbmRFbGVtZW50KFN0cmluZyBzLCBpbnQgaSkgewoJCU5vZGVMaXN0IG5vZGVsaXN0ID0geG1sRWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShzKTsKCQlpbnQgaiA9IG5vZGVsaXN0ID09IG51bGwgPyAwIDogbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7CgkJZm9yIChpbnQgayA9IDA7IGsgPCBqOyBrKyspIHsKCQkJTm9kZSBub2RlID0gbm9kZWxpc3QuaXRlbShrKTsKCQkJU3RyaW5nIHMxID0gbm9kZS5nZXROb2RlTmFtZSgpLnRyaW0oKTsKCQkJaWYgKHMxLmVxdWFscyhzKSAmJiBrID09IGkpCgkJCQlyZXR1cm4gZmFjdG9yeS5uZXdJbnN0YW5jZSgoRWxlbWVudCkgbm9kZSk7CgkJfQoJCgkJcmV0dXJuIGNyZWF0ZUVsZW1lbnQocyk7Cgl9CgoJcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVWYWx1ZShTdHJpbmcgcykgewoJCUF0dHIgYXR0ciA9IHhtbEVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZShzKTsKCQlpZiAoYXR0ciAhPSBudWxsKQoJCQlyZXR1cm4gYXR0ci5nZXRWYWx1ZSgpOwoJCWVsc2UKCQkJcmV0dXJuIG51bGw7Cgl9CgkKCXB1YmxpYyBTdHJpbmcgZ2V0RWxlbWVudE5hbWUoKSB7CgkJcmV0dXJuIHhtbEVsZW1lbnQuZ2V0Tm9kZU5hbWUoKTsKCX0KCQoJcHVibGljIFN0cmluZyBnZXRFbGVtZW50VmFsdWUoKSB7CgkJcmV0dXJuIGdldEVsZW1lbnRWYWx1ZSh4bWxFbGVtZW50KTsKCX0KCQoJcHJvdGVjdGVkIHN0YXRpYyBTdHJpbmcgZ2V0RWxlbWVudFZhbHVlKEVsZW1lbnQgZWxlbWVudCkgewoJCVN0cmluZyBzID0gZWxlbWVudC5nZXROb2RlVmFsdWUoKTsKCQlpZiAocyAhPSBudWxsKQoJCQlyZXR1cm4gczsKCQlOb2RlTGlzdCBub2RlbGlzdCA9IGVsZW1lbnQuZ2V0Q2hpbGROb2RlcygpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykKCQkJaWYgKG5vZGVsaXN0Lml0ZW0oaSkgaW5zdGFuY2VvZiBUZXh0KQoJCQkJcmV0dXJuICgoVGV4dCkgbm9kZWxpc3QuaXRlbShpKSkuZ2V0RGF0YSgpOwoJCgkJcmV0dXJuIG51bGw7Cgl9CgkKCXB1YmxpYyBFbGVtZW50IGdldFN1YkVsZW1lbnQoU3RyaW5nIHMpIHsKCQlOb2RlTGlzdCBub2RlbGlzdCA9IHhtbEVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUocyk7CgkJaW50IGkgPSBub2RlbGlzdCA9PSBudWxsID8gMCA6IG5vZGVsaXN0LmdldExlbmd0aCgpOwoJCWZvciAoaW50IGogPSAwOyBqIDwgaTsgaisrKSB7CgkJCU5vZGUgbm9kZSA9IG5vZGVsaXN0Lml0ZW0oaik7CgkJCVN0cmluZyBzMSA9IG5vZGUuZ2V0Tm9kZU5hbWUoKS50cmltKCk7CgkJCWlmIChzMS5lcXVhbHMocykpCgkJCQlyZXR1cm4gKEVsZW1lbnQpIG5vZGU7CgkJfQoJCgkJcmV0dXJuIG51bGw7Cgl9CgoJcHVibGljIFN0cmluZyBnZXRTdWJFbGVtZW50VmFsdWUoU3RyaW5nIHMpIHsKCQlFbGVtZW50IGVsZW1lbnQgPSBnZXRTdWJFbGVtZW50KHMpOwoJCWlmIChlbGVtZW50ID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCgkJU3RyaW5nIHZhbHVlID0gZ2V0RWxlbWVudFZhbHVlKGVsZW1lbnQpOwoJCWlmICh2YWx1ZSA9PSBudWxsKQoJCQlyZXR1cm4gbnVsbDsKCQkKCQlyZXR1cm4gdmFsdWUudHJpbSgpOwoJfQoKCXB1YmxpYyBib29sZWFuIHJlbW92ZUF0dHJpYnV0ZShTdHJpbmcgcykgewoJCXRyeSB7CgkJCXhtbEVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKHMpOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KCglwdWJsaWMgYm9vbGVhbiByZW1vdmVFbGVtZW50KFN0cmluZyBzLCBpbnQgaSkgewoJCU5vZGVMaXN0IG5vZGVsaXN0ID0geG1sRWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShzKTsKCQlpbnQgaiA9IG5vZGVsaXN0ID09IG51bGwgPyAwIDogbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7CgkJZm9yIChpbnQgayA9IDA7IGsgPCBqOyBrKyspIHsKCQkJTm9kZSBub2RlID0gbm9kZWxpc3QuaXRlbShrKTsKCQkJU3RyaW5nIHMxID0gbm9kZS5nZXROb2RlTmFtZSgpLnRyaW0oKTsKCQkJaWYgKHMxLmVxdWFscyhzKSAmJiBrID09IGkpIHsKCQkJCXhtbEVsZW1lbnQucmVtb3ZlQ2hpbGQobm9kZSk7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0KCQoJCXJldHVybiBmYWxzZTsKCX0KCglwdWJsaWMgdm9pZCBzZXRBdHRyaWJ1dGVWYWx1ZShTdHJpbmcgcywgU3RyaW5nIHMxKSB7CgkJQXR0ciBhdHRyID0geG1sRWxlbWVudC5nZXRBdHRyaWJ1dGVOb2RlKHMpOwoJCWlmIChhdHRyID09IG51bGwpCgkJCWF0dHIgPSBhZGRBdHRyaWJ1dGUocywgczEpOwoJCWVsc2UKCQkJYXR0ci5zZXRWYWx1ZShzMSk7Cgl9CgoJdm9pZCBzZXRFbGVtZW50KEVsZW1lbnQgZWxlbWVudCkgewoJCXhtbEVsZW1lbnQgPSBlbGVtZW50OwoJfQoKCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBzZXRFbGVtZW50VmFsdWUoRWxlbWVudCBlbGVtZW50LCBTdHJpbmcgdmFsdWUpIHsKCQlTdHJpbmcgcyA9IGVsZW1lbnQuZ2V0Tm9kZVZhbHVlKCk7CgkJaWYgKHMgIT0gbnVsbCkgewoJCQllbGVtZW50LnNldE5vZGVWYWx1ZSh2YWx1ZSk7CgkJCXJldHVybjsKCQl9CgkJTm9kZUxpc3Qgbm9kZWxpc3QgPSBlbGVtZW50LmdldENoaWxkTm9kZXMoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IG5vZGVsaXN0LmdldExlbmd0aCgpOyBpKyspCgkJCWlmIChub2RlbGlzdC5pdGVtKGkpIGluc3RhbmNlb2YgVGV4dCkgewoJCQkJVGV4dCB0ZXh0ID0gKFRleHQpIG5vZGVsaXN0Lml0ZW0oaSk7CgkJCQl0ZXh0LnNldERhdGEodmFsdWUpOwoJCQkJcmV0dXJuOwoJCQl9CgkKCQlyZXR1cm47Cgl9CgoJdm9pZCBzZXRGYWN0b3J5KEZhY3RvcnkgZmFjdG9yeTEpIHsKCQlmYWN0b3J5ID0gZmFjdG9yeTE7Cgl9CgoJcHVibGljIHZvaWQgc2V0U3ViRWxlbWVudFZhbHVlKFN0cmluZyBzLCBTdHJpbmcgdmFsdWUpIHsKCQlFbGVtZW50IGVsZW1lbnQgPSBnZXRTdWJFbGVtZW50KHMpOwoJCWlmIChlbGVtZW50ID09IG51bGwpIHsKCQkJZWxlbWVudCA9IGZhY3RvcnkuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChzKTsKCQkJZWxlbWVudC5hcHBlbmRDaGlsZChmYWN0b3J5LmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJ0ZW1wIikpOwoJCQl4bWxFbGVtZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpOwoJCX0KCQlzZXRFbGVtZW50VmFsdWUoZWxlbWVudCwgdmFsdWUpOwoJfQoKCXB1YmxpYyBpbnQgc2l6ZU9mRWxlbWVudChTdHJpbmcgcykgewoJCU5vZGVMaXN0IG5vZGVsaXN0ID0geG1sRWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShzKTsKCQlpbnQgaSA9IG5vZGVsaXN0ID09IG51bGwgPyAwIDogbm9kZWxpc3QuZ2V0TGVuZ3RoKCk7CgkJcmV0dXJuIGk7Cgl9CgoJcHVibGljIHZvaWQgdXBkYXRlRWxlbWVudFZhbHVlKFN0cmluZyBzKSB7CgkJdHJ5IHsKCQkJeG1sRWxlbWVudC5zZXROb2RlVmFsdWUocyk7CgkJfSBjYXRjaCAoRE9NRXhjZXB0aW9uIGV4KSB7CgkJCU5vZGVMaXN0IG5vZGVsaXN0ID0geG1sRWxlbWVudC5nZXRDaGlsZE5vZGVzKCk7CgkJCWludCBpID0gbm9kZWxpc3QgPT0gbnVsbCA/IDAgOiBub2RlbGlzdC5nZXRMZW5ndGgoKTsKCQkJaWYgKGkgPiAwKSB7CgkJCQlmb3IgKGludCBqID0gMDsgaiA8IGk7IGorKykKCQkJCQlpZiAobm9kZWxpc3QuaXRlbShqKSBpbnN0YW5jZW9mIFRleHQpIHsKCQkJCQkJKChUZXh0KSBub2RlbGlzdC5pdGVtKGopKS5zZXREYXRhKHMpOwoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQl9IGVsc2UgewoJCQkJeG1sRWxlbWVudC5hcHBlbmRDaGlsZChmYWN0b3J5LmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHMpKTsKCQkJfQoJCX0KCX0KfQo=