/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 - 2 0 1 9 Ġthe Ġoriginal Ġauthor Ġor Ġauthors . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . uch uh imo . kon f Ċ Ċ import Ġjava . util . Collections Ċ Ċ /** Ċ Ġ* ĠTree Ġnode Ġthat Ġrepresents Ġinternal Ġstructure Ġof Ġconfig / source . Ċ Ġ*/ Ċ interface ĠTreeNode Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChildren Ġnodes Ġin Ġthis Ġtree Ġnode Ġwith Ġtheir Ġnames Ġas Ġkeys . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġchildren : ĠMutable Map < String , ĠTreeNode > ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAssoci ate Ġpath Ġwith Ġspecified Ġnode . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpath Ġpath ĊĠĠĠĠ Ġ* Ġ@ param Ġnode Ġassociated Ġnode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoperator Ġfun Ġset ( path : ĠPath , Ġnode : ĠTreeNode ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( path . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠPath Conflict Exception ( path . name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġpath . first () ĊĠĠĠĠĠĠĠ Ġif Ġ( this Ġis ĠLeaf Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠPath Conflict Exception ( path . name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( path . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchildren [ key ] Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrest Ġ= Ġpath . drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġchild Ġ= Ġchildren [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( child Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild Ġ= ĠContainer Node ( mutable Map Of ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchildren [ key ] Ġ= Ġchild ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild [ rest ] Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ(_ : ĠPath Conflict Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠPath Conflict Exception ( path . name ) ĊĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this Ġis ĠMap Node Ġ&& Ġis Place Holder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Place Holder Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAssoci ate Ġpath Ġwith Ġspecified Ġnode . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpath Ġpath ĊĠĠĠĠ Ġ* Ġ@ param Ġnode Ġassociated Ġnode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoperator Ġfun Ġset ( path : ĠString , Ġnode : ĠTreeNode ) Ġ{ ĊĠĠĠĠĠĠĠ Ġset ( path . to Path (), Ġnode ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhether Ġthis Ġtree Ġnode Ġcontains Ġnode ( s ) Ġin Ġspecified Ġpath Ġor Ġnot . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpath Ġitem Ġpath ĊĠĠĠĠ Ġ* Ġ@ return Ġ` true ` Ġif Ġthis Ġtree Ġnode Ġcontains Ġnode ( s ) Ġin Ġspecified Ġpath , Ġ` false ` Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoperator Ġfun Ġcontains ( path : ĠPath ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( path . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġpath . first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrest Ġ= Ġpath . drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġchildren [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġrest Ġin Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġtree Ġnode Ġin Ġspecified Ġpath Ġif Ġthis Ġtree Ġnode Ġcontains Ġvalue ( s ) Ġin Ġspecified Ġpath , ĊĠĠĠĠ Ġ* Ġ` null ` Ġotherwise . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpath Ġitem Ġpath ĊĠĠĠĠ Ġ* Ġ@ return Ġtree Ġnode Ġin Ġspecified Ġpath Ġif Ġthis Ġtree Ġnode Ġcontains Ġvalue ( s ) Ġin Ġspecified Ġpath , ĊĠĠĠĠ Ġ* Ġ` null ` Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget OrNull ( path : ĠPath ): ĠTreeNode ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( path . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġpath . first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrest Ġ= Ġpath . drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġchildren [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult ?. get OrNull ( rest ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġtree Ġnode Ġin Ġspecified Ġpath Ġif Ġthis Ġtree Ġnode Ġcontains Ġvalue ( s ) Ġin Ġspecified Ġpath , ĊĠĠĠĠ Ġ* Ġ` null ` Ġotherwise . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġpath Ġitem Ġpath ĊĠĠĠĠ Ġ* Ġ@ return Ġtree Ġnode Ġin Ġspecified Ġpath Ġif Ġthis Ġtree Ġnode Ġcontains Ġvalue ( s ) Ġin Ġspecified Ġpath , ĊĠĠĠĠ Ġ* Ġ` null ` Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget OrNull ( path : ĠString ): ĠTreeNode ? Ġ= Ġget OrNull ( path . to Path ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġa Ġnode Ġbacking Ġby Ġspecified Ġfallback Ġnode . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġfallback Ġfallback Ġnode ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġnode Ġbacking Ġby Ġspecified Ġfallback Ġnode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġwith Fallback ( fallback : ĠTreeNode ): ĠTreeNode Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġtraverse Tree ( facade : ĠTreeNode , Ġfallback : ĠTreeNode , Ġpath : ĠPath ): ĠTreeNode Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( facade Ġis ĠLeaf Node Ġ|| Ġfallback Ġis ĠLeaf Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfac ade ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠContainer Node ( facade . children . to Mutable Map (). also Ġ{ Ġmap Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( key , Ġchild ) Ġin Ġfallback . children ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġin Ġfac ade . children ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap [ key ] Ġ= Ġtraverse Tree ( facade . children . getValue ( key ), Ġchild , Ġpath Ġ+ Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap [ key ] Ġ= Ġchild ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtraverse Tree ( this , Ġfallback , Ġ"". to Path ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġa Ġnode Ġover l apped Ġby Ġthe Ġspecified Ġfac ade Ġnode . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġfac ade Ġthe Ġfac ade Ġnode ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġnode Ġover l apped Ġby Ġthe Ġspecified Ġfac ade Ġnode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoperator Ġfun Ġplus ( facade : ĠTreeNode ): ĠTreeNode Ġ= Ġfac ade . with Fallback ( this ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġa Ġtree Ġnode Ġcontaining Ġall Ġnodes Ġof Ġthe Ġoriginal Ġtree Ġnode ĊĠĠĠĠ Ġ* Ġexcept Ġthe Ġnodes Ġcontained Ġin Ġthe Ġgiven Ġ[ other ] Ġtree Ġnode . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġtree Ġnode ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoperator Ġfun Ġminus ( other : ĠTreeNode ): ĠTreeNode Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġtraverse Tree ( left : ĠTreeNode , Ġright : ĠTreeNode ): ĠTreeNode Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( left Ġis ĠLeaf Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEmpty Node ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( right Ġis ĠLeaf Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠEmpty Node ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġleft Keys Ġ= Ġleft . children . keys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġright Keys Ġ= Ġright . children . keys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdiff Keys Ġ= Ġleft Keys Ġ- Ġright Keys ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshared Keys Ġ= Ġleft Keys . intersect ( right Keys ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchildren Ġ= Ġmutable Map Of < String , ĠTreeNode >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdiff Keys . forEach Ġ{ Ġkey Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchildren [ key ] Ġ= Ġleft . children [ key ] !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshared Keys . forEach Ġ{ Ġkey Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchild Ġ= Ġtraverse Tree ( left . children [ key ] !! , Ġright . children [ key ] !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( child Ġ!= ĠEmpty Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchildren [ key ] Ġ= Ġchild ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( children . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEmpty Node ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContainer Node ( children ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtraverse Tree ( this , Ġother ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠList Ġof Ġall Ġpaths Ġin Ġthis Ġtree Ġnode . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġpaths : ĠList < String > ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmutable ListOf < String >(). also Ġ{ Ġlist Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtraverse Tree ( node : ĠTreeNode , Ġpath : ĠPath ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node Ġis ĠLeaf Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist . add ( path . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children . forEach Ġ{ Ġ( key , Ġchild ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Tree ( child , Ġpath Ġ+ Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Tree ( this , Ġ"". to Path ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfirst Path ( predicate : Ġ( TreeNode ) Ġ-> ĠBoolean ): ĠPath ? Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġtraverse Tree ( node : ĠTreeNode , Ġpath : ĠPath ): ĠPath ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( predicate ( node )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpath ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children . forEach Ġ{ Ġ( key , Ġchild ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatch Path Ġ= Ġtraverse Tree ( child , Ġpath Ġ+ Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( match Path Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmatch Path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtraverse Tree ( this , Ġ"". to Path ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMap Ġof Ġall Ġleaves Ġindexed Ġby Ġpaths Ġin Ġthis Ġtree Ġnode . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġleaf By Path : ĠMap < String , ĠTreeNode > ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmutable Map Of < String , ĠTreeNode >(). also Ġ{ Ġmap Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfun Ġtraverse Tree ( node : ĠTreeNode , Ġpath : ĠPath ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( node Ġis ĠLeaf Node ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap [ path . name ] Ġ= Ġnode ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode . children . forEach Ġ{ Ġ( key , Ġchild ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Tree ( child , Ġpath Ġ+ Ġkey ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtraverse Tree ( this , Ġ"". to Path ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġwithout Place Holder (): ĠTreeNode Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNull Node Ġ-> Ġreturn Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠValue Node Ġ-> Ġreturn Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠListNode Ġ-> Ġreturn Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMap Node Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Children Ġ= Ġchildren . map Values Ġ{ Ġ(_, Ġchild ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchild . without Place Holder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Children . isNotEmpty () Ġ&& Ġnew Children . all Ġ{ Ġ(_, Ġchild ) Ġ-> Ġchild Ġis ĠMap Node Ġ&& Ġchild . is Place Holder Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠContainer Node . place Holder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwith Map ( new Children . filter Values Ġ{ Ġ!( it Ġis ĠMap Node Ġ&& Ġit . is Place Holder ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġthis ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠisEmpty (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEmpty Node Ġ-> Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMap Node Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġchildren . isEmpty () Ġ|| Ġchildren . all Ġ{ Ġ(_, Ġchild ) Ġ-> Ġchild . isEmpty () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Place Holder Node (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMap Node Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Place Holder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġchildren . isNotEmpty () Ġ&& Ġchildren . all Ġ{ Ġ(_, Ġchild ) Ġ-> Ġchild . is Place Holder Node () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ interface ĠLeaf Node Ġ: ĠTreeNode Ċ Ċ interface ĠMap Node Ġ: ĠTreeNode Ġ{ ĊĠĠĠ Ġfun Ġwith Map ( map : ĠMap < String , ĠTreeNode >): ĠMap Node Ġ= Ġthrow ĠNotImplementedError () ĊĠĠĠ Ġvar Ġis Place Holder : ĠBoolean Ċ } Ċ Ċ val Ġempty Mutable Map : ĠMutable Map < String , ĠTreeNode > Ġ= ĠCollections . unmodifiable Map ( mutable Map Of ()) Ċ Ċ interface ĠValue Node Ġ: ĠLeaf Node Ġ{ ĊĠĠĠ Ġval Ġvalue : ĠAny ĊĠĠĠ Ġoverride Ġval Ġchildren : ĠMutable Map < String , ĠTreeNode > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġempty Mutable Map Ċ } Ċ Ċ interface ĠNull Node Ġ: ĠLeaf Node Ċ Ċ interface ĠListNode Ġ: ĠLeaf Node Ġ{ ĊĠĠĠ Ġval Ġlist : ĠList < TreeNode > ĊĠĠĠ Ġfun Ġwith List ( list : ĠList < TreeNode >): ĠListNode Ġ= Ġthrow ĠNotImplementedError () Ċ } Ċ Ċ /** Ċ Ġ* ĠTree Ġnode Ġthat Ġcontains Ġchildren Ġnodes . Ċ Ġ*/ Ċ open Ġclass ĠContainer Node ( ĊĠĠĠ Ġoverride Ġval Ġchildren : ĠMutable Map < String , ĠTreeNode >, ĊĠĠĠ Ġoverride Ġvar Ġis Place Holder : ĠBoolean Ġ= Ġfalse Ċ ) Ġ: ĠMap Node Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġwith Map ( map : ĠMap < String , ĠTreeNode >): ĠMap Node Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġis Place Holder Ġ= Ġmap . isEmpty () Ġ&& Ġthis . is Place Holder ĊĠĠĠĠĠĠĠ Ġif Ġ( map Ġis ĠMutable Map < String , ĠTreeNode >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠContainer Node ( map , Ġis Place Holder ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠContainer Node ( map . to Mutable Map (), Ġis Place Holder ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġempty (): ĠContainer Node Ġ= ĠContainer Node ( mutable Map Of ()) ĊĠĠĠĠĠĠĠ Ġfun Ġplace Holder (): ĠContainer Node Ġ= ĠContainer Node ( mutable Map Of (), Ġtrue ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠTree Ġnode Ġthat Ġrepresents Ġa Ġempty Ġtree . Ċ Ġ*/ Ċ object ĠEmpty Node Ġ: ĠLeaf Node Ġ{ ĊĠĠĠ Ġoverride Ġval Ġchildren : ĠMutable Map < String , ĠTreeNode > Ġ= Ġempty Mutable Map Ċ } Ċ