/**
 * This example is adapted from an example in: 
 * 
 * J. Eifrig, S. Smith, V. Trifonov, 
 * Sound Polymorphic Type Inference for Objects, OOPSLA 1995, pp. 169-184. 
 *
 * http://www.cs.jhu.edu/labs/pll/constraints/#7
 */

interface Operation
{
  void apply(View v);
}

class View
{
  View dep;

  public void doall(Operation f) {
    f.apply(this);
    if (dep != null) 
      dep.doall(f);
  }

  public void setDep(View v) {
    dep = v;
  }
}

class GView extends View
{
  public void draw() {
    // ...
  }
}

class DrawOperation implements Operation
{
  public void apply(View v) {
    ((GView)v).draw();
  }
}

class OPSLA95 
{
  public static void main(String[] args) {
    View v1 = new View();
    View g1 = new GView();
    View g2 = new GView();
    View g3 = new GView();

    g1.setDep(v1);
    g2.setDep(g3);
    g2.doall(new DrawOperation());
  }
}