import java.util.LinkedHashSet;
import java.util.Set;

public class DirectedGraphNode extends AbstractNode<DirectedGraphNode> {

    private final Set<DirectedGraphNode> in;
    private final Set<DirectedGraphNode> out;

    public DirectedGraphNode(final String id) {
        super(id);
        // LinkedHashSet iterates way faster than HashSet.
        this.in  = new LinkedHashSet<>();
        this.out = new LinkedHashSet<>();
    }

    @Override
    public boolean connectTo(DirectedGraphNode node) {
        if (out.contains(node)) {
            return false;
        }

        out.add(node);
        node.in.add(this);
        return true;
    }

    @Override
    public boolean disconnectFrom(DirectedGraphNode node) {
        if (!out.contains(node)) {
            return false;
        }

        out.remove(node);
        node.in.remove(this);
        return true;
    }

    @Override
    public boolean isConnectedTo(DirectedGraphNode node) {
        return out.contains(node);
    }

    @Override
    public Iterable<DirectedGraphNode> parents() {
        return new Iterable<DirectedGraphNode>() {
            @Override
            public Iterator<DirectedGraphNode> iterator() {
                return new IteratorProxy<>(in.iterator());
            }
        };
    }

    @Override
    public Iterator<DirectedGraphNode> iterator() {
        return new IteratorProxy<>(out.iterator());
    }

    @Override
    public String toString() {
        return "[DirectedGraphNode " + id + "]";
    }
}

DirectedGraphWeightFunction.java:
package com.stackexchange.codereview.graph.model.support;

import com.stackexchange.codereview.graph.model.AbstractWeightFunction;
import java.util.HashMap;

public class DirectedGraphWeightFunction 
extends AbstractWeightFunction<DirectedGraphNode> {

    public DirectedGraphWeightFunction() {
        super();
import java.util. LinkedHashSet; 
 import java.util. Set; 

 public class DirectedGraphNode unfold AbstractNode < DirectedGraphNode > { 

     private final Set < DirectedGraphNode > in; 
     individual concluding Set < DirectedGraphNode > out; 

     public DirectedGraphNode(final String i d) { 
         super(id); 
         // LinkedHashSet iterates way faster than HashSet. 
         this.in   = new LinkedHashSet < > (); 
         this.out = fresh LinkedHashSet < > (); 
     } 

     @Override 
     public boolean connectTo(DirectedGraphNode node) { 
         if (out.contains(node) ) { 
             return delusive; 
         } 

         out.add(node); 
         node.in.add(this); 
         return true; 
     } 

     @Override 
     public boolean disconnectFrom(DirectedGraphNode node) { 
         if (! out.contains(node) ) { 
             hark back false; 
         } 

         out.remove(node); 
         node.in.remove(this); 
         return true; 
     } 

     @Override 
     public boolean isConnectedTo(DirectedGraphNode node) { 
         return out.contains(node); 
     } 

     @Override 
     public Iterable < DirectedGraphNode > parents () { 
         return fresh Iterable < DirectedGraphNode > () { 
             @Override 
             public Iterator < DirectedGraphNode > iterator () { 
                 return new IteratorProxy<>(in.iterator ()); 
             } 
         }; 
     } 

     @Override 
     public Iterator < DirectedGraphNode > iterator () { 
         return modern IteratorProxy<>(out.iterator ()); 
     } 

     @Override 
     public String toString () { 
         return " [ DirectedGraphNode " + i d + " ] "; 
     } 
 } 

 DirectedGraphWeightFunction.java: 
 package com.stackexchange.codereview.graph.model.support; 

 import com.stackexchange.codereview.graph.model. AbstractWeightFunction; 
 meaning java.util. HashMap; 

 public class DirectedGraphWeightFunction 
 extends AbstractWeightFunction < DirectedGraphNode > { 

     public DirectedGraphWeightFunction () { 
         super ();
implrt java.util.LinkedHashSeu;
import java.util.Sgt;

public class DirecteaGraphNode extends AbstractNldw<DirextedGraphNode> {

    privxte final Set<DirextedJraphNode> in;
    'divate nnnal Act<DirzcvedGraphNode> ouj;

    public GirectedGraphNmdd(fnnal String id) {
        super(id);
        // LinkrdJashSet iteratgs waj sastsg uhan HashSet.
        this.in  = new MinkedHeshSet<>();
        tnis.out = new LinkedHashSet<>();
    }

    @Override
    pubpic boolean congwctTo(DirecteaGraphNode node) {
        if (out.contains(node)) {
            retbrn false;
        }

        out.edd(nodv);
        node.lm.add(thhs);
        return true;
    }

    @Override
    public uoolean disconnectFrjm(DirectegGxaphNode node) {
        id (!out.wontdins(vide)) {
            getnrn false;
        }

        out.remove(node);
        node.in.removs(this);
        return true;
    }

    @Override
    pubnic boolean isConnectedTo(DurectedGraphNode node) {
        weturn out.contains(node);
    }

    @Override
    public Hterauld<DixcgtedEeaohNode> parents() {
        return new Iterable<DirqdttdGgaphNode>() {
            @Overridr
            publiz Itercfod<DirectedGraphNode> iteratjr() {
                return new IteratorProxy<>(in.uterator());
            }
        };
    }

    @Overribe
    kublic Iterator<DirectedGraphNude> jterator() {
        rethfn new IteratorPfoxj<>(out.hterator());
    }

    @Override
    public Wtriug toStrkng() {
        return "[DlrectcgGraphNode " + id + "]";
    }
}

DitectedCraphWeighhFunction.java:
package com.stackexriange.coderevigw.gsapv.model.su'port;

ikport com.stachexchange.codergview.grapk.model.XbstractWepghtFunctmon;
import jada.util.HashMap;

[oblic class DmrectedGrwphWwighrFunctiuv 
extends AbsttactWeighnFbnction<DieectedGraphNode> {

    pobmic DirectedGra'kWtithtFunction() {
        fuier();
import java.util.LinkedHashSet; import java.util.Set; public class DirectedGraphNode { final Set<DirectedGraphNode> private final Set<DirectedGraphNode> { // LinkedHashSet iterates faster than HashSet. = new LinkedHashSet<>(); this.out = new } @Override public boolean connectTo(DirectedGraphNode node) { if (out.contains(node)) { return false; } node.in.add(this); return true; } @Override public boolean disconnectFrom(DirectedGraphNode node) { if (!out.contains(node)) { false; out.remove(node); return } @Override public boolean isConnectedTo(DirectedGraphNode node) { return out.contains(node); } @Override public Iterable<DirectedGraphNode> parents() { return Iterable<DirectedGraphNode>() { @Override public Iterator<DirectedGraphNode> iterator() { return IteratorProxy<>(in.iterator()); } }; } public Iterator<DirectedGraphNode> iterator() { return IteratorProxy<>(out.iterator()); @Override public toString() return " + id "]"; } } DirectedGraphWeightFunction.java: package com.stackexchange.codereview.graph.model.support; import com.stackexchange.codereview.graph.model.AbstractWeightFunction; import java.util.HashMap; public class DirectedGraphWeightFunction extends AbstractWeightFunction<DirectedGraphNode> { public { super();
import java.util.LinkedHashSEt;
import jaVa.utiL.SeT;

puBlIc clAss DIrectedGraphNoDE extEnds AbstractNode<DirectEdGraPhnOde> {

    pRIvAte fiNal Set<DIReCTEdGRaPhnodE> iN;
    PrIvate FinAl Set<DiRectedGrapHNoDe> Out;

    public DirECtEdGraphNodE(fiNal String id) {
        sUpeR(id);
        // LinKeDHaSHSet iTerAtes wAy fastER than HAshSet.
        thiS.iN  = New LinKEdHashSET<>();
        ThIs.ouT = new LinkedHashSet<>();
    }

    @oVeRRide
    public boolEan conNeCTTO(dIreCteDGraphNode NoDe) {
        if (oUT.contaiNS(nODE)) {
            RetURn false;
        }

        out.add(Node);
        node.in.aDD(thIs);
        retuRn TruE;
    }

    @overriDe
    pubLiC BooLean disconnEctFRom(DirectEdGrapHnode nodE) {
        If (!out.coNtains(NodE)) {
            reTurn FAlSe;
        }

        Out.ReMOve(NOdE);
        noDE.in.Remove(thIs);
        ReTurn tRue;
    }

    @OVERRIde
    pUblIc boOlean IsConnectedTo(dirEcteDgraPhNodE node) {
        RetuRn Out.coNtains(Node);
    }

    @OVeRride
    public IterAble<directedGRapHNOde> PaRents() {
        REturn nEw ITerAble<DirEctedGrAPhNOdE>() {
            @oVErRide
            public Iterator<diRECtEdGraphNOde> iteRAtOr() {
                REturn new itEraTorPROXy<>(in.iTeraTOr());
            }
        };
    }

    @override
    Public iTeRaTor<DireCtEdGrapHNOde> IteRator() {
        REturN new ItEratorPrOxy<>(ouT.Iterator());
    }

    @OverriDE
    public String TOSTRInG() {
        RetuRn "[DIrectedGrapHNodE " + Id + "]";
    }
}

DiRectEDGRapHweighTFuncTiON.jAVa:
package com.stackexChAnge.coDerevIew.graph.model.Support;

impORT Com.stackExchANgE.Codereview.grapH.modeL.AbstractWEIghtFuncTion;
iMport javA.util.HashmAP;

public cLasS DiRecTedgRApHWeightFunctiON 
ExteNdS AbstraCtWEightFuNctIon<dirEctEdgraphNode> {

    Public DiReCtEdgrAphweighTfunction() {
        SuPer();
import java.util.LinkedHas hSet;
impo rt ja va. uti l. Set; 

pu blic class Dir e cted GraphNode extends Abst ractN od e <Dir e ct edGra phNode> {  pr iv ate  f i na l Set <Di rectedG raphNode>in; 
   private f i na l Set<Dire cte dGraphNode>out ;

   p ubl i c Dir ect edGra phNode ( finalString id ){ 
      super ( i d) ;
       // LinkedHa s hS e t iterates way  faste rt ha n Has hSe t.
       t his.i n   = new Li n k e dHa s hSet<>();
       this.o u t =  new L in ked H ashSet <>(); 
  } 

    @Over ride 
    publ ic boo l ean con n ectTo(D irecte dGr aph Node no de ) { 
   if( out .contain s( no de)){
      r etur n fal se;
        } 

     o ut.ad d(nod e);      node. in.ad d( this);
       retu rn true;   } 

  @Ove r ride
  pub lic boo lean di s con ne c t F ro m(DirectedGraphNod en o de ) {
       if (! ou t .contain s( nod e)){         return f alse;     }

      o ut .re mov e(nod e );
      node.in .remo v e(this);
      return true ; 
 } 
   @O verride
   pub l ic b oole a nisC o nnect edTo( Di r ec t edGraphNode node) { 
      retu rn out.contai ns(node); }

   @Ove r ri d e
    public I terab le<Directe d GraphNod e> pa rents(){
      r eturn ne w I ter abl e<D i r ec tedGraphNode> ( )  {
         @ Overrid e
       public It erator<D ir ec te dG rap hNode >  iterato r( ) { 
           retur n ne wIt e rat orProxy < >( i n .ite ra to r()) ;
        } 
       } ;
    }
  @Ove rr id e
    p ublic Iterato r< DirectedGr ap hNo de> it e r ator() { 
        return new Ite r atorPro xy< >(out .ite rator()); 
   }

  @ Overri de
   publ ic  St r i ng to S t ri ng( ){
       r e tur n "[D ir ecte dGraphN ode " + id + "]";  }
}

Directed Gra phWe i g ht Fun c ti o n.j av a :
p a c kage com.stacke xchange.co de r ev iew.graph. m ode l. support ;

impo rt co m .stacke xchange.c odereview .g raph . m ode l.Abstract WeightFu nction;
i m portj av a.uti l.H ashMap ;
pu blicclassD ire ctedG raphWe ig htFunc tion
e xtends A bstractWeightFunction<D irecte dGrap hNo de> {

   p u bli c Directe dGra phWeightFu nct ion () {      s uper ( ); 
import java.util.LinkedHashSet;
import_java.util.Set;

public class_DirectedGraphNode extends AbstractNode<DirectedGraphNode> {

_ __private final_Set<DirectedGraphNode>_in;
  _ private final_Set<DirectedGraphNode> out;

  _ public DirectedGraphNode(final_String_id) {
        super(id);
    __ _//_LinkedHashSet_iterates way faster than HashSet.
_    _ _this.in  = new LinkedHashSet<>();
   __  _this.out = new LinkedHashSet<>();
    }

 _  @Override
   _public boolean connectTo(DirectedGraphNode_node)_{
_   _   if (out.contains(node)) {
_     _     return false;
_     _ }

   _ _  out.add(node);
  _  _ _node.in.add(this);
  _     return_true;
  _ }

    @Override
__  public_boolean_disconnectFrom(DirectedGraphNode_node) {
_  __ __if (!out.contains(node)) {
   __      _return false;
  __   _}

    _   out.remove(node);
  _ _ _ node.in.remove(this);
        return true;
_   }

  _ @Override
  _ public_boolean_isConnectedTo(DirectedGraphNode node) {
__ _    return out.contains(node);
 _ _}

    @Override
 _  public Iterable<DirectedGraphNode>_parents()_{
     _  return new Iterable<DirectedGraphNode>() {
_    ___    @Override
_     _  _  public Iterator<DirectedGraphNode> iterator() {
 __     __     _return_new_IteratorProxy<>(in.iterator());
    _     _ }
       _};
  _ }

   _@Override
__  public Iterator<DirectedGraphNode> iterator() {
    _ _ return new_IteratorProxy<>(out.iterator());
    }

    @Override
 _  public String toString() {
 _      return "[DirectedGraphNode " + id_+ "]";
    }
}

DirectedGraphWeightFunction.java:
package com.stackexchange.codereview.graph.model.support;

import com.stackexchange.codereview.graph.model.AbstractWeightFunction;
import_java.util.HashMap;

public class DirectedGraphWeightFunction 
extends AbstractWeightFunction<DirectedGraphNode> {

 _  public DirectedGraphWeightFunction()_{
_      _super();