package Ġcom . strument a . kol as u . model Ċ Ċ import Ġjava . util . LinkedList Ċ import Ġkotlin . collections . HashMap Ċ import Ġkotlin . reflect . K Mutable Property Ċ import Ġkotlin . reflect . K Parameter Ċ import Ġkotlin . reflect . K Property Ċ import Ġkotlin . reflect . K Property 1 Ċ import Ġkotlin . reflect . K Visibility Ċ import Ġkotlin . reflect . full . find Annotation Ċ import Ġkotlin . reflect . full . member Properties Ċ import Ġkotlin . reflect . full . primary Constructor Ċ Ċ private Ġval Ġ< T Ġ: ĠNode > ĠT . contain ment Properties : ĠCollection < K Property 1 < T , Ġ* >> ĊĠĠĠ Ġget () Ġ= Ġthis . java Class . kotlin . member Properties ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . visibility Ġ== ĠK Visibility . PUBLIC Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . find Annotation < Derived >() Ġ== Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . find Annotation < Link >() Ġ== Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . name Ġ!= Ġ" parent " Ġ} Ċ Ċ fun ĠNode . assign Parents () Ġ{ ĊĠĠĠ Ġthis . children . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġit . parent Ġ= Ġthis ĊĠĠĠĠĠĠĠ Ġit . assign Parents () ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠNode . process ( operation : Ġ( Node ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġoperation ( this ) ĊĠĠĠ Ġcontain ment Properties . forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġp . get ( this ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( v ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Ġ-> Ġv . process ( operation ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCollection < *> Ġ-> Ġv . forEach Ġ{ Ġ( it Ġas ? ĠNode )?. process ( operation ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠNode . find ( predicate : Ġ( Node ) Ġ-> ĠBoolean ): ĠNode ? Ġ{ ĊĠĠĠ Ġif Ġ( predicate ( this )) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} ĊĠĠĠ Ġcontain ment Properties . forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġp . get ( this ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( v ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġv . find ( predicate ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġres ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCollection < *> Ġ-> Ġv . forEach Ġ{ Ġ( it Ġas ? ĠNode )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġres Ġ= Ġit . find ( predicate ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( res Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġres ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġnull Ċ } Ċ Ċ fun Ġ< T Ġ: ĠNode > ĠNode . specific Process ( klass : ĠClass < T >, Ġoperation : Ġ( T ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġprocess Ġ{ Ġif Ġ( klass . is Instance ( it )) Ġ{ ĊĠĠĠĠĠĠĠ Ġoperation ( it Ġas ĠT ) Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġ< T Ġ: ĠNode > ĠNode . collect ByType ( klass : ĠClass < T >): ĠList < T > Ġ{ ĊĠĠĠ Ġval Ġres Ġ= ĠLinkedList < T >() ĊĠĠĠ Ġthis . specific Process ( klass , Ġ{ Ġres . add ( it ) Ġ}) ĊĠĠĠ Ġreturn Ġres Ċ } Ċ Ċ fun ĠNode . process Consider ing Parent ( operation : Ġ( Node , ĠNode ?) Ġ-> ĠUnit , Ġparent : ĠNode ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġoperation ( this , Ġparent ) ĊĠĠĠ Ġthis . contain ment Properties . forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġp . get ( this ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( v ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Ġ-> Ġv . process Consider ing Parent ( operation , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCollection < *> Ġ-> Ġv . forEach Ġ{ Ġ( it Ġas ? ĠNode )?. process Consider ing Parent ( operation , Ġthis ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ val ĠNode . children : ĠList < Node > ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchildren Ġ= ĠLinkedList < Node >() ĊĠĠĠĠĠĠĠ Ġcontain ment Properties . forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġp . get ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( v ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Ġ-> Ġchildren . add ( v ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCollection < *> Ġ-> Ġv . forEach Ġ{ Ġif Ġ( it Ġis ĠNode ) Ġchildren . add ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġchildren . toList () ĊĠĠĠ Ġ} Ċ Ċ // ĠTODO Ġre implement Ġusing Ġtransform Children Ċ fun ĠNode . transform ( operation : Ġ( Node ) Ġ-> ĠNode , Ġin Place : ĠBoolean Ġ= Ġfalse ): ĠNode Ġ{ ĊĠĠĠ Ġif Ġ( in Place ) ĠTODO () ĊĠĠĠ Ġoperation ( this ) ĊĠĠĠ Ġval Ġchanges Ġ= ĠHashMap < String , ĠAny >() ĊĠĠĠ Ġrelevant Member Properties (). forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġp . get ( this ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( v ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġv . transform ( operation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newValue Ġ!= Ġv ) Ġchanges [ p . name ] Ġ= ĠnewValue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCollection < *> Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġv . map Ġ{ Ġif Ġ( it Ġis ĠNode ) Ġit . transform ( operation ) Ġelse Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newValue Ġ!= Ġv ) Ġchanges [ p . name ] Ġ= ĠnewValue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġvar Ġinstance To Transform Ġ= Ġthis ĊĠĠĠ Ġif Ġ(! changes . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconstructor Ġ= Ġthis . java Class . kotlin . primary Constructor !! ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠHashMap < K Parameter , ĠAny ?> () ĊĠĠĠĠĠĠĠ Ġconstructor . parameters . forEach Ġ{ Ġparam Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( changes . containsKey ( param . name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams [ param ] Ġ= Ġchanges [ param . name ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams [ param ] Ġ= Ġthis . java Class . kotlin . member Properties . find Ġ{ Ġparam . name Ġ== Ġit . name Ġ} !!. get ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinstance To Transform Ġ= Ġconstructor . call By ( params ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġoperation ( instance To Transform ) Ċ } Ċ Ċ class ĠImmutable Property Exception ( property : ĠK Property <* >, Ġnode : ĠNode ) Ġ: ĊĠĠĠ ĠRuntimeException (" Cannot Ġmutate Ġproperty Ġ'${ property . name }' Ġof Ġnode Ġ$ node Ġ( class : Ġ${ node . java Class . canonical Name }) ") Ċ Ċ fun ĠNode . transform Children ( operation : Ġ( Node ) Ġ-> ĠNode , Ġin Place : ĠBoolean Ġ= Ġfalse ): ĠNode Ġ{ ĊĠĠĠ Ġval Ġchanges Ġ= ĠHashMap < String , ĠAny >() ĊĠĠĠ Ġrelevant Member Properties (). forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġp . get ( this ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( v ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNode Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġoperation ( v ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newValue Ġ!= Ġv ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( in Place ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( p Ġis ĠK Mutable Property <* >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp . setter . call ( this , ĠnewValue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠImmutable Property Exception ( p , Ġv ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges [ p . name ] Ġ= ĠnewValue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCollection < *> Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( in Place ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( v Ġis ĠList <* >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġv . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelement Ġ= Ġv [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( element Ġis ĠNode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġoperation ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newValue Ġ!= Ġelement ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( v Ġis ĠMutable List <* >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( v Ġas ĠMutable List < Node >) [ i ] Ġ= ĠnewValue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠImmutable Property Exception ( p , Ġelement ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġv . map Ġ{ Ġif Ġ( it Ġis ĠNode ) Ġoperation ( it ) Ġelse Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( newValue Ġ!= Ġv ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanges [ p . name ] Ġ= ĠnewValue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġvar Ġinstance To Transform Ġ= Ġthis ĊĠĠĠ Ġif Ġ(! changes . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconstructor Ġ= Ġthis . java Class . kotlin . primary Constructor !! ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠHashMap < K Parameter , ĠAny ?> () ĊĠĠĠĠĠĠĠ Ġconstructor . parameters . forEach Ġ{ Ġparam Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( changes . containsKey ( param . name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams [ param ] Ġ= Ġchanges [ param . name ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams [ param ] Ġ= Ġthis . java Class . kotlin . member Properties . find Ġ{ Ġparam . name Ġ== Ġit . name Ġ} !!. get ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinstance To Transform Ġ= Ġconstructor . call By ( params ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġinstance To Transform Ċ } Ċ Ċ fun ĠNode . replace ( other : ĠNode ) Ġ{ ĊĠĠĠ Ġif Ġ( this . parent Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Parent Ġnot Ġset ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġthis . parent !!. transform Children ( in Place Ġ= Ġtrue , Ġoperation Ġ= Ġ{ Ġif Ġ( it Ġ== Ġthis ) Ġother Ġelse Ġit Ġ}) Ċ } Ċ