LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChDKSAyMDA2LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAgICAgICoKICogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCgpwYWNrYWdlIGNvbS5pYm0uaWN1LnRlc3RzOwoKaW1wb3J0IGphdmEubWF0aC5CaWdJbnRlZ2VyOwppbXBvcnQgamF2YS50ZXh0LkZpZWxkUG9zaXRpb247CmltcG9ydCBqYXZhLnRleHQuUGFyc2VFeGNlcHRpb247CmltcG9ydCBqYXZhLnRleHQuUGFyc2VQb3NpdGlvbjsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CgppbXBvcnQgY29tLmlibS5pY3UudGV4dC5OdW1iZXJGb3JtYXQ7CmltcG9ydCBjb20uaWJtLmljdS51dGlsLlVMb2NhbGU7CgpwdWJsaWMgY2xhc3MgTnVtYmVyRm9ybWF0VGVzdCBleHRlbmRzIElDVVRlc3RDYXNlIHsKCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0Lk51bWJlckZvcm1hdChOdW1iZXJGb3JtYXQpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0TnVtYmVyRm9ybWF0KCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IG5ldyBOdW1iZXJGb3JtYXQoamF2YS50ZXh0Lk51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpKTsKICAgICAgICBhc3NlcnRFcXVhbHMobmYsIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmZvcm1hdChPYmplY3QsIFN0cmluZ0J1ZmZlciwgRmllbGRQb3NpdGlvbiknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXRPYmplY3RTdHJpbmdCdWZmZXJGaWVsZFBvc2l0aW9uKCkgewogICAgICAgIE51bWJlciBudW0gPSBuZXcgTG9uZygxMjM0TCk7CiAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICBGaWVsZFBvc2l0aW9uIGZwID0gbmV3IEZpZWxkUG9zaXRpb24oMCk7CiAgICAgICAgTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCkuZm9ybWF0KG51bSwgYnVmLCBmcCk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLDIzNCIsIGJ1Zi50b1N0cmluZygpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LnBhcnNlT2JqZWN0KFN0cmluZywgUGFyc2VQb3NpdGlvbiknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZU9iamVjdFN0cmluZ1BhcnNlUG9zaXRpb24oKSB7CiAgICAgICAgUGFyc2VQb3NpdGlvbiBwcCA9IG5ldyBQYXJzZVBvc2l0aW9uKDApOwogICAgICAgIE9iamVjdCByZXN1bHQgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5wYXJzZSgiMSwyMzQiLCBwcCk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKHJlc3VsdCwgbmV3IExvbmcoMTIzNCkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZm9ybWF0KGRvdWJsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXREb3VibGUoKSB7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLDIzNC41NjciLCBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5mb3JtYXQoMTIzNC41NjcpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmZvcm1hdChsb25nKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdExvbmcoKSB7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxLDIzNCIsIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLmZvcm1hdCgxMjM0TCkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZm9ybWF0KEJpZ0ludGVnZXIpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QmlnSW50ZWdlcigpIHsKICAgICAgICAvLyBub3RlLCBqYXZhIGRvZXNuJ3QgaGFuZGxlIGJpZ2ludGVnZXIgd2l0aCBmdWxsIHByZWNpc2lvbi4KICAgICAgICBCaWdJbnRlZ2VyIGJpID0gbmV3IEJpZ0ludGVnZXIoIjEyMzQ1NiIpOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLDQ1NiIsIGphdmEudGV4dC5OdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5mb3JtYXQoYmkpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmZvcm1hdChkb3VibGUsIFN0cmluZ0J1ZmZlciwgRmllbGRQb3NpdGlvbiknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RGb3JtYXREb3VibGVTdHJpbmdCdWZmZXJGaWVsZFBvc2l0aW9uKCkgewogICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgRmllbGRQb3NpdGlvbiBmcCA9IG5ldyBGaWVsZFBvc2l0aW9uKDApOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLDQ1Ni43ODkiLCBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5mb3JtYXQoMTIzNDU2Ljc4OSwgYnVmLCBmcCkudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5mb3JtYXQobG9uZywgU3RyaW5nQnVmZmVyLCBGaWVsZFBvc2l0aW9uKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEZvcm1hdExvbmdTdHJpbmdCdWZmZXJGaWVsZFBvc2l0aW9uKCkgewogICAgICAgIFN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgRmllbGRQb3NpdGlvbiBmcCA9IG5ldyBGaWVsZFBvc2l0aW9uKDApOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLDQ1NiIsIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLmZvcm1hdCgxMjM0NTZMLCBidWYsIGZwKS50b1N0cmluZygpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmZvcm1hdChCaWdJbnRlZ2VyLCBTdHJpbmdCdWZmZXIsIEZpZWxkUG9zaXRpb24pJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0Rm9ybWF0QmlnSW50ZWdlclN0cmluZ0J1ZmZlckZpZWxkUG9zaXRpb24oKSB7CiAgICAgICAgLy8gbm90ZSwgamF2YSBkb2Vzbid0IGhhbmRsZSBiaWdpbnRlZ2VyIHdpdGggZnVsbCBwcmVjaXNpb24uCiAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICBGaWVsZFBvc2l0aW9uIGZwID0gbmV3IEZpZWxkUG9zaXRpb24oMCk7CiAgICAgICAgQmlnSW50ZWdlciBiaSA9IG5ldyBCaWdJbnRlZ2VyKCIxMjM0NTYiKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyw0NTYiLCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCkuZm9ybWF0KGJpLCBidWYsIGZwKS50b1N0cmluZygpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LnBhcnNlKFN0cmluZywgUGFyc2VQb3NpdGlvbiknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVN0cmluZ1BhcnNlUG9zaXRpb24oKSB7CiAgICAgICAgUGFyc2VQb3NpdGlvbiBwcCA9IG5ldyBQYXJzZVBvc2l0aW9uKDMpOwogICAgICAgIGFzc2VydEVxdWFscyhuZXcgTG9uZygxMjM0NTYpLCBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKS5wYXJzZSgieHh4MTIzLDQ1Nnl5eSIsIHBwKSk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKDEwLCBwcC5nZXRJbmRleCgpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LnBhcnNlKFN0cmluZyknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RQYXJzZVN0cmluZygpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgTnVtYmVyIHJlc3VsdCA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLnBhcnNlKCIxMjMsNDU2LHl5eSIpOwogICAgICAgIGFzc2VydEVxdWFscyhuZXcgTG9uZygxMjM0NTYpLCByZXN1bHQpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuaXNQYXJzZUludGVnZXJPbmx5KCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RJc1BhcnNlSW50ZWdlck9ubHkoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgbmYuc2V0UGFyc2VJbnRlZ2VyT25seSh0cnVlKTsKICAgICAgICBhc3NlcnRUcnVlKG5mLmlzUGFyc2VJbnRlZ2VyT25seSgpKTsKICAgICAgICBuZi5zZXRQYXJzZUludGVnZXJPbmx5KGZhbHNlKTsKICAgICAgICBhc3NlcnRGYWxzZShuZi5pc1BhcnNlSW50ZWdlck9ubHkoKSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5zZXRQYXJzZUludGVnZXJPbmx5KGJvb2xlYW4pJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0U2V0UGFyc2VJbnRlZ2VyT25seSgpIHRocm93cyBQYXJzZUV4Y2VwdGlvbiB7CiAgICAgICAgU3RyaW5nIHN0ciA9ICIxMjMuNDU2LHl5eSI7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBEb3VibGUoMTIzLjQ1NiksIG5mLnBhcnNlKHN0cikpOwogICAgICAgIG5mLnNldFBhcnNlSW50ZWdlck9ubHkodHJ1ZSk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKG5ldyBMb25nKDEyMyksIG5mLnBhcnNlKHN0cikpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEdldEluc3RhbmNlKCkgewogICAgICAgIC8vIHVzZWQgZXZlcnl3aGVyZSwgbm8gbmVlZCB0byB0ZXN0CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0SW5zdGFuY2VMb2NhbGUoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5HRVJNQU5ZKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyw0NTYiLCBuZi5mb3JtYXQoMTIzLjQ1NikpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoVUxvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRJbnN0YW5jZVVMb2NhbGUoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKFVMb2NhbGUuR0VSTUFOWSk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMsNDU2IiwgbmYuZm9ybWF0KDEyMy40NTYpKTsgICAgICAgICAgICAKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROdW1iZXJJbnN0YW5jZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UoKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyw0NTYuNzg5IiwgbmYuZm9ybWF0KDEyMzQ1Ni43ODkpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKExvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROdW1iZXJJbnN0YW5jZUxvY2FsZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UoTG9jYWxlLkdFUk1BTlkpOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLjQ1Niw3ODkiLCBuZi5mb3JtYXQoMTIzNDU2Ljc4OSkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZ2V0TnVtYmVySW5zdGFuY2UoVUxvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXROdW1iZXJJbnN0YW5jZVVMb2NhbGUoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldE51bWJlckluc3RhbmNlKFVMb2NhbGUuR0VSTUFOWSk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMuNDU2LDc4OSIsIG5mLmZvcm1hdCgxMjM0NTYuNzg5KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UoKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEdldEludGVnZXJJbnN0YW5jZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKCk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMsNDU3IiwgbmYuZm9ybWF0KDEyMzQ1Ni43ODkpKTsgLy8gcm91bmRzCiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRJbnRlZ2VySW5zdGFuY2UoTG9jYWxlKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEdldEludGVnZXJJbnN0YW5jZUxvY2FsZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW50ZWdlckluc3RhbmNlKExvY2FsZS5HRVJNQU5ZKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMy40NTciLCBuZi5mb3JtYXQoMTIzNDU2Ljc4OSkpOyAvLyByb3VuZHMKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZShVTG9jYWxlKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEdldEludGVnZXJJbnN0YW5jZVVMb2NhbGUoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEludGVnZXJJbnN0YW5jZShVTG9jYWxlLkdFUk1BTlkpOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLjQ1NyIsIG5mLmZvcm1hdCgxMjM0NTYuNzg5KSk7IC8vIHJvdW5kcwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZSgpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0Q3VycmVuY3lJbnN0YW5jZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZSgpOwogICAgICAgIGFzc2VydEVxdWFscygiJDEyMyw0NTYuOTkiLCBuZi5mb3JtYXQoMTIzNDU2Ljk5KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKExvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDdXJyZW5jeUluc3RhbmNlTG9jYWxlKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRDdXJyZW5jeUluc3RhbmNlKExvY2FsZS5HRVJNQU5ZKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMy40NTYsOTkggCIsIG5mLmZvcm1hdCgxMjM0NTYuOTkpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldEN1cnJlbmN5SW5zdGFuY2UoVUxvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRDdXJyZW5jeUluc3RhbmNlVUxvY2FsZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0Q3VycmVuY3lJbnN0YW5jZShVTG9jYWxlLkdFUk1BTlkpOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLjQ1Niw5OSCAIiwgbmYuZm9ybWF0KDEyMzQ1Ni45OSkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQZXJjZW50SW5zdGFuY2UoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZSgpOwogICAgICAgIGFzc2VydEVxdWFscygiMTIzLDQ1NiUiLCBuZi5mb3JtYXQoMTIzNC41NikpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZ2V0UGVyY2VudEluc3RhbmNlKExvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQZXJjZW50SW5zdGFuY2VMb2NhbGUoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldFBlcmNlbnRJbnN0YW5jZShMb2NhbGUuR0VSTUFOWSk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjMuNDU2JSIsIG5mLmZvcm1hdCgxMjM0LjU2KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UoVUxvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRQZXJjZW50SW5zdGFuY2VVTG9jYWxlKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRQZXJjZW50SW5zdGFuY2UoVUxvY2FsZS5HRVJNQU5ZKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMy40NTYlIiwgbmYuZm9ybWF0KDEyMzQuNTYpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldFNjaWVudGlmaWNJbnN0YW5jZSgpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2NpZW50aWZpY0luc3RhbmNlKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRTY2llbnRpZmljSW5zdGFuY2UoKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIi4xMjM0NTZFNCIsIG5mLmZvcm1hdCgxMjM0LjU2KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRTY2llbnRpZmljSW5zdGFuY2UoTG9jYWxlKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdEdldFNjaWVudGlmaWNJbnN0YW5jZUxvY2FsZSgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0U2NpZW50aWZpY0luc3RhbmNlKExvY2FsZS5HRVJNQU5ZKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIiwxMjM0NTZFNCIsIG5mLmZvcm1hdCgxMjM0LjU2KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRTY2llbnRpZmljSW5zdGFuY2UoVUxvY2FsZSknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRTY2llbnRpZmljSW5zdGFuY2VVTG9jYWxlKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRTY2llbnRpZmljSW5zdGFuY2UoVUxvY2FsZS5HRVJNQU5ZKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIiwxMjM0NTZFNCIsIG5mLmZvcm1hdCgxMjM0LjU2KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRBdmFpbGFibGVMb2NhbGVzKCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRBdmFpbGFibGVMb2NhbGVzKCkgewogICAgICAgIExvY2FsZVtdIGlsb2NhbGVzID0gTnVtYmVyRm9ybWF0LmdldEF2YWlsYWJsZUxvY2FsZXMoKTsKICAgICAgICBpZiAoSUNVVGVzdENhc2UudGVzdGluZ1dyYXBwZXIpIHsKICAgICAgICAgICAgTG9jYWxlW10gamxvY2FsZXMgPSBqYXZhLnRleHQuTnVtYmVyRm9ybWF0LmdldEF2YWlsYWJsZUxvY2FsZXMoKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbG9jYWxlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgYXNzZXJ0RXF1YWxzKGpsb2NhbGVzW2ldLCBpbG9jYWxlc1tpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRBdmFpbGFibGVVTG9jYWxlcygpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0QXZhaWxhYmxlVUxvY2FsZXMoKSB7CiAgICAgICAgVUxvY2FsZVtdIHVsb2NhbGVzID0gTnVtYmVyRm9ybWF0LmdldEF2YWlsYWJsZVVMb2NhbGVzKCk7CiAgICAgICAgaWYgKElDVVRlc3RDYXNlLnRlc3RpbmdXcmFwcGVyKSB7CiAgICAgICAgICAgIExvY2FsZVtdIGpsb2NhbGVzID0gamF2YS50ZXh0Lk51bWJlckZvcm1hdC5nZXRBdmFpbGFibGVMb2NhbGVzKCk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdWxvY2FsZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIGFzc2VydEVxdWFscyhqbG9jYWxlc1tpXSwgdWxvY2FsZXNbaV0udG9Mb2NhbGUoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5pc0dyb3VwaW5nVXNlZCgpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0SXNHcm91cGluZ1VzZWQoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgbmYuc2V0R3JvdXBpbmdVc2VkKHRydWUpOwogICAgICAgIGFzc2VydFRydWUobmYuaXNHcm91cGluZ1VzZWQoKSk7CiAgICAgICAgbmYuc2V0R3JvdXBpbmdVc2VkKGZhbHNlKTsKICAgICAgICBhc3NlcnRGYWxzZShuZi5pc0dyb3VwaW5nVXNlZCgpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LnNldEdyb3VwaW5nVXNlZChib29sZWFuKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdFNldEdyb3VwaW5nVXNlZCgpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjEyMyw0NTYsNzg5IiwgbmYuZm9ybWF0KDEyMzQ1Njc4OSkpOwogICAgICAgIG5mLnNldEdyb3VwaW5nVXNlZChmYWxzZSk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKCIxMjM0NTY3ODkiLCBuZi5mb3JtYXQoMTIzNDU2Nzg5KSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWF4aW11bUludGVnZXJEaWdpdHMoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgbmYuc2V0TWF4aW11bUludGVnZXJEaWdpdHMoNCk7CiAgICAgICAgYXNzZXJ0RXF1YWxzKDQsIG5mLmdldE1heGltdW1JbnRlZ2VyRGlnaXRzKCkpOwogICAgICAgIG5mLnNldE1heGltdW1JbnRlZ2VyRGlnaXRzKDYpOwogICAgICAgIGFzc2VydEVxdWFscyg2LCBuZi5nZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpKTsKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LnNldE1heGltdW1JbnRlZ2VyRGlnaXRzKGludCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRNYXhpbXVtSW50ZWdlckRpZ2l0cygpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKICAgICAgICBuZi5zZXRNYXhpbXVtSW50ZWdlckRpZ2l0cyg0KTsKICAgICAgICBhc3NlcnRFcXVhbHMoIjMsNDU2IiwgbmYuZm9ybWF0KDEyMzQ1NikpOyAvLyBoaWdoIGRpZ2l0cyB0cnVuY2F0ZWQKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RHZXRNaW5pbXVtSW50ZWdlckRpZ2l0cygpIHsKICAgICAgICBOdW1iZXJGb3JtYXQgbmYgPSBOdW1iZXJGb3JtYXQuZ2V0SW5zdGFuY2UoKTsKICAgICAgICBuZi5zZXRNaW5pbXVtSW50ZWdlckRpZ2l0cyg0KTsKICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbmYuZ2V0TWluaW11bUludGVnZXJEaWdpdHMoKSk7CiAgICAgICAgbmYuc2V0TWluaW11bUludGVnZXJEaWdpdHMoNik7CiAgICAgICAgYXNzZXJ0RXF1YWxzKDYsIG5mLmdldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuc2V0TWluaW11bUludGVnZXJEaWdpdHMoaW50KScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdFNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOwogICAgICAgIG5mLnNldE1pbmltdW1JbnRlZ2VyRGlnaXRzKDQpOwogICAgICAgIGFzc2VydEVxdWFscygiMCwwMTIiLCBuZi5mb3JtYXQoMTIpKTsgLy8gcGFkIG91dCB3aXRoIHplcm8sIGdyb3VwaW5nIHN0aWxsIHVzZWQKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldE1heGltdW1GcmFjdGlvbkRpZ2l0cygpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOwogICAgICAgIG5mLnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cyg0KTsKICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbmYuZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkpOwogICAgICAgIG5mLnNldE1heGltdW1GcmFjdGlvbkRpZ2l0cyg2KTsKICAgICAgICBhc3NlcnRFcXVhbHMoNiwgbmYuZ2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKCkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKGludCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRNYXhpbXVtRnJhY3Rpb25EaWdpdHMoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgbmYuc2V0TWF4aW11bUZyYWN0aW9uRGlnaXRzKDQpOwogICAgICAgIGFzc2VydEVxdWFscygiMS4yMzQ2IiwgbmYuZm9ybWF0KDEuMjM0NTY3OCkpOyAvLyBsb3cgZGlnaXRzIHJvdW5kZWQKICAgIH0KCiAgICAvKgogICAgICogVGVzdCBtZXRob2QgZm9yICdjb20uaWJtLmljdS54LnRleHQuTnVtYmVyRm9ybWF0LmdldE1pbmltdW1GcmFjdGlvbkRpZ2l0cygpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0R2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCkgewogICAgICAgIE51bWJlckZvcm1hdCBuZiA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpOwogICAgICAgIG5mLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyg0KTsKICAgICAgICBhc3NlcnRFcXVhbHMoNCwgbmYuZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCkpOwogICAgICAgIG5mLnNldE1pbmltdW1GcmFjdGlvbkRpZ2l0cyg2KTsKICAgICAgICBhc3NlcnRFcXVhbHMoNiwgbmYuZ2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKCkpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKGludCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RTZXRNaW5pbXVtRnJhY3Rpb25EaWdpdHMoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgbmYuc2V0TWluaW11bUZyYWN0aW9uRGlnaXRzKDQpOwogICAgICAgIGFzc2VydEVxdWFscygiMS4yMDAwIiwgbmYuZm9ybWF0KDEuMikpOwogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQudG9TdHJpbmcoKScKICAgICAqLwogICAgcHVibGljIHZvaWQgdGVzdFRvU3RyaW5nKCkgewogICAgICAgIGFzc2VydE5vdE51bGwoTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCkudG9TdHJpbmcoKSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5oYXNoQ29kZSgpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0SGFzaENvZGUoKSB7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5mID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCk7CiAgICAgICAgTnVtYmVyRm9ybWF0IGVxID0gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKExvY2FsZS5VUyk7CiAgICAgICAgTnVtYmVyRm9ybWF0IG5lcSA9IE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZShMb2NhbGUuR0VSTUFOWSk7CiAgICAgICAgICAgICAgICAKICAgICAgICBJQ1VUZXN0Q2FzZS50ZXN0RUhDUyhuZiwgZXEsIG5lcSk7CiAgICB9CgogICAgLyoKICAgICAqIFRlc3QgbWV0aG9kIGZvciAnY29tLmlibS5pY3UueC50ZXh0Lk51bWJlckZvcm1hdC5jbG9uZSgpJwogICAgICovCiAgICBwdWJsaWMgdm9pZCB0ZXN0Q2xvbmUoKSB7CiAgICAgICAgLy8gc2VlIHRlc3RIYXNoQ29kZQogICAgfQoKICAgIC8qCiAgICAgKiBUZXN0IG1ldGhvZCBmb3IgJ2NvbS5pYm0uaWN1LngudGV4dC5OdW1iZXJGb3JtYXQuZXF1YWxzKE9iamVjdCknCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHRlc3RFcXVhbHNPYmplY3QoKSB7CiAgICAgICAgLy8gc2VlIHRlc3RIYXNoQ29kZQogICAgfQp9Cg==