diff --git a/.refactorfirst/refactor-first.json b/.refactorfirst/refactor-first.json index c175841d..b431de34 100644 --- a/.refactorfirst/refactor-first.json +++ b/.refactorfirst/refactor-first.json @@ -2,19 +2,19 @@ "project" : { "name" : "RefactorFirst", "version" : "0.11.0-SNAPSHOT", - "repoUrl" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/", - "baseDir" : "c:\\Code\\RefactorFirst", - "scanTimestamp" : "10/3/26, 3:43 PM", + "repoUrl" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/", + "baseDir" : "C:\\Code\\RefactorFirst", + "scanTimestamp" : "10/4/26, 4:37 PM", "hasAnyDisharmony" : true, "analysisFailed" : false }, "classMap" : { "graphId" : "classGraph", "classCount" : 154, - "relationshipCount" : 299, + "relationshipCount" : 300, "dotThreshold" : 4000, "dotThresholdExceeded" : false, - "dot" : "strict digraph G {\nChangePronenessRanker -> ScmLogInfo [ label = \"5\" weight = \"5\" ];\nChangePronenessRanker -> GitLogReader [ label = \"2\" weight = \"2\" ];\nGitLogReader -> org_hjug_git_GitLogReader_CommitWalkStats [ label = \"4\" weight = \"4\" ];\nGitLogReader -> ScmLogInfo [ label = \"3\" weight = \"3\" ];\nMain -> ReportCommand [ label = \"1\" weight = \"1\" ];\nReportCommand -> ReportType [ label = \"1\" weight = \"1\" ];\nReportCommand -> ReportWriter [ label = \"1\" weight = \"1\" ];\nReportCommand -> SimpleHtmlReport [ label = \"4\" weight = \"4\" ];\nReportCommand -> HtmlReport [ label = \"2\" weight = \"2\" ];\nReportCommand -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nReportCommand -> CsvReport [ label = \"3\" weight = \"3\" ];\nCodebaseGraphDTO -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"4\" weight = \"4\" ];\nCodebaseGraphDTO -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"4\" weight = \"4\" ];\nCompositeGraphBuilder -> GraphBuilderConfig [ label = \"4\" weight = \"4\" ];\nCompositeGraphBuilder -> CodebaseGraphDTO [ label = \"10\" weight = \"10\" ];\nCompositeGraphBuilder -> JavaSourceFileGraphBuilder [ label = \"3\" weight = \"3\" ];\nCompositeGraphBuilder -> KotlinSourceFileGraphBuilder [ label = \"3\" weight = \"3\" ];\nCompositeGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"2\" weight = \"2\" ];\nCompositeGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> SourceFileGraphBuilder [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> GraphDependencyCollector [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> JavaVisitor [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> GraphMetricsCollector [ label = \"5\" weight = \"5\" ];\nJavaSourceFileGraphBuilder -> MetricsCollectingVisitor [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> AbstractDependencyVisitor [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> Java25ParserFactory [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> DisharmonyDetector [ label = \"18\" weight = \"18\" ];\nJavaSourceFileGraphBuilder -> ClassMetrics [ label = \"3\" weight = \"3\" ];\nJavaSourceFileGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"3\" weight = \"3\" ];\nJavaSourceFileGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"3\" weight = \"3\" ];\nKotlinSourceFileGraphBuilder -> SourceFileGraphBuilder [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> GraphDependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> KotlinDependencyVisitor [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> GraphMetricsCollector [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> KotlinMetricsCollectingVisitor [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> JavaSourceFileGraphBuilder [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"1\" weight = \"1\" ];\nSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"1\" weight = \"1\" ];\nGraphDependencyCollector -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nClassMetrics -> MethodMetrics [ label = \"13\" weight = \"13\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony -> ClassMetrics [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony -> MethodMetrics [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyDetector -> ClassMetrics [ label = \"99\" weight = \"99\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"30\" weight = \"30\" ];\nDisharmonyDetector -> DisharmonyMetric [ label = \"44\" weight = \"44\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"15\" weight = \"15\" ];\nDisharmonyDetector -> MethodMetrics [ label = \"40\" weight = \"40\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry [ label = \"5\" weight = \"5\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData [ label = \"10\" weight = \"10\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_Clone [ label = \"20\" weight = \"20\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry -> ClassMetrics [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry -> MethodMetrics [ label = \"2\" weight = \"2\" ];\nDisharmonyMetric -> org_hjug_graphbuilder_metrics_DisharmonyMetric_Direction [ label = \"1\" weight = \"1\" ];\nGraphMetricsCollector -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nGraphMetricsCollector -> ClassMetrics [ label = \"33\" weight = \"33\" ];\nGraphMetricsCollector -> MethodMetrics [ label = \"10\" weight = \"10\" ];\nKotlinMetricsCollectingVisitor -> GraphMetricsCollector [ label = \"2\" weight = \"2\" ];\nKotlinMetricsCollectingVisitor -> MetricsVisitorState [ label = \"2\" weight = \"2\" ];\nKotlinMetricsCollectingVisitor -> MetricsVisitorLogic [ label = \"17\" weight = \"17\" ];\nKotlinMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"1\" weight = \"1\" ];\nKotlinMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"1\" weight = \"1\" ];\nKotlinMetricsCollectingVisitor -> ClassMetrics [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> GraphMetricsCollector [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> MetricsVisitorState [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> MetricsVisitorLogic [ label = \"10\" weight = \"10\" ];\nMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"1\" weight = \"1\" ];\nMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"1\" weight = \"1\" ];\nMetricsVisitorLogic -> MetricsVisitorState [ label = \"12\" weight = \"12\" ];\nMetricsVisitorLogic -> GraphMetricsCollector [ label = \"13\" weight = \"13\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"4\" weight = \"4\" ];\nMetricsVisitorLogic -> ClassMetrics [ label = \"28\" weight = \"28\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate [ label = \"2\" weight = \"2\" ];\nMetricsVisitorLogic -> MethodMetrics [ label = \"31\" weight = \"31\" ];\nMetricsVisitorLogic -> ComplexityCalculator [ label = \"4\" weight = \"4\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"3\" weight = \"3\" ];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot -> ClassMetrics [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot -> MethodMetrics [ label = \"2\" weight = \"2\" ];\nMetricsVisitorState -> ClassMetrics [ label = \"1\" weight = \"1\" ];\nMetricsVisitorState -> MethodMetrics [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> DependencyVisitorState [ label = \"2\" weight = \"2\" ];\nAbstractDependencyVisitor -> DependencyCollector [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> org_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> BaseTypeProcessor [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> DependencyVisitorLogic [ label = \"14\" weight = \"14\" ];\nBaseTypeProcessor -> TypeDependencyExtractor [ label = \"3\" weight = \"3\" ];\nBaseTypeProcessor -> DependencyCollector [ label = \"3\" weight = \"3\" ];\nDependencyVisitorLogic -> DependencyVisitorState [ label = \"14\" weight = \"14\" ];\nDependencyVisitorLogic -> SourcePathResolver [ label = \"2\" weight = \"2\" ];\nDependencyVisitorLogic -> org_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot [ label = \"3\" weight = \"3\" ];\nDependencyVisitorLogic -> UnattributedTypeFqnResolver [ label = \"1\" weight = \"1\" ];\nDependencyVisitorState -> BaseTypeProcessor [ label = \"2\" weight = \"2\" ];\nJavaVisitor -> AbstractDependencyVisitor [ label = \"2\" weight = \"2\" ];\nJavaVisitor -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> DependencyCollector [ label = \"7\" weight = \"7\" ];\nKotlinDependencyVisitor -> BaseTypeProcessor [ label = \"8\" weight = \"8\" ];\nKotlinDependencyVisitor -> DependencyVisitorState [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> org_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> DependencyVisitorLogic [ label = \"17\" weight = \"17\" ];\nCostBenefitCalculator -> GitLogReader [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> ChangePronenessRanker [ label = \"3\" weight = \"3\" ];\nCostBenefitCalculator -> CBORule [ label = \"1\" weight = \"1\" ];\nCostBenefitCalculator -> GodClass [ label = \"10\" weight = \"10\" ];\nCostBenefitCalculator -> ScmLogInfo [ label = \"16\" weight = \"16\" ];\nCostBenefitCalculator -> RankedDisharmony [ label = \"20\" weight = \"20\" ];\nCostBenefitCalculator -> CodebaseGraphDTO [ label = \"10\" weight = \"10\" ];\nCostBenefitCalculator -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> GodClassRanker [ label = \"6\" weight = \"6\" ];\nCostBenefitCalculator -> DisharmonyInstance [ label = \"11\" weight = \"11\" ];\nCostBenefitCalculator -> DisharmonyRanker [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"2\" weight = \"2\" ];\nCostBenefitCalculator -> Disharmony [ label = \"5\" weight = \"5\" ];\nCostBenefitCalculator -> CBOClass [ label = \"6\" weight = \"6\" ];\nCycleNode -> Disharmony [ label = \"1\" weight = \"1\" ];\nCycleNode -> ScmLogInfo [ label = \"1\" weight = \"1\" ];\nCycleRanker -> CodebaseGraphDTO [ label = \"2\" weight = \"2\" ];\nCycleRanker -> CompositeGraphBuilder [ label = \"3\" weight = \"3\" ];\nCycleRanker -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nCycleRanker -> RankedCycle [ label = \"7\" weight = \"7\" ];\nCycleRanker -> CircularReferenceChecker [ label = \"2\" weight = \"2\" ];\nCycleRanker -> CycleNode [ label = \"3\" weight = \"3\" ];\nRankedCycle -> CycleNode [ label = \"2\" weight = \"2\" ];\nRankedDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> GodClass [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> ScmLogInfo [ label = \"3\" weight = \"3\" ];\nRankedDisharmony -> CBOClass [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nCBOClass -> Disharmony [ label = \"1\" weight = \"1\" ];\nDisharmonyInstance -> Disharmony [ label = \"1\" weight = \"1\" ];\nDisharmonyInstance -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyRanker -> DisharmonyInstance [ label = \"7\" weight = \"7\" ];\nDisharmonyRanker -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyRanker -> org_hjug_metrics_DisharmonyRanker_ValueExtractor [ label = \"3\" weight = \"3\" ];\nDisharmonyRanker -> org_hjug_metrics_DisharmonyRanker_RankSetter [ label = \"3\" weight = \"3\" ];\nGodClass -> Disharmony [ label = \"1\" weight = \"1\" ];\nGodClassRanker -> GodClass [ label = \"18\" weight = \"18\" ];\nEdgeRemovalCalculator -> DSM [ label = \"4\" weight = \"4\" ];\nEdgeRemovalCalculator -> CircularReferenceChecker [ label = \"6\" weight = \"6\" ];\nEdgeRemovalCalculator -> EdgeToRemoveInfo [ label = \"7\" weight = \"7\" ];\nSparseIntDWGEdgeRemovalCalculator -> EdgeToRemoveInfo [ label = \"3\" weight = \"3\" ];\nFeedbackArcSetSolver -> org_hjug_feedback_arc_approximate_FeedbackArcSetResult [ label = \"2\" weight = \"2\" ];\nEdgeInfoCalculator -> EdgeInfo [ label = \"4\" weight = \"4\" ];\nMinimumFeedbackArcSetSolver -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nMinimumFeedbackArcSetSolver -> org_hjug_feedback_arc_exact_FeedbackArcSetResult [ label = \"2\" weight = \"2\" ];\nLineDigraph -> LineVertex [ label = \"68\" weight = \"68\" ];\nPageRankFAS -> SuperTypeToken [ label = \"3\" weight = \"3\" ];\nPageRankFAS -> LineDigraph [ label = \"13\" weight = \"13\" ];\nPageRankFAS -> LineVertex [ label = \"25\" weight = \"25\" ];\nCycleRemovalComputer -> CircularReferenceChecker [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> EnhancedParameterComputer [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label = \"4\" weight = \"4\" ];\nCycleRemovalComputer -> DirectedFeedbackVertexSetSolver [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> DirectedFeedbackVertexSetResult [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> PageRankFAS [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> CycleRemovalResult [ label = \"1\" weight = \"1\" ];\nFeedbackVertexSetSolver -> FeedbackVertexSetResult [ label = \"16\" weight = \"16\" ];\nFeedbackVertexSetSolver -> org_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate [ label = \"5\" weight = \"5\" ];\nDirectedFeedbackVertexSetSolver -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nDirectedFeedbackVertexSetSolver -> DirectedFeedbackVertexSetResult [ label = \"4\" weight = \"4\" ];\nDirectedFeedbackVertexSetSolver -> org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats [ label = \"4\" weight = \"4\" ];\nDirectedFeedbackVertexSetSolver -> org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext [ label = \"1\" weight = \"1\" ];\nEnhancedParameterComputer -> TreewidthComputer [ label = \"6\" weight = \"6\" ];\nEnhancedParameterComputer -> FeedbackVertexSetComputer [ label = \"6\" weight = \"6\" ];\nEnhancedParameterComputer -> ModulatorComputer [ label = \"5\" weight = \"5\" ];\nEnhancedParameterComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nEnhancedParameterComputer -> org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label = \"14\" weight = \"14\" ];\nEnhancedParameterComputer -> org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label = \"6\" weight = \"6\" ];\nFeedbackVertexSetComputer -> SuperTypeToken [ label = \"4\" weight = \"4\" ];\nModulatorComputer -> TreewidthComputer [ label = \"14\" weight = \"14\" ];\nModulatorComputer -> FeedbackVertexSetComputer [ label = \"5\" weight = \"5\" ];\nModulatorComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nModulatorComputer -> org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label = \"2\" weight = \"2\" ];\nParameterComputer -> TreewidthComputer [ label = \"7\" weight = \"7\" ];\nParameterComputer -> FeedbackVertexSetComputer [ label = \"6\" weight = \"6\" ];\nParameterComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nParameterComputer -> org_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters [ label = \"4\" weight = \"4\" ];\nGraphDataGenerator -> RankedDisharmony [ label = \"2\" weight = \"2\" ];\nCsvReportTask -> RefactorFirstExtension [ label = \"8\" weight = \"8\" ];\nCsvReportTask -> CsvReport [ label = \"3\" weight = \"3\" ];\nCsvReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nHtmlReportTask -> RefactorFirstExtension [ label = \"13\" weight = \"13\" ];\nHtmlReportTask -> HtmlReport [ label = \"2\" weight = \"2\" ];\nHtmlReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nHtmlReportTask -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nJsonReportTask -> RefactorFirstExtension [ label = \"3\" weight = \"3\" ];\nJsonReportTask -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nJsonReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReportTask -> RefactorFirstExtension [ label = \"13\" weight = \"13\" ];\nSimpleHtmlReportTask -> SimpleHtmlReport [ label = \"3\" weight = \"3\" ];\nSimpleHtmlReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nMavenReportOutputDirectory -> ReportWriter [ label = \"1\" weight = \"1\" ];\nRefactorFirstHtmlReport -> HtmlReport [ label = \"2\" weight = \"2\" ];\nRefactorFirstHtmlReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstHtmlReport -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenCsvReport -> CsvReport [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenCsvReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenJsonGenerator -> JsonGenerator [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenJsonReport -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenJsonReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenReport -> HtmlReport [ label = \"2\" weight = \"2\" ];\nRefactorFirstMavenReport -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nRefactorFirstSimpleHtmlReport -> SimpleHtmlReport [ label = \"3\" weight = \"3\" ];\nRefactorFirstSimpleHtmlReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nCsvReport -> GitLogReader [ label = \"4\" weight = \"4\" ];\nCsvReport -> ReportWriter [ label = \"3\" weight = \"3\" ];\nCsvReport -> RankedDisharmony [ label = \"3\" weight = \"3\" ];\nCsvReport -> CostBenefitCalculator [ label = \"5\" weight = \"5\" ];\nHtmlReport -> SimpleHtmlReport [ label = \"9\" weight = \"9\" ];\nHtmlReport -> RankedDisharmony [ label = \"1\" weight = \"1\" ];\nHtmlReport -> GraphDataGenerator [ label = \"5\" weight = \"5\" ];\nHtmlReport -> CodebaseGraphDTO [ label = \"17\" weight = \"17\" ];\nHtmlReport -> RankedCycle [ label = \"3\" weight = \"3\" ];\nJsonReport -> JsonReportDisharmonyEntry [ label = \"1\" weight = \"1\" ];\nJsonReportDisharmonyEntry -> RankedDisharmony [ label = \"1\" weight = \"1\" ];\nJsonReportExecutor -> CostBenefitCalculator [ label = \"5\" weight = \"5\" ];\nJsonReportExecutor -> RankedDisharmony [ label = \"2\" weight = \"2\" ];\nJsonReportExecutor -> JsonReportDisharmonyEntry [ label = \"2\" weight = \"2\" ];\nJsonReportExecutor -> JsonReport [ label = \"3\" weight = \"3\" ];\nJsonReportExecutor -> ReportWriter [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> HtmlReport [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> RefactorFirstReportDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> CodebaseGraphDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> GitLogReader [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> CycleRanker [ label = \"5\" weight = \"5\" ];\nJsonGenerator -> RankedCycle [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> CycleRemovalComputer [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> CycleRemovalResult [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> RankedDisharmony [ label = \"10\" weight = \"10\" ];\nJsonGenerator -> CostBenefitCalculator [ label = \"6\" weight = \"6\" ];\nJsonGenerator -> org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label = \"17\" weight = \"17\" ];\nJsonGenerator -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> SimpleHtmlReport [ label = \"31\" weight = \"31\" ];\nJsonGenerator -> ProjectMetadataDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> GraphVisualDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassRelationshipDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> PackageRelationshipDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> PackageRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> DisharmonySectionDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> CycleSummaryDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> LargestCycleDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> CycleBreakdownRowDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassCyclesDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> ChartJsBubbleDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> DisharmonyChartDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> DisharmonyMetric [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableRowDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableCellDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableDTO [ label = \"1\" weight = \"1\" ];\nClassCyclesDTO -> CycleSummaryDTO [ label = \"2\" weight = \"2\" ];\nClassCyclesDTO -> LargestCycleDTO [ label = \"1\" weight = \"1\" ];\nClassRelationshipsToRemoveDTO -> ClassRelationshipDTO [ label = \"2\" weight = \"2\" ];\nDisharmonyChartDTO -> ChartJsBubbleDTO [ label = \"2\" weight = \"2\" ];\nDisharmonySectionDTO -> DisharmonyChartDTO [ label = \"1\" weight = \"1\" ];\nDisharmonySectionDTO -> DisharmonyTableDTO [ label = \"1\" weight = \"1\" ];\nDisharmonyTableDTO -> DisharmonyTableRowDTO [ label = \"2\" weight = \"2\" ];\nDisharmonyTableRowDTO -> DisharmonyTableCellDTO [ label = \"2\" weight = \"2\" ];\nLargestCycleDTO -> CycleBreakdownRowDTO [ label = \"2\" weight = \"2\" ];\nPackageRelationshipsToRemoveDTO -> PackageRelationshipDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ProjectMetadataDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> GraphVisualDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ClassRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> PackageRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> DisharmonySectionDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ClassCyclesDTO [ label = \"1\" weight = \"1\" ];\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"3\" weight = \"3\" ];\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_ReportWriteException [ label = \"3\" weight = \"3\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> ReportWriter [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label = \"34\" weight = \"34\" ];\nSimpleHtmlReport -> ReportWriter [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> GitLogReader [ label = \"5\" weight = \"5\" ];\nSimpleHtmlReport -> CycleRanker [ label = \"5\" weight = \"5\" ];\nSimpleHtmlReport -> RankedCycle [ label = \"10\" weight = \"10\" ];\nSimpleHtmlReport -> CodebaseGraphDTO [ label = \"13\" weight = \"13\" ];\nSimpleHtmlReport -> CycleRemovalComputer [ label = \"4\" weight = \"4\" ];\nSimpleHtmlReport -> CycleRemovalResult [ label = \"2\" weight = \"2\" ];\nSimpleHtmlReport -> RankedDisharmony [ label = \"16\" weight = \"16\" ];\nSimpleHtmlReport -> CostBenefitCalculator [ label = \"6\" weight = \"6\" ];\nSimpleHtmlReport -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> DisharmonyMetric [ label = \"3\" weight = \"3\" ];\nConsole -> io_confluent_ksql_cli_console_Console_RowCaptor [ label = \"4\" weight = \"4\" ];\nConsole -> io_confluent_ksql_cli_console_Console_NoOpRowCaptor [ label = \"1\" weight = \"1\" ];\nConsole -> io_confluent_ksql_cli_console_Console_CliCmdExecutor [ label = \"4\" weight = \"4\" ];\nio_confluent_ksql_cli_console_Console_NoOpRowCaptor -> io_confluent_ksql_cli_console_Console_RowCaptor [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 [ label=\"AbstractDependencyVisitor$1\"];\nCycleSummaryDTO [];\nJsonReport [];\nDisharmonyTableCellDTO [];\nEdgeRemovalCalculator [];\nSimpleHtmlReport [];\nLineDigraph [];\nCsvReportTask [];\nRefactorFirstExtension [];\norg_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label=\"SimpleHtmlReport$DisharmonySpec\"];\nGraphMetricsCollector [];\nDisharmonyInstance [];\norg_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext [ label=\"DirectedFeedbackVertexSetSolver$PathContext\"];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label=\"MetricsVisitorLogic$ClassStateSnapshot\"];\nDisharmonySectionDTO [];\nMavenReportOutputDirectory [];\nPackageRelationshipsToRemoveDTO [];\nCompositeGraphBuilder [];\nPackageRelationshipDTO [];\nMetricsCollectingVisitor [];\nKotlinSourceFileGraphBuilder [];\nMethodMetrics [];\nCodebaseGraphDTO [];\nRankedDisharmony [];\nFeedbackVertexSetResult [];\nRefactorFirstMavenJsonReport [];\nCycleRemovalComputer [];\nJsonReportTask [];\nDSM [];\nJsonReportDisharmonyEntry [];\norg_hjug_graphbuilder_metrics_DisharmonyMetric_Direction [ label=\"DisharmonyMetric$Direction\"];\nio_confluent_ksql_cli_console_Console_RowCaptor [ label=\"Console$RowCaptor\"];\nCycleBreakdownRowDTO [];\nDisharmonyDetector [];\nCircularReferenceChecker [];\nFeedbackArcSetSolver [];\nCycleRemovalResult [];\norg_hjug_refactorfirst_report_ReportWriter_ReportWriteException [ label=\"ReportWriter$ReportWriteException\"];\nAbstractDependencyVisitor [];\nJava25ParserFactory [];\nProjectMetadataDTO [];\norg_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters [ label=\"ParameterComputer$Parameters\"];\nLargestCycleDTO [];\nRankedCycle [];\nClassRelationshipDTO [];\nDisharmonyRanker [];\norg_hjug_git_GitLogReader_CommitWalkStats [ label=\"GitLogReader$CommitWalkStats\"];\nGraphVisualDTO [];\nDisharmonyTableRowDTO [];\nChangePronenessRanker [];\nScmLogInfo [];\nKotlinMetricsCollectingVisitor [];\nEdgeToRemoveInfo [];\nDirectedFeedbackVertexSetSolver [];\nGraphBuilderConfig [];\nMinimumFeedbackArcSetSolver [];\norg_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot [ label=\"DependencyVisitorLogic$ClassSnapshot\"];\nRefactorFirstMavenReport [];\nEdgeInfoCalculator [];\nRefactorFirstMavenJsonGenerator [];\nCycleRanker [];\nReportCommand [];\nDisharmonyChartDTO [];\nRefactorFirstPlugin [];\nDependencyCollector [];\nCostBenefitCalculator [];\nEdgeInfo [];\nGitLogReader [];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate [ label=\"MetricsVisitorLogic$OverridePredicate\"];\nGraphDependencyCollector [];\nDependencyVisitorLogic [];\nDisharmony [];\nio_confluent_ksql_cli_console_Console_NoOpRowCaptor [ label=\"Console$NoOpRowCaptor\"];\nClassMetrics [];\nSparseIntDWGEdgeRemovalCalculator [];\nRefactorFirstSimpleHtmlReport [];\nClassRelationshipsToRemoveDTO [];\nCsvReport [];\nDisharmonyTableDTO [];\nJsonGenerator [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData [ label=\"DisharmonyDetector$FlaggedClassData\"];\norg_hjug_metrics_DisharmonyRanker_RankSetter [ label=\"DisharmonyRanker$RankSetter\"];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label=\"ReportWriter$SecureDirectoryOps\"];\nChartJsBubbleDTO [];\nHtmlReport [];\nDisharmonyMetric [];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label=\"MetricsVisitorLogic$MethodStateSnapshot\"];\norg_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats [ label=\"DirectedFeedbackVertexSetSolver$PathComputationStats\"];\nLineVertex [];\norg_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label=\"ModulatorComputer$ModulatorResult\"];\nGodClass [];\nDirectedFeedbackVertexSetResult [];\nRefactorFirstReportDTO [];\nio_confluent_ksql_cli_console_Console_CliCmdExecutor [ label=\"Console$CliCmdExecutor\"];\nKotlinDependencyVisitor [];\norg_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate [ label=\"FeedbackVertexSetSolver$CutCandidate\"];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_Clone [ label=\"DisharmonyDetector$Clone\"];\nCBOClass [];\nMain [];\nJavaSourceFileGraphBuilder [];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label=\"ReportWriter$SecureDirectoryOpsImpl\"];\nGodClassRanker [];\norg_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 [ label=\"KotlinDependencyVisitor$1\"];\norg_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label=\"EnhancedParameterComputer$EnhancedParameters\"];\nConsole [];\nCycleNode [];\nFeedbackVertexSetComputer [];\nCBORule [];\nReportType [];\nParameterComputer [];\nComplexityCalculator [];\nRefactorFirstMavenCsvReport [];\nReportWriter [ color=red style=filled];\nMetricsVisitorLogic [];\norg_hjug_metrics_DisharmonyRanker_ValueExtractor [ label=\"DisharmonyRanker$ValueExtractor\"];\nMetricsVisitorState [];\nTypeDependencyExtractor [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label=\"DisharmonyDetector$ClassDisharmony\"];\nHtmlReportTask [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry [ label=\"DisharmonyDetector$MethodEntry\"];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label=\"ReportWriter$FallbackDirectoryOps\"];\norg_hjug_feedback_arc_approximate_FeedbackArcSetResult [ label=\"FeedbackArcSetResult\"];\nJavaVisitor [];\nJsonReportExecutor [];\nBaseTypeProcessor [];\nEnhancedParameterComputer [];\nFeedbackVertexSetSolver [];\nGraphDataGenerator [];\nDependencyVisitorState [];\norg_hjug_feedback_arc_exact_FeedbackArcSetResult [ label=\"FeedbackArcSetResult\"];\nUnattributedTypeFqnResolver [];\nSourceFileGraphBuilder [];\nSuperTypeToken [];\nPageRankFAS [];\nSourcePathResolver [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label=\"DisharmonyDetector$MethodDisharmony\"];\nSimpleHtmlReportTask [];\nRefactorFirstHtmlReport [];\nClassCyclesDTO [];\nTreewidthComputer [];\nModulatorComputer [];\n}", + "dot" : "strict digraph G {\nChangePronenessRanker -> ScmLogInfo [ label = \"5\" weight = \"5\" ];\nChangePronenessRanker -> GitLogReader [ label = \"2\" weight = \"2\" ];\nGitLogReader -> org_hjug_git_GitLogReader_CommitWalkStats [ label = \"4\" weight = \"4\" ];\nGitLogReader -> ScmLogInfo [ label = \"3\" weight = \"3\" ];\nMain -> ReportCommand [ label = \"1\" weight = \"1\" ];\nReportCommand -> ReportType [ label = \"1\" weight = \"1\" ];\nReportCommand -> ReportWriter [ label = \"1\" weight = \"1\" ];\nReportCommand -> SimpleHtmlReport [ label = \"4\" weight = \"4\" ];\nReportCommand -> HtmlReport [ label = \"2\" weight = \"2\" ];\nReportCommand -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nReportCommand -> CsvReport [ label = \"3\" weight = \"3\" ];\nCodebaseGraphDTO -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"4\" weight = \"4\" ];\nCodebaseGraphDTO -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"4\" weight = \"4\" ];\nCompositeGraphBuilder -> GraphBuilderConfig [ label = \"4\" weight = \"4\" ];\nCompositeGraphBuilder -> CodebaseGraphDTO [ label = \"10\" weight = \"10\" ];\nCompositeGraphBuilder -> JavaSourceFileGraphBuilder [ label = \"3\" weight = \"3\" ];\nCompositeGraphBuilder -> KotlinSourceFileGraphBuilder [ label = \"3\" weight = \"3\" ];\nCompositeGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"2\" weight = \"2\" ];\nCompositeGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> SourceFileGraphBuilder [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> GraphDependencyCollector [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> JavaVisitor [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> GraphMetricsCollector [ label = \"5\" weight = \"5\" ];\nJavaSourceFileGraphBuilder -> MetricsCollectingVisitor [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> AbstractDependencyVisitor [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"2\" weight = \"2\" ];\nJavaSourceFileGraphBuilder -> Java25ParserFactory [ label = \"1\" weight = \"1\" ];\nJavaSourceFileGraphBuilder -> DisharmonyDetector [ label = \"18\" weight = \"18\" ];\nJavaSourceFileGraphBuilder -> ClassMetrics [ label = \"3\" weight = \"3\" ];\nJavaSourceFileGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"3\" weight = \"3\" ];\nJavaSourceFileGraphBuilder -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"3\" weight = \"3\" ];\nKotlinSourceFileGraphBuilder -> SourceFileGraphBuilder [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> GraphDependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> KotlinDependencyVisitor [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> GraphMetricsCollector [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> KotlinMetricsCollectingVisitor [ label = \"2\" weight = \"2\" ];\nKotlinSourceFileGraphBuilder -> JavaSourceFileGraphBuilder [ label = \"1\" weight = \"1\" ];\nKotlinSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"1\" weight = \"1\" ];\nSourceFileGraphBuilder -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nSourceFileGraphBuilder -> CodebaseGraphDTO [ label = \"1\" weight = \"1\" ];\nGraphDependencyCollector -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nClassMetrics -> MethodMetrics [ label = \"13\" weight = \"13\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony -> ClassMetrics [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony -> MethodMetrics [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyDetector -> ClassMetrics [ label = \"99\" weight = \"99\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"30\" weight = \"30\" ];\nDisharmonyDetector -> DisharmonyMetric [ label = \"44\" weight = \"44\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"15\" weight = \"15\" ];\nDisharmonyDetector -> MethodMetrics [ label = \"40\" weight = \"40\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry [ label = \"5\" weight = \"5\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData [ label = \"10\" weight = \"10\" ];\nDisharmonyDetector -> org_hjug_graphbuilder_metrics_DisharmonyDetector_Clone [ label = \"20\" weight = \"20\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry -> ClassMetrics [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry -> MethodMetrics [ label = \"2\" weight = \"2\" ];\nDisharmonyMetric -> org_hjug_graphbuilder_metrics_DisharmonyMetric_Direction [ label = \"1\" weight = \"1\" ];\nGraphMetricsCollector -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nGraphMetricsCollector -> ClassMetrics [ label = \"33\" weight = \"33\" ];\nGraphMetricsCollector -> MethodMetrics [ label = \"10\" weight = \"10\" ];\nKotlinMetricsCollectingVisitor -> GraphMetricsCollector [ label = \"2\" weight = \"2\" ];\nKotlinMetricsCollectingVisitor -> MetricsVisitorState [ label = \"2\" weight = \"2\" ];\nKotlinMetricsCollectingVisitor -> MetricsVisitorLogic [ label = \"17\" weight = \"17\" ];\nKotlinMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"1\" weight = \"1\" ];\nKotlinMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"1\" weight = \"1\" ];\nKotlinMetricsCollectingVisitor -> ClassMetrics [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> GraphMetricsCollector [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> MetricsVisitorState [ label = \"2\" weight = \"2\" ];\nMetricsCollectingVisitor -> MetricsVisitorLogic [ label = \"10\" weight = \"10\" ];\nMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"1\" weight = \"1\" ];\nMetricsCollectingVisitor -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"1\" weight = \"1\" ];\nMetricsVisitorLogic -> MetricsVisitorState [ label = \"12\" weight = \"12\" ];\nMetricsVisitorLogic -> GraphMetricsCollector [ label = \"13\" weight = \"13\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label = \"4\" weight = \"4\" ];\nMetricsVisitorLogic -> ClassMetrics [ label = \"28\" weight = \"28\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate [ label = \"2\" weight = \"2\" ];\nMetricsVisitorLogic -> MethodMetrics [ label = \"31\" weight = \"31\" ];\nMetricsVisitorLogic -> ComplexityCalculator [ label = \"4\" weight = \"4\" ];\nMetricsVisitorLogic -> org_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label = \"3\" weight = \"3\" ];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot -> ClassMetrics [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot -> MethodMetrics [ label = \"2\" weight = \"2\" ];\nMetricsVisitorState -> ClassMetrics [ label = \"1\" weight = \"1\" ];\nMetricsVisitorState -> MethodMetrics [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> DependencyVisitorState [ label = \"2\" weight = \"2\" ];\nAbstractDependencyVisitor -> DependencyCollector [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> org_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> BaseTypeProcessor [ label = \"1\" weight = \"1\" ];\nAbstractDependencyVisitor -> DependencyVisitorLogic [ label = \"14\" weight = \"14\" ];\nBaseTypeProcessor -> TypeDependencyExtractor [ label = \"3\" weight = \"3\" ];\nBaseTypeProcessor -> DependencyCollector [ label = \"3\" weight = \"3\" ];\nDependencyVisitorLogic -> DependencyVisitorState [ label = \"14\" weight = \"14\" ];\nDependencyVisitorLogic -> SourcePathResolver [ label = \"2\" weight = \"2\" ];\nDependencyVisitorLogic -> org_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot [ label = \"3\" weight = \"3\" ];\nDependencyVisitorLogic -> UnattributedTypeFqnResolver [ label = \"1\" weight = \"1\" ];\nDependencyVisitorState -> BaseTypeProcessor [ label = \"2\" weight = \"2\" ];\nJavaVisitor -> AbstractDependencyVisitor [ label = \"2\" weight = \"2\" ];\nJavaVisitor -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> DependencyCollector [ label = \"7\" weight = \"7\" ];\nKotlinDependencyVisitor -> BaseTypeProcessor [ label = \"8\" weight = \"8\" ];\nKotlinDependencyVisitor -> DependencyVisitorState [ label = \"2\" weight = \"2\" ];\norg_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 -> DependencyCollector [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> org_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 [ label = \"1\" weight = \"1\" ];\nKotlinDependencyVisitor -> DependencyVisitorLogic [ label = \"17\" weight = \"17\" ];\nCostBenefitCalculator -> GitLogReader [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> ChangePronenessRanker [ label = \"3\" weight = \"3\" ];\nCostBenefitCalculator -> CBORule [ label = \"1\" weight = \"1\" ];\nCostBenefitCalculator -> GodClass [ label = \"10\" weight = \"10\" ];\nCostBenefitCalculator -> ScmLogInfo [ label = \"16\" weight = \"16\" ];\nCostBenefitCalculator -> RankedDisharmony [ label = \"20\" weight = \"20\" ];\nCostBenefitCalculator -> CodebaseGraphDTO [ label = \"10\" weight = \"10\" ];\nCostBenefitCalculator -> org_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> GodClassRanker [ label = \"6\" weight = \"6\" ];\nCostBenefitCalculator -> DisharmonyInstance [ label = \"11\" weight = \"11\" ];\nCostBenefitCalculator -> DisharmonyRanker [ label = \"4\" weight = \"4\" ];\nCostBenefitCalculator -> org_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label = \"2\" weight = \"2\" ];\nCostBenefitCalculator -> Disharmony [ label = \"5\" weight = \"5\" ];\nCostBenefitCalculator -> CBOClass [ label = \"6\" weight = \"6\" ];\nCycleNode -> Disharmony [ label = \"1\" weight = \"1\" ];\nCycleNode -> ScmLogInfo [ label = \"1\" weight = \"1\" ];\nCycleRanker -> CodebaseGraphDTO [ label = \"2\" weight = \"2\" ];\nCycleRanker -> CompositeGraphBuilder [ label = \"3\" weight = \"3\" ];\nCycleRanker -> GraphBuilderConfig [ label = \"1\" weight = \"1\" ];\nCycleRanker -> RankedCycle [ label = \"7\" weight = \"7\" ];\nCycleRanker -> CircularReferenceChecker [ label = \"2\" weight = \"2\" ];\nCycleRanker -> CycleNode [ label = \"3\" weight = \"3\" ];\nRankedCycle -> CycleNode [ label = \"2\" weight = \"2\" ];\nRankedDisharmony -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> GodClass [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> ScmLogInfo [ label = \"3\" weight = \"3\" ];\nRankedDisharmony -> CBOClass [ label = \"1\" weight = \"1\" ];\nRankedDisharmony -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nCBOClass -> Disharmony [ label = \"1\" weight = \"1\" ];\nDisharmonyInstance -> Disharmony [ label = \"1\" weight = \"1\" ];\nDisharmonyInstance -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyRanker -> DisharmonyInstance [ label = \"7\" weight = \"7\" ];\nDisharmonyRanker -> DisharmonyMetric [ label = \"1\" weight = \"1\" ];\nDisharmonyRanker -> org_hjug_metrics_DisharmonyRanker_ValueExtractor [ label = \"3\" weight = \"3\" ];\nDisharmonyRanker -> org_hjug_metrics_DisharmonyRanker_RankSetter [ label = \"3\" weight = \"3\" ];\nGodClass -> Disharmony [ label = \"1\" weight = \"1\" ];\nGodClassRanker -> GodClass [ label = \"18\" weight = \"18\" ];\nEdgeRemovalCalculator -> DSM [ label = \"4\" weight = \"4\" ];\nEdgeRemovalCalculator -> CircularReferenceChecker [ label = \"6\" weight = \"6\" ];\nEdgeRemovalCalculator -> EdgeToRemoveInfo [ label = \"7\" weight = \"7\" ];\nSparseIntDWGEdgeRemovalCalculator -> EdgeToRemoveInfo [ label = \"3\" weight = \"3\" ];\nFeedbackArcSetSolver -> org_hjug_feedback_arc_approximate_FeedbackArcSetResult [ label = \"2\" weight = \"2\" ];\nEdgeInfoCalculator -> EdgeInfo [ label = \"4\" weight = \"4\" ];\nMinimumFeedbackArcSetSolver -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nMinimumFeedbackArcSetSolver -> org_hjug_feedback_arc_exact_FeedbackArcSetResult [ label = \"2\" weight = \"2\" ];\nLineDigraph -> LineVertex [ label = \"68\" weight = \"68\" ];\nPageRankFAS -> SuperTypeToken [ label = \"3\" weight = \"3\" ];\nPageRankFAS -> LineDigraph [ label = \"12\" weight = \"12\" ];\nPageRankFAS -> LineVertex [ label = \"39\" weight = \"39\" ];\nCycleRemovalComputer -> CircularReferenceChecker [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> EnhancedParameterComputer [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label = \"4\" weight = \"4\" ];\nCycleRemovalComputer -> DirectedFeedbackVertexSetSolver [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> DirectedFeedbackVertexSetResult [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> PageRankFAS [ label = \"2\" weight = \"2\" ];\nCycleRemovalComputer -> CycleRemovalResult [ label = \"1\" weight = \"1\" ];\nFeedbackVertexSetSolver -> FeedbackVertexSetResult [ label = \"16\" weight = \"16\" ];\nFeedbackVertexSetSolver -> org_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate [ label = \"5\" weight = \"5\" ];\nDirectedFeedbackVertexSetSolver -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nDirectedFeedbackVertexSetSolver -> DirectedFeedbackVertexSetResult [ label = \"4\" weight = \"4\" ];\nDirectedFeedbackVertexSetSolver -> org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats [ label = \"4\" weight = \"4\" ];\nDirectedFeedbackVertexSetSolver -> org_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext [ label = \"1\" weight = \"1\" ];\nEnhancedParameterComputer -> TreewidthComputer [ label = \"6\" weight = \"6\" ];\nEnhancedParameterComputer -> FeedbackVertexSetComputer [ label = \"6\" weight = \"6\" ];\nEnhancedParameterComputer -> ModulatorComputer [ label = \"5\" weight = \"5\" ];\nEnhancedParameterComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nEnhancedParameterComputer -> org_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label = \"14\" weight = \"14\" ];\nEnhancedParameterComputer -> org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label = \"6\" weight = \"6\" ];\nFeedbackVertexSetComputer -> SuperTypeToken [ label = \"4\" weight = \"4\" ];\nModulatorComputer -> TreewidthComputer [ label = \"14\" weight = \"14\" ];\nModulatorComputer -> FeedbackVertexSetComputer [ label = \"5\" weight = \"5\" ];\nModulatorComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nModulatorComputer -> org_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label = \"2\" weight = \"2\" ];\nParameterComputer -> TreewidthComputer [ label = \"7\" weight = \"7\" ];\nParameterComputer -> FeedbackVertexSetComputer [ label = \"6\" weight = \"6\" ];\nParameterComputer -> SuperTypeToken [ label = \"2\" weight = \"2\" ];\nParameterComputer -> org_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters [ label = \"4\" weight = \"4\" ];\nGraphDataGenerator -> RankedDisharmony [ label = \"2\" weight = \"2\" ];\nCsvReportTask -> RefactorFirstExtension [ label = \"8\" weight = \"8\" ];\nCsvReportTask -> CsvReport [ label = \"3\" weight = \"3\" ];\nCsvReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nHtmlReportTask -> RefactorFirstExtension [ label = \"13\" weight = \"13\" ];\nHtmlReportTask -> HtmlReport [ label = \"2\" weight = \"2\" ];\nHtmlReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nHtmlReportTask -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nJsonReportTask -> RefactorFirstExtension [ label = \"3\" weight = \"3\" ];\nJsonReportTask -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nJsonReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReportTask -> RefactorFirstExtension [ label = \"13\" weight = \"13\" ];\nSimpleHtmlReportTask -> SimpleHtmlReport [ label = \"3\" weight = \"3\" ];\nSimpleHtmlReportTask -> RefactorFirstPlugin [ label = \"1\" weight = \"1\" ];\nMavenReportOutputDirectory -> ReportWriter [ label = \"1\" weight = \"1\" ];\nRefactorFirstHtmlReport -> HtmlReport [ label = \"2\" weight = \"2\" ];\nRefactorFirstHtmlReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstHtmlReport -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenCsvReport -> CsvReport [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenCsvReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenJsonGenerator -> JsonGenerator [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenJsonReport -> JsonReportExecutor [ label = \"3\" weight = \"3\" ];\nRefactorFirstMavenJsonReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nRefactorFirstMavenReport -> HtmlReport [ label = \"2\" weight = \"2\" ];\nRefactorFirstMavenReport -> SimpleHtmlReport [ label = \"1\" weight = \"1\" ];\nRefactorFirstSimpleHtmlReport -> SimpleHtmlReport [ label = \"3\" weight = \"3\" ];\nRefactorFirstSimpleHtmlReport -> MavenReportOutputDirectory [ label = \"1\" weight = \"1\" ];\nCsvReport -> GitLogReader [ label = \"4\" weight = \"4\" ];\nCsvReport -> ReportWriter [ label = \"3\" weight = \"3\" ];\nCsvReport -> RankedDisharmony [ label = \"3\" weight = \"3\" ];\nCsvReport -> CostBenefitCalculator [ label = \"5\" weight = \"5\" ];\nHtmlReport -> SimpleHtmlReport [ label = \"9\" weight = \"9\" ];\nHtmlReport -> RankedDisharmony [ label = \"1\" weight = \"1\" ];\nHtmlReport -> GraphDataGenerator [ label = \"5\" weight = \"5\" ];\nHtmlReport -> CodebaseGraphDTO [ label = \"17\" weight = \"17\" ];\nHtmlReport -> RankedCycle [ label = \"3\" weight = \"3\" ];\nJsonReport -> JsonReportDisharmonyEntry [ label = \"1\" weight = \"1\" ];\nJsonReportDisharmonyEntry -> RankedDisharmony [ label = \"1\" weight = \"1\" ];\nJsonReportExecutor -> CostBenefitCalculator [ label = \"5\" weight = \"5\" ];\nJsonReportExecutor -> RankedDisharmony [ label = \"2\" weight = \"2\" ];\nJsonReportExecutor -> JsonReportDisharmonyEntry [ label = \"2\" weight = \"2\" ];\nJsonReportExecutor -> JsonReport [ label = \"3\" weight = \"3\" ];\nJsonReportExecutor -> ReportWriter [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> HtmlReport [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> RefactorFirstReportDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> CodebaseGraphDTO [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> GitLogReader [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> CycleRanker [ label = \"5\" weight = \"5\" ];\nJsonGenerator -> RankedCycle [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> CycleRemovalComputer [ label = \"4\" weight = \"4\" ];\nJsonGenerator -> CycleRemovalResult [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> RankedDisharmony [ label = \"10\" weight = \"10\" ];\nJsonGenerator -> CostBenefitCalculator [ label = \"6\" weight = \"6\" ];\nJsonGenerator -> org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label = \"17\" weight = \"17\" ];\nJsonGenerator -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> SimpleHtmlReport [ label = \"33\" weight = \"33\" ];\nJsonGenerator -> ProjectMetadataDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> GraphVisualDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassRelationshipDTO [ label = \"6\" weight = \"6\" ];\nJsonGenerator -> ClassRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> PackageRelationshipDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> PackageRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> DisharmonySectionDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> CycleSummaryDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> LargestCycleDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> CycleBreakdownRowDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> ClassCyclesDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> ChartJsBubbleDTO [ label = \"3\" weight = \"3\" ];\nJsonGenerator -> DisharmonyChartDTO [ label = \"1\" weight = \"1\" ];\nJsonGenerator -> DisharmonyMetric [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableRowDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableCellDTO [ label = \"2\" weight = \"2\" ];\nJsonGenerator -> DisharmonyTableDTO [ label = \"1\" weight = \"1\" ];\nClassCyclesDTO -> CycleSummaryDTO [ label = \"2\" weight = \"2\" ];\nClassCyclesDTO -> LargestCycleDTO [ label = \"1\" weight = \"1\" ];\nClassRelationshipsToRemoveDTO -> ClassRelationshipDTO [ label = \"2\" weight = \"2\" ];\nDisharmonyChartDTO -> ChartJsBubbleDTO [ label = \"2\" weight = \"2\" ];\nDisharmonySectionDTO -> DisharmonyChartDTO [ label = \"1\" weight = \"1\" ];\nDisharmonySectionDTO -> DisharmonyTableDTO [ label = \"1\" weight = \"1\" ];\nDisharmonyTableDTO -> DisharmonyTableRowDTO [ label = \"2\" weight = \"2\" ];\nDisharmonyTableRowDTO -> DisharmonyTableCellDTO [ label = \"2\" weight = \"2\" ];\nLargestCycleDTO -> CycleBreakdownRowDTO [ label = \"2\" weight = \"2\" ];\nPackageRelationshipDTO -> ClassRelationshipDTO [ label = \"2\" weight = \"2\" ];\nPackageRelationshipsToRemoveDTO -> PackageRelationshipDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ProjectMetadataDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> GraphVisualDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ClassRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> PackageRelationshipsToRemoveDTO [ label = \"1\" weight = \"1\" ];\nRefactorFirstReportDTO -> DisharmonySectionDTO [ label = \"2\" weight = \"2\" ];\nRefactorFirstReportDTO -> ClassCyclesDTO [ label = \"1\" weight = \"1\" ];\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"3\" weight = \"3\" ];\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_ReportWriteException [ label = \"3\" weight = \"3\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> ReportWriter [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> org_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label = \"34\" weight = \"34\" ];\nSimpleHtmlReport -> ReportWriter [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> GitLogReader [ label = \"5\" weight = \"5\" ];\nSimpleHtmlReport -> CycleRanker [ label = \"5\" weight = \"5\" ];\nSimpleHtmlReport -> RankedCycle [ label = \"10\" weight = \"10\" ];\nSimpleHtmlReport -> CodebaseGraphDTO [ label = \"13\" weight = \"13\" ];\nSimpleHtmlReport -> CycleRemovalComputer [ label = \"4\" weight = \"4\" ];\nSimpleHtmlReport -> CycleRemovalResult [ label = \"2\" weight = \"2\" ];\nSimpleHtmlReport -> RankedDisharmony [ label = \"16\" weight = \"16\" ];\nSimpleHtmlReport -> CostBenefitCalculator [ label = \"6\" weight = \"6\" ];\nSimpleHtmlReport -> DisharmonyInstance [ label = \"1\" weight = \"1\" ];\nSimpleHtmlReport -> DisharmonyMetric [ label = \"3\" weight = \"3\" ];\nConsole -> io_confluent_ksql_cli_console_Console_RowCaptor [ label = \"4\" weight = \"4\" ];\nConsole -> io_confluent_ksql_cli_console_Console_NoOpRowCaptor [ label = \"1\" weight = \"1\" ];\nConsole -> io_confluent_ksql_cli_console_Console_CliCmdExecutor [ label = \"4\" weight = \"4\" ];\nio_confluent_ksql_cli_console_Console_NoOpRowCaptor -> io_confluent_ksql_cli_console_Console_RowCaptor [ label = \"1\" weight = \"1\" ];\norg_hjug_graphbuilder_visitor_AbstractDependencyVisitor_1 [ label=\"AbstractDependencyVisitor$1\"];\nCycleSummaryDTO [];\nJsonReport [];\nDisharmonyTableCellDTO [];\nEdgeRemovalCalculator [];\nSimpleHtmlReport [];\nLineDigraph [];\nCsvReportTask [];\nRefactorFirstExtension [];\norg_hjug_refactorfirst_report_SimpleHtmlReport_DisharmonySpec [ label=\"SimpleHtmlReport$DisharmonySpec\"];\nGraphMetricsCollector [];\nDisharmonyInstance [];\norg_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathContext [ label=\"DirectedFeedbackVertexSetSolver$PathContext\"];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_ClassStateSnapshot [ label=\"MetricsVisitorLogic$ClassStateSnapshot\"];\nDisharmonySectionDTO [];\nMavenReportOutputDirectory [];\nPackageRelationshipsToRemoveDTO [];\nCompositeGraphBuilder [];\nPackageRelationshipDTO [];\nMetricsCollectingVisitor [];\nKotlinSourceFileGraphBuilder [];\nMethodMetrics [];\nCodebaseGraphDTO [];\nRankedDisharmony [];\nFeedbackVertexSetResult [];\nRefactorFirstMavenJsonReport [];\nCycleRemovalComputer [];\nJsonReportTask [];\nDSM [];\nJsonReportDisharmonyEntry [];\norg_hjug_graphbuilder_metrics_DisharmonyMetric_Direction [ label=\"DisharmonyMetric$Direction\"];\nio_confluent_ksql_cli_console_Console_RowCaptor [ label=\"Console$RowCaptor\"];\nCycleBreakdownRowDTO [];\nDisharmonyDetector [];\nCircularReferenceChecker [];\nFeedbackArcSetSolver [];\nCycleRemovalResult [];\norg_hjug_refactorfirst_report_ReportWriter_ReportWriteException [ label=\"ReportWriter$ReportWriteException\"];\nAbstractDependencyVisitor [];\nJava25ParserFactory [];\nProjectMetadataDTO [];\norg_hjug_feedback_vertex_kernelized_ParameterComputer_Parameters [ label=\"ParameterComputer$Parameters\"];\nLargestCycleDTO [];\nRankedCycle [];\nClassRelationshipDTO [];\nDisharmonyRanker [];\norg_hjug_git_GitLogReader_CommitWalkStats [ label=\"GitLogReader$CommitWalkStats\"];\nGraphVisualDTO [];\nDisharmonyTableRowDTO [];\nChangePronenessRanker [];\nScmLogInfo [];\nKotlinMetricsCollectingVisitor [];\nEdgeToRemoveInfo [];\nDirectedFeedbackVertexSetSolver [];\nGraphBuilderConfig [];\nMinimumFeedbackArcSetSolver [];\norg_hjug_graphbuilder_visitor_DependencyVisitorLogic_ClassSnapshot [ label=\"DependencyVisitorLogic$ClassSnapshot\"];\nRefactorFirstMavenReport [];\nEdgeInfoCalculator [];\nRefactorFirstMavenJsonGenerator [];\nCycleRanker [];\nReportCommand [];\nDisharmonyChartDTO [];\nRefactorFirstPlugin [];\nDependencyCollector [];\nCostBenefitCalculator [];\nEdgeInfo [];\nGitLogReader [];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_OverridePredicate [ label=\"MetricsVisitorLogic$OverridePredicate\"];\nGraphDependencyCollector [];\nDependencyVisitorLogic [];\nDisharmony [];\nio_confluent_ksql_cli_console_Console_NoOpRowCaptor [ label=\"Console$NoOpRowCaptor\"];\nClassMetrics [];\nSparseIntDWGEdgeRemovalCalculator [];\nRefactorFirstSimpleHtmlReport [];\nClassRelationshipsToRemoveDTO [];\nCsvReport [];\nDisharmonyTableDTO [];\nJsonGenerator [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_FlaggedClassData [ label=\"DisharmonyDetector$FlaggedClassData\"];\norg_hjug_metrics_DisharmonyRanker_RankSetter [ label=\"DisharmonyRanker$RankSetter\"];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label=\"ReportWriter$SecureDirectoryOps\"];\nChartJsBubbleDTO [];\nHtmlReport [];\nDisharmonyMetric [];\norg_hjug_graphbuilder_metrics_MetricsVisitorLogic_MethodStateSnapshot [ label=\"MetricsVisitorLogic$MethodStateSnapshot\"];\norg_hjug_feedback_vertex_kernelized_DirectedFeedbackVertexSetSolver_PathComputationStats [ label=\"DirectedFeedbackVertexSetSolver$PathComputationStats\"];\nLineVertex [];\norg_hjug_feedback_vertex_kernelized_ModulatorComputer_ModulatorResult [ label=\"ModulatorComputer$ModulatorResult\"];\nGodClass [];\nDirectedFeedbackVertexSetResult [];\nRefactorFirstReportDTO [];\nio_confluent_ksql_cli_console_Console_CliCmdExecutor [ label=\"Console$CliCmdExecutor\"];\nKotlinDependencyVisitor [];\norg_hjug_feedback_vertex_approximate_FeedbackVertexSetSolver_CutCandidate [ label=\"FeedbackVertexSetSolver$CutCandidate\"];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_Clone [ label=\"DisharmonyDetector$Clone\"];\nCBOClass [];\nMain [];\nJavaSourceFileGraphBuilder [];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label=\"ReportWriter$SecureDirectoryOpsImpl\"];\nGodClassRanker [];\norg_hjug_graphbuilder_visitor_KotlinDependencyVisitor_1 [ label=\"KotlinDependencyVisitor$1\"];\norg_hjug_feedback_vertex_kernelized_EnhancedParameterComputer_EnhancedParameters [ label=\"EnhancedParameterComputer$EnhancedParameters\"];\nConsole [];\nCycleNode [];\nFeedbackVertexSetComputer [];\nCBORule [];\nReportType [];\nParameterComputer [];\nComplexityCalculator [];\nRefactorFirstMavenCsvReport [];\nReportWriter [ color=red style=filled];\nMetricsVisitorLogic [];\norg_hjug_metrics_DisharmonyRanker_ValueExtractor [ label=\"DisharmonyRanker$ValueExtractor\"];\nMetricsVisitorState [];\nTypeDependencyExtractor [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_ClassDisharmony [ label=\"DisharmonyDetector$ClassDisharmony\"];\nHtmlReportTask [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodEntry [ label=\"DisharmonyDetector$MethodEntry\"];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label=\"ReportWriter$FallbackDirectoryOps\"];\norg_hjug_feedback_arc_approximate_FeedbackArcSetResult [ label=\"FeedbackArcSetResult\"];\nJavaVisitor [];\nJsonReportExecutor [];\nBaseTypeProcessor [];\nEnhancedParameterComputer [];\nFeedbackVertexSetSolver [];\nGraphDataGenerator [];\nDependencyVisitorState [];\norg_hjug_feedback_arc_exact_FeedbackArcSetResult [ label=\"FeedbackArcSetResult\"];\nUnattributedTypeFqnResolver [];\nSourceFileGraphBuilder [];\nSuperTypeToken [];\nPageRankFAS [];\nSourcePathResolver [];\norg_hjug_graphbuilder_metrics_DisharmonyDetector_MethodDisharmony [ label=\"DisharmonyDetector$MethodDisharmony\"];\nSimpleHtmlReportTask [];\nRefactorFirstHtmlReport [];\nClassCyclesDTO [];\nTreewidthComputer [];\nModulatorComputer [];\n}", "hasEdges" : false }, "classRelationshipsToRemove" : { @@ -27,7 +27,7 @@ "sourceMarked" : false, "targetMarked" : false, "weight" : 1, - "renderedLabel" : "ReportWriter$SecureDirectoryOps → ReportWriter$SecureDirectoryOpsImpl : 1", + "renderedLabel" : "ReportWriter$SecureDirectoryOps → ReportWriter$SecureDirectoryOpsImpl : 1", "priority" : 1, "cycleCount" : 1, "effortRank" : 1, @@ -39,7 +39,7 @@ "sourceMarked" : false, "targetMarked" : false, "weight" : 1, - "renderedLabel" : "ReportWriter$SecureDirectoryOps → ReportWriter$FallbackDirectoryOps : 1", + "renderedLabel" : "ReportWriter$SecureDirectoryOps → ReportWriter$FallbackDirectoryOps : 1", "priority" : 2, "cycleCount" : 1, "effortRank" : 1, @@ -53,7 +53,7 @@ "relationshipCount" : 37, "dotThreshold" : 4000, "dotThresholdExceeded" : false, - "dot" : "strict digraph G {\npackage_622c04a26e1ba36b6ebca283 -> package_864d6940ac14438961598d5a [ label = \"10\" weight = \"10\" ];\npackage_622c04a26e1ba36b6ebca283 -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_275b39592e996f9bc7d2bab4 -> package_179967d6e66ef95e5ec582dc [ label = \"12\" weight = \"12\" ];\npackage_275b39592e996f9bc7d2bab4 -> package_98c578ab6c4dd833f53d3aee [ label = \"6\" weight = \"6\" color = \"red\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_275b39592e996f9bc7d2bab4 [ label = \"10\" weight = \"10\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_d36e09db80f0e2bbc4ffd5c7 [ label = \"4\" weight = \"4\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_179967d6e66ef95e5ec582dc [ label = \"37\" weight = \"37\" ];\npackage_179967d6e66ef95e5ec582dc -> package_275b39592e996f9bc7d2bab4 [ label = \"1\" weight = \"1\" color = \"red\" ];\npackage_d36e09db80f0e2bbc4ffd5c7 -> package_275b39592e996f9bc7d2bab4 [ label = \"14\" weight = \"14\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_cc2439ece2ff219a79eb369d [ label = \"27\" weight = \"27\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_d6011c21970de8ae7eafff05 [ label = \"1\" weight = \"1\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_869fe932642cb7510df73c8d [ label = \"46\" weight = \"46\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_275b39592e996f9bc7d2bab4 [ label = \"16\" weight = \"16\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_179967d6e66ef95e5ec582dc [ label = \"7\" weight = \"7\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_6da3c08ea2d561edab77673f [ label = \"2\" weight = \"2\" ];\npackage_869fe932642cb7510df73c8d -> package_179967d6e66ef95e5ec582dc [ label = \"2\" weight = \"2\" ];\npackage_5770287cc40afd5bd6812d59 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"2\" weight = \"2\" ];\npackage_d30a7a8d892c5e6113a07e84 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"3\" weight = \"3\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_6da3c08ea2d561edab77673f [ label = \"2\" weight = \"2\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_d2f1dd27b2e43b88238a4c05 [ label = \"10\" weight = \"10\" color = \"red\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_d30a7a8d892c5e6113a07e84 [ label = \"2\" weight = \"2\" color = \"red\" ];\npackage_d2f1dd27b2e43b88238a4c05 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"12\" weight = \"12\" ];\npackage_e16f87ed4cbaa8972b66b80b -> package_bfb0d6f0cb59390b479b08a1 [ label = \"2\" weight = \"2\" ];\npackage_c28460328a6700365ccc109d -> package_864d6940ac14438961598d5a [ label = \"9\" weight = \"9\" ];\npackage_c28460328a6700365ccc109d -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_5a5b226dc916c25cd94e86c9 -> package_864d6940ac14438961598d5a [ label = \"16\" weight = \"16\" ];\npackage_5a5b226dc916c25cd94e86c9 -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_864d6940ac14438961598d5a -> package_cc2439ece2ff219a79eb369d [ label = \"11\" weight = \"11\" ];\npackage_864d6940ac14438961598d5a -> package_bfb0d6f0cb59390b479b08a1 [ label = \"73\" weight = \"73\" ];\npackage_864d6940ac14438961598d5a -> package_e16f87ed4cbaa8972b66b80b [ label = \"5\" weight = \"5\" ];\npackage_864d6940ac14438961598d5a -> package_275b39592e996f9bc7d2bab4 [ label = \"33\" weight = \"33\" ];\npackage_bb20afe0ec6010144ae2060c -> package_bfb0d6f0cb59390b479b08a1 [ label = \"8\" weight = \"8\" ];\npackage_bb20afe0ec6010144ae2060c -> package_864d6940ac14438961598d5a [ label = \"2\" weight = \"2\" ];\npackage_864d6940ac14438961598d5a -> package_8b5bd27cd192f3c043f79d74 [ label = \"29\" weight = \"29\" ];\npackage_864d6940ac14438961598d5a -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"12\" weight = \"12\" ];\npackage_864d6940ac14438961598d5a -> package_869fe932642cb7510df73c8d [ label = \"2\" weight = \"2\" ];\npackage_864d6940ac14438961598d5a -> package_179967d6e66ef95e5ec582dc [ label = \"5\" weight = \"5\" ];\npackage_6da3c08ea2d561edab77673f [label=\"org.hjug.dsm\"];\npackage_5a5b226dc916c25cd94e86c9 [label=\"org.hjug.mavenreport\"];\npackage_d30a7a8d892c5e6113a07e84 [label=\"org.hjug.feedback.arc.pageRank\"];\npackage_d6011c21970de8ae7eafff05 [label=\"org.hjug.metrics.rules\"];\npackage_179967d6e66ef95e5ec582dc [label=\"org.hjug.graphbuilder.metrics\"];\npackage_98c578ab6c4dd833f53d3aee [label=\"org.hjug.graphbuilder.graphbuilder\"];\npackage_8b5bd27cd192f3c043f79d74 [label=\"org.hjug.refactorfirst.report.model\"];\npackage_cc2439ece2ff219a79eb369d [label=\"org.hjug.git\"];\npackage_bb20afe0ec6010144ae2060c [label=\"org.hjug.refactorfirst.report.json\"];\npackage_d36e09db80f0e2bbc4ffd5c7 [label=\"org.hjug.graphbuilder.visitor\"];\npackage_0b6cea3e7e0dde98e8d142c3 [label=\"org.hjug.feedback\"];\npackage_275b39592e996f9bc7d2bab4 [label=\"org.hjug.graphbuilder\" color=red style=filled];\npackage_869fe932642cb7510df73c8d [label=\"org.hjug.metrics\"];\npackage_864d6940ac14438961598d5a [label=\"org.hjug.refactorfirst.report\"];\npackage_e16f87ed4cbaa8972b66b80b [label=\"org.hjug.gdg\"];\npackage_c28460328a6700365ccc109d [label=\"org.hjug.gradlereport\"];\npackage_5770287cc40afd5bd6812d59 [label=\"org.hjug.feedback.arc.exact\"];\npackage_622c04a26e1ba36b6ebca283 [label=\"org.hjug.refactorfirst\"];\npackage_bfb0d6f0cb59390b479b08a1 [label=\"org.hjug.cbc\" color=red style=filled];\npackage_d2f1dd27b2e43b88238a4c05 [label=\"org.hjug.feedback.vertex.kernelized\"];\n}", + "dot" : "strict digraph G {\npackage_622c04a26e1ba36b6ebca283 -> package_864d6940ac14438961598d5a [ label = \"10\" weight = \"10\" ];\npackage_622c04a26e1ba36b6ebca283 -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_275b39592e996f9bc7d2bab4 -> package_179967d6e66ef95e5ec582dc [ label = \"12\" weight = \"12\" ];\npackage_275b39592e996f9bc7d2bab4 -> package_98c578ab6c4dd833f53d3aee [ label = \"6\" weight = \"6\" color = \"red\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_275b39592e996f9bc7d2bab4 [ label = \"10\" weight = \"10\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_d36e09db80f0e2bbc4ffd5c7 [ label = \"4\" weight = \"4\" ];\npackage_98c578ab6c4dd833f53d3aee -> package_179967d6e66ef95e5ec582dc [ label = \"37\" weight = \"37\" ];\npackage_179967d6e66ef95e5ec582dc -> package_275b39592e996f9bc7d2bab4 [ label = \"1\" weight = \"1\" color = \"red\" ];\npackage_d36e09db80f0e2bbc4ffd5c7 -> package_275b39592e996f9bc7d2bab4 [ label = \"14\" weight = \"14\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_cc2439ece2ff219a79eb369d [ label = \"27\" weight = \"27\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_d6011c21970de8ae7eafff05 [ label = \"1\" weight = \"1\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_869fe932642cb7510df73c8d [ label = \"46\" weight = \"46\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_275b39592e996f9bc7d2bab4 [ label = \"16\" weight = \"16\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_179967d6e66ef95e5ec582dc [ label = \"7\" weight = \"7\" ];\npackage_bfb0d6f0cb59390b479b08a1 -> package_6da3c08ea2d561edab77673f [ label = \"2\" weight = \"2\" ];\npackage_869fe932642cb7510df73c8d -> package_179967d6e66ef95e5ec582dc [ label = \"2\" weight = \"2\" ];\npackage_5770287cc40afd5bd6812d59 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"2\" weight = \"2\" ];\npackage_d30a7a8d892c5e6113a07e84 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"3\" weight = \"3\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_6da3c08ea2d561edab77673f [ label = \"2\" weight = \"2\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_d2f1dd27b2e43b88238a4c05 [ label = \"10\" weight = \"10\" color = \"red\" ];\npackage_0b6cea3e7e0dde98e8d142c3 -> package_d30a7a8d892c5e6113a07e84 [ label = \"2\" weight = \"2\" color = \"red\" ];\npackage_d2f1dd27b2e43b88238a4c05 -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"12\" weight = \"12\" ];\npackage_e16f87ed4cbaa8972b66b80b -> package_bfb0d6f0cb59390b479b08a1 [ label = \"2\" weight = \"2\" ];\npackage_c28460328a6700365ccc109d -> package_864d6940ac14438961598d5a [ label = \"9\" weight = \"9\" ];\npackage_c28460328a6700365ccc109d -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_5a5b226dc916c25cd94e86c9 -> package_864d6940ac14438961598d5a [ label = \"16\" weight = \"16\" ];\npackage_5a5b226dc916c25cd94e86c9 -> package_bb20afe0ec6010144ae2060c [ label = \"3\" weight = \"3\" ];\npackage_864d6940ac14438961598d5a -> package_cc2439ece2ff219a79eb369d [ label = \"11\" weight = \"11\" ];\npackage_864d6940ac14438961598d5a -> package_bfb0d6f0cb59390b479b08a1 [ label = \"73\" weight = \"73\" ];\npackage_864d6940ac14438961598d5a -> package_e16f87ed4cbaa8972b66b80b [ label = \"5\" weight = \"5\" ];\npackage_864d6940ac14438961598d5a -> package_275b39592e996f9bc7d2bab4 [ label = \"34\" weight = \"34\" ];\npackage_bb20afe0ec6010144ae2060c -> package_bfb0d6f0cb59390b479b08a1 [ label = \"8\" weight = \"8\" ];\npackage_bb20afe0ec6010144ae2060c -> package_864d6940ac14438961598d5a [ label = \"2\" weight = \"2\" ];\npackage_864d6940ac14438961598d5a -> package_8b5bd27cd192f3c043f79d74 [ label = \"33\" weight = \"33\" ];\npackage_864d6940ac14438961598d5a -> package_0b6cea3e7e0dde98e8d142c3 [ label = \"12\" weight = \"12\" ];\npackage_864d6940ac14438961598d5a -> package_869fe932642cb7510df73c8d [ label = \"2\" weight = \"2\" ];\npackage_864d6940ac14438961598d5a -> package_179967d6e66ef95e5ec582dc [ label = \"5\" weight = \"5\" ];\npackage_6da3c08ea2d561edab77673f [label=\"org.hjug.dsm\"];\npackage_5a5b226dc916c25cd94e86c9 [label=\"org.hjug.mavenreport\"];\npackage_d30a7a8d892c5e6113a07e84 [label=\"org.hjug.feedback.arc.pageRank\"];\npackage_d6011c21970de8ae7eafff05 [label=\"org.hjug.metrics.rules\"];\npackage_179967d6e66ef95e5ec582dc [label=\"org.hjug.graphbuilder.metrics\"];\npackage_98c578ab6c4dd833f53d3aee [label=\"org.hjug.graphbuilder.graphbuilder\"];\npackage_8b5bd27cd192f3c043f79d74 [label=\"org.hjug.refactorfirst.report.model\"];\npackage_cc2439ece2ff219a79eb369d [label=\"org.hjug.git\"];\npackage_bb20afe0ec6010144ae2060c [label=\"org.hjug.refactorfirst.report.json\"];\npackage_d36e09db80f0e2bbc4ffd5c7 [label=\"org.hjug.graphbuilder.visitor\"];\npackage_0b6cea3e7e0dde98e8d142c3 [label=\"org.hjug.feedback\"];\npackage_275b39592e996f9bc7d2bab4 [label=\"org.hjug.graphbuilder\" color=red style=filled];\npackage_869fe932642cb7510df73c8d [label=\"org.hjug.metrics\"];\npackage_864d6940ac14438961598d5a [label=\"org.hjug.refactorfirst.report\"];\npackage_e16f87ed4cbaa8972b66b80b [label=\"org.hjug.gdg\"];\npackage_c28460328a6700365ccc109d [label=\"org.hjug.gradlereport\"];\npackage_5770287cc40afd5bd6812d59 [label=\"org.hjug.feedback.arc.exact\"];\npackage_622c04a26e1ba36b6ebca283 [label=\"org.hjug.refactorfirst\"];\npackage_bfb0d6f0cb59390b479b08a1 [label=\"org.hjug.cbc\" color=red style=filled];\npackage_d2f1dd27b2e43b88238a4c05 [label=\"org.hjug.feedback.vertex.kernelized\"];\n}", "hasEdges" : true }, "packageRelationshipsToRemove" : { @@ -66,44 +66,140 @@ "sourceMarked" : false, "targetMarked" : true, "weight" : 1, - "renderedLabel" : "org.hjug.graphbuilder.metrics → org.hjug.graphbuilder* : 1", + "renderedLabel" : "org.hjug.graphbuilder.metrics → org.hjug.graphbuilder* : 1", "priority" : 1, "cycleCount" : 1, "effortRank" : 1, - "classRelationshipsToBreakPackage" : [ "GraphMetricsCollector → DependencyCollector : 1" ] + "classRelationshipsToBreakPackage" : [ { + "sourceClass" : "org.hjug.graphbuilder.metrics.GraphMetricsCollector", + "targetClass" : "org.hjug.graphbuilder.DependencyCollector", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 1, + "renderedLabel" : "GraphMetricsCollector → DependencyCollector : 1", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + } ] }, { "sourcePackage" : "org.hjug.feedback", "targetPackage" : "org.hjug.feedback.arc.pageRank", "sourceMarked" : false, "targetMarked" : false, "weight" : 2, - "renderedLabel" : "org.hjug.feedback → org.hjug.feedback.arc.pageRank : 2", + "renderedLabel" : "org.hjug.feedback → org.hjug.feedback.arc.pageRank : 2", "priority" : 2, "cycleCount" : 1, "effortRank" : 2, - "classRelationshipsToBreakPackage" : [ "CycleRemovalComputer → PageRankFAS : 2" ] + "classRelationshipsToBreakPackage" : [ { + "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", + "targetClass" : "org.hjug.feedback.arc.pageRank.PageRankFAS", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 2, + "renderedLabel" : "CycleRemovalComputer → PageRankFAS : 2", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + } ] }, { "sourcePackage" : "org.hjug.graphbuilder", "targetPackage" : "org.hjug.graphbuilder.graphbuilder", "sourceMarked" : true, "targetMarked" : false, "weight" : 6, - "renderedLabel" : "org.hjug.graphbuilder* → org.hjug.graphbuilder.graphbuilder : 6", + "renderedLabel" : "org.hjug.graphbuilder* → org.hjug.graphbuilder.graphbuilder : 6", "priority" : 3, "cycleCount" : 1, "effortRank" : 6, - "classRelationshipsToBreakPackage" : [ "CompositeGraphBuilder → KotlinSourceFileGraphBuilder : 3", "CompositeGraphBuilder → JavaSourceFileGraphBuilder : 3" ] + "classRelationshipsToBreakPackage" : [ { + "sourceClass" : "org.hjug.graphbuilder.CompositeGraphBuilder", + "targetClass" : "org.hjug.graphbuilder.graphbuilder.JavaSourceFileGraphBuilder", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 3, + "renderedLabel" : "CompositeGraphBuilder → JavaSourceFileGraphBuilder : 3", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.graphbuilder.CompositeGraphBuilder", + "targetClass" : "org.hjug.graphbuilder.graphbuilder.KotlinSourceFileGraphBuilder", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 3, + "renderedLabel" : "CompositeGraphBuilder → KotlinSourceFileGraphBuilder : 3", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + } ] }, { "sourcePackage" : "org.hjug.feedback", "targetPackage" : "org.hjug.feedback.vertex.kernelized", "sourceMarked" : false, "targetMarked" : false, "weight" : 10, - "renderedLabel" : "org.hjug.feedback → org.hjug.feedback.vertex.kernelized : 10", + "renderedLabel" : "org.hjug.feedback → org.hjug.feedback.vertex.kernelized : 10", "priority" : 4, "cycleCount" : 1, "effortRank" : 10, - "classRelationshipsToBreakPackage" : [ "CycleRemovalComputer → DirectedFeedbackVertexSetSolver : 2", "CycleRemovalComputer → DirectedFeedbackVertexSetResult : 2", "CycleRemovalComputer → EnhancedParameterComputer : 2", "CycleRemovalComputer → EnhancedParameterComputer$EnhancedParameters : 4" ] + "classRelationshipsToBreakPackage" : [ { + "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", + "targetClass" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetResult", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 2, + "renderedLabel" : "CycleRemovalComputer → DirectedFeedbackVertexSetResult : 2", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", + "targetClass" : "org.hjug.feedback.vertex.kernelized.DirectedFeedbackVertexSetSolver", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 2, + "renderedLabel" : "CycleRemovalComputer → DirectedFeedbackVertexSetSolver : 2", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", + "targetClass" : "org.hjug.feedback.vertex.kernelized.EnhancedParameterComputer", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 2, + "renderedLabel" : "CycleRemovalComputer → EnhancedParameterComputer : 2", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + }, { + "sourceClass" : "org.hjug.feedback.CycleRemovalComputer", + "targetClass" : "org.hjug.feedback.vertex.kernelized.EnhancedParameterComputer$EnhancedParameters", + "sourceMarked" : false, + "targetMarked" : false, + "weight" : 4, + "renderedLabel" : "CycleRemovalComputer → EnhancedParameterComputer$EnhancedParameters : 4", + "priority" : 0, + "cycleCount" : 0, + "effortRank" : 0, + "alsoRemovesPackageRelationship" : false, + "packageCycleCount" : 0 + } ] } ] }, "hasDisharmonies" : true, @@ -128,7 +224,7 @@ "changePronenessRank" : 1, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -137,7 +233,7 @@ "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "JsonGenerator.java", "align" : "left" }, { "content" : "1", @@ -149,10 +245,10 @@ "content" : "1", "align" : "right" }, { - "content" : "10/2/26, 7:43 AM", + "content" : "10/4/26, 3:17 PM", "align" : "right" }, { - "content" : "8", + "content" : "14", "align" : "right" } ] } ] @@ -178,7 +274,7 @@ "changePronenessRank" : 2, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/RefactorFirstExtension.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/RefactorFirstExtension.java" }, { "id" : "MetricsVisitorState.java", "label" : "MetricsVisitorState.java", @@ -190,7 +286,7 @@ "changePronenessRank" : 3, "color" : "rgba(137, 119, 74, 0.75)", "borderColor" : "rgb(137, 119, 74)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorState.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorState.java" }, { "id" : "Attributes.java", "label" : "Attributes.java", @@ -202,7 +298,7 @@ "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/Attributes.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/Attributes.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -211,7 +307,7 @@ "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "RefactorFirstExtension.java", + "content" : "RefactorFirstExtension.java", "align" : "left" }, { "content" : "1", @@ -231,7 +327,7 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorState.java", + "content" : "MetricsVisitorState.java", "align" : "left" }, { "content" : "2", @@ -251,7 +347,7 @@ } ] }, { "cells" : [ { - "content" : "Attributes.java", + "content" : "Attributes.java", "align" : "left" }, { "content" : "3", @@ -292,7 +388,7 @@ "changePronenessRank" : 1, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -301,7 +397,7 @@ "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "1", @@ -342,7 +438,7 @@ "changePronenessRank" : 4, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" }, { "id" : "JsonGenerator.java", "label" : "JsonGenerator.java", @@ -354,7 +450,7 @@ "changePronenessRank" : 5, "color" : "rgba(186, 92, 63, 0.75)", "borderColor" : "rgb(186, 92, 63)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", @@ -366,7 +462,7 @@ "changePronenessRank" : 2, "color" : "rgba(137, 119, 74, 0.75)", "borderColor" : "rgb(137, 119, 74)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "id" : "AttributeHandler2.java", "label" : "AttributeHandler2.java", @@ -378,7 +474,7 @@ "changePronenessRank" : 3, "color" : "rgba(88, 147, 85, 0.75)", "borderColor" : "rgb(88, 147, 85)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler2.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler2.java" }, { "id" : "AttributeHandler.java", "label" : "AttributeHandler.java", @@ -390,7 +486,7 @@ "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -399,7 +495,7 @@ "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "HtmlReport.java", + "content" : "HtmlReport.java", "align" : "left" }, { "content" : "1", @@ -411,15 +507,15 @@ "content" : "2", "align" : "right" }, { - "content" : "9/30/26, 9:07 PM", + "content" : "10/3/26, 4:43 PM", "align" : "right" }, { - "content" : "62", + "content" : "64", "align" : "right" } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "JsonGenerator.java", "align" : "left" }, { "content" : "2", @@ -431,15 +527,15 @@ "content" : "3", "align" : "right" }, { - "content" : "10/2/26, 7:43 AM", + "content" : "10/4/26, 3:17 PM", "align" : "right" }, { - "content" : "8", + "content" : "5", "align" : "right" } ] }, { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left" }, { "content" : "3", @@ -459,7 +555,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler2.java", + "content" : "AttributeHandler2.java", "align" : "left" }, { "content" : "4", @@ -479,7 +575,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler.java", + "content" : "AttributeHandler.java", "align" : "left" }, { "content" : "5", @@ -506,33 +602,45 @@ "methodLevel" : false, "problem" : "Child class adds many new public methods, but doesn't override or use many of the parent class's methods", "solution" : "Do one or more of the following:
- Make public child methods unused outside of the class non-public.
- Pull duplicated methods in child classes into the parent class.
- Move methods in the child class that are unrelated to the parent class to another class.
- Remove the child class from the hierarchy.", - "maxPriority" : 2, + "maxPriority" : 3, "chart" : { "canvasId" : "chart_TB", "bubbles" : [ { + "id" : "JsonGenerator.java", + "label" : "JsonGenerator.java", + "x" : 2, + "y" : 3, + "r" : 24, + "priority" : 1, + "effortRank" : 2, + "changePronenessRank" : 3, + "color" : "rgba(235, 64, 52, 0.75)", + "borderColor" : "rgb(235, 64, 52)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + }, { "id" : "AttributeHandler2.java", "label" : "AttributeHandler2.java", "x" : 1, "y" : 1, - "r" : 24, - "priority" : 1, + "r" : 15, + "priority" : 2, "effortRank" : 1, "changePronenessRank" : 1, - "color" : "rgba(235, 64, 52, 0.75)", - "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler2.java" + "color" : "rgba(137, 119, 74, 0.75)", + "borderColor" : "rgb(137, 119, 74)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler2.java" }, { "id" : "HtmlReport.java", "label" : "HtmlReport.java", - "x" : 2, + "x" : 3, "y" : 2, "r" : 6, - "priority" : 2, - "effortRank" : 2, + "priority" : 3, + "effortRank" : 3, "changePronenessRank" : 2, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/HtmlReport.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -541,11 +649,31 @@ "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "AttributeHandler2.java", + "content" : "JsonGenerator.java", "align" : "left" }, { "content" : "1", "align" : "right" + }, { + "content" : "3", + "align" : "right" + }, { + "content" : "2", + "align" : "right" + }, { + "content" : "10/4/26, 3:17 PM", + "align" : "right" + }, { + "content" : "14", + "align" : "right" + } ] + }, { + "cells" : [ { + "content" : "AttributeHandler2.java", + "align" : "left" + }, { + "content" : "2", + "align" : "right" }, { "content" : "1", "align" : "right" @@ -561,22 +689,22 @@ } ] }, { "cells" : [ { - "content" : "HtmlReport.java", + "content" : "HtmlReport.java", "align" : "left" }, { - "content" : "2", + "content" : "3", "align" : "right" }, { "content" : "2", "align" : "right" }, { - "content" : "2", + "content" : "3", "align" : "right" }, { - "content" : "9/30/26, 9:07 PM", + "content" : "10/3/26, 4:43 PM", "align" : "right" }, { - "content" : "62", + "content" : "64", "align" : "right" } ] } ] @@ -602,7 +730,7 @@ "changePronenessRank" : 5, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/HtmlReportTask.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/HtmlReportTask.java" }, { "id" : "SimpleHtmlReportTask.java", "label" : "SimpleHtmlReportTask.java", @@ -614,7 +742,7 @@ "changePronenessRank" : 4, "color" : "rgba(186, 92, 63, 0.75)", "borderColor" : "rgb(186, 92, 63)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/SimpleHtmlReportTask.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/refactor-first-gradle-plugin/src/main/java/org/hjug/gradlereport/SimpleHtmlReportTask.java" }, { "id" : "AttributeHandler.java", "label" : "AttributeHandler.java", @@ -626,7 +754,7 @@ "changePronenessRank" : 3, "color" : "rgba(137, 119, 74, 0.75)", "borderColor" : "rgb(137, 119, 74)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", @@ -638,7 +766,7 @@ "changePronenessRank" : 2, "color" : "rgba(88, 147, 85, 0.75)", "borderColor" : "rgb(88, 147, 85)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "id" : "AttributeHandler2.java", "label" : "AttributeHandler2.java", @@ -650,7 +778,7 @@ "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler2.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler2.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -659,7 +787,7 @@ "headers" : [ "Class", "Priority", "Change Proneness Rank", "Effort Rank", "Duplicate Partners", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "HtmlReportTask.java", + "content" : "HtmlReportTask.java", "align" : "left" }, { "content" : "1", @@ -682,7 +810,7 @@ } ] }, { "cells" : [ { - "content" : "SimpleHtmlReportTask.java", + "content" : "SimpleHtmlReportTask.java", "align" : "left" }, { "content" : "2", @@ -705,7 +833,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler.java", + "content" : "AttributeHandler.java", "align" : "left" }, { "content" : "3", @@ -728,7 +856,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left" }, { "content" : "4", @@ -751,7 +879,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler2.java", + "content" : "AttributeHandler2.java", "align" : "left" }, { "content" : "5", @@ -795,7 +923,7 @@ "changePronenessRank" : 9, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", @@ -807,7 +935,7 @@ "changePronenessRank" : 6, "color" : "rgba(215, 75, 56, 0.75)", "borderColor" : "rgb(215, 75, 56)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", @@ -819,7 +947,7 @@ "changePronenessRank" : 7, "color" : "rgba(196, 86, 61, 0.75)", "borderColor" : "rgb(196, 86, 61)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "DependencyVisitorLogic.java", "label" : "DependencyVisitorLogic.java", @@ -831,7 +959,7 @@ "changePronenessRank" : 8, "color" : "rgba(176, 97, 65, 0.75)", "borderColor" : "rgb(176, 97, 65)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java" }, { "id" : "DisharmonyDetector.java", "label" : "DisharmonyDetector.java", @@ -843,7 +971,7 @@ "changePronenessRank" : 10, "color" : "rgba(157, 108, 70, 0.75)", "borderColor" : "rgb(157, 108, 70)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { "id" : "JsonGenerator.java", "label" : "JsonGenerator.java", @@ -855,7 +983,7 @@ "changePronenessRank" : 11, "color" : "rgba(137, 119, 74, 0.75)", "borderColor" : "rgb(137, 119, 74)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", @@ -867,7 +995,7 @@ "changePronenessRank" : 6, "color" : "rgba(117, 130, 78, 0.75)", "borderColor" : "rgb(117, 130, 78)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", @@ -879,7 +1007,7 @@ "changePronenessRank" : 4, "color" : "rgba(98, 141, 83, 0.75)", "borderColor" : "rgb(98, 141, 83)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", @@ -891,7 +1019,7 @@ "changePronenessRank" : 4, "color" : "rgba(78, 152, 87, 0.75)", "borderColor" : "rgb(78, 152, 87)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "id" : "AttributeHandler2.java", "label" : "AttributeHandler2.java", @@ -903,7 +1031,7 @@ "changePronenessRank" : 2, "color" : "rgba(59, 163, 92, 0.75)", "borderColor" : "rgb(59, 163, 92)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler2.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler2.java" }, { "id" : "AttributeHandler.java", "label" : "AttributeHandler.java", @@ -915,7 +1043,7 @@ "changePronenessRank" : 3, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -924,7 +1052,7 @@ "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "CompositeGraphBuilder.java", + "content" : "CompositeGraphBuilder.java", "align" : "left" }, { "content" : "reconcileUnattributedVertices(Unknown,Unknown,Map<String,String>)", @@ -947,7 +1075,7 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "handleMemberReference(MetricsVisitorState,GraphMetricsCollector,Unknown)", @@ -970,7 +1098,7 @@ } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "addBypassEdges(V,Set<V>)", @@ -993,7 +1121,7 @@ } ] }, { "cells" : [ { - "content" : "DependencyVisitorLogic.java", + "content" : "DependencyVisitorLogic.java", "align" : "left" }, { "content" : "enterClassDeclaration(DependencyVisitorState,Unknown,boolean,SourcePathResolver)", @@ -1016,7 +1144,7 @@ } ] }, { "cells" : [ { - "content" : "DisharmonyDetector.java", + "content" : "DisharmonyDetector.java", "align" : "left" }, { "content" : "detectSignificantDuplication(List<ClassMetrics>)", @@ -1039,7 +1167,7 @@ } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "JsonGenerator.java", "align" : "left" }, { "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", @@ -1054,15 +1182,15 @@ "content" : "9", "align" : "right" }, { - "content" : "10/2/26, 7:43 AM", + "content" : "10/4/26, 3:17 PM", "align" : "right" }, { - "content" : "8", + "content" : "14", "align" : "right" } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "enterClass(MetricsVisitorState,GraphMetricsCollector,Unknown)", @@ -1085,7 +1213,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left" }, { "content" : "perform(Unknown)", @@ -1108,7 +1236,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left" }, { "content" : "apply(Unknown,Unknown)", @@ -1131,7 +1259,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler2.java", + "content" : "AttributeHandler2.java", "align" : "left" }, { "content" : "apply(Unknown,Unknown)", @@ -1154,7 +1282,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler.java", + "content" : "AttributeHandler.java", "align" : "left" }, { "content" : "apply(Unknown,Unknown)", @@ -1198,31 +1326,31 @@ "changePronenessRank" : 5, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { - "id" : "MetricsVisitorLogic.java", - "label" : "MetricsVisitorLogic.java", - "x" : 3, - "y" : 4, + "id" : "JsonGenerator.java", + "label" : "JsonGenerator.java", + "x" : 4, + "y" : 6, "r" : 20, "priority" : 2, - "effortRank" : 3, - "changePronenessRank" : 4, + "effortRank" : 4, + "changePronenessRank" : 6, "color" : "rgba(196, 86, 61, 0.75)", "borderColor" : "rgb(196, 86, 61)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { - "id" : "JsonGenerator.java", - "label" : "JsonGenerator.java", - "x" : 5, - "y" : 6, + "id" : "MetricsVisitorLogic.java", + "label" : "MetricsVisitorLogic.java", + "x" : 3, + "y" : 4, "r" : 17, "priority" : 3, - "effortRank" : 5, - "changePronenessRank" : 6, + "effortRank" : 3, + "changePronenessRank" : 4, "color" : "rgba(157, 108, 70, 0.75)", "borderColor" : "rgb(157, 108, 70)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", @@ -1234,7 +1362,7 @@ "changePronenessRank" : 2, "color" : "rgba(117, 130, 78, 0.75)", "borderColor" : "rgb(117, 130, 78)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandlerAndSorter.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", @@ -1246,7 +1374,7 @@ "changePronenessRank" : 4, "color" : "rgba(78, 152, 87, 0.75)", "borderColor" : "rgb(78, 152, 87)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "AttributeHandler.java", "label" : "AttributeHandler.java", @@ -1258,7 +1386,7 @@ "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandler.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandler.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -1267,7 +1395,7 @@ "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "ReportWriter.java", + "content" : "ReportWriter.java", "align" : "left" }, { "content" : "writeAtomically(Path,String)", @@ -1290,53 +1418,53 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "JsonGenerator.java", "align" : "left" }, { - "content" : "leaveClass(MetricsVisitorState,GraphMetricsCollector,Unknown,MetricsVisitorLogic$ClassStateSnapshot)", + "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", "align" : "left" }, { "content" : "2", "align" : "right" }, { - "content" : "4", + "content" : "6", "align" : "right" }, { - "content" : "3", + "content" : "4", "align" : "right" }, { - "content" : "8/19/26, 7:20 PM", + "content" : "10/4/26, 3:17 PM", "align" : "right" }, { - "content" : "1", + "content" : "14", "align" : "right" } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { - "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", + "content" : "leaveClass(MetricsVisitorState,GraphMetricsCollector,Unknown,MetricsVisitorLogic$ClassStateSnapshot)", "align" : "left" }, { "content" : "3", "align" : "right" }, { - "content" : "6", + "content" : "4", "align" : "right" }, { - "content" : "5", + "content" : "3", "align" : "right" }, { - "content" : "10/2/26, 7:43 AM", + "content" : "8/19/26, 7:20 PM", "align" : "right" }, { - "content" : "8", + "content" : "1", "align" : "right" } ] }, { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left" }, { "content" : "apply(Unknown,Unknown)", @@ -1359,7 +1487,7 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "leaveMethod(MetricsVisitorState,GraphMetricsCollector,MetricsVisitorLogic$MethodStateSnapshot)", @@ -1382,7 +1510,7 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandler.java", + "content" : "AttributeHandler.java", "align" : "left" }, { "content" : "apply(Unknown,Unknown)", @@ -1412,201 +1540,213 @@ "methodLevel" : true, "problem" : "Method calls too many methods from a few unrelated classes (often in a separate package).", "solution" : "Move the calling method to a class more closely related to the other classes that the original method can call.", - "maxPriority" : 16, + "maxPriority" : 17, "chart" : { "canvasId" : "chart_INTENSIVE_COUPLING", "bubbles" : [ { "id" : "SimpleHtmlReport.java", "label" : "SimpleHtmlReport.java", - "x" : 4, - "y" : 14, + "x" : 5, + "y" : 15, "r" : 24, "priority" : 1, - "effortRank" : 4, - "changePronenessRank" : 14, + "effortRank" : 5, + "changePronenessRank" : 15, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" }, { "id" : "CompositeGraphBuilder.java", "label" : "CompositeGraphBuilder.java", "x" : 2, - "y" : 10, + "y" : 11, "r" : 23, "priority" : 2, "effortRank" : 2, - "changePronenessRank" : 10, - "color" : "rgba(222, 71, 55, 0.75)", - "borderColor" : "rgb(222, 71, 55)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "changePronenessRank" : 11, + "color" : "rgba(223, 71, 55, 0.75)", + "borderColor" : "rgb(223, 71, 55)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { "id" : "SimpleHtmlReport.java", "label" : "SimpleHtmlReport.java", - "x" : 7, - "y" : 14, + "x" : 8, + "y" : 15, "r" : 22, "priority" : 3, - "effortRank" : 7, - "changePronenessRank" : 14, - "color" : "rgba(209, 79, 58, 0.75)", - "borderColor" : "rgb(209, 79, 58)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" + "effortRank" : 8, + "changePronenessRank" : 15, + "color" : "rgba(211, 78, 58, 0.75)", + "borderColor" : "rgb(211, 78, 58)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" }, { "id" : "SimpleHtmlReport.java", "label" : "SimpleHtmlReport.java", "x" : 8, - "y" : 14, - "r" : 20, + "y" : 15, + "r" : 21, "priority" : 4, "effortRank" : 8, - "changePronenessRank" : 14, - "color" : "rgba(196, 86, 61, 0.75)", - "borderColor" : "rgb(196, 86, 61)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" + "changePronenessRank" : 15, + "color" : "rgba(198, 85, 60, 0.75)", + "borderColor" : "rgb(198, 85, 60)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java" }, { "id" : "JsonGenerator.java", "label" : "JsonGenerator.java", "x" : 11, - "y" : 16, - "r" : 19, + "y" : 17, + "r" : 20, "priority" : 5, "effortRank" : 11, - "changePronenessRank" : 16, - "color" : "rgba(183, 93, 64, 0.75)", - "borderColor" : "rgb(183, 93, 64)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "changePronenessRank" : 17, + "color" : "rgba(186, 92, 63, 0.75)", + "borderColor" : "rgb(186, 92, 63)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + }, { + "id" : "JsonGenerator.java", + "label" : "JsonGenerator.java", + "x" : 12, + "y" : 17, + "r" : 18, + "priority" : 6, + "effortRank" : 12, + "changePronenessRank" : 17, + "color" : "rgba(174, 98, 66, 0.75)", + "borderColor" : "rgb(174, 98, 66)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" }, { "id" : "OptimalBackEdgeRemover.java", "label" : "OptimalBackEdgeRemover.java", "x" : 1, "y" : 5, - "r" : 18, - "priority" : 6, + "r" : 17, + "priority" : 7, "effortRank" : 1, "changePronenessRank" : 5, - "color" : "rgba(170, 101, 67, 0.75)", - "borderColor" : "rgb(170, 101, 67)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/dsm/OptimalBackEdgeRemover.java" + "color" : "rgba(162, 105, 69, 0.75)", + "borderColor" : "rgb(162, 105, 69)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/dsm/OptimalBackEdgeRemover.java" }, { "id" : "FeedbackVertexSetSolver.java", "label" : "FeedbackVertexSetSolver.java", "x" : 4, "y" : 8, - "r" : 17, - "priority" : 7, + "r" : 16, + "priority" : 8, "effortRank" : 4, "changePronenessRank" : 8, - "color" : "rgba(157, 108, 70, 0.75)", - "borderColor" : "rgb(157, 108, 70)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" + "color" : "rgba(149, 112, 71, 0.75)", + "borderColor" : "rgb(149, 112, 71)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" }, { - "id" : "JsonGenerator.java", - "label" : "JsonGenerator.java", - "x" : 12, - "y" : 16, - "r" : 16, - "priority" : 8, - "effortRank" : 12, - "changePronenessRank" : 16, - "color" : "rgba(144, 115, 73, 0.75)", - "borderColor" : "rgb(144, 115, 73)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java" + "id" : "PageRankFAS.java", + "label" : "PageRankFAS.java", + "x" : 5, + "y" : 9, + "r" : 15, + "priority" : 9, + "effortRank" : 5, + "changePronenessRank" : 9, + "color" : "rgba(137, 119, 74, 0.75)", + "borderColor" : "rgb(137, 119, 74)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 3, "y" : 6, "r" : 14, - "priority" : 9, + "priority" : 10, "effortRank" : 3, "changePronenessRank" : 6, - "color" : "rgba(130, 123, 75, 0.75)", - "borderColor" : "rgb(130, 123, 75)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "color" : "rgba(125, 126, 77, 0.75)", + "borderColor" : "rgb(125, 126, 77)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { "id" : "CompositeGraphBuilder.java", "label" : "CompositeGraphBuilder.java", - "x" : 7, - "y" : 10, + "x" : 8, + "y" : 11, "r" : 13, - "priority" : 10, - "effortRank" : 7, - "changePronenessRank" : 10, - "color" : "rgba(117, 130, 78, 0.75)", - "borderColor" : "rgb(117, 130, 78)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" + "priority" : 11, + "effortRank" : 8, + "changePronenessRank" : 11, + "color" : "rgba(113, 133, 80, 0.75)", + "borderColor" : "rgb(113, 133, 80)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", - "x" : 5, + "x" : 6, "y" : 7, "r" : 12, - "priority" : 11, - "effortRank" : 5, + "priority" : 12, + "effortRank" : 6, "changePronenessRank" : 7, - "color" : "rgba(104, 137, 81, 0.75)", - "borderColor" : "rgb(104, 137, 81)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "color" : "rgba(100, 140, 82, 0.75)", + "borderColor" : "rgb(100, 140, 82)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "DisharmonyDetector.java", "label" : "DisharmonyDetector.java", "x" : 11, - "y" : 11, + "y" : 12, "r" : 11, - "priority" : 12, + "priority" : 13, "effortRank" : 11, - "changePronenessRank" : 11, - "color" : "rgba(91, 145, 84, 0.75)", - "borderColor" : "rgb(91, 145, 84)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "changePronenessRank" : 12, + "color" : "rgba(88, 147, 85, 0.75)", + "borderColor" : "rgb(88, 147, 85)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", "x" : 3, "y" : 1, - "r" : 10, - "priority" : 13, + "r" : 9, + "priority" : 14, "effortRank" : 3, "changePronenessRank" : 1, - "color" : "rgba(78, 152, 87, 0.75)", - "borderColor" : "rgb(78, 152, 87)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + "color" : "rgba(76, 153, 88, 0.75)", + "borderColor" : "rgb(76, 153, 88)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", - "x" : 6, + "x" : 7, "y" : 4, "r" : 8, - "priority" : 14, - "effortRank" : 6, + "priority" : 15, + "effortRank" : 7, "changePronenessRank" : 4, - "color" : "rgba(65, 159, 90, 0.75)", - "borderColor" : "rgb(65, 159, 90)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "color" : "rgba(64, 160, 91, 0.75)", + "borderColor" : "rgb(64, 160, 91)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", "x" : 9, "y" : 4, "r" : 7, - "priority" : 15, + "priority" : 16, "effortRank" : 9, "changePronenessRank" : 4, - "color" : "rgba(52, 167, 93, 0.75)", - "borderColor" : "rgb(52, 167, 93)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "color" : "rgba(51, 167, 93, 0.75)", + "borderColor" : "rgb(51, 167, 93)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", "x" : 10, "y" : 4, "r" : 6, - "priority" : 16, + "priority" : 17, "effortRank" : 10, "changePronenessRank" : 4, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -1615,7 +1755,7 @@ "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "SimpleHtmlReport.java", + "content" : "SimpleHtmlReport.java", "align" : "left" }, { "content" : "simplifyDuplicatePartners(String)", @@ -1624,21 +1764,21 @@ "content" : "1", "align" : "right" }, { - "content" : "14", + "content" : "15", "align" : "right" }, { - "content" : "4", + "content" : "5", "align" : "right" }, { - "content" : "9/23/26, 6:59 AM", + "content" : "10/4/26, 2:29 PM", "align" : "right" }, { - "content" : "98", + "content" : "99", "align" : "right" } ] }, { "cells" : [ { - "content" : "CompositeGraphBuilder.java", + "content" : "CompositeGraphBuilder.java", "align" : "left" }, { "content" : "reconcileUnattributedVertices(Unknown,Unknown,Map<String,String>)", @@ -1647,7 +1787,7 @@ "content" : "2", "align" : "right" }, { - "content" : "10", + "content" : "11", "align" : "right" }, { "content" : "2", @@ -1661,53 +1801,53 @@ } ] }, { "cells" : [ { - "content" : "SimpleHtmlReport.java", + "content" : "SimpleHtmlReport.java", "align" : "left" }, { - "content" : "renderDisharmonyInfo(String,SimpleHtmlReport$DisharmonySpec,boolean,List<RankedDisharmony>)", + "content" : "generateReport(boolean,int,boolean,boolean,String,String,String,File)", "align" : "left" }, { "content" : "3", "align" : "right" }, { - "content" : "14", + "content" : "15", "align" : "right" }, { - "content" : "7", + "content" : "8", "align" : "right" }, { - "content" : "9/23/26, 6:59 AM", + "content" : "10/4/26, 2:29 PM", "align" : "right" }, { - "content" : "98", + "content" : "99", "align" : "right" } ] }, { "cells" : [ { - "content" : "SimpleHtmlReport.java", + "content" : "SimpleHtmlReport.java", "align" : "left" }, { - "content" : "generateReport(boolean,int,boolean,boolean,String,String,String,File)", + "content" : "renderDisharmonyInfo(String,SimpleHtmlReport$DisharmonySpec,boolean,List<RankedDisharmony>)", "align" : "left" }, { "content" : "4", "align" : "right" }, { - "content" : "14", + "content" : "15", "align" : "right" }, { "content" : "8", "align" : "right" }, { - "content" : "9/23/26, 6:59 AM", + "content" : "10/4/26, 2:29 PM", "align" : "right" }, { - "content" : "98", + "content" : "99", "align" : "right" } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "JsonGenerator.java", "align" : "left" }, { "content" : "buildDisharmonySection(SimpleHtmlReport$DisharmonySpec,boolean,List<RankedDisharmony>,String)", @@ -1716,28 +1856,51 @@ "content" : "5", "align" : "right" }, { - "content" : "16", + "content" : "17", "align" : "right" }, { "content" : "11", "align" : "right" }, { - "content" : "10/2/26, 7:43 AM", + "content" : "10/4/26, 3:17 PM", "align" : "right" }, { - "content" : "8", + "content" : "14", "align" : "right" } ] }, { "cells" : [ { - "content" : "OptimalBackEdgeRemover.java", + "content" : "JsonGenerator.java", "align" : "left" }, { - "content" : "findOptimalBackEdgesToRemove()", + "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", "align" : "left" }, { "content" : "6", "align" : "right" + }, { + "content" : "17", + "align" : "right" + }, { + "content" : "12", + "align" : "right" + }, { + "content" : "10/4/26, 3:17 PM", + "align" : "right" + }, { + "content" : "14", + "align" : "right" + } ] + }, { + "cells" : [ { + "content" : "OptimalBackEdgeRemover.java", + "align" : "left" + }, { + "content" : "findOptimalBackEdgesToRemove()", + "align" : "left" + }, { + "content" : "7", + "align" : "right" }, { "content" : "5", "align" : "right" @@ -1753,13 +1916,13 @@ } ] }, { "cells" : [ { - "content" : "FeedbackVertexSetSolver.java", + "content" : "FeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "solveRecursive(Unknown,Set<V>)", "align" : "left" }, { - "content" : "7", + "content" : "8", "align" : "right" }, { "content" : "8", @@ -1776,36 +1939,36 @@ } ] }, { "cells" : [ { - "content" : "JsonGenerator.java", + "content" : "PageRankFAS.java", "align" : "left" }, { - "content" : "generateReportData(boolean,int,boolean,boolean,String,String,String,File)", + "content" : "computePageRank(LineDigraph<V,E>)", "align" : "left" }, { - "content" : "8", + "content" : "9", "align" : "right" }, { - "content" : "16", + "content" : "9", "align" : "right" }, { - "content" : "12", + "content" : "5", "align" : "right" }, { - "content" : "10/2/26, 7:43 AM", + "content" : "10/4/26, 4:34 PM", "align" : "right" }, { - "content" : "8", + "content" : "5", "align" : "right" } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "TreewidthComputer.java", "align" : "left" }, { "content" : "minDegreeEliminationTreewidth(Unknown)", "align" : "left" }, { - "content" : "9", + "content" : "10", "align" : "right" }, { "content" : "6", @@ -1822,19 +1985,19 @@ } ] }, { "cells" : [ { - "content" : "CompositeGraphBuilder.java", + "content" : "CompositeGraphBuilder.java", "align" : "left" }, { "content" : "getEnclosingClassFqn(String)", "align" : "left" }, { - "content" : "10", + "content" : "11", "align" : "right" }, { - "content" : "10", + "content" : "11", "align" : "right" }, { - "content" : "7", + "content" : "8", "align" : "right" }, { "content" : "9/5/26, 1:41 PM", @@ -1845,19 +2008,19 @@ } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "computeMinimumVertexCut(V,Set<V>,int)", "align" : "left" }, { - "content" : "11", + "content" : "12", "align" : "right" }, { "content" : "7", "align" : "right" }, { - "content" : "5", + "content" : "6", "align" : "right" }, { "content" : "8/26/26, 7:48 PM", @@ -1868,16 +2031,16 @@ } ] }, { "cells" : [ { - "content" : "DisharmonyDetector.java", + "content" : "DisharmonyDetector.java", "align" : "left" }, { "content" : "detectSignificantDuplication(List<ClassMetrics>)", "align" : "left" }, { - "content" : "12", + "content" : "13", "align" : "right" }, { - "content" : "11", + "content" : "12", "align" : "right" }, { "content" : "11", @@ -1891,13 +2054,13 @@ } ] }, { "cells" : [ { - "content" : "MinimumFeedbackArcSetSolver.java", + "content" : "MinimumFeedbackArcSetSolver.java", "align" : "left" }, { "content" : "solveRelaxedProblem()", "align" : "left" }, { - "content" : "13", + "content" : "14", "align" : "right" }, { "content" : "1", @@ -1914,19 +2077,19 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "handleMemberReference(MetricsVisitorState,GraphMetricsCollector,Unknown)", "align" : "left" }, { - "content" : "14", + "content" : "15", "align" : "right" }, { "content" : "4", "align" : "right" }, { - "content" : "6", + "content" : "7", "align" : "right" }, { "content" : "8/19/26, 7:20 PM", @@ -1937,13 +2100,13 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "enterMethod(MetricsVisitorState,Unknown,MetricsVisitorLogic$OverridePredicate)", "align" : "left" }, { - "content" : "15", + "content" : "16", "align" : "right" }, { "content" : "4", @@ -1960,13 +2123,13 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "enterClass(MetricsVisitorState,GraphMetricsCollector,Unknown)", "align" : "left" }, { - "content" : "16", + "content" : "17", "align" : "right" }, { "content" : "4", @@ -1990,57 +2153,57 @@ "methodLevel" : true, "problem" : "Method calls a few methods in many classes", "solution" : "Reduce the size of the calling method. Extract methods from the calling method into the target classes.", - "maxPriority" : 33, + "maxPriority" : 34, "chart" : { "canvasId" : "chart_DISPERSED_COUPLING", "bubbles" : [ { "id" : "GraphMetricsCollector.java", "label" : "GraphMetricsCollector.java", "x" : 1, - "y" : 31, + "y" : 32, "r" : 24, "priority" : 1, "effortRank" : 1, - "changePronenessRank" : 31, + "changePronenessRank" : 32, "color" : "rgba(235, 64, 52, 0.75)", "borderColor" : "rgb(235, 64, 52)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java" }, { "id" : "GitLogReader.java", "label" : "GitLogReader.java", "x" : 2, - "y" : 30, + "y" : 31, "r" : 23, "priority" : 2, "effortRank" : 2, - "changePronenessRank" : 30, + "changePronenessRank" : 31, "color" : "rgba(229, 67, 53, 0.75)", "borderColor" : "rgb(229, 67, 53)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/change-proneness-ranker/src/main/java/org/hjug/git/GitLogReader.java" }, { - "id" : "ReportWriter.java", - "label" : "ReportWriter.java", - "x" : 4, - "y" : 29, + "id" : "DisharmonyDetector.java", + "label" : "DisharmonyDetector.java", + "x" : 8, + "y" : 34, "r" : 23, "priority" : 3, - "effortRank" : 4, - "changePronenessRank" : 29, + "effortRank" : 8, + "changePronenessRank" : 34, "color" : "rgba(223, 71, 55, 0.75)", "borderColor" : "rgb(223, 71, 55)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" }, { - "id" : "DisharmonyDetector.java", - "label" : "DisharmonyDetector.java", - "x" : 8, - "y" : 33, + "id" : "ReportWriter.java", + "label" : "ReportWriter.java", + "x" : 4, + "y" : 29, "r" : 22, "priority" : 4, - "effortRank" : 8, - "changePronenessRank" : 33, + "effortRank" : 4, + "changePronenessRank" : 29, "color" : "rgba(217, 74, 56, 0.75)", "borderColor" : "rgb(217, 74, 56)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { "id" : "FeedbackVertexSetSolver.java", "label" : "FeedbackVertexSetSolver.java", @@ -2050,9 +2213,9 @@ "priority" : 5, "effortRank" : 2, "changePronenessRank" : 26, - "color" : "rgba(211, 78, 58, 0.75)", - "borderColor" : "rgb(211, 78, 58)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" + "color" : "rgba(211, 77, 57, 0.75)", + "borderColor" : "rgb(211, 77, 57)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/approximate/FeedbackVertexSetSolver.java" }, { "id" : "ReportWriter.java", "label" : "ReportWriter.java", @@ -2062,333 +2225,345 @@ "priority" : 6, "effortRank" : 5, "changePronenessRank" : 29, - "color" : "rgba(204, 81, 59, 0.75)", - "borderColor" : "rgb(204, 81, 59)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + "color" : "rgba(205, 81, 59, 0.75)", + "borderColor" : "rgb(205, 81, 59)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + }, { + "id" : "PageRankFAS.java", + "label" : "PageRankFAS.java", + "x" : 9, + "y" : 30, + "r" : 21, + "priority" : 7, + "effortRank" : 9, + "changePronenessRank" : 30, + "color" : "rgba(199, 84, 60, 0.75)", + "borderColor" : "rgb(199, 84, 60)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java" }, { "id" : "KotlinSourceFileGraphBuilder.java", "label" : "KotlinSourceFileGraphBuilder.java", "x" : 12, - "y" : 32, - "r" : 21, - "priority" : 7, + "y" : 33, + "r" : 20, + "priority" : 8, "effortRank" : 12, - "changePronenessRank" : 32, - "color" : "rgba(198, 85, 60, 0.75)", - "borderColor" : "rgb(198, 85, 60)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java" + "changePronenessRank" : 33, + "color" : "rgba(193, 87, 61, 0.75)", + "borderColor" : "rgb(193, 87, 61)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java" }, { "id" : "ReportWriter.java", "label" : "ReportWriter.java", "x" : 10, "y" : 29, "r" : 20, - "priority" : 8, + "priority" : 9, "effortRank" : 10, "changePronenessRank" : 29, - "color" : "rgba(192, 88, 62, 0.75)", - "borderColor" : "rgb(192, 88, 62)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" + "color" : "rgba(187, 91, 63, 0.75)", + "borderColor" : "rgb(187, 91, 63)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/report/src/main/java/org/hjug/refactorfirst/report/ReportWriter.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", "x" : 8, "y" : 25, - "r" : 20, - "priority" : 9, + "r" : 19, + "priority" : 10, "effortRank" : 8, "changePronenessRank" : 25, - "color" : "rgba(186, 92, 63, 0.75)", - "borderColor" : "rgb(186, 92, 63)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "color" : "rgba(182, 94, 64, 0.75)", + "borderColor" : "rgb(182, 94, 64)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "MetricsVisitorLogic.java", "label" : "MetricsVisitorLogic.java", "x" : 3, "y" : 19, "r" : 19, - "priority" : 10, + "priority" : 11, "effortRank" : 3, "changePronenessRank" : 19, - "color" : "rgba(180, 95, 64, 0.75)", - "borderColor" : "rgb(180, 95, 64)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" + "color" : "rgba(176, 97, 65, 0.75)", + "borderColor" : "rgb(176, 97, 65)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/MetricsVisitorLogic.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", "x" : 9, "y" : 25, "r" : 18, - "priority" : 11, + "priority" : 12, "effortRank" : 9, "changePronenessRank" : 25, - "color" : "rgba(174, 98, 66, 0.75)", - "borderColor" : "rgb(174, 98, 66)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "color" : "rgba(170, 101, 67, 0.75)", + "borderColor" : "rgb(170, 101, 67)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 7, "y" : 22, - "r" : 18, - "priority" : 12, + "r" : 17, + "priority" : 13, "effortRank" : 7, "changePronenessRank" : 22, - "color" : "rgba(168, 102, 67, 0.75)", - "borderColor" : "rgb(168, 102, 67)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "color" : "rgba(164, 104, 68, 0.75)", + "borderColor" : "rgb(164, 104, 68)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 4, "y" : 17, "r" : 17, - "priority" : 13, + "priority" : 14, "effortRank" : 4, "changePronenessRank" : 17, - "color" : "rgba(162, 105, 69, 0.75)", - "borderColor" : "rgb(162, 105, 69)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(158, 107, 69, 0.75)", + "borderColor" : "rgb(158, 107, 69)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 4, "y" : 17, - "r" : 17, - "priority" : 14, + "r" : 16, + "priority" : 15, "effortRank" : 4, "changePronenessRank" : 17, - "color" : "rgba(155, 109, 70, 0.75)", - "borderColor" : "rgb(155, 109, 70)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(152, 111, 71, 0.75)", + "borderColor" : "rgb(152, 111, 71)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 9, "y" : 22, "r" : 16, - "priority" : 15, + "priority" : 16, "effortRank" : 9, "changePronenessRank" : 22, - "color" : "rgba(149, 112, 71, 0.75)", - "borderColor" : "rgb(149, 112, 71)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "color" : "rgba(146, 114, 72, 0.75)", + "borderColor" : "rgb(146, 114, 72)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 5, "y" : 17, - "r" : 16, - "priority" : 16, + "r" : 15, + "priority" : 17, "effortRank" : 5, "changePronenessRank" : 17, - "color" : "rgba(143, 116, 73, 0.75)", - "borderColor" : "rgb(143, 116, 73)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(140, 117, 73, 0.75)", + "borderColor" : "rgb(140, 117, 73)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "TreewidthComputer.java", "label" : "TreewidthComputer.java", "x" : 10, "y" : 22, "r" : 15, - "priority" : 17, + "priority" : 18, "effortRank" : 10, "changePronenessRank" : 22, - "color" : "rgba(137, 119, 74, 0.75)", - "borderColor" : "rgb(137, 119, 74)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" + "color" : "rgba(134, 121, 75, 0.75)", + "borderColor" : "rgb(134, 121, 75)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/TreewidthComputer.java" }, { "id" : "DirectedFeedbackVertexSetSolver.java", "label" : "DirectedFeedbackVertexSetSolver.java", "x" : 13, "y" : 25, "r" : 14, - "priority" : 18, + "priority" : 19, "effortRank" : 13, "changePronenessRank" : 25, - "color" : "rgba(131, 122, 75, 0.75)", - "borderColor" : "rgb(131, 122, 75)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" + "color" : "rgba(128, 124, 76, 0.75)", + "borderColor" : "rgb(128, 124, 76)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/DirectedFeedbackVertexSetSolver.java" }, { "id" : "FeedbackVertexSetComputer.java", "label" : "FeedbackVertexSetComputer.java", "x" : 4, "y" : 15, "r" : 14, - "priority" : 19, + "priority" : 20, "effortRank" : 4, "changePronenessRank" : 15, - "color" : "rgba(125, 126, 77, 0.75)", - "borderColor" : "rgb(125, 126, 77)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" + "color" : "rgba(122, 127, 77, 0.75)", + "borderColor" : "rgb(122, 127, 77)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 6, "y" : 17, "r" : 13, - "priority" : 20, + "priority" : 21, "effortRank" : 6, "changePronenessRank" : 17, - "color" : "rgba(119, 129, 78, 0.75)", - "borderColor" : "rgb(119, 129, 78)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(116, 131, 79, 0.75)", + "borderColor" : "rgb(116, 131, 79)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 7, "y" : 17, "r" : 13, - "priority" : 21, + "priority" : 22, "effortRank" : 7, "changePronenessRank" : 17, - "color" : "rgba(113, 133, 80, 0.75)", - "borderColor" : "rgb(113, 133, 80)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(110, 134, 80, 0.75)", + "borderColor" : "rgb(110, 134, 80)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 8, "y" : 17, "r" : 12, - "priority" : 22, + "priority" : 23, "effortRank" : 8, "changePronenessRank" : 17, - "color" : "rgba(106, 136, 81, 0.75)", - "borderColor" : "rgb(106, 136, 81)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(104, 137, 81, 0.75)", + "borderColor" : "rgb(104, 137, 81)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 8, "y" : 17, - "r" : 12, - "priority" : 23, + "r" : 11, + "priority" : 24, "effortRank" : 8, "changePronenessRank" : 17, - "color" : "rgba(100, 140, 82, 0.75)", - "borderColor" : "rgb(100, 140, 82)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(98, 141, 83, 0.75)", + "borderColor" : "rgb(98, 141, 83)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "CycleRemovalComputer.java", "label" : "CycleRemovalComputer.java", "x" : 9, "y" : 18, "r" : 11, - "priority" : 24, + "priority" : 25, "effortRank" : 9, "changePronenessRank" : 18, - "color" : "rgba(94, 143, 84, 0.75)", - "borderColor" : "rgb(94, 143, 84)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java" + "color" : "rgba(92, 144, 84, 0.75)", + "borderColor" : "rgb(92, 144, 84)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/CycleRemovalComputer.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", "x" : 4, "y" : 10, - "r" : 11, - "priority" : 25, + "r" : 10, + "priority" : 26, "effortRank" : 4, "changePronenessRank" : 10, - "color" : "rgba(88, 147, 85, 0.75)", - "borderColor" : "rgb(88, 147, 85)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + "color" : "rgba(87, 147, 85, 0.75)", + "borderColor" : "rgb(87, 147, 85)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", "x" : 4, "y" : 10, "r" : 10, - "priority" : 26, + "priority" : 27, "effortRank" : 4, "changePronenessRank" : 10, - "color" : "rgba(82, 150, 86, 0.75)", - "borderColor" : "rgb(82, 150, 86)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + "color" : "rgba(81, 151, 87, 0.75)", + "borderColor" : "rgb(81, 151, 87)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "LineDigraph.java", "label" : "LineDigraph.java", "x" : 8, "y" : 14, "r" : 9, - "priority" : 27, + "priority" : 28, "effortRank" : 8, "changePronenessRank" : 14, - "color" : "rgba(76, 153, 88, 0.75)", - "borderColor" : "rgb(76, 153, 88)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/LineDigraph.java" + "color" : "rgba(75, 154, 88, 0.75)", + "borderColor" : "rgb(75, 154, 88)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/LineDigraph.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 11, "y" : 17, "r" : 9, - "priority" : 28, + "priority" : 29, "effortRank" : 11, "changePronenessRank" : 17, - "color" : "rgba(70, 157, 89, 0.75)", - "borderColor" : "rgb(70, 157, 89)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "color" : "rgba(69, 157, 89, 0.75)", + "borderColor" : "rgb(69, 157, 89)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "FeedbackVertexSetComputer.java", "label" : "FeedbackVertexSetComputer.java", "x" : 10, "y" : 15, "r" : 8, - "priority" : 29, + "priority" : 30, "effortRank" : 10, "changePronenessRank" : 15, - "color" : "rgba(64, 160, 91, 0.75)", - "borderColor" : "rgb(64, 160, 91)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" + "color" : "rgba(63, 161, 91, 0.75)", + "borderColor" : "rgb(63, 161, 91)", + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/FeedbackVertexSetComputer.java" }, { "id" : "ModulatorComputer.java", "label" : "ModulatorComputer.java", "x" : 12, "y" : 17, "r" : 8, - "priority" : 30, + "priority" : 31, "effortRank" : 12, "changePronenessRank" : 17, "color" : "rgba(57, 164, 92, 0.75)", "borderColor" : "rgb(57, 164, 92)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/vertex/kernelized/ModulatorComputer.java" }, { "id" : "MinimumFeedbackArcSetSolver.java", "label" : "MinimumFeedbackArcSetSolver.java", "x" : 7, "y" : 10, "r" : 7, - "priority" : 31, + "priority" : 32, "effortRank" : 7, "changePronenessRank" : 10, "color" : "rgba(51, 167, 93, 0.75)", "borderColor" : "rgb(51, 167, 93)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/exact/MinimumFeedbackArcSetSolver.java" }, { "id" : "FeedbackArcSetSolver.java", "label" : "FeedbackArcSetSolver.java", "x" : 4, "y" : 3, "r" : 7, - "priority" : 32, + "priority" : 33, "effortRank" : 4, "changePronenessRank" : 3, "color" : "rgba(45, 171, 95, 0.75)", "borderColor" : "rgb(45, 171, 95)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/graph-algorithms/src/main/java/org/hjug/feedback/arc/approximate/FeedbackArcSetSolver.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/graph-algorithms/src/main/java/org/hjug/feedback/arc/approximate/FeedbackArcSetSolver.java" }, { "id" : "AttributeHandlerAndSorter.java", "label" : "AttributeHandlerAndSorter.java", "x" : 7, "y" : 1, "r" : 6, - "priority" : 33, + "priority" : 34, "effortRank" : 7, "changePronenessRank" : 1, "color" : "rgba(39, 174, 96, 0.75)", "borderColor" : "rgb(39, 174, 96)", - "url" : "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/refactorfirst/RefactorFirst/blob/4ca6a4f0f8c0350a67f38089212ae42dae5d607c/test-resources/src/main/resources/AttributeHandlerAndSorter.java" + "url" : "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/refactorfirst/RefactorFirst/blob/5258928239a496b74a704c7653240b82a325ccab/test-resources/src/main/resources/AttributeHandlerAndSorter.java" } ], "xaxisLabel" : "Effort to refactor", "yaxisLabel" : "Relative churn (impact)" @@ -2397,7 +2572,7 @@ "headers" : [ "Class", "Method", "Priority", "Change Proneness Rank", "Effort Rank", "Most Recent Commit Date", "Commit Count" ], "rows" : [ { "cells" : [ { - "content" : "GraphMetricsCollector.java", + "content" : "GraphMetricsCollector.java", "align" : "left" }, { "content" : "finalizeMetrics()", @@ -2406,7 +2581,7 @@ "content" : "1", "align" : "right" }, { - "content" : "31", + "content" : "32", "align" : "right" }, { "content" : "1", @@ -2420,7 +2595,7 @@ } ] }, { "cells" : [ { - "content" : "GitLogReader.java", + "content" : "GitLogReader.java", "align" : "left" }, { "content" : "captureChangeCountByCommitTimestamp()", @@ -2429,7 +2604,7 @@ "content" : "2", "align" : "right" }, { - "content" : "30", + "content" : "31", "align" : "right" }, { "content" : "2", @@ -2443,53 +2618,53 @@ } ] }, { "cells" : [ { - "content" : "ReportWriter.java", + "content" : "DisharmonyDetector.java", "align" : "left" }, { - "content" : "openSecurePath()", + "content" : "detectFeatureEnvy(List<ClassMetrics>)", "align" : "left" }, { "content" : "3", "align" : "right" }, { - "content" : "29", + "content" : "34", "align" : "right" }, { - "content" : "4", + "content" : "8", "align" : "right" }, { - "content" : "9/5/26, 8:03 AM", + "content" : "9/5/26, 1:41 PM", "align" : "right" }, { - "content" : "10", + "content" : "15", "align" : "right" } ] }, { "cells" : [ { - "content" : "DisharmonyDetector.java", + "content" : "ReportWriter.java", "align" : "left" }, { - "content" : "detectFeatureEnvy(List<ClassMetrics>)", + "content" : "openSecurePath()", "align" : "left" }, { "content" : "4", "align" : "right" }, { - "content" : "33", + "content" : "29", "align" : "right" }, { - "content" : "8", + "content" : "4", "align" : "right" }, { - "content" : "9/5/26, 1:41 PM", + "content" : "9/5/26, 8:03 AM", "align" : "right" }, { - "content" : "15", + "content" : "10", "align" : "right" } ] }, { "cells" : [ { - "content" : "FeedbackVertexSetSolver.java", + "content" : "FeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "computeFractionalSolution()", @@ -2512,7 +2687,7 @@ } ] }, { "cells" : [ { - "content" : "ReportWriter.java", + "content" : "ReportWriter.java", "align" : "left" }, { "content" : "writeAtomically(Path,String)", @@ -2535,16 +2710,39 @@ } ] }, { "cells" : [ { - "content" : "KotlinSourceFileGraphBuilder.java", + "content" : "PageRankFAS.java", "align" : "left" }, { - "content" : "buildGraph(String,String,GraphBuilderConfig)", + "content" : "createLineDigraphEdgesDFS(Unknown,LineDigraph<V,E>,Map<E,LineVertex<V,E>>,V,LineVertex<V,E>,Set<V>)", "align" : "left" }, { "content" : "7", "align" : "right" }, { - "content" : "32", + "content" : "30", + "align" : "right" + }, { + "content" : "9", + "align" : "right" + }, { + "content" : "10/4/26, 4:34 PM", + "align" : "right" + }, { + "content" : "5", + "align" : "right" + } ] + }, { + "cells" : [ { + "content" : "KotlinSourceFileGraphBuilder.java", + "align" : "left" + }, { + "content" : "buildGraph(String,String,GraphBuilderConfig)", + "align" : "left" + }, { + "content" : "8", + "align" : "right" + }, { + "content" : "33", "align" : "right" }, { "content" : "12", @@ -2558,13 +2756,13 @@ } ] }, { "cells" : [ { - "content" : "ReportWriter.java", + "content" : "ReportWriter.java", "align" : "left" }, { "content" : "writeAtomicallySecure(SecureDirectoryStream<Path>,Path,String)", "align" : "left" }, { - "content" : "8", + "content" : "9", "align" : "right" }, { "content" : "29", @@ -2581,13 +2779,13 @@ } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "createMinimalBypass(V,Set<V>,Set<E>)", "align" : "left" }, { - "content" : "9", + "content" : "10", "align" : "right" }, { "content" : "25", @@ -2604,13 +2802,13 @@ } ] }, { "cells" : [ { - "content" : "MetricsVisitorLogic.java", + "content" : "MetricsVisitorLogic.java", "align" : "left" }, { "content" : "handleMethodInvocation(MetricsVisitorState,GraphMetricsCollector,Unknown)", "align" : "left" }, { - "content" : "10", + "content" : "11", "align" : "right" }, { "content" : "19", @@ -2627,13 +2825,13 @@ } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "findBypassChain(V,Set<V>)", "align" : "left" }, { - "content" : "11", + "content" : "12", "align" : "right" }, { "content" : "25", @@ -2650,13 +2848,13 @@ } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "TreewidthComputer.java", "align" : "left" }, { "content" : "computeEta(Unknown,Set<V>)", "align" : "left" }, { - "content" : "12", + "content" : "13", "align" : "right" }, { "content" : "22", @@ -2673,13 +2871,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeBetweennessCentrality(Unknown)", "align" : "left" }, { - "content" : "13", + "content" : "14", "align" : "right" }, { "content" : "17", @@ -2696,13 +2894,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeGreedyDegreeModulator(Unknown,int,int)", "align" : "left" }, { - "content" : "14", + "content" : "15", "align" : "right" }, { "content" : "17", @@ -2719,13 +2917,13 @@ } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "TreewidthComputer.java", "align" : "left" }, { "content" : "greedyTriangulationTreewidth(Unknown)", "align" : "left" }, { - "content" : "15", + "content" : "16", "align" : "right" }, { "content" : "22", @@ -2742,13 +2940,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeFeedbackVertexSetModulator(Unknown,int,int)", "align" : "left" }, { - "content" : "16", + "content" : "17", "align" : "right" }, { "content" : "17", @@ -2765,13 +2963,13 @@ } ] }, { "cells" : [ { - "content" : "TreewidthComputer.java", + "content" : "TreewidthComputer.java", "align" : "left" }, { "content" : "fillInHeuristicTreewidth(Unknown)", "align" : "left" }, { - "content" : "17", + "content" : "18", "align" : "right" }, { "content" : "22", @@ -2788,13 +2986,13 @@ } ] }, { "cells" : [ { - "content" : "DirectedFeedbackVertexSetSolver.java", + "content" : "DirectedFeedbackVertexSetSolver.java", "align" : "left" }, { "content" : "addBypassEdges(V,Set<V>)", "align" : "left" }, { - "content" : "18", + "content" : "19", "align" : "right" }, { "content" : "25", @@ -2811,13 +3009,13 @@ } ] }, { "cells" : [ { - "content" : "FeedbackVertexSetComputer.java", + "content" : "FeedbackVertexSetComputer.java", "align" : "left" }, { "content" : "stronglyConnectedComponentsBasedFVS(Unknown)", "align" : "left" }, { - "content" : "19", + "content" : "20", "align" : "right" }, { "content" : "15", @@ -2834,13 +3032,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeSingleSourceBetweennessContributionsParallel(Unknown,V)", "align" : "left" }, { - "content" : "20", + "content" : "21", "align" : "right" }, { "content" : "17", @@ -2857,13 +3055,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "originalComputeBetweennessCentrality(Unknown)", "align" : "left" }, { - "content" : "21", + "content" : "22", "align" : "right" }, { "content" : "17", @@ -2880,13 +3078,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeSingleSourceBetweennessContributions(Unknown,V)", "align" : "left" }, { - "content" : "22", + "content" : "23", "align" : "right" }, { "content" : "17", @@ -2903,13 +3101,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeBetweennessCentralityAdaptive(Unknown)", "align" : "left" }, { - "content" : "23", + "content" : "24", "align" : "right" }, { "content" : "17", @@ -2926,13 +3124,13 @@ } ] }, { "cells" : [ { - "content" : "CycleRemovalComputer.java", + "content" : "CycleRemovalComputer.java", "align" : "left" }, { "content" : "computeCycleRemovalInformation(Unknown)", "align" : "left" }, { - "content" : "24", + "content" : "25", "align" : "right" }, { "content" : "18", @@ -2949,13 +3147,13 @@ } ] }, { "cells" : [ { - "content" : "MinimumFeedbackArcSetSolver.java", + "content" : "MinimumFeedbackArcSetSolver.java", "align" : "left" }, { "content" : "findShortestPath(Unknown,V)", "align" : "left" }, { - "content" : "25", + "content" : "26", "align" : "right" }, { "content" : "10", @@ -2972,13 +3170,13 @@ } ] }, { "cells" : [ { - "content" : "MinimumFeedbackArcSetSolver.java", + "content" : "MinimumFeedbackArcSetSolver.java", "align" : "left" }, { "content" : "solve()", "align" : "left" }, { - "content" : "26", + "content" : "27", "align" : "right" }, { "content" : "10", @@ -2995,13 +3193,13 @@ } ] }, { "cells" : [ { - "content" : "LineDigraph.java", + "content" : "LineDigraph.java", "align" : "left" }, { "content" : "topologicalSort()", "align" : "left" }, { - "content" : "27", + "content" : "28", "align" : "right" }, { "content" : "14", @@ -3018,13 +3216,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeTreewidthDecompositionModulator(Unknown,int,int)", "align" : "left" }, { - "content" : "28", + "content" : "29", "align" : "right" }, { "content" : "17", @@ -3041,13 +3239,13 @@ } ] }, { "cells" : [ { - "content" : "FeedbackVertexSetComputer.java", + "content" : "FeedbackVertexSetComputer.java", "align" : "left" }, { "content" : "degreeBasedFeedbackVertexSet(Unknown)", "align" : "left" }, { - "content" : "29", + "content" : "30", "align" : "right" }, { "content" : "15", @@ -3064,13 +3262,13 @@ } ] }, { "cells" : [ { - "content" : "ModulatorComputer.java", + "content" : "ModulatorComputer.java", "align" : "left" }, { "content" : "computeBottleneckVertexModulator(Unknown,int,int)", "align" : "left" }, { - "content" : "30", + "content" : "31", "align" : "right" }, { "content" : "17", @@ -3087,13 +3285,13 @@ } ] }, { "cells" : [ { - "content" : "MinimumFeedbackArcSetSolver.java", + "content" : "MinimumFeedbackArcSetSolver.java", "align" : "left" }, { "content" : "computeInitialHeuristicSolution()", "align" : "left" }, { - "content" : "31", + "content" : "32", "align" : "right" }, { "content" : "10", @@ -3110,13 +3308,13 @@ } ] }, { "cells" : [ { - "content" : "FeedbackArcSetSolver.java", + "content" : "FeedbackArcSetSolver.java", "align" : "left" }, { "content" : "solve()", "align" : "left" }, { - "content" : "32", + "content" : "33", "align" : "right" }, { "content" : "3", @@ -3133,13 +3331,13 @@ } ] }, { "cells" : [ { - "content" : "AttributeHandlerAndSorter.java", + "content" : "AttributeHandlerAndSorter.java", "align" : "left" }, { "content" : "perform(Unknown)", "align" : "left" }, { - "content" : "33", + "content" : "34", "align" : "right" }, { "content" : "1", @@ -3174,16 +3372,16 @@ "dot" : "strict digraph G {\nReportWriter -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"3\" weight = \"3\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps -> org_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label = \"1\" weight = \"1\" color = \"red\" ];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl -> ReportWriter [ label = \"1\" weight = \"1\" ];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOps [ label=\"ReportWriter$SecureDirectoryOps\"];\norg_hjug_refactorfirst_report_ReportWriter_FallbackDirectoryOps [ label=\"ReportWriter$FallbackDirectoryOps\"];\nReportWriter [ color=red style=filled];\norg_hjug_refactorfirst_report_ReportWriter_SecureDirectoryOpsImpl [ label=\"ReportWriter$SecureDirectoryOpsImpl\"];\n}", "dotThresholdExceeded" : false, "breakdown" : [ { - "className" : "ReportWriter$SecureDirectoryOps", + "className" : "ReportWriter$SecureDirectoryOps", "edgesHtml" : "ReportWriter$SecureDirectoryOps → ReportWriter$SecureDirectoryOpsImpl : 1*
\nReportWriter$SecureDirectoryOps → ReportWriter$FallbackDirectoryOps : 1*
\n" }, { - "className" : "ReportWriter$FallbackDirectoryOps", + "className" : "ReportWriter$FallbackDirectoryOps", "edgesHtml" : "ReportWriter$FallbackDirectoryOps → ReportWriter$SecureDirectoryOps : 1
\nReportWriter$FallbackDirectoryOps → ReportWriter : 1
\n" }, { - "className" : "ReportWriter*", + "className" : "ReportWriter*", "edgesHtml" : "ReportWriter → ReportWriter$SecureDirectoryOps : 3
\n" }, { - "className" : "ReportWriter$SecureDirectoryOpsImpl", + "className" : "ReportWriter$SecureDirectoryOpsImpl", "edgesHtml" : "ReportWriter$SecureDirectoryOpsImpl → ReportWriter$SecureDirectoryOps : 1
\nReportWriter$SecureDirectoryOpsImpl → ReportWriter : 1
\n" } ] } diff --git a/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java b/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java index f28e4381..83e56805 100644 --- a/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java +++ b/graph-algorithms/src/main/java/org/hjug/feedback/arc/pageRank/PageRankFAS.java @@ -2,7 +2,6 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import lombok.extern.slf4j.Slf4j; import org.hjug.feedback.SuperTypeToken; import org.jgrapht.Graph; @@ -98,11 +97,49 @@ private E processStronglyConnectedComponent(Graph graph, Set scc) { // Run PageRank on line digraph Map, Double> pageRankScores = computePageRank(lineDigraph); - // Find the edge (line vertex) with highest PageRank score - return pageRankScores.entrySet().parallelStream() - .max(Map.Entry.comparingByValue()) - .map(entry -> entry.getKey().getOriginalEdge()) - .orElse(null); + // Deterministically select the edge (line vertex) with the highest PageRank score + return selectHighestScoredEdge(pageRankScores); + } + + /** + * Canonical, run-stable total order over line vertices: by the string form of the source + * vertex, then of the target vertex. Because the analyzed graphs never contain parallel + * edges, {@code (source, target)} uniquely identifies an edge, making this a total order + * over line vertices. Every ordering-sensitive step of the algorithm (PageRank accumulation, + * max-score selection, line-digraph DFS start) follows this order so that repeated runs on + * the same input graph — e.g. by the htmlReport and the jsonReport — produce identical + * feedback arc sets. + */ + private Comparator> lineVertexOrder() { + return Comparator.comparing((LineVertex lineVertex) -> String.valueOf(lineVertex.getSource())) + .thenComparing(lineVertex -> String.valueOf(lineVertex.getTarget())); + } + + /** + * Deterministically selects the line vertex carrying the highest PageRank score. Ties — + * which are common in symmetric cycles where every candidate edge scores identically — are + * broken by the canonical line-vertex order so the selection cannot vary between runs. + * + * @param pageRankScores PageRank score per line vertex + * @return the original edge of the highest-scored line vertex, or {@code null} when empty + */ + private E selectHighestScoredEdge(Map, Double> pageRankScores) { + LineVertex best = null; + double bestScore = Double.NEGATIVE_INFINITY; + for (Map.Entry, Double> entry : pageRankScores.entrySet()) { + double score = entry.getValue(); + boolean tiedWinner = score == bestScore && best != null && isCanonicallyBefore(entry.getKey(), best); + if (best == null || score > bestScore || tiedWinner) { + best = entry.getKey(); + bestScore = score; + } + } + return best != null ? best.getOriginalEdge() : null; + } + + /** Returns whether the candidate precedes the incumbent in canonical source/target order. */ + private boolean isCanonicallyBefore(LineVertex candidate, LineVertex incumbent) { + return lineVertexOrder().compare(candidate, incumbent) < 0; } /** @@ -138,10 +175,13 @@ private void createLineDigraphEdges( Graph graph, LineDigraph lineDigraph, Map> edgeToLineVertex) { Set visited = ConcurrentHashMap.newKeySet(); - // Start DFS from a random vertex if graph is not empty + // Start DFS from the canonically smallest vertex so the traversal — and therefore the + // resulting line-digraph edge set — is identical on every run if (!graph.vertexSet().isEmpty()) { - V startVertex = graph.vertexSet().iterator().next(); - createLineDigraphEdgesDFS(graph, lineDigraph, edgeToLineVertex, startVertex, null, visited); + graph.vertexSet().stream() + .min(Comparator.comparing(String::valueOf)) + .ifPresent(startVertex -> createLineDigraphEdgesDFS( + graph, lineDigraph, edgeToLineVertex, startVertex, null, visited)); } } @@ -158,8 +198,11 @@ private void createLineDigraphEdgesDFS( Set visited) { visited.add(vertex); - // Get outgoing edges from current vertex - Set outgoingEdges = graph.outgoingEdgesOf(vertex); + // Iterate outgoing edges in canonical (target-vertex) order rather than the graph's + // internal set order, so the traversal — and therefore the line-digraph edge set and + // the FAS selection — cannot vary with the order edges were added to the graph + List outgoingEdges = new ArrayList<>(graph.outgoingEdgesOf(vertex)); + outgoingEdges.sort(Comparator.comparing(edge -> String.valueOf(graph.getEdgeTarget(edge)))); for (E edge : outgoingEdges) { V target = graph.getEdgeTarget(edge); @@ -191,6 +234,10 @@ private void createLineDigraphEdgesDFS( /** * Compute PageRank scores on the line digraph (Algorithm 4 implementation) + * Accumulation is sequential and iterates vertices and their outgoing neighbors in the + * canonical line-vertex order, keeping the floating-point sums bit-identical across runs — + * a parallel merge would introduce run-dependent rounding and, through it, different + * feedback arc selections in different report executions. * @param lineDigraph The line digraph * @return Map of line vertices to their PageRank scores */ @@ -200,58 +247,56 @@ private Map, Double> computePageRank(LineDigraph lineDigr if (numVertices == 0) return new HashMap<>(); + // Canonical iteration order for vertices and adjacency keeps every run identical + List> orderedVertices = new ArrayList<>(vertices); + orderedVertices.sort(lineVertexOrder()); + Map, List>> orderedOutgoing = new HashMap<>(); + for (LineVertex v : orderedVertices) { + List> outgoing = new ArrayList<>(lineDigraph.getOutgoingNeighbors(v)); + outgoing.sort(lineVertexOrder()); + orderedOutgoing.put(v, outgoing); + } + // Initialize PageRank scores - Map, Double> currentScores = - new ConcurrentHashMap<>(Math.max(16, (int) (numVertices / 0.75f) + 1)); + Map, Double> currentScores = new HashMap<>(Math.max(16, (int) (numVertices / 0.75f) + 1)); final double initialScore = 1.0 / numVertices; - // No lambdas here, so nothing captures a non-final variable - for (LineVertex v : vertices) { + for (LineVertex v : orderedVertices) { currentScores.put(v, initialScore); } // Run PageRank iterations for (int iteration = 0; iteration < pageRankIterations; iteration++) { // Fresh map each iteration; pre-seed zeros so all vertices exist in the map - ConcurrentMap, Double> newScores = new ConcurrentHashMap<>(currentScores.size()); + Map, Double> newScores = new HashMap<>(currentScores.size()); - for (LineVertex v : vertices) { + for (LineVertex v : orderedVertices) { newScores.put(v, 0.0); } - // Do one iteration in parallel; lambdas only see method parameters (effectively final) - applyOneIteration(vertices, lineDigraph, currentScores, newScores); + // One sequential iteration in canonical order; lambdas only see method parameters + for (LineVertex v : orderedVertices) { + double score = currentScores.get(v); + List> outgoing = orderedOutgoing.get(v); + + if (outgoing.isEmpty()) { + // Sink: keep score on itself + newScores.merge(v, score, Double::sum); + } else { + double scorePerEdge = score / outgoing.size(); + for (LineVertex target : outgoing) { + newScores.merge(target, scorePerEdge, Double::sum); + } + } + } - // Swap for next iteration (this reassigns local variables, not captured by lambdas) + // Swap for next iteration currentScores = newScores; } return currentScores; } - private void applyOneIteration( - Set> vertices, - LineDigraph lineDigraph, - Map, Double> currentScores, - ConcurrentMap, Double> newScores) { - - vertices.parallelStream().forEach(vertex -> { - double score = currentScores.get(vertex); - Set> outgoing = lineDigraph.getOutgoingNeighbors(vertex); - - if (outgoing.isEmpty()) { - // Sink: keep score on itself - newScores.merge(vertex, score, Double::sum); - } else { - double scorePerEdge = score / outgoing.size(); - // Inner loop kept sequential: nested parallel often hurts more than it helps - for (LineVertex target : outgoing) { - newScores.merge(target, scorePerEdge, Double::sum); - } - } - }); - } - /** * Find strongly connected components using Kosaraju's algorithm */ diff --git a/graph-algorithms/src/test/java/org/hjug/feedback/arc/pageRank/PageRankFASDeterminismTest.java b/graph-algorithms/src/test/java/org/hjug/feedback/arc/pageRank/PageRankFASDeterminismTest.java new file mode 100644 index 00000000..490021bc --- /dev/null +++ b/graph-algorithms/src/test/java/org/hjug/feedback/arc/pageRank/PageRankFASDeterminismTest.java @@ -0,0 +1,189 @@ +package org.hjug.feedback.arc.pageRank; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; +import org.hjug.feedback.SuperTypeToken; +import org.jgrapht.Graph; +import org.jgrapht.alg.cycle.CycleDetector; +import org.jgrapht.graph.DefaultDirectedGraph; +import org.jgrapht.graph.DefaultEdge; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** + * Regression tests pinning the run-to-run determinism of {@link PageRankFAS#computeFeedbackArcSet()}. + * + *

Both the htmlReport and the jsonReport invoke the same cycle-removal pipeline on the same + * package graph, so a non-deterministic feedback arc selection makes the two reports disagree on + * which package relationships (and, transitively, which class relationships) to remove. This + * suite reproduces the exact package-SCC shape that caused the htmlReport / jsonReport + * discrepancy between the {@code org.hjug.feedback} and + * {@code org.hjug.feedback.vertex.kernelized} packages.

+ */ +class PageRankFASDeterminismTest { + + private static final String FEEDBACK = "org.hjug.feedback"; + private static final String PAGE_RANK = "org.hjug.feedback.arc.pageRank"; + private static final String KERNELIZED = "org.hjug.feedback.vertex.kernelized"; + + /** Builds the package-SCC shape observed in the RefactorFirst report output. */ + private Graph createFeedbackPackageScc() { + Graph graph = new DefaultDirectedGraph<>(DefaultEdge.class); + graph.addVertex(FEEDBACK); + graph.addVertex(PAGE_RANK); + graph.addVertex(KERNELIZED); + graph.addEdge(FEEDBACK, PAGE_RANK); + graph.addEdge(PAGE_RANK, FEEDBACK); + graph.addEdge(FEEDBACK, KERNELIZED); + graph.addEdge(KERNELIZED, FEEDBACK); + return graph; + } + + /** Copies the graph topology with fresh edges so each run can remove edges independently. */ + private Graph copyGraph(Graph original) { + Graph copy = new DefaultDirectedGraph<>(DefaultEdge.class); + original.vertexSet().forEach(copy::addVertex); + original.edgeSet() + .forEach(edge -> + copy.addEdge(original.getEdgeSource(edge), original.getEdgeTarget(edge), new DefaultEdge())); + return copy; + } + + /** Converts edges to sorted source/target keys for comparison across graph copies. */ + private Set edgeKeys(Graph graph, Set edges) { + Set keys = new TreeSet<>(); + for (DefaultEdge edge : edges) { + keys.add(graph.getEdgeSource(edge) + " -> " + graph.getEdgeTarget(edge)); + } + return keys; + } + + /** Verifies repeated runs select the same edges and break both cycles in the package SCC. */ + @DisplayName("computeFeedbackArcSet selects the same edges on every run for the feedback package SCC") + @Test + void computeFeedbackArcSet_isDeterministicAcrossRuns() { + // Given: the package SCC from the RefactorFirst report whose tied PageRank scores made + // htmlReport and jsonReport pick different package edges to remove + Graph template = createFeedbackPackageScc(); + + // When: the same algorithm runs many times on fresh copies of the same graph + Set firstRun = null; + for (int i = 0; i < 300; i++) { + Graph graph = copyGraph(template); + PageRankFAS pageRankFAS = new PageRankFAS<>(graph, new SuperTypeToken<>() {}); + Set run = edgeKeys(graph, pageRankFAS.computeFeedbackArcSet()); + if (firstRun == null) { + firstRun = run; + } else { + assertEquals( + firstRun, + run, + "computeFeedbackArcSet must select identical edges across runs; run " + i + " differed"); + } + } + + // Then: the selection breaks both 2-cycles, so the graph is acyclic after removal + Graph graph = copyGraph(template); + PageRankFAS pageRankFAS = new PageRankFAS<>(graph, new SuperTypeToken<>() {}); + Set feedbackArcSet = pageRankFAS.computeFeedbackArcSet(); + assertEquals(2, feedbackArcSet.size(), "Both 2-cycles require exactly one removed edge each"); + feedbackArcSet.forEach(graph::removeEdge); + assertTrue( + !new CycleDetector<>(graph).detectCycles(), + "Removing the feedback arc set must leave the graph acyclic"); + } + + /** Verifies repeatable feedback arc selection and cycle removal in a larger symmetric graph. */ + @DisplayName("computeFeedbackArcSet is deterministic for a graph with parallel tie candidates") + @Test + void computeFeedbackArcSet_isDeterministicForLargerTiedGraph() { + // Given: a larger symmetric SCC where many edges tie on PageRank score + Graph template = new DefaultDirectedGraph<>(DefaultEdge.class); + for (int i = 0; i < 6; i++) { + template.addVertex("P" + i); + } + for (int i = 0; i < 6; i++) { + template.addEdge("P" + i, "P" + (i + 1) % 6); + template.addEdge("P" + i, "P" + (i + 2) % 6); + } + + // When: the algorithm runs repeatedly on fresh copies + Set firstRun = null; + for (int i = 0; i < 100; i++) { + Graph graph = copyGraph(template); + PageRankFAS pageRankFAS = new PageRankFAS<>(graph, new SuperTypeToken<>() {}); + Set run = edgeKeys(graph, pageRankFAS.computeFeedbackArcSet()); + if (firstRun == null) { + firstRun = run; + } else { + assertEquals( + firstRun, + run, + "computeFeedbackArcSet must select identical edges across runs; run " + i + " differed"); + } + } + + // Then: the selection is a valid feedback arc set + Graph graph = copyGraph(template); + PageRankFAS pageRankFAS = new PageRankFAS<>(graph, new SuperTypeToken<>() {}); + Set feedbackArcSet = pageRankFAS.computeFeedbackArcSet(); + Set removed = new HashSet<>(feedbackArcSet); + removed.forEach(graph::removeEdge); + assertTrue( + !new CycleDetector<>(graph).detectCycles(), + "Removing the feedback arc set must leave the graph acyclic"); + } + + /** Verifies edge insertion order does not change feedback arc selection for overlapping cycles. */ + @DisplayName("computeFeedbackArcSet is independent of the order edges were added to the graph") + @Test + void computeFeedbackArcSet_isDeterministicAcrossEdgeInsertionOrders() { + // Given: one logical SCC expressing multiple overlapping cycles + String[][] logicalEdges = { + {"A", "B"}, + {"B", "C"}, + {"C", "A"}, // triangle 1 + {"A", "D"}, + {"D", "E"}, + {"E", "A"}, // triangle 2 + {"B", "E"}, + {"D", "B"}, // cross edges + }; + + // And: several different edge insertion orders of the same logical edges + int[][] permutations = { + {0, 1, 2, 3, 4, 5, 6, 7}, // as declared + {7, 6, 5, 4, 3, 2, 1, 0}, // reversed + {3, 0, 6, 2, 5, 1, 7, 4}, // interleaved + {5, 2, 7, 1, 4, 6, 0, 3}, // another interleave + }; + + // When: the feedback arc set is computed for each insertion order + Set firstOrder = null; + for (int[] permutation : permutations) { + Graph graph = new DefaultDirectedGraph<>(DefaultEdge.class); + for (int edgeIndex : permutation) { + String[] logicalEdge = logicalEdges[edgeIndex]; + graph.addVertex(logicalEdge[0]); + graph.addVertex(logicalEdge[1]); + graph.addEdge(logicalEdge[0], logicalEdge[1]); + } + PageRankFAS pageRankFAS = new PageRankFAS<>(graph, new SuperTypeToken<>() {}); + Set fas = edgeKeys(graph, pageRankFAS.computeFeedbackArcSet()); + + // Then: every insertion order selects the identical feedback arc set + if (firstOrder == null) { + firstOrder = fas; + } else { + assertEquals( + firstOrder, + fas, + "computeFeedbackArcSet must not depend on the order edges were added to the graph"); + } + } + } +} diff --git a/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java b/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java index e3abd549..f7102e97 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/JsonGenerator.java @@ -23,6 +23,7 @@ import org.hjug.graphbuilder.metrics.DisharmonyMetric; import org.hjug.metrics.DisharmonyInstance; import org.hjug.refactorfirst.report.model.*; +import org.jgrapht.graph.AsSubgraph; import org.jgrapht.graph.DefaultWeightedEdge; @Slf4j @@ -384,8 +385,8 @@ public RefactorFirstReportDTO generateReportData( targetUrl = repoUrl + endVertex.replace('.', '/'); } - List breakClassRels = - cells.length > 4 && !cells[4].isBlank() ? List.of(cells[4].split("
")) : List.of(); + List breakClassRels = buildClassRelationshipsToBreakPackage( + classRelationshipsInPackageRelationship, repoUrl, codebaseGraphDTO); // Build rendered label with links to package directories String renderedLabel = @@ -841,6 +842,71 @@ private String buildPackageLinkLabel( return newLabel.toString(); } + /** + * Converts the class edges behind a package edge into structured DTOs. + * Cycle membership is calculated for every class edge from {@code classCycles} before the + * DTOs are constructed: {@code classEdgeCycleCounts} only covers edges of the class + * feedback arc set, so relying on it reported the nested edges — which are generally not + * feedback-arc-set members — as members of zero class cycles. + */ + List buildClassRelationshipsToBreakPackage( + Set classEdges, String repoUrl, CodebaseGraphDTO codebaseGraphDTO) { + if (classEdges == null || classEdges.isEmpty()) { + return List.of(); + } + + List orderedClassEdges = sortedClassEdgesInPackageRelationship(classEdges); + Map cycleCounts = new LinkedHashMap<>(); + for (DefaultWeightedEdge classEdge : orderedClassEdges) { + cycleCounts.put(classEdge, countClassCyclesContaining(classEdge)); + } + + List relationships = new ArrayList<>(); + for (DefaultWeightedEdge classEdge : orderedClassEdges) { + String[] vertexes = extractVertexes(classEdge); + String startVertex = vertexes[0].trim(); + String endVertex = vertexes[1].trim(); + + String sourcePath = + codebaseGraphDTO.getClassToSourceFilePathMapping().get(startVertex); + String targetPath = + codebaseGraphDTO.getClassToSourceFilePathMapping().get(endVertex); + String sourceUrl = (sourcePath != null && !sourcePath.isBlank()) ? repoUrl + sourcePath : ""; + String targetUrl = (targetPath != null && !targetPath.isBlank()) ? repoUrl + targetPath : ""; + int weight = (int) classGraph.getEdgeWeight(classEdge); + + relationships.add(ClassRelationshipDTO.builder() + .sourceClass(startVertex) + .targetClass(endVertex) + .sourceMarked(classesToRemove.contains(startVertex)) + .targetMarked(classesToRemove.contains(endVertex)) + .weight(weight) + .renderedLabel( + buildClassLinkLabel(startVertex, endVertex, sourceUrl, targetUrl, classesToRemove, weight)) + .cycleCount(cycleCounts.get(classEdge)) + .build()); + } + return relationships; + } + + /** + * Counts how many of the detected class cycles contain the given class edge — the same + * counting {@code CycleRemovalComputer} applies to the edges it marks for removal. Returns + * {@code 0} when no class cycles are available. + */ + private int countClassCyclesContaining(DefaultWeightedEdge classEdge) { + if (classCycles == null || classCycles.isEmpty()) { + return 0; + } + int cycleCount = 0; + for (AsSubgraph cycle : classCycles.values()) { + if (cycle.containsEdge(classEdge)) { + cycleCount++; + } + } + return cycleCount; + } + /** * Builds a rendered label with HTML links to class files. * Transforms "GraphMetricsCollector → DependencyCollector : 1" diff --git a/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java b/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java index ec4d5546..4f09587c 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/SimpleHtmlReport.java @@ -649,11 +649,10 @@ String[] getPackageRelationshipDisharmony( Set classRelationshipsInPackageRelationship = codebaseGraphDTO.getClassRelationshipsInPackageRelationship().get(edgeInfo.getEdge()); - Set classEdges = new HashSet<>(); - if (classRelationshipsInPackageRelationship != null) { - for (DefaultWeightedEdge defaultWeightedEdge : classRelationshipsInPackageRelationship) { - classEdges.add(renderClassEdge(defaultWeightedEdge, repoUrl, codebaseGraphDTO)); - } + Set classEdges = new LinkedHashSet<>(); + for (DefaultWeightedEdge defaultWeightedEdge : + sortedClassEdgesInPackageRelationship(classRelationshipsInPackageRelationship)) { + classEdges.add(renderClassEdge(defaultWeightedEdge, repoUrl, codebaseGraphDTO)); } return new String[] { @@ -665,6 +664,24 @@ String[] getPackageRelationshipDisharmony( }; } + /** + * Deterministically orders the class edges behind a package relationship so that every + * report type (HTML, JSON) lists them identically on every run. The backing set's iteration + * order is identity-hash based and varies between executions, which made the htmlReport and + * the jsonReport disagree on the order of the class relationships to remove. + * + * @param classEdges the class edges mapped to a package relationship; may be {@code null} + * @return the edges ordered by source class FQN, then target class FQN + */ + List sortedClassEdgesInPackageRelationship(Set classEdges) { + if (classEdges == null || classEdges.isEmpty()) { + return List.of(); + } + return classEdges.stream() + .sorted(Comparator.comparing(classGraph::getEdgeSource).thenComparing(classGraph::getEdgeTarget)) + .toList(); + } + /** Renders summary rows for the ranked class cycles. */ private String renderClassCycleSummary(List rankedCycles) { StringBuilder stringBuilder = new StringBuilder(); diff --git a/report/src/main/java/org/hjug/refactorfirst/report/model/PackageRelationshipDTO.java b/report/src/main/java/org/hjug/refactorfirst/report/model/PackageRelationshipDTO.java index c38d4c10..5ec4692d 100644 --- a/report/src/main/java/org/hjug/refactorfirst/report/model/PackageRelationshipDTO.java +++ b/report/src/main/java/org/hjug/refactorfirst/report/model/PackageRelationshipDTO.java @@ -23,5 +23,5 @@ public class PackageRelationshipDTO { private int effortRank; @Builder.Default - private List classRelationshipsToBreakPackage = new ArrayList<>(); + private List classRelationshipsToBreakPackage = new ArrayList<>(); } diff --git a/report/src/main/resources/templates/refactor-first-report.mustache b/report/src/main/resources/templates/refactor-first-report.mustache index 428beaae..7f1faf27 100644 --- a/report/src/main/resources/templates/refactor-first-report.mustache +++ b/report/src/main/resources/templates/refactor-first-report.mustache @@ -298,7 +298,7 @@ {{cycleCount}} {{effortRank}} {{#classRelationshipsToBreakPackage}} - {{{.}}}
{{/classRelationshipsToBreakPackage}} + {{{renderedLabel}}}
{{/classRelationshipsToBreakPackage}} {{/packageRelationshipsToRemove.relationships}} diff --git a/report/src/test/java/org/hjug/refactorfirst/report/JsonGeneratorTest.java b/report/src/test/java/org/hjug/refactorfirst/report/JsonGeneratorTest.java index 39238787..7f5ed731 100644 --- a/report/src/test/java/org/hjug/refactorfirst/report/JsonGeneratorTest.java +++ b/report/src/test/java/org/hjug/refactorfirst/report/JsonGeneratorTest.java @@ -9,6 +9,8 @@ import java.nio.file.Path; import java.util.Comparator; import org.hjug.refactorfirst.report.model.ChartJsBubbleDTO; +import org.hjug.refactorfirst.report.model.ClassRelationshipDTO; +import org.hjug.refactorfirst.report.model.PackageRelationshipDTO; import org.hjug.refactorfirst.report.model.RefactorFirstReportDTO; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -426,4 +428,98 @@ public ClassB(ClassA classA) { "renderedLabel should have target=\"_blank\" attribute"); } } + + /** + * Verifies that class relationships that break a package cycle are serialized as + * structured {@link ClassRelationshipDTO}s with class names, markers and a rendered label. + */ + @Test + void given_packageCycle_when_reportGenerated_then_classRelationshipsToBreakPackageAreStructuredDTOs() + throws Exception { + // Given: two packages with a circular class dependency + File repoDir = tempDir.toFile(); + new File(repoDir, ".git").mkdirs(); + + File pkgA = new File(repoDir, "src/main/java/com/example/pkga"); + File pkgB = new File(repoDir, "src/main/java/com/example/pkgb"); + pkgA.mkdirs(); + pkgB.mkdirs(); + + Files.writeString( + new File(pkgA, "ClassA.java").toPath(), + """ + package com.example.pkga; + + public class ClassA { + private com.example.pkgb.ClassB classB; + + public ClassA(com.example.pkgb.ClassB classB) { + this.classB = classB; + } + } + """); + Files.writeString( + new File(pkgB, "ClassB.java").toPath(), + """ + package com.example.pkgb; + + public class ClassB { + private com.example.pkga.ClassA classA; + + public ClassB(com.example.pkga.ClassA classA) { + this.classA = classA; + } + } + """); + + new ProcessBuilder("git", "init").directory(repoDir).start().waitFor(); + new ProcessBuilder("git", "config", "user.email", "test@test.com") + .directory(repoDir) + .start() + .waitFor(); + new ProcessBuilder("git", "config", "user.name", "Test") + .directory(repoDir) + .start() + .waitFor(); + new ProcessBuilder("git", "add", ".").directory(repoDir).start().waitFor(); + new ProcessBuilder("git", "commit", "-m", "initial") + .directory(repoDir) + .start() + .waitFor(); + + // When + new JsonGenerator().execute(0, true, false, true, "src/test", "PackageCycleProject", "1.0.0", repoDir, null); + + // Then + Path jsonFile = tempDir.resolve(".refactorfirst").resolve("refactor-first.json"); + RefactorFirstReportDTO report = objectMapper.readValue(jsonFile.toFile(), RefactorFirstReportDTO.class); + assertNotNull(report.getPackageRelationshipsToRemove()); + assertNotNull( + report.getPackageRelationshipsToRemove().getRelationships(), + "Package relationships to remove should be present"); + assertFalse( + report.getPackageRelationshipsToRemove().getRelationships().isEmpty(), + "Fixture produced no package relationships to remove"); + + int totalClassRelationships = 0; + for (PackageRelationshipDTO packageRel : + report.getPackageRelationshipsToRemove().getRelationships()) { + assertNotNull(packageRel.getClassRelationshipsToBreakPackage()); + for (ClassRelationshipDTO classRel : packageRel.getClassRelationshipsToBreakPackage()) { + totalClassRelationships++; + assertTrue( + classRel.getSourceClass().startsWith("com.example.pkg"), + "sourceClass should be a fully qualified class name: " + classRel.getSourceClass()); + assertTrue( + classRel.getTargetClass().startsWith("com.example.pkg"), + "targetClass should be a fully qualified class name: " + classRel.getTargetClass()); + assertTrue(classRel.getWeight() >= 1, "weight should be at least 1"); + assertNotNull(classRel.getRenderedLabel(), "ClassRelationshipDTO should have renderedLabel"); + assertTrue( + classRel.getRenderedLabel().contains("→"), + "renderedLabel should contain the relationship arrow"); + } + } + assertTrue(totalClassRelationships > 0, "Expected at least one class relationship to break the package cycle"); + } } diff --git a/report/src/test/java/org/hjug/refactorfirst/report/PackageRelationshipClassEdgeCycleCountTest.java b/report/src/test/java/org/hjug/refactorfirst/report/PackageRelationshipClassEdgeCycleCountTest.java new file mode 100644 index 00000000..f07401c4 --- /dev/null +++ b/report/src/test/java/org/hjug/refactorfirst/report/PackageRelationshipClassEdgeCycleCountTest.java @@ -0,0 +1,115 @@ +package org.hjug.refactorfirst.report; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import org.hjug.dsm.CircularReferenceChecker; +import org.hjug.graphbuilder.CodebaseGraphDTO; +import org.hjug.refactorfirst.report.model.ClassRelationshipDTO; +import org.jgrapht.Graph; +import org.jgrapht.graph.AsSubgraph; +import org.jgrapht.graph.DefaultDirectedWeightedGraph; +import org.jgrapht.graph.DefaultWeightedEdge; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** + * The nested class relationships inside a package relationship (the "class relationships to + * remove to break the package relationship") are generally not part of the class feedback arc + * set, so {@code classEdgeCycleCounts} — which {@code CycleRemovalComputer} populates only for + * feedback-arc-set edges — never contains them. Reporting {@code 0} for such edges falsely + * claims membership in zero class cycles. These tests pin that the nested DTOs carry the real + * class-cycle membership, calculated from the already-available {@code classCycles}. + */ +class PackageRelationshipClassEdgeCycleCountTest { + + private static final String PKG_A = "org.example.pkgA"; + private static final String PKG_B = "org.example.pkgB"; + private static final String ALPHA = PKG_A + ".Alpha"; + private static final String BETA = PKG_B + ".Beta"; + private static final String DELTA = PKG_A + ".Delta"; + private static final String REPO_URL = "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/example/repo/blob/"; + + /** Alpha and Beta form a 2-cycle; Delta -> Beta hangs off the cycle and is in no cycle. */ + private Graph createClassGraph() { + Graph classGraph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); + classGraph.addVertex(ALPHA); + classGraph.addVertex(BETA); + classGraph.addVertex(DELTA); + + DefaultWeightedEdge alphaToBeta = classGraph.addEdge(ALPHA, BETA); + classGraph.setEdgeWeight(alphaToBeta, 5); + DefaultWeightedEdge betaToAlpha = classGraph.addEdge(BETA, ALPHA); + classGraph.setEdgeWeight(betaToAlpha, 2); + DefaultWeightedEdge deltaToBeta = classGraph.addEdge(DELTA, BETA); + classGraph.setEdgeWeight(deltaToBeta, 1); + + return classGraph; + } + + /** Creates a DTO mock with no source paths so relationships render without file links. */ + private CodebaseGraphDTO mockDto() { + CodebaseGraphDTO dto = Mockito.mock(CodebaseGraphDTO.class); + Mockito.when(dto.getClassToSourceFilePathMapping()).thenReturn(new HashMap<>()); + return dto; + } + + /** Verifies nested relationships count detected class cycles even outside the feedback arc set. */ + @DisplayName("nested class relationships report their real class-cycle membership, not a defaulted zero") + @Test + void buildClassRelationshipsToBreakPackage_reportsActualCycleMembership() throws Exception { + // Given: a class graph whose Alpha -> Beta and Beta -> Alpha edges participate in the + // Alpha/Beta class cycle, and a Delta -> Beta edge that participates in no cycle + Graph classGraph = createClassGraph(); + DefaultWeightedEdge alphaToBeta = classGraph.getEdge(ALPHA, BETA); + DefaultWeightedEdge betaToAlpha = classGraph.getEdge(BETA, ALPHA); + DefaultWeightedEdge deltaToBeta = classGraph.getEdge(DELTA, BETA); + + JsonGenerator generator = new JsonGenerator(); + generator.classGraph = classGraph; + // The class cycles, built the same way CycleRemovalComputer builds them + Map> cycles = + new CircularReferenceChecker().getCycles(classGraph); + generator.classCycles = cycles; + assertEquals(1, cycles.size(), "Test graph must contain exactly one class cycle"); + assertEquals( + 1, + cycles.values().stream() + .filter(c -> c.containsEdge(alphaToBeta)) + .count(), + "The Alpha -> Beta edge must be a member of the class cycle"); + + // The nested edges are absent from classEdgeCycleCounts (which only covers + // feedback-arc-set edges), so their membership must be calculated from classCycles + Set classEdgesInPackageRelationship = new LinkedHashSet<>(); + classEdgesInPackageRelationship.add(alphaToBeta); + classEdgesInPackageRelationship.add(betaToAlpha); + classEdgesInPackageRelationship.add(deltaToBeta); + + // When: the nested class-relationship DTOs are built for the package edge + var relationships = + generator.buildClassRelationshipsToBreakPackage(classEdgesInPackageRelationship, REPO_URL, mockDto()); + + // Then: each nested DTO reports its real class-cycle membership + ClassRelationshipDTO alphaToBetaDto = relationships.stream() + .filter(r -> r.getSourceClass().equals(ALPHA)) + .findFirst() + .orElseThrow(); + ClassRelationshipDTO betaToAlphaDto = relationships.stream() + .filter(r -> r.getSourceClass().equals(BETA)) + .findFirst() + .orElseThrow(); + ClassRelationshipDTO deltaToBetaDto = relationships.stream() + .filter(r -> r.getSourceClass().equals(DELTA)) + .findFirst() + .orElseThrow(); + + assertEquals(1, alphaToBetaDto.getCycleCount(), "Alpha -> Beta is in the class cycle, so its count must be 1"); + assertEquals(1, betaToAlphaDto.getCycleCount(), "Beta -> Alpha is in the class cycle, so its count must be 1"); + assertEquals(0, deltaToBetaDto.getCycleCount(), "Delta -> Beta is in no class cycle, so its count must be 0"); + } +} diff --git a/report/src/test/java/org/hjug/refactorfirst/report/PackageRelationshipClassEdgeOrderTest.java b/report/src/test/java/org/hjug/refactorfirst/report/PackageRelationshipClassEdgeOrderTest.java new file mode 100644 index 00000000..a3462b5b --- /dev/null +++ b/report/src/test/java/org/hjug/refactorfirst/report/PackageRelationshipClassEdgeOrderTest.java @@ -0,0 +1,233 @@ +package org.hjug.refactorfirst.report; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.hjug.cbc.RankedDisharmony; +import org.hjug.graphbuilder.CodebaseGraphDTO; +import org.hjug.refactorfirst.report.model.ClassRelationshipDTO; +import org.jgrapht.Graph; +import org.jgrapht.graph.DefaultDirectedWeightedGraph; +import org.jgrapht.graph.DefaultWeightedEdge; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** + * The htmlReport and the jsonReport both render the class relationships that must be removed to + * break a package relationship. Those class edges are stored in a + * {@code HashSet} whose iteration order is identity-hash based, so the two + * report types (and repeated runs of the same report) could list the same relationships in + * different orders. These tests pin a deterministic, source-ordered rendering shared by both + * reports. + */ +class PackageRelationshipClassEdgeOrderTest { + + private static final String PKG_A = "org.example.pkgA"; + private static final String PKG_B = "org.example.pkgB"; + private static final String REPO_URL = "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/example/repo/blob/"; + + /** Number of class edges crossing the package boundary. */ + private static final int EDGE_COUNT = 12; + + /** + * Builds the class graph with {@link #EDGE_COUNT} edges from {@link #PKG_A} to + * {@link #PKG_B}, plus two edges sharing one source whose targets' natural order differs + * from their insertion order ({@code TargetZ} is inserted before {@code TargetB}). + */ + private Graph createClassGraph() { + Graph classGraph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); + for (int i = 0; i < EDGE_COUNT; i++) { + String source = PKG_A + ".Class" + (char) ('A' + i); + String target = PKG_B + ".Target" + (char) ('A' + i); + classGraph.addVertex(source); + classGraph.addVertex(target); + DefaultWeightedEdge edge = classGraph.addEdge(source, target); + classGraph.setEdgeWeight(edge, i + 1); + } + + // Same-source edges whose target order differs from insertion order: TargetZ is added + // first, but TargetB must be rendered first because it sorts first + String multiSource = PKG_A + ".Multi"; + String targetZ = PKG_B + ".TargetZ"; + String targetB = PKG_B + ".TargetB"; + classGraph.addVertex(multiSource); + classGraph.addVertex(targetZ); + classGraph.addVertex(targetB); + DefaultWeightedEdge multiToTargetZ = classGraph.addEdge(multiSource, targetZ); + classGraph.setEdgeWeight(multiToTargetZ, EDGE_COUNT + 1); + DefaultWeightedEdge multiToTargetB = classGraph.addEdge(multiSource, targetB); + classGraph.setEdgeWeight(multiToTargetB, EDGE_COUNT + 2); + + return classGraph; + } + + /** Builds a package graph with a single A -> B edge. */ + private Graph createPackageGraph() { + Graph packageGraph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class); + packageGraph.addVertex(PKG_A); + packageGraph.addVertex(PKG_B); + packageGraph.addEdge(PKG_A, PKG_B); + return packageGraph; + } + + /** Inserts the given edges into a fresh HashSet in the given order. */ + private Set newSetInOrder(Collection edges, int rotation) { + List rotated = new ArrayList<>(edges); + Collections.rotate(rotated, rotation); + return new HashSet<>(rotated); + } + + /** Injects a graph fixture into a field declared by the shared HTML report base class. */ + private void setField(Object target, String fieldName, Object value) throws Exception { + Field field = SimpleHtmlReport.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, value); + } + + /** Maps the package edge to its class edges in a DTO mock with no source file paths. */ + private CodebaseGraphDTO mockDto(DefaultWeightedEdge packageEdge, Set classEdges) { + CodebaseGraphDTO dto = Mockito.mock(CodebaseGraphDTO.class); + Map> relationships = new HashMap<>(); + relationships.put(packageEdge, classEdges); + Mockito.when(dto.getClassRelationshipsInPackageRelationship()).thenReturn(relationships); + Mockito.when(dto.getClassToSourceFilePathMapping()).thenReturn(new HashMap<>()); + return dto; + } + + /** Creates a ranked package-edge fixture with priority, cycle count and effort rank set to one. */ + private RankedDisharmony mockRankedDisharmony(DefaultWeightedEdge packageEdge) { + RankedDisharmony edgeInfo = Mockito.mock(RankedDisharmony.class); + Mockito.when(edgeInfo.getEdge()).thenReturn(packageEdge); + Mockito.when(edgeInfo.getPriority()).thenReturn(1); + Mockito.when(edgeInfo.getCycleCount()).thenReturn(1); + Mockito.when(edgeInfo.getEffortRank()).thenReturn(1); + return edgeInfo; + } + + /** Renders the class-relationship cell of the package-relationship table for the given DTO. */ + private String renderHtmlCell(SimpleHtmlReport report, RankedDisharmony edgeInfo, CodebaseGraphDTO dto) + throws Exception { + Method method = SimpleHtmlReport.class.getDeclaredMethod( + "getPackageRelationshipDisharmony", RankedDisharmony.class, String.class, CodebaseGraphDTO.class); + method.setAccessible(true); + String[] cells = (String[]) method.invoke(report, edgeInfo, REPO_URL, dto); + return cells[4]; + } + + /** Builds the JSON DTO list of class relationships behind the package edge for the given DTO. */ + private List buildJsonList(JsonGenerator generator, CodebaseGraphDTO dto) { + DefaultWeightedEdge packageEdge = dto.getClassRelationshipsInPackageRelationship() + .keySet() + .iterator() + .next(); + return generator.buildClassRelationshipsToBreakPackage( + dto.getClassRelationshipsInPackageRelationship().get(packageEdge), REPO_URL, dto); + } + + /** Verifies HTML and JSON use the same source/target order across class-edge set insertions. */ + @DisplayName( + "class relationships behind a package edge render in the same deterministic order regardless of set insertion order") + @Test + void classRelationshipsToBreakPackage_areOrderedDeterministically() throws Exception { + // Given: a class graph with edges crossing a package boundary, and DTOs whose + // class-relationship sets are populated in many different insertion orders + Graph classGraph = createClassGraph(); + Graph packageGraph = createPackageGraph(); + DefaultWeightedEdge packageEdge = packageGraph.edgeSet().iterator().next(); + List edges = new ArrayList<>(classGraph.edgeSet()); + RankedDisharmony edgeInfo = mockRankedDisharmony(packageEdge); + + String firstHtmlCell = null; + List firstJsonList = null; + for (int rotation = 0; rotation < 24; rotation++) { + Set classEdges = newSetInOrder(edges, rotation); + CodebaseGraphDTO dto = mockDto(packageEdge, classEdges); + + SimpleHtmlReport htmlReport = new SimpleHtmlReport(); + setField(htmlReport, "classGraph", classGraph); + setField(htmlReport, "packageGraph", packageGraph); + String htmlCell = renderHtmlCell(htmlReport, edgeInfo, dto); + + JsonGenerator jsonGenerator = new JsonGenerator(); + setField(jsonGenerator, "classGraph", classGraph); + setField(jsonGenerator, "packageGraph", packageGraph); + List jsonList = buildJsonList(jsonGenerator, dto); + List jsonSources = + jsonList.stream().map(ClassRelationshipDTO::getSourceClass).toList(); + + // When: comparing each rotated insertion order against the first one + if (firstHtmlCell == null) { + firstHtmlCell = htmlCell; + firstJsonList = jsonList; + } else { + assertEquals( + firstHtmlCell, + htmlCell, + "HTML class-relationship cell must not depend on set insertion order (rotation " + rotation + + ")"); + assertEquals( + firstJsonList.stream() + .map(ClassRelationshipDTO::getSourceClass) + .toList(), + jsonSources, + "JSON class-relationship order must not depend on set insertion order (rotation " + rotation + + ")"); + } + } + + // Then: the order is the deterministic source-class order, identical in both reports + List expectedOrder = edges.stream() + .sorted((e1, e2) -> { + int bySource = classGraph.getEdgeSource(e1).compareTo(classGraph.getEdgeSource(e2)); + return bySource != 0 + ? bySource + : classGraph.getEdgeTarget(e1).compareTo(classGraph.getEdgeTarget(e2)); + }) + .toList(); + assertEquals( + expectedOrder.stream().map(classGraph::getEdgeSource).toList(), + firstJsonList.stream().map(ClassRelationshipDTO::getSourceClass).toList(), + "JSON class relationships must be ordered by source class FQN"); + String expectedHtmlCell = String.join( + "
", + expectedOrder.stream() + .map(edge -> simpleName(classGraph.getEdgeSource(edge)) + " → " + + simpleName(classGraph.getEdgeTarget(edge)) + " : " + + (int) classGraph.getEdgeWeight(edge)) + .toList()); + assertEquals( + expectedHtmlCell, + firstHtmlCell, + "HTML class-relationship cell must list the same edges in the same order as the JSON report"); + + // And: edges sharing a source render their targets in natural order — not insertion + // order — in both reports (TargetZ was inserted first, but TargetB sorts first) + List multiSourceTargets = firstJsonList.stream() + .filter(r -> r.getSourceClass().equals(PKG_A + ".Multi")) + .map(ClassRelationshipDTO::getTargetClass) + .toList(); + assertEquals( + List.of(PKG_B + ".TargetB", PKG_B + ".TargetZ"), + multiSourceTargets, + "JSON must order same-source class relationships by target class FQN, not insertion order"); + assertTrue( + firstHtmlCell.indexOf("Multi → TargetB") < firstHtmlCell.indexOf("Multi → TargetZ"), + "HTML must render same-source targets in the same order as the JSON report"); + } + + /** Extracts the final name segment from a fully qualified class name for expected HTML labels. */ + private static String simpleName(String fqn) { + return fqn.substring(fqn.lastIndexOf('.') + 1); + } +}