{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"codehealth","informationUri":"https://codehealth.canine.dev","rules":[{"id":"D1","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D1"},{"id":"D2","name":"Cognitive Complexity","shortDescription":{"text":"Cognitive Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D2"},{"id":"D3","name":"God Classes","shortDescription":{"text":"God Classes"},"helpUri":"https://codehealth.canine.dev/dimensions/D3"},{"id":"D4","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/D4"},{"id":"D8","name":"Code Coverage","shortDescription":{"text":"Code Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/D8"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"]}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"AX9","name":"CQS / query purity","shortDescription":{"text":"CQS / query purity"},"helpUri":"https://codehealth.canine.dev/dimensions/AX9"},{"id":"ES1","name":"Fold determinism","shortDescription":{"text":"Fold determinism"},"helpUri":"https://codehealth.canine.dev/dimensions/ES1"},{"id":"ES2","name":"Immutable events","shortDescription":{"text":"Immutable events"},"helpUri":"https://codehealth.canine.dev/dimensions/ES2"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"X31","name":"Test-only surface in a production module","shortDescription":{"text":"Test-only surface in a production module"},"helpUri":"https://codehealth.canine.dev/dimensions/X31"},{"id":"X9","name":"Subsumed condition operand","shortDescription":{"text":"Subsumed condition operand"},"helpUri":"https://codehealth.canine.dev/dimensions/X9"}]}},"results":[{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uac_make.parse_opts (cyclomatic 94): nksip_call_uac_make.parse_opts has cyclomatic complexity 94 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"406b33956939da675c0c7c1a8be9448cd3fcfa9f198a8a60b113dc0635e4e837"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_reply.parse (cyclomatic 76): nksip_reply.parse has cyclomatic complexity 76 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_reply.erl"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f9734406f930fd77065e049972d33bbb6000f91ed3dd221fce0ddd5ee52884e"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_sipmsg.get_meta (cyclomatic 66): nksip_sipmsg.get_meta has cyclomatic complexity 66 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sipmsg.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"e469d34e5e039214410da3d69e350a72666affe8d639e00a94ed751658e8f145"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uas_make.parse_opts (cyclomatic 65): nksip_call_uas_make.parse_opts has cyclomatic complexity 65 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_make.erl"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"68f8cc2a0688e58978bb97ff551b85eaf05cb04db2909038c516c20e3a76142b"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uac_dialog.do_response (cyclomatic 47): nksip_call_uac_dialog.do_response has cyclomatic complexity 47 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"954bfaeb98fdf04e8f07a9e57cfff941df236ebfc98b7b0cba06be44fe80c577"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uas_dialog.do_response (cyclomatic 47): nksip_call_uas_dialog.do_response has cyclomatic complexity 47 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_dialog.erl"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7f9839aeaceaa5a855d894199e5df4ec4013308c0e54e0fe8d4b1102d51ff89"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_headers.update (cyclomatic 37): nksip_headers.update has cyclomatic complexity 37 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_headers.erl"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"b57292515c65b7c1f43d9907db051d60fda3c10e6f4591eeee0934d159d5fe55"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uas_dialog.do_request (cyclomatic 30): nksip_call_uas_dialog.do_request has cyclomatic complexity 30 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_dialog.erl"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7c1f052c9d2eb3ac9dca2e770daefe8441af100221b9e28a80cdcb3315d27ef"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uac_reply.do_reply (cyclomatic 29): nksip_call_uac_reply.do_reply has cyclomatic complexity 29 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_reply.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"259786b980322c987304f60f6b03c9e80aacdc173fc43d614996ccb5223b64f4"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_parse_via.domain (cyclomatic 26): nksip_parse_via.domain has cyclomatic complexity 26 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_via.erl"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"87ad14ed2c9cb069f681769508c521c2d2e01a94339e2c97c0ee7ac896f44da4"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_reply.post (cyclomatic 25): nksip_reply.post has cyclomatic complexity 25 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_reply.erl"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c50eed9b8e1ebed036fc5b53e2aba7204607a7825256841e4ce2a8a0ad8db10"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_sdp.unparse (cyclomatic 25): nksip_sdp.unparse has cyclomatic complexity 25 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing. This is NOT this file\u0027s highest cyclomatic complexity: nksip_sdp.parse_sdp (cyclomatic 29) is higher and carries no row of its own \u2014 it was excluded as a flat dispatcher (a long switch/match over independent cases: many branches, almost no nesting), which this dimension does not treat as a refactor obligation. It is named here so the ranking you see in this file is not mistaken for the whole of it; the excluded function is counted neither in this dimension\u0027s figures nor in its score."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfdba7e1ac87db0de5fdc037efe8647be4dbbfb6f8c481ffff51091d2b598f0e"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_sipmsg.header (cyclomatic 24): nksip_sipmsg.header has cyclomatic complexity 24 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sipmsg.erl"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"2356d715fcc5a88944783ed815835fa209494e1c32a5f5dd593efafe0d160a83"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_event.update (cyclomatic 22): nksip_call_event.update has cyclomatic complexity 22 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"74e7e5247b12fa73e60f5c001ea189bc0b07cb8b323c0c996007f2ec144a4142"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_dialog.target_update (cyclomatic 21): nksip_call_dialog.target_update has cyclomatic complexity 21 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a74f7bb8fc3bd60f63bc728ccc6f94c38533360886395866fbfd33b7c6f0b8c"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_uac_auto_outbound_callbacks.nksip_uac_auto_register_upd_reg (cyclomatic 21): nksip_uac_auto_outbound_callbacks.nksip_uac_auto_register_upd_reg has cyclomatic complexity 21 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_outbound_callbacks.erl"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1bf471a458f66840091387b4473c3a0e2e8f5cddad7850ef1e3197dc328d3aa"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_dialog.do_update (cyclomatic 20): nksip_call_dialog.do_update has cyclomatic complexity 20 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f8f617e1b9e8f8fc501a7abae2e7f6200d9b15a9b3c6869faaf5b2d23f89e50"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_subscription_lib.state (cyclomatic 20): nksip_subscription_lib.state has cyclomatic complexity 20 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_subscription_lib.erl"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"5124e8d2b572fb77c6e879991960446554508c842f59d3c7b8af3913d024faef"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_outbound.proxy_opts (cyclomatic 20): nksip_outbound.proxy_opts has cyclomatic complexity 20 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"3addfdac57d146efe5dbef94c7c5ef503863a83bf44fd5178f27275d403eabfe"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uac_dialog.pre_request (cyclomatic 19): nksip_call_uac_dialog.pre_request has cyclomatic complexity 19 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dd632db02d4ae4a7c4b222b5dcd48f7d95a885e3a5964d0c3696e4668069f71"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_parse_header.parse (cyclomatic 19): nksip_parse_header.parse has cyclomatic complexity 19 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing. This is NOT this file\u0027s highest cyclomatic complexity: nksip_parse_header.header (cyclomatic 22) is higher and carries no row of its own \u2014 it was excluded as a flat dispatcher (a long switch/match over independent cases: many branches, almost no nesting), which this dimension does not treat as a refactor obligation. It is named here so the ranking you see in this file is not mistaken for the whole of it; the excluded function is counted neither in this dimension\u0027s figures nor in its score."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_header.erl"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7311af0492ee14f4a2a27d20532aa003f3a0291df1b406c944a0808f4227873"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_event.uas_response (cyclomatic 18): nksip_call_event.uas_response has cyclomatic complexity 18 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"37d8e36fc18ad286051b6f49e2bd85655180f30c7e3f42091476ded79a76cce4"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_parse_via.port (cyclomatic 18): nksip_parse_via.port has cyclomatic complexity 18 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_via.erl"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fb1467df3b1d4a9cc131680e358a696c79fae479e691db6c526f86485403987"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_event.uac_response (cyclomatic 16): nksip_call_event.uac_response has cyclomatic complexity 16 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"13d21f60b9c7d881d757858c4d46f93b67e8798c3e4e7796aa85189d3ee0677d"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_event.uas_request (cyclomatic 16): nksip_call_event.uas_request has cyclomatic complexity 16 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbe0a856861bdbbcfbd7005665d68a352c33386afeb5f74f09207fc6ad4b90cf"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_call_uac_send.send (cyclomatic 16): nksip_call_uac_send.send has cyclomatic complexity 16 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_send.erl"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"e982d57eae59db704986cd9a859c0635e14bd77ab5ebc936ffaa911010d2a7b8"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_outbound.add_headers (cyclomatic 16): nksip_outbound.add_headers has cyclomatic complexity 16 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"da7eeef887e92153c4489c29103c8b959ab9564109fd3fba157e6719a9ab535b"}},{"ruleId":"D1","level":"warning","message":{"text":"nksip_outbound.do_proxy_opts (cyclomatic 16): nksip_outbound.do_proxy_opts has cyclomatic complexity 16 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"51982fdbf0e040d789192ee199339e68baea67fe5b4b3bf18eed1d0fddb761d9"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uac_make.parse_opts (cognitive 45): nksip_call_uac_make.parse_opts has cognitive complexity 45 (threshold 15). Drivers by points: match/switch 19 (32 pts), boolean chains 13 (nesting depth added 13). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6e27f4c77a46eb641edc58535053c69238df206a7ffb0d1863170f985313776"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_sdp.unparse (cognitive 44): nksip_sdp.unparse has cognitive complexity 44 (threshold 15). Drivers by points: match/switch 26 (34 pts), loops 7 (10 pts) (nesting depth added 11). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"c67deaad323a8eebbc5af38fb15edf2aad193bca80d50f4bdb77c0898e7b6a48"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_sipmsg.get_meta (cognitive 39): nksip_sipmsg.get_meta has cognitive complexity 39 (threshold 15). Drivers by points: match/switch 24 (36 pts), boolean chains 3 (nesting depth added 12). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sipmsg.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"9184b53c55bd818130e1297de5a66a88369177bf3b87ceaf9de2d4224ec1bb76"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_subscription_lib.state (cognitive 35): nksip_subscription_lib.state has cognitive complexity 35 (threshold 15). Drivers by points: match/switch 14 (27 pts), error handling 2 (5 pts), boolean chains 3 (nesting depth added 16). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_subscription_lib.erl"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"2def6d4a31f4e9b00a6f4b5c61b99d7abd310c8e470554517538c3c15b7c9d4d"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uas_make.parse_opts (cognitive 34): nksip_call_uas_make.parse_opts has cognitive complexity 34 (threshold 15). Drivers by points: match/switch 18 (29 pts), boolean chains 5 (nesting depth added 11). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_make.erl"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"766cba95c72197e4e9ce71f30fda9fb23f3b568e673e5c1ac47cc452edf46d72"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uac_dialog.do_response (cognitive 33): nksip_call_uac_dialog.do_response has cognitive complexity 33 (threshold 15). Drivers by points: match/switch 24 (26 pts), boolean chains 7 (nesting depth added 2). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"02ac5b888f55fbfa98fa866e5490593c01fa8603978bfbaa5e478b1af2474ccd"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_outbound.proxy_opts (cognitive 31): nksip_outbound.proxy_opts has cognitive complexity 31 (threshold 15). Drivers by points: match/switch 12 (28 pts), boolean chains 3 (nesting depth added 16). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"aeb3ed3574632f6a97e15328e02b1f6dfe0d0b99fcae4d638a060928a4d780d0"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uas_dialog.do_response (cognitive 30): nksip_call_uas_dialog.do_response has cognitive complexity 30 (threshold 15). Drivers by points: match/switch 21 (22 pts), boolean chains 8 (nesting depth added 1). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_dialog.erl"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"d322766e805f6654b4563c59d03727496f4ffa24257e5749d149277d56adcab8"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_parse.packet (cognitive 29): nksip_parse.packet has cognitive complexity 29 (threshold 15). Drivers by points: match/switch 10 (22 pts), error handling 2 (6 pts), boolean chains 1 (nesting depth added 16). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse.erl"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"2322840dc89b0028682fea6d310d4bccf27f1ac8be1ff1eb1f13d1c7af61fc93"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_reply.parse (cognitive 27): nksip_reply.parse has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 16, match/switch 8 (11 pts) (nesting depth added 3). The drivers above price the dispatch low by construction \u2014 a dispatch is charged once however many cases it lists, while each branch inside an arm is charged in full \u2014 so most of this count is what the case bodies hold, and the arms are where it can be reduced. To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_reply.erl"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"50a5ade739b3fe2ea9a9262ae2fe3914c493841c6195c264b5ecbdff5281eb21"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_gruu_lib.find (cognitive 27): nksip_gruu_lib.find has cognitive complexity 27 (threshold 15). Drivers by points: if/else 3 (12 pts), match/switch 5 (7 pts), loops 2 (6 pts), error handling 1 (2 pts) (nesting depth added 16). The drivers above price the dispatch low by construction \u2014 a dispatch is charged once however many cases it lists, while each branch inside an arm is charged in full \u2014 so most of this count is what the case bodies hold, and the arms are where it can be reduced. To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_gruu_lib.erl"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7164235e9d3abdf47c3e0d9bcb7b9541d9f9fafe5f07bb7b6a8d804c8831f47"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_dialog.target_update (cognitive 25): nksip_call_dialog.target_update has cognitive complexity 25 (threshold 15). Drivers by points: match/switch 15 (22 pts), boolean chains 3 (nesting depth added 7). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c0232b6aee265abb9cf4fd4fd35c78127b12fb34ce6a848e934c7a6037584bb"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_parse.packet (cognitive 25): nksip_parse.packet has cognitive complexity 25 (threshold 15). Drivers by points: match/switch 8 (18 pts), error handling 2 (6 pts), boolean chains 1 (nesting depth added 14). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse.erl"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"24b4ba0fb7ecafb8fef4bb98ee44db67a13d789e56d15e00cfee1e41e4a6038c"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_sipmsg.header (cognitive 25): nksip_sipmsg.header has cognitive complexity 25 (threshold 15). Drivers by points: match/switch 12 (17 pts), loops 4 (8 pts) (nesting depth added 9). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sipmsg.erl"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"f53e48dda462c48bc9a70d7f4b4813015f938564e59a532c39a3f01f48436f88"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_100rel.send_prack (cognitive 25): nksip_100rel.send_prack has cognitive complexity 25 (threshold 15). Drivers by points: match/switch 13 (21 pts), error handling 2 (4 pts) (nesting depth added 10). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_100rel.erl"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9602763d852c75e4f4858ebee25bb1b6521da7aee185ddf84ae14a12c311a90"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_auth.make_request (cognitive 23): nksip_auth.make_request has cognitive complexity 23 (threshold 15). Drivers by points: match/switch 11 (20 pts), loops 1 (2 pts), error handling 1 (nesting depth added 10). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_auth.erl"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"14791c421cbcd68af58d456705e2442a29e93a35b8b0c5cdc05f69ec691c3cf5"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_timers_lib.uac_received_422 (cognitive 23): nksip_timers_lib.uac_received_422 has cognitive complexity 23 (threshold 15). Drivers by points: match/switch 11 (21 pts), boolean chains 2 (nesting depth added 10). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_lib.erl"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c16071db772e4d138153306a3a09bd86625418b841139ec5cf603d857659946"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_protocol.extract (cognitive 22): nksip_protocol.extract has cognitive complexity 22 (threshold 15). Drivers by points: match/switch 9 (15 pts), boolean chains 4, error handling 1 (3 pts) (nesting depth added 8). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_protocol.erl"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6ec271f3330545af157e2feeb3e53ae681ff036999da20fd3de04336f31c0f5"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_uac_auto_outbound_callbacks.nksip_uac_auto_register_upd_reg (cognitive 22): nksip_uac_auto_outbound_callbacks.nksip_uac_auto_register_upd_reg has cognitive complexity 22 (threshold 15). Drivers by points: match/switch 10 (20 pts), loops 1 (2 pts) (nesting depth added 11). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_outbound_callbacks.erl"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6b083a83baa73a1fb043fedbdb75cb2dda68f0de724399dd9ee07ca4bc7111d"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_auth.make_auth_request (cognitive 21): nksip_auth.make_auth_request has cognitive complexity 21 (threshold 15). Drivers by points: match/switch 13 (19 pts), boolean chains 2 (nesting depth added 6). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_auth.erl"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a57804d8bef2d8d54600d56cea3cbfa0ce7b1146613789cc5a0c883eabc198a"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uas_make.make (cognitive 20): nksip_call_uas_make.make has cognitive complexity 20 (threshold 15). Drivers by points: match/switch 12 (19 pts), error handling 1 (nesting depth added 7). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_make.erl"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"c71b6a394f7780274a71b23654c08160f6cf8db8ce2d50e801a283b843d357b4"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_headers.update (cognitive 20): nksip_headers.update has cognitive complexity 20 (threshold 15). Drivers by points: match/switch 12 (13 pts), loops 4 (7 pts) (nesting depth added 4). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_headers.erl"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e4c4d8d5637cc203cbb201b70253e2656ffaa9d7c042939f6f44e3196fafee5"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_parse_via.port (cognitive 20): nksip_parse_via.port has cognitive complexity 20 (threshold 15). Drivers by points: match/switch 9 (11 pts), boolean chains 5, error handling 2 (4 pts) (nesting depth added 4). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_via.erl"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b74db15dea214db5c489c29ae3247a6d24ac4ef4e5acd81210d138667a5e5ca"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_auth.check_auth_header (cognitive 19): nksip_auth.check_auth_header has cognitive complexity 19 (threshold 15). Drivers by points: match/switch 9 (16 pts), boolean chains 2, if/else 1 (nesting depth added 7). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_auth.erl"},"region":{"startLine":448}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b64a5c5d9a42fa50fa29cb2cebb877caa6e918047f40d40fa333836a9f12590"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_parse_sipmsg.parse (cognitive 19): nksip_parse_sipmsg.parse has cognitive complexity 19 (threshold 15). Drivers by points: match/switch 8 (15 pts), boolean chains 3, error handling 1 (nesting depth added 7). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_sipmsg.erl"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"213c8bab1b6fc7f42d62fcf2096950eb98c1d6ddd338a5fe8ab59ab29d3af806"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_reply.post (cognitive 19): nksip_reply.post has cognitive complexity 19 (threshold 15). Drivers by points: match/switch 9 (10 pts), boolean chains 9 (nesting depth added 1). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_reply.erl"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef222a6821aec944309254d045bc7e8cd98690b5684c3a918c73468061fc0210"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_event.update (cognitive 18): nksip_call_event.update has cognitive complexity 18 (threshold 15). Drivers by points: match/switch 15, boolean chains 3. To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"da68593c8152ee589ca1e0e579589ac26f9743849571892af68d0cc2ca23f137"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uac_dialog.pre_request (cognitive 18): nksip_call_uac_dialog.pre_request has cognitive complexity 18 (threshold 15). Drivers by points: match/switch 4 (10 pts), boolean chains 6, if/else 2 (nesting depth added 6). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"c30db39c716469ea5de34ef34389b8f5815036fb65e8129a344f8c757d29cc06"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_parse_header.parse (cognitive 18): nksip_parse_header.parse has cognitive complexity 18 (threshold 15). Drivers by points: match/switch 6 (13 pts), boolean chains 4, error handling 1 (nesting depth added 7). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_header.erl"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"38c8865c0cd5744f8ebb45b62c6c18f468bd4dcc15ac8dcdf234fcd1e3144129"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_outbound.add_headers (cognitive 18): nksip_outbound.add_headers has cognitive complexity 18 (threshold 15). Drivers by points: match/switch 12 (16 pts), boolean chains 2 (nesting depth added 4). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"2663b1d924853b155a2a8a4581280a7455b0ffcf25b707c20dc8fd9c33070658"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_timers_lib.uas_check_422 (cognitive 18): nksip_timers_lib.uas_check_422 has cognitive complexity 18 (threshold 15). Drivers by points: match/switch 8 (17 pts), boolean chains 1 (nesting depth added 9). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_lib.erl"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b01c10b5e5f4ddf3ffab87642cfc56799450a67e3838d2044fa45a9dedddac7"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_outbound.do_proxy_opts (cognitive 17): nksip_outbound.do_proxy_opts has cognitive complexity 17 (threshold 15). Drivers by points: match/switch 7 (16 pts), boolean chains 1 (nesting depth added 9). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"957554031e91fbe7af62ab491a7b9c93817c96391b1d177b737e9e403ea8dbbc"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_timers_lib.uas_dialog_response (cognitive 17): nksip_timers_lib.uas_dialog_response has cognitive complexity 17 (threshold 15). Drivers by points: match/switch 9 (14 pts), boolean chains 3 (nesting depth added 5). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_lib.erl"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"30601f72a895642650ac6606c37e21f66a20851f9786d63dea6ce76edaacab84"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uac_make.make (cognitive 16): nksip_call_uac_make.make has cognitive complexity 16 (threshold 15). Drivers by points: match/switch 7 (13 pts), boolean chains 2, error handling 1 (nesting depth added 6). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffeb2bcb66ad91e745de20aac6cd76e4201c443b9c5420cd8639e7e14f07ff47"}},{"ruleId":"D2","level":"warning","message":{"text":"nksip_call_uac_resp.response (cognitive 16): nksip_call_uac_resp.response has cognitive complexity 16 (threshold 15). Drivers by points: match/switch 10 (12 pts), boolean chains 3, if/else 1 (nesting depth added 2). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_resp.erl"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"008db79cc60c24aac36f4991405e91d11c4187973b96aab11fd984dc1ab7f91c"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyFunctions: srv_id_dummy_old: TooManyFunctions \u2014 83 functions. The bar is 30 functions; this is 53 over it, 2.77\u00D7 the bar. The counted members are a module\u0027s functions \u2014 a module holds no instance state, so there is no shared data to group them by and no type to move them onto. To reduce it, extract each cohesive family of functions into a new module of its own and have this one delegate to it, so no single module carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"priv/doc_src/srv_id_dummy_old.erl"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7692a2f11c24aa69116e18440a314e0b1ec76bc8666d740e764ec5fb7fd3eea"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyFunctions: srv_id_dummy: TooManyFunctions \u2014 62 functions. The bar is 30 functions; this is 32 over it, 2.07\u00D7 the bar. The counted members are a module\u0027s functions \u2014 a module holds no instance state, so there is no shared data to group them by and no type to move them onto. To reduce it, extract each cohesive family of functions into a new module of its own and have this one delegate to it, so no single module carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"priv/doc_src/srv_id_dummy.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b1c94b3dc408396c55d4601e987c771c2993e24b53ce60da0e633564c7d6bde"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyFunctions: nksip_callbacks: TooManyFunctions \u2014 42 functions. The bar is 30 functions; this is 12 over it, 1.40\u00D7 the bar. The counted members are a module\u0027s functions \u2014 a module holds no instance state, so there is no shared data to group them by and no type to move them onto. To reduce it, extract each cohesive family of functions into a new module of its own and have this one delegate to it, so no single module carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_callbacks.erl"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a8ab39000808a240ae0b7eb27d39ca0a5aeaa05196b485818b79f193cecdd15"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: src/nksip_call_dialog.erl: FileTooLong \u2014 556 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 56 over it, 1.11\u00D7 the bar. In this language a module is exactly one source file, so its length cannot be moved into sibling files of the same module. To reduce it, extract each cohesive family of functions into a new module of its own and have this one delegate to it, so no one module has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb0773576ffd6afd5fe5beff20d87d363a852bebf053ed1d822d44c678421ce4"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: src/nksip_auth.erl: FileTooLong \u2014 523 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 23 over it, 1.05\u00D7 the bar. In this language a module is exactly one source file, so its length cannot be moved into sibling files of the same module. To reduce it, extract each cohesive family of functions into a new module of its own and have this one delegate to it, so no one module has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_auth.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21ac17741de2ff33cb31021d20a0e873e03604ec825e14f4cb4d6a0890210f51"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: src/nksip_sdp.erl: FileTooLong \u2014 518 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 18 over it, 1.04\u00D7 the bar. In this language a module is exactly one source file, so its length cannot be moved into sibling files of the same module. To reduce it, extract each cohesive family of functions into a new module of its own and have this one delegate to it, so no one module has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"581e4e0687b3899db6f6385043678ab9ba3826a97cd3ad9d4a02d0ad88cb5b7d"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (110 shared lines): src/nksip_call_uac_dialog.erl:284-472 | src/nksip_call_uas_dialog.erl:270-457 \u2014 These two members are variants of one another: 110 of their lines are already reported as duplicated blocks below, spread through both bodies rather than gathered into one. Read them as a single construct written twice. The repair is at the members\u0027 grain \u2014 factor the shared pipeline into one implementation the two call with their differences as parameters or as an injected step, or, where the difference is systematic (sync against async, one transport against another), generate one from the other. Extracting the individual blocks below is not the same fix: it leaves the two bodies in place and the next edit still has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a92e754a1136d1249465ee2e45927934aec8b89c11d7a3ae538f2ce03f408e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (59 shared lines): src/nksip_call_uac_make.erl:248-491 | src/nksip_call_uas_make.erl:132-319 \u2014 These two members are variants of one another: 59 of their lines are already reported as duplicated blocks below, spread through both bodies rather than gathered into one. Read them as a single construct written twice. The repair is at the members\u0027 grain \u2014 factor the shared pipeline into one implementation the two call with their differences as parameters or as an injected step, or, where the difference is systematic (sync against async, one transport against another), generate one from the other. Extracting the individual blocks below is not the same fix: it leaves the two bodies in place and the next edit still has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"910c5cc2e6127a8b47531cbc483b5173e61fbd84e30ff05730c86be84d991999"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): src/nksip_call_uac_dialog.erl:426-450 | src/nksip_call_uas_dialog.erl:411-435 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":426}}}],"partialFingerprints":{"codehealthFindingId/v1":"8936ae41974897ca8961a2c0a4096f69e28676c4d20d870de4145953c8b87d05"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): src/plugins/nksip_uac_auto_register_callbacks.erl:362-382 | src/plugins/nksip_uac_auto_register_callbacks.erl:419-439 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_register_callbacks.erl"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"f19434fe83d12ba72bdff143256e73b90db1421babc348769382e88d850c69a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): src/nksip_call_uac_make.erl:291-310 | src/nksip_call_uas_make.erl:177-196 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_make.erl\u0060 and \u0060src/nksip_call_uas_make.erl\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 59 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a1d4d7d40359da1c00af175372e4e9cb751ea4db7f53b8fb52e4f843f62195d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201318 lines \u00D7 2): src/nksip_call_uac_dialog.erl:333-350 | src/nksip_call_uas_dialog.erl:319-334 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec4af5384f8b719e8cd027e719d2c124f2ded07e1a3f5bdf9d36f05422ecee5f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/nksip_call_uac_dialog.erl:386-402 | src/nksip_call_uas_dialog.erl:345-361 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":386}}}],"partialFingerprints":{"codehealthFindingId/v1":"f25f35b6083f18e8ba538faabbd8f55b01fe48b747431be6d3c1d304868eb6dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/nksip_parse.erl:232-248 | src/nksip_parse.erl:305-321 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse.erl"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"e993f9bbeedf430b6cc42335fcd768cbd48fb6c173076cf18232480164f9f384"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 2): src/nksip_call_dialog.erl:175-190 | src/plugins/nksip_timers_callbacks.erl:115-129 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"2be16581f0618c8bb415d07f4dc9c4824af055b860ed38844667cab460a8c280"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): src/nksip_call_uac_dialog.erl:284-297 | src/nksip_call_uas_dialog.erl:270-283 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3ea5be43293ae1785f501570a5388e1a8e5cae282875ba40c781981136921b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): src/nksip_call_uac_make.erl:362-375 | src/nksip_call_uas_make.erl:213-226 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_make.erl\u0060 and \u0060src/nksip_call_uas_make.erl\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 59 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"f76445678497f6d2d1c1d77c0160e8346b19ba63c51ac45544e04ef8c3f51c4f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): src/nksip_call_uac_make.erl:396-408 | src/nksip_call_uas_make.erl:237-249 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_make.erl\u0060 and \u0060src/nksip_call_uas_make.erl\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 59 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"0191f9a59b8a879acd8542969a29afc5e0b79856378e9afc9a9b753b5b0720ed"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/nksip_call_uac_make.erl:259-270 | src/nksip_call_uas_make.erl:147-158 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_make.erl\u0060 and \u0060src/nksip_call_uas_make.erl\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 59 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bc6d21bfb43a9dd594595eb61bab2de4a1742a8faabdbd66e5b9cd3d8177dbf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/nksip_call_uac_dialog.erl:315-325 | src/nksip_call_uas_dialog.erl:301-311 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"0264bde892cb54dd5b742a71588e17a87a672871637ad76273b3d52df72fa6fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/nksip_parse.erl:259-269 | src/nksip_parse.erl:332-342 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse.erl"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"216ae8578a09c1a8575156cfcc052c4359eebc45f2881cf1b50fd4b8d68e6ebc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/nksip_sdp.erl:256-267 | src/nksip_sdp.erl:300-310 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a67ecb08ce5bd94443ec7591ec7fc2a832fb8254e0236cb9070d10550f8323c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): src/nksip_call_uac_dialog.erl:418-427 | src/nksip_call_uas_dialog.erl:377-386 | src/nksip_call_uas_dialog.erl:403-412 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"f335bcd9c5a09bd0da0f6c37faa0a15f4924362b33c8d72bd13b225b221d0719"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): src/nksip_call_event.erl:114-123 | src/nksip_call_event.erl:232-240 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9705ab6dbb4d5cdd67eec7286102fd53c4fbe6e09c4b1f10e732389f45e033c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/nksip_call_uac_dialog.erl:407-416 | src/nksip_call_uas_dialog.erl:366-375 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb4528cf21ac1503aa803755017ccf4edfb754b3bc165cd0afa085b676f81021"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/nksip_call_uac_transp.erl:240-249 | src/plugins/nksip_outbound.erl:251-260 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_transp.erl"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5a2e699fd3f2891012f0817b7aca9f7e93602291acc8e875bb8b5e4e993805d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/nksip_headers.erl:129-138 | src/nksip_headers.erl:154-163 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_headers.erl"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cc2e96deb7ce28be1e0e347895bbda1db4a3271fcf8bcdc0537c8f60d8eecc2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/plugins/nksip_registrar_plugin.erl:44-53 | src/plugins/nksip_uac_auto_outbound_plugin.erl:49-58 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_registrar_plugin.erl"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b7e32eb843c404f7ece304a440064d6adf95649bb3213eb0e7fb14e386a86e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): src/nksip_call_uac_dialog.erl:261-269 | src/nksip_call_uas_dialog.erl:246-254 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"b77bccf997ada220f8cd98fb73b639773982b4aa8c24963d3d54982b972c442b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): src/nksip_call_uac_transp.erl:252-260 | src/plugins/nksip_outbound.erl:275-283 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_transp.erl"},"region":{"startLine":252}}}],"partialFingerprints":{"codehealthFindingId/v1":"30840c51fff554d6a8b8d80570066b149fa67259b58fcd5747fac1d0d1740f3c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): src/nksip_sdp_util.erl:258-266 | src/nksip_sdp_util.erl:284-292 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp_util.erl"},"region":{"startLine":258}}}],"partialFingerprints":{"codehealthFindingId/v1":"feda2219d9b799dc5e0ce046a5ba1e2f3c0370c0017b99825b8ad3d6888c03e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): priv/doc_src/srv_id_dummy_old.erl:254-261 | priv/doc_src/srv_id_dummy_old.erl:263-270 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"priv/doc_src/srv_id_dummy_old.erl"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"738969507d38ff03bfe08c66224f4bc69421c266200c1566fe94835f15a92704"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/nksip_dialog.erl:116-123 | src/nksip_subscription.erl:108-115 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog.erl"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2f4582de67007432a5dc113d9121526777a4b74a4dec23d59d794261083466a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/nksip_dialog.erl:133-140 | src/nksip_subscription.erl:125-132 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog.erl"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bd0d257636521073fb821a3a0357e432d6a102a600203d3c83922926f94a736"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/nksip_dialog_lib.erl:195-202 | src/nksip_sipmsg.erl:512-519 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog_lib.erl"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"955a55cb7a9d9b5cccb86a9e1c0cef811d612e4e834d4e15e1ec6e78162f373d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/nksip_dialog_lib.erl:201-208 | src/nksip_subscription_lib.erl:150-157 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog_lib.erl"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ff06b03335762230591c04987f0af991d190ac8bf81f3259cd64cbf94f422f4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/nksip_parse_sipmsg.erl:43-50 | src/nksip_parse_sipmsg.erl:68-75 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_sipmsg.erl"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"af7eed5c930f42d847d63be91f14245a242104084128e698092b91a902fec867"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/plugins/nksip_timers_lib.erl:143-150 | src/plugins/nksip_timers_lib.erl:160-167 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_lib.erl"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"43ee5d291d2d132fd4c8ffa24beb3bce7bba3e7ac42e7fb2b14c38f472647600"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/plugins/nksip_uac_auto_outbound_callbacks.erl:184-191 | src/plugins/nksip_uac_auto_register_callbacks.erl:314-321 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_outbound_callbacks.erl"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6d98de89221785f725ece6dafece54c24e2e5097379a0c862789f4a15013f8d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/plugins/nksip_uac_auto_outbound_callbacks.erl:233-241 | src/plugins/nksip_uac_auto_register_callbacks.erl:341-348 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_outbound_callbacks.erl"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"3515ea89204ae80671c3f019849010c1bf3b6a31ae091bde4f25291a1d475a09"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): src/nksip_dialog_lib.erl:204-210 | src/nksip_sipmsg.erl:521-527 | src/nksip_subscription_lib.erl:153-159 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog_lib.erl"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"72310f9d3675b1c0253c04f62a69fd0147b85f0e8023abebdeb6f8ae26fc76d6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20137 lines \u00D7 3): src/plugins/nksip_timers_lib.erl:88-94 | src/plugins/nksip_timers_lib.erl:143-148 | src/plugins/nksip_timers_lib.erl:160-165 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_lib.erl"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7ef9c53cb5efa2f6a2972f1f7997acdfd3d124591b30a8644fdb1af4c3833c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): src/nksip_call_uac_dialog.erl:466-472 | src/nksip_call_uas_dialog.erl:451-457 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":466}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fbc86c1363dbc04655c4a4dafd035969fe7554e5f66df7fe8ee03a83f77bcec"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): src/nksip_call_dialog.erl:442-447 | src/nksip_call_dialog.erl:455-460 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"26260c641bfbf339035643d86a5d27dec284e932aaa254edbde8eefadb3f28a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): src/nksip_call_uac_dialog.erl:568-574 | src/nksip_call_uas_dialog.erl:499-505 \u2014 before extracting anything, compare \u0060src/nksip_call_uac_dialog.erl\u0060 and \u0060src/nksip_call_uas_dialog.erl\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 128 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":568}}}],"partialFingerprints":{"codehealthFindingId/v1":"9645387785a666725c9cf7f2bf56a168289a703b95e92a3f4c17d1e4ae583acf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): src/nksip_dialog_lib.erl:180-186 | src/nksip_sipmsg.erl:497-503 | src/nksip_subscription_lib.erl:124-130 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog_lib.erl"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3b5c437fd6e3757ae5dffaff33f91612528ad2efc4212c9f270c31f53e108f8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): src/plugins/nksip_event_compositor_plugin.erl:46-52 | src/plugins/nksip_registrar_plugin.erl:47-53 | src/plugins/nksip_uac_auto_outbound_plugin.erl:52-58 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_event_compositor_plugin.erl"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"625cd7dc8335188037555f5beea7de985eed9364b276391b3698558be2dc226a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): src/plugins/nksip_gruu_plugin.erl:39-43 | src/plugins/nksip_outbound_plugin.erl:34-38 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_gruu_plugin.erl"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"12cc672c8b18852ab1dbb0c31dc595e4ecc02f3f1a1edd34c093020484d2a2a7"}},{"ruleId":"D8","level":"warning","message":{"text":"Coverage not measured \u2014 no coverage collector is wired up: Coverage NOT MEASURED: \u0060--collect:\u0022XPlat Code Coverage\u0022\u0060 names a data collector that ships in the \u0060coverlet.collector\u0060 package, and this repository wires up none \u2014 no test project references it and no runsettings declares one. The absence of coverage here is therefore not evidence about the suite or about our analyzer environment: without a collector, \u0060--collect\u0060 produces nothing even from a suite that builds and passes. Add a \u0060coverlet.collector\u0060 PackageReference to the test project(s) (or commit the Cobertura/OpenCover/lcov report your CI produces) and real coverage will be measured. It is excluded from the score rather than counted as a near-zero defect."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"62e63e619c28f057e129f2997c965d32a457366a9ce18ca019ffb6bdfba85c99"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating source dependency: nklib: Runtime dependency \u0060nklib\u0060 is fetched from source in rebar.config and tracks branch \u0060master\u0060 \u2014 the declaration pins no immutable revision, so \u0060rebar3 upgrade\u0060 moves this dependency to code nobody reviewed. Pin it with \u0060{tag, \u0022v1.2.3\u0022}\u0060 or \u0060{ref, \u0022\u003Cfull commit SHA\u003E\u0022}\u0060."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9b62f69fa4b9a6e04911e0b16b03ac5f8a83f8d97b5c806ed1b7a3260934ab9a"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating source dependency: nkpacket: Runtime dependency \u0060nkpacket\u0060 is fetched from source in rebar.config and tracks branch \u0060master\u0060 \u2014 the declaration pins no immutable revision, so \u0060rebar3 upgrade\u0060 moves this dependency to code nobody reviewed. Pin it with \u0060{tag, \u0022v1.2.3\u0022}\u0060 or \u0060{ref, \u0022\u003Cfull commit SHA\u003E\u0022}\u0060."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cffcb0bcc02933ce37a005f1a4072a1419c7713944b51e61e202392c0ef493a0"}},{"ruleId":"D12","level":"warning","message":{"text":"Floating source dependency: nkserver: Runtime dependency \u0060nkserver\u0060 is fetched from source in rebar.config and tracks branch \u0060master\u0060 \u2014 the declaration pins no immutable revision, so \u0060rebar3 upgrade\u0060 moves this dependency to code nobody reviewed. Pin it with \u0060{tag, \u0022v1.2.3\u0022}\u0060 or \u0060{ref, \u0022\u003Cfull commit SHA\u003E\u0022}\u0060."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fa8ae097b662e9e467d60b0e06a819db7e703247888067cf921a6ac31bc7f3b3"}},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b57a5e505a0c870ec5c0165dd10be1d6e9cba850a5504b01f1d301b12da78cd0"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uac_make.erl: src/nksip_call_uac_make.erl changed 5 times in last 90 days, max cyclomatic complexity 94 in nksip_call_uac_make.parse_opts at line 248. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uac_make.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_make.erl"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6ec85affbc35523a24ded48d49689adc1759208ef0826bb3451a121a09ab93a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_reply.erl: src/nksip_reply.erl changed 5 times in last 90 days, max cyclomatic complexity 76 in nksip_reply.parse at line 196. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_reply.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_reply.erl"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"174ca04d616dd801760ed6e576c6b1d8d3d7577e5df4b9082b5e5731d6250018"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_sipmsg.erl: src/nksip_sipmsg.erl changed 5 times in last 90 days, max cyclomatic complexity 66 in nksip_sipmsg.get_meta at line 63. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_sipmsg.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sipmsg.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ef2efe3c94b4644f08764b5f49867eef876d791bd11daa752beb824afbd3c1a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uas_make.erl: src/nksip_call_uas_make.erl changed 5 times in last 90 days, max cyclomatic complexity 65 in nksip_call_uas_make.parse_opts at line 132. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uas_make.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_make.erl"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"2304e5bc7179c94cfa3e7232a52ce7933d361949b596dc453748643a6cb63088"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_unparse.erl: src/nksip_unparse.erl changed 4 times in last 90 days, max cyclomatic complexity 72 in nksip_unparse.response_phrase at line 428. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_unparse.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_unparse.erl"},"region":{"startLine":428}}}],"partialFingerprints":{"codehealthFindingId/v1":"e28c17a02cd25036f676101a000c23a37edc5426cd23bf6f0ff133313f767f5a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uac_dialog.erl: src/nksip_call_uac_dialog.erl changed 5 times in last 90 days, max cyclomatic complexity 47 in nksip_call_uac_dialog.do_response at line 284. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uac_dialog.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"023b4fa81c3c62c620f2a173e6ac93896838d0df4424c026f7ca12d614ab3318"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uas_dialog.erl: src/nksip_call_uas_dialog.erl changed 5 times in last 90 days, max cyclomatic complexity 47 in nksip_call_uas_dialog.do_response at line 270. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uas_dialog.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_dialog.erl"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"26624af52f7b0a9479651eb35d5a513ec2e9e74afb84def89dc47cad3bc6ebef"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_dialog_lib.erl: src/nksip_dialog_lib.erl changed 5 times in last 90 days, max cyclomatic complexity 38 in nksip_dialog_lib.get_meta at line 92. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_dialog_lib.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_dialog_lib.erl"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"3190ae3b88beb2c374d88cbf535fcad38f4241c4d78d2d2ddf666f1331249f9a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_router.erl: src/nksip_router.erl changed 5 times in last 90 days, max cyclomatic complexity 33 in nksip_router.pos2name at line 340. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_router.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_router.erl"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7caac62cabfe449db29ba397f3752cf0bbde1ed3f2e5fe5b3e6a47138687c44"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uac_reply.erl: src/nksip_call_uac_reply.erl changed 5 times in last 90 days, max cyclomatic complexity 29 in nksip_call_uac_reply.do_reply at line 63. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uac_reply.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_reply.erl"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a899b5d3ad34c8d1034ac4319329df78ed5afb68af678006896241ed092ebc2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/plugins/nksip_uac_auto_outbound_callbacks.erl: src/plugins/nksip_uac_auto_outbound_callbacks.erl changed 6 times in last 90 days, max cyclomatic complexity 21 in nksip_uac_auto_outbound_callbacks.nksip_uac_auto_register_upd_reg at line 256. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/plugins/nksip_uac_auto_outbound_callbacks.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_outbound_callbacks.erl"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"088bf425f01ae828d788dd74ff74305ede8531a47f1a0ec58683e58d4ff4b187"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/plugins/nksip_outbound.erl: src/plugins/nksip_outbound.erl changed 6 times in last 90 days, max cyclomatic complexity 20 in nksip_outbound.proxy_opts at line 69. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/plugins/nksip_outbound.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_outbound.erl"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"6484490c646e79de95f36be6456b7b64389408ce8b44d5d53f738673507debbc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_headers.erl: src/nksip_headers.erl changed 3 times in last 90 days, max cyclomatic complexity 37 in nksip_headers.update at line 110. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_headers.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_headers.erl"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"42fed57a8c5d7d59ff8d77804cfee3c77c6883d89c3e53ed2f8aa59d60b733db"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_event.erl: src/nksip_call_event.erl changed 5 times in last 90 days, max cyclomatic complexity 22 in nksip_call_event.update at line 267. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_event.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_event.erl"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2e39651732bf9842b9a37907aac2cba7e2923972a515930bbffa888e594cdc4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_dialog.erl: src/nksip_call_dialog.erl changed 5 times in last 90 days, max cyclomatic complexity 21 in nksip_call_dialog.target_update at line 229. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_dialog.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_dialog.erl"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"314239f5e4aa1eb69583d1456bc8602df1dc8b91cf2063c9c4202a117a85999e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_protocol.erl: src/nksip_protocol.erl changed 5 times in last 90 days, max cyclomatic complexity 20 in nksip_protocol.do_parse at line 349. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_protocol.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_protocol.erl"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e89cd4767dfa6cb5600450c1734ad16242dd465044b09c9c8270393f5031d0a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_subscription_lib.erl: src/nksip_subscription_lib.erl changed 5 times in last 90 days, max cyclomatic complexity 20 in nksip_subscription_lib.state at line 231. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_subscription_lib.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_subscription_lib.erl"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"75287e11a036a39f16cedae3ca19d19afc94ef7f5d113cc43f12190da7007716"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_proxy.erl: src/nksip_call_proxy.erl changed 5 times in last 90 days, max cyclomatic complexity 18 in nksip_call_proxy.normalize_uriset at line 221. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_proxy.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_proxy.erl"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"341ace776a8f26f96bef368cca29321355a0ca62fcda53f4640ea24fd2026854"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uas_process.erl: src/nksip_call_uas_process.erl changed 5 times in last 90 days, max cyclomatic complexity 18 in nksip_call_uas_process.do_method at line 304. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uas_process.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_process.erl"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbfab604a04cf7a1b8aba1860c77fed7a642e16c14fb50cb34b429f4db32242d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_parse_header.erl: src/nksip_parse_header.erl changed 4 times in last 90 days, max cyclomatic complexity 22 in nksip_parse_header.header at line 136. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_parse_header.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_header.erl"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a4b43547015a3778d3d7ee01353702a1d880ff8297e9d8a9dcfe2c4d21de4a5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_sdp.erl: src/nksip_sdp.erl changed 3 times in last 90 days, max cyclomatic complexity 29 in nksip_sdp.parse_sdp at line 358. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_sdp.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"028b6402ecd640336a56ef2b1c418067d8740a8d4e8940d9d6d89b819a10f4c0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_parse.erl: src/nksip_parse.erl changed 5 times in last 90 days, max cyclomatic complexity 17 in nksip_parse.method at line 71. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_parse.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse.erl"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"c58007d3d8e129bb2bf43833f86f9d971ce734e53560630e994622bcaefbd111"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uas_route.erl: src/nksip_call_uas_route.erl changed 5 times in last 90 days, max cyclomatic complexity 16 in nksip_call_uas_route.route_reply at line 201. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uas_route.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_route.erl"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"62539cae20626398b30d43f39d5a4f71898d2f8964b67667b5dec1f123861ada"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_parse_via.erl: src/nksip_parse_via.erl changed 3 times in last 90 days, max cyclomatic complexity 26 in nksip_parse_via.domain at line 131. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_parse_via.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_via.erl"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"c93385cd2532c4fa24ee6db6079b93cab2662d907cea7c62f898d86e3637a328"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_auth.erl: src/nksip_auth.erl changed 5 times in last 90 days, max cyclomatic complexity 15 in nksip_auth.parse_header_value_check at line 698. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_auth.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_auth.erl"},"region":{"startLine":698}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e00ee9dc0ea1d6d96b0aa7a1e9719db161b37ae4fa1b27259676da8dbab1990"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uac_resp.erl: src/nksip_call_uac_resp.erl changed 5 times in last 90 days, max cyclomatic complexity 15 in nksip_call_uac_resp.response at line 43. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uac_resp.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_resp.erl"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"649594fb87f3208dc97cb995fdfb4e3229545c6486583fde7dbac6d592a85d81"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/plugins/nksip_timers_lib.erl: src/plugins/nksip_timers_lib.erl changed 5 times in last 90 days, max cyclomatic complexity 15 in nksip_timers_lib.uas_dialog_response at line 365. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/plugins/nksip_timers_lib.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_lib.erl"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ba552ed87c6da09a56b8eba0b4f585f91671fd4cc95b7b4f1eda5b9097c8924"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uas_timer.erl: src/nksip_call_uas_timer.erl changed 4 times in last 90 days, max cyclomatic complexity 17 in nksip_call_uas_timer.do_timer at line 61. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uas_timer.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_timer.erl"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe815015fa19f1028f38f8c55a47ae19de75d7aae66210cb6bb4d4a0e25977ac"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uac_send.erl: src/nksip_call_uac_send.erl changed 4 times in last 90 days, max cyclomatic complexity 16 in nksip_call_uac_send.send at line 41. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uac_send.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_send.erl"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"75226f0ceaf53c8e3dda8fc67a32943cbccf57dd7c8be259d34b2fb7dcbe0c5d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_parse_sipmsg.erl: src/nksip_parse_sipmsg.erl changed 3 times in last 90 days, max cyclomatic complexity 21 in nksip_parse_sipmsg.long_name at line 199. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_parse_sipmsg.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_parse_sipmsg.erl"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fef38f499d5185ec07c5a43be7c673ac44ccda3e8aedb5171f4d25ea73c621b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/plugins/nksip_timers_callbacks.erl: src/plugins/nksip_timers_callbacks.erl changed 4 times in last 90 days, max cyclomatic complexity 15 in nksip_timers_callbacks.nksip_dialog_update at line 55. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/plugins/nksip_timers_callbacks.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_timers_callbacks.erl"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ebf97fbd40e8728854489117830e6deefcefc9adf4cfe4134967c39002dff7d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/nksip_call_uac_timer.erl: src/nksip_call_uac_timer.erl changed 2 times in last 90 days, max cyclomatic complexity 20 in nksip_call_uac_timer.do_timer at line 59. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2018-10-18..2019-01-16, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272018-10-18 15:49:55 \u002B01:00\u0027 --until=\u00272019-01-16 15:49:55 \u002B01:00\u0027 --full-history --no-merges -- src/nksip_call_uac_timer.erl\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_timer.erl"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"b42fae612ab1faf84ad9f275deaa022ffc9000f46126bccfa813c58ffa5d658f"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: % Hack to accept b= inside a= (Freeswitch) \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":416}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a9a625189096f6170ebfa1c93be483538162738943ce8abcad2feb774967891"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: % Hack to accept b= inside a= (Freeswitch) \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_sdp.erl"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d8e87bd8d52c61f8761f81191614a0ca11fe4abe2ce25c26a09e4d8ed3f33bd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: % TODO 16.6.4: If ruri or top route has sips, and not received with \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060% REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas_route.erl"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a0cd35740c1fc2f637a41761a86a090fee96f01e302702ebb910d0467fc5ad2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: %% TODO: Is this working? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060% REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uas.erl"},"region":{"startLine":348}}}],"partialFingerprints":{"codehealthFindingId/v1":"a75a55b2f2158a8c77ab9d208037d996229035cfe81cb3f5228a5fcb2ad23fba"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: % Hack to find remote dialog \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"test/tests/t17_prack.erl"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"e95754f13a64ec3f7175fc47a62e4abd8b954bd0c06b2a9aabe9b9194bc14d35"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: % Hack to find remote dialog \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"test/tests/t09_invite.erl"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"a48a44532ff9d4756919f53d8d848812e52f6f61ca9a2fa4077f0c78b8f2bd75"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: % TODO: Should fire timer C, sometimes it fires timer B \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060% REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"test/tests/t03_uac.erl"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"a66f9e43deb054628a3d7f6a2a99761ba1b71c5b6272c97699936c1b95adf18e"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: No installation, build or setup instructions are present in the single README document. Add an install section covering Erlang/OTP requirements, rebar3 usage (mix.exs), and a one-line build command."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa6bfcd5c6ae231d1b8ee99bced50b832d1f61cde9da6cbb533467b879a57db"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no usage examples: The README lacks any runnable usage examples or \u0022how to run it\u0022 guidance. Add a short Quick Start section showing how to start NkSIP, send an OPTIONS request, and receive responses."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1355eb4e127a4bc9236772ce1c46f09510aa9286e7a06d1e47f308229df19049"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no contributor guidance: No contribution guidelines are present in the single README document. Add Contributing notes covering pull-request format, plugin development, and how to run tests."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"620f29787918fa3406ae55cb63eefa1b50410845435c4e47bda852816aaea084"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8ebc9fba44e2268c648c8c9a355ebb8727fbb9adb47a6e772b55d027ba064a38"},"properties":{"commitSha":"6db0820c4031a330d248d08503f24f0f9c26fe6a"}},{"ruleId":"D28","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3cdfd7beb31b791ae18dcb425e21eb157c842e7bbcd522cc330573c1a6538db1"}},{"ruleId":"D34","level":"note","message":{"text":"Dormant codebase: 81 of 81 significant files have no living knowledge \u2014 the codebase as a whole is dormant, not 81 separate risks. Counted over 81 of the 108 production source files in this repository: the rest are under the ~2,400-byte size floor this dimension measures over. Re-engage owners or document before change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4c69f1e54b7dd6fe9029dd02df6ba8f8145b789f2f18dbdaa086c40ded49dba6"}},{"ruleId":"D34","level":"note","message":{"text":"Most significant orphaned file: One of the orphaned files carrying the most lost knowledge \u2014 ranked by size weighted by the file\u0027s role in the codebase, the same weighting behind the score above, so core code outranks equally large plumbing. A reasonable place to start a read-through before the aggregate risk above bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_auth.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"27a817afd35a13aa4dd27787972ab8effcbfb0843cdcb943b3be8225d91c2cae"}},{"ruleId":"D34","level":"note","message":{"text":"Most significant orphaned file: One of the orphaned files carrying the most lost knowledge \u2014 ranked by size weighted by the file\u0027s role in the codebase, the same weighting behind the score above, so core code outranks equally large plumbing. A reasonable place to start a read-through before the aggregate risk above bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_callbacks.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a54f7fede9d15c8c59a41ee2323e2ea156c7a8bcf286dc34c99504c276baaaee"}},{"ruleId":"D34","level":"note","message":{"text":"Most significant orphaned file: One of the orphaned files carrying the most lost knowledge \u2014 ranked by size weighted by the file\u0027s role in the codebase, the same weighting behind the score above, so core code outranks equally large plumbing. A reasonable place to start a read-through before the aggregate risk above bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/nksip_call_uac_dialog.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc16514b122bdab1d4bd09bb4d349844552a8f64d8b3d1b1da37489ee077c3c6"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: nksip_uac_auto_outbound_callbacks.erl \u2194 nksip_uac_auto_register_callbacks.erl: \u0060src/plugins/nksip_uac_auto_outbound_callbacks.erl\u0060 and \u0060src/plugins/nksip_uac_auto_register_callbacks.erl\u0060 change together 58% of the time (11 of the 19 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency between them. They sit in the same directory, but in this ecosystem each file is its own module \u2014 a sibling reference still needs an import \u2014 so the missing import edge is real: the coupling runs through shared behaviour, not a declared dependency. If they duplicate structure, extract the common part into one unit; otherwise the coupling is hidden and worth breaking. You can check this without leaving the row: of the 11 shared commits counted here, the most recent 3 are \u0060a59d93b7\u0060 Add untracked files; \u0060aa77b5fc\u0060 Sync with last nkservice (at that commit the files were still \u0060plugins/src/nksip_uac_auto_outbound_callbacks.erl\u0060 and \u0060plugins/src/nksip_uac_auto_register_callbacks.erl\u0060); \u00600b724c51\u0060 Cleanup (at that commit the files were still \u0060plugins/src/nksip_uac_auto_outbound_callbacks.erl\u0060 and \u0060plugins/src/nksip_uac_auto_register_callbacks.erl\u0060) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/plugins/nksip_uac_auto_outbound_callbacks.erl"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7078f4ef08afd3451c3f2cafb765860d242818547de7af4e1c2f2cae0167e8d"}},{"ruleId":"M2","level":"note","message":{"text":"No ADRs: No Architecture Decision Records found \u2014 no conventional ADR directory, no numbered \u0060NNNN-title\u0060 documents in any markup this check reads, and nothing ADR-shaped by content. Design rationale recorded elsewhere (a design-notes tree, a mailing list, pull-request discussion) is not visible to this check and is not re-findable per decision, so a future maintainer cannot ask why one choice was made and get an answer."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"670b3d6e36a756d63097d0dfbf90afd5fc761308800b9354894a07c3f4e4aa14"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README claims Erlang application server but the repository is a single source file (src/nksip_callbacks.erl) with no project or directory tree \u2014 searched for: \u0060application server\u0060. Each was matched case- and separator-insensitively against file and directory NAMES anywhere in the tree, and against the CONTENTS of manifest files (package.json, *.csproj, *.props, *.slnx, *.yml, Dockerfile); the README\u0027s own prose never counts, so a claim is never refuted by merely being made. Nothing outside that search was read \u2014 a footprint living only in a submodule, in a file type not listed here, or under a name none of those terms matches is not seen, and this row is then wrong."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"343bbbd51ceb8de7a9ff88d79f7c797abf9b5921f8727b67b4d0f4f8a22c5e49"}},{"ruleId":"P1","level":"warning","message":{"text":"No CI pipeline: No CI workflow found (.github/workflows, azure-pipelines.yml, .gitlab-ci.yml, \u2026) \u2014 changes aren\u0027t gated by an automated build/test."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"44f01af96e50474fba2df84d95ddf4f7e1d34c29c307830b9efc9057daa6b670"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Command Injection","shortDescription":{"text":"Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"OS Command Injection","shortDescription":{"text":"OS Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Cross-site Scripting (XSS)","shortDescription":{"text":"Cross-site Scripting (XSS)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"SQL Injection","shortDescription":{"text":"SQL Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Code Injection","shortDescription":{"text":"Code Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":3,"secretScannerRunsExcluded":0}},"redactionTokens":["A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."]}]}