public class Process implements CSProcess
{
  private ChannelOutput verhoog;
  private ChannelOutput prolaag;
 
  public Process(ChannelOutput verhoog, ChannelOutput prolaag)
  {
    super();
    this.verhoog = verhoog;
    this.prolaag = prolaag;
  }
 
  public void run()
  {
    this.prolaag.write(null);
    // critical section
    this.verhoog.write(null);
  }
} 
public class Semaphore implements CSProcess
{
  private int value;
  private AltingChannelInput verhoog;
  private AltingChannelInput prolaag;
 
  public Semaphore(int value, AltingChannelInput verhoog, AltingChannelInput prolaag)
  {
    super();
    this.value = value;
    this.verhoog = verhoog;
    this.prolaag = prolaag;
  }
 
  public void run()
  {
    final int ALTERNATIVES = 2;
    final int V = 0;
    final int P = 1;
    final Guard[] guard = new Guard[ALTERNATIVES];
    guard[V] = this.verhoog;
    guard[P] = this.prolaag;
    final boolean[] precondition = new boolean[ALTERNATIVES];
    precondition[V] = true;
    final Alternative alternative = new Alternative(guard);
    while (true)
    {
      precondition[P] = this.value > 0;
      switch (alternative.select(precondition))
      {
        case V:
          this.verhoog.read(); 
          this.value++;
          break;
        case P:
          this.prolaag.read(); 
          this.value--;
          break;
      }
    }
  }
}
public class Main
{
  public static void main(String[] args)
  {
    Any2OneChannel verhoog = Channel.any2one();
    Any2OneChannel prolaag = Channel.any2one();
    Semaphore semaphore = new Semaphore(1, verhoog.in(), prolaag.in());
    Process one = new Process(verhoog.out(), prolaag.out());
    Process two = new Process(verhoog.out(), prolaag.out());
    CSProcess[] process = { semaphore, one, two };
    Parallel parallel = new Parallel(process);
    parallel.run();
  }
}