package Ġde . ma ib orn w ol ff . code chart a . filter . structure modifier Ċ Ċ import Ġde . ma ib orn w ol ff . code chart a . model . AttributeType Ċ import Ġde . ma ib orn w ol ff . code chart a . model . Black list Item Ċ import Ġde . ma ib orn w ol ff . code chart a . model . Edge Ċ import Ġde . ma ib orn w ol ff . code chart a . model . Mutable Node Ċ import Ġde . ma ib orn w ol ff . code chart a . model . Project Ċ import Ġde . ma ib orn w ol ff . code chart a . model . Project Builder Ċ import Ġmu . Kotlin Logging Ċ Ċ class ĠSub Project Extractor ( private Ġval Ġproject : ĠProject ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{ Ġ} ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġpath : ĠString ĊĊĠĠĠ Ġfun Ġextract ( path : ĠString ): ĠProject Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . path Ġ= Ġpath ĊĠĠĠĠĠĠĠ Ġval Ġpath Segments Ġ= Ġpath . remove Prefix ("/ "). split ("/ "). filter Ġ{ Ġit . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠProject Builder ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Root ( extract Nodes ( path Segments , Ġproject . root Node . to Mutable Node ())), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġextract Edges ( path ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcopy Attribute Types (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcopy Black list () ĊĠĠĠĠĠĠĠ Ġ). build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġextract Nodes ( extraction Pattern : ĠList < String >, Ġnode : ĠMutable Node ): ĠMutable List < Mutable Node > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchildren : ĠSet < Mutable Node > Ġ= Ġnode . children ĊĠĠĠĠĠĠĠ Ġval Ġextracted Nodes : ĠMutable List < Mutable Node > Ġ= Ġmutable ListOf () ĊĊĠĠĠĠĠĠĠ Ġval Ġcurrent Search Pattern Ġ= Ġextraction Pattern . first OrNull () ĊĠĠĠĠĠĠĠ Ġif Ġ( current Search Pattern Ġ== Ġnode . name ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( extraction Pattern . size Ġ== Ġ 1 ) Ġnode . children . to Mutable List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġchildren . map Ġ{ Ġchild Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextract Nodes ( extraction Pattern . drop ( 1 ), Ġchild ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. flatten (). to Mutable List () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġextracted Nodes ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Root ( nodes : ĠMutable List < Mutable Node >): ĠList < Mutable Node > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( nodes . size Ġ== Ġ 0 ) Ġlogger . warn (" No Ġnodes Ġwith Ġthe Ġspecified Ġpath Ġ($ path ) Ġwere Ġf ond . ĠThe Ġresulting Ġproject Ġis Ġtherefore Ġempty ") ĊĊĠĠĠĠĠĠĠ Ġval Ġroot Node Ġ= Ġproject . root Node . to Mutable Node () ĊĠĠĠĠĠĠĠ Ġroot Node . children Ġ= Ġnodes . to Mutable Set () ĊĠĠĠĠĠĠĠ Ġreturn Ġmutable ListOf ( root Node ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġextract Edges ( extraction Pattern : ĠString ): ĠMutable List < Edge > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtrimmed Extraction Pattern Ġ= Ġ"/" Ġ+ Ġextraction Pattern . remove Suffix ("/ "). remove Prefix ("/") ĊĠĠĠĠĠĠĠ Ġreturn Ġextract Rename d Edges For Pattern ( trimmed Extraction Pattern ). to Mutable List () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġextract Rename d Edges For Pattern ( pattern : ĠString ): ĠList < Edge > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġproject . edges . filter Ġ{ Ġit . from NodeName . startsWith ( pattern ) Ġ&& Ġit . to NodeName . startsWith ( pattern ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġedge Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedge . from NodeName Ġ= Ġ"/ root " Ġ+ Ġedge . from NodeName . remove Prefix ( pattern ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedge . to NodeName Ġ= Ġ"/ root " Ġ+ Ġedge . to NodeName . remove Prefix ( pattern ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedge ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcopy Attribute Types (): ĠMutable Map < String , ĠMutable Map < String , ĠAttribute Type >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmerged Attribute Types : ĠMutable Map < String , ĠMutable Map < String , ĠAttribute Type >> Ġ= Ġmutable Map Of () ĊĠĠĠĠĠĠĠ Ġproject . attribute Types . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmerged Attribute Types [ it . key ] Ġ= Ġit . value ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmerged Attribute Types . to Mutable Map () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcopy Black list (): ĠMutable List < Black list Item > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġproject . blacklist . to Mutable List () ĊĠĠĠ Ġ} Ċ } Ċ