Using the book "Adaptive Object-Oriented Software: The Demeter
Method" with
the Java Programming Language and the Unified Modeling Language
and DemeterJ (formerly called Demeter/Java)
===============================================================

The book "Adaptive Object-Oriented Software: The Demeter
Method" (called the AP book)
introduces the concepts behind Adaptive Programming (AP).
At the time of the writing of the book, C++ was the language of
choice to write the sample programs in the book. Now we consider
Java a better choice.

Since the publication of the book, the conceptual structure of AP
has also improved and therefore we combine the power of Java
with the new form of adaptive programming into DemeterJ.

AP needs a graphical representation for class graphs. Because the
Booch, Rumbaugh and Jacobson notations are currently popular
and because they were integrated into the Unified Modeling
Language (UML), we use now the UML notation for class diagrams.

It is recommended that you read the rest of this document after you have
read the first four chapters of the AP book.

DemeterJ is a design notation for Java programs. In this
document we motivate the new notation and show how
to translate it into Java.

DemeterJ has its origin in Linda Seiter's thesis,
a paper by Seiter/Palsberg/Lieberherr and in Doug Orleans
implementation of several forms of visitor objects for Stklos
and for Java. DemeterJ is not only a design notation for Java
but it is also executable. 
DemeterJ is written 
as a DemeterJ program. Author: Doug Orleans and the Demeter team.

======================================
NAME CHANGES

The terminal classes have been renamed as follows:

C++                     Java
---                     ----
DemNumber               Integer
DemString               String
DemIdent                Ident
DemText                 Text
DemReal                 Double

Integer and String and Double are defined in package java.lang.
======================================


Introduction to the design/programming language DemeterJ

The important concepts added to the oo concepts are:
traversals, visitor classes and objects and class dictionaries.

Traversals are defined by traversal strategy graphs (strategies, for short).
A strategy defines navigational intent. It expresses a
high-level view for traversing a group of collaborating objects.
See chapters 1, 4 and 7 of the AP book.
A visitor object defines the code which will be called by
some traversal. Visitor objects are defined by visitor
classes. They are like ordinary classes but have 
additional methods such as before, after, around, init, return.

Strategies are like the sketch of a house, visitors
provide the most important details of the planned
house and class dictionaries provide all the structural details,
resulting in a finished house (executable program).

Traversals set up a framework for calling visitors and the
visitors themselves call back to the traversals.
During execution of the program there is a ping pong play 
between the traversals and visitors with the traversals
always starting the game.

Strategies are expressed in a similar way as in the AP book.
The stars have been deleted from the keywords.

Visitors consist 99% of Java code. When you write them
you may use all the features of Java. In the AP book, visitors
are expressed by wrappers. See pages 425/426 for a discussion
of the Visitor and Adaptive Visitor pattern.

Class dictionaries are essentially identical to the ones described in
the AP book, except that LL(k) class dictionaries for k>1
are now supported. There is additional syntax added so that you
can use classes defined in the Java libraries in your
class dictionaries. Also, the terminal classes have been
adapted to the Java predefined classes.

So how does DemeterJ differ from the design notation
used in the AP book? The most important difference is that
traversal specifications are now more general (and more efficient).
Also, wrappers have been replaced by visitors, although the wrapper
style of programming is also supported by DemeterJ as
syntactic sugar. Whenever you see
a wrapper in the AP book, think of it as a method
in some visitor. Prefix wrappers are mapped to before methods
and suffix wrappers are mapped to after methods.

Regarding the UML notation, we refer the reader to the
documents from Rational.

We need to learn the syntax of DemeterJ.
As a general rule, all Java code is between the symbols
(@ and @) or between {{ and }}.

The traversal notation has changed in that traversals are now
defined for a specific class, making the from part unnecessary in some
cases.
A simple "to Target" in class Source means "from Source to Target".
More importantly, the traversal specification notation has been
generalized and the implementation has been made exponentially better.
For the paper describing strategies and the compilation approach taken by 
DemeterJ, see:

ftp://ftp.ccs.neu.edu/pub/people/lieber/strategies.ps

An example of a traversal specification is:

Conglomerate {
  //define traversal method
  traversal allSalaries(SummationVisitor s) {
      bypassing -> *,subsidiaries,* 
    to Salary}
}

In the AP book, the notation

*from* Conglomerate
  *bypassing* -> *,subsidiaries,*
*to* Salary

is used.

The visitor notation defines a class with before, after, around,
return and init
methods. The implementation of the methods is given in Java.
The visitor methods specify incremental behavior
which has to be executed in addition to the traversals.

The structure of the visitor class is defined in the class dictionary.
An example is:

SummationVisitor = <total> Integer.

The total part is used to accumulate a total during the traversal.

The before and after methods are defined with
with a syntax as shown in the following example:

SummationVisitor {
  before Salary (@ 
    total = 
      new Integer(total.intValue() + host.get_v().intValue()); @)
}

Instantiation of a visitor object and using it with a traversal,
uses the standard Java syntax. Only visitor objects may be given
as arguments to traversal functions.

The following code creates a visitor object and 
passes it to a traversal function.

      // create a visitor of class
      // SummationVisitor = <total> Integer.
      // and set total to 0
      SummationVisitor s = new SummationVisitor(new Integer(0));
      // call traversal function
      // s modifies the behavior of the traversal
      this.allSalaries(s);
      return s.get_total().intValue(); }

For a complete example using the traversal allSalaries
and the SummationVisitor class, see the Conglomerate example
in the chapter tour below.

UML notation

The graphical syntax of the UML language is defined in
the documents by Rational Inc.
Here we show how the class graphs defined in the AP book
appear in the UML notation.
(All dashed lines should be solid lines.)

The reason why we switch from the Demeter class graph notation
to the UML notation is to avoid confusion. Many software
developers in industry are using a notation which is
a predecessor to UML and therefore similar to UML. 
Therefore, it is more useful for your COOP or regular job
to know UML.

construction class A
=====================================================

--------
|  A   |
--------

alternation class A
=====================================================

--------------
|<<abstract>>|
|     A      |
--------------

or, by using italics font for A.

--------
|  A   |
--------

visitor class A
=====================================================

--------------
|<<visitor>> |
|     A      |
--------------

repetition class
=====================================================

non-existent, is represented by cardinalities

There is no symbol for terminal classes in DemeterJ.
They only appear on the right side of an attribute.
All terminal classes must be buffered by a construction class.

construction edge from A to B with label x
=====================================================
Is represented by an association with navigation direction
(unless B is a terminal class).
Is represented by an association with a role name
and the multiplicity of the class of the role.

required

--------                   --------
|  A   |                1  |  B   |
|      | ----------------->|      |
--------                x  --------


optional


--------                   --------
|  A   |              0..1 |  B   |
|      | ----------------->|      |
--------                x  --------





if B is a terminal class, x is an attribute

-------------
|  A        |
-------------
|x:Integer |
-------------


alternation edge from B to A (B is the super class)
=====================================================


--------                   --------
|  A   | ----------------|>|  B   |
--------                   --------

The arrow |> is open, not filled. 

repetition edge
represented by an association with a role name
and the multiplicity of the class of the role.


required


--------                   --------
|  A   |              1..* |  B   |
|      | ----------------->|      |
--------                x  --------

In the AP book this is written as:
A = <x> List(B).
List(S) ~ S {S}.
B = .

optional


--------                   --------
|  A   |                *  |  B   |
|      | ----------------->|      |
--------                x  --------

In the AP book this is written as:
A = <x> List(B).
List(S) ~ {S}.
B = .

For further information on the class dictionary and UML
notation, see:

http://www.ccs.neu.edu/research/demeter/demeter-method/uml-syntax-discussion/uml-and-cds.txt


Motivation for replacing wrappers by visitors

For understanding the motivation,
we assume that you have read chapter 10 about transportation
patterns in the AP book.

DemeterJ programs which use visitor classes are longer than 
the corresponding Demeter/C++ versions. For example,
compare the behavioral part in the Conglomerate example
with Fig. 1.7 in the AP book.
But it may be worth the effort because of higher potential for reuse
and better modularity.
DemeterJ also supports the same style of inlining of visitors
as Demeter/C++.

For example, we can write:

    A{
      int CountCertainEs() do S {
       before E (@ return_val++; @)
      }
    }

Where S is a traversal strategy defined outside.

Working with visitors has an overhead:

In the AP book we wrote:

  *wrapper* A (@ do something; @)

With explicit visitor classes,
we have to define a visitor class in the class dictionary,
which has a part for each function argument needed by the wrapper.
The visitor class also needs a part for the return value and
for each transported object.
Then we have to instantiate the visitor class and give
the right arguments to the constructor.
Then we have to give the visitor as an argument to 
a traversal. And finally we have to write the equivalent
of the wrapper in terms of a method of the visitor class.
This requires now that we use "host" where we used "this"
before. 

So it is justified to ask what we gain with explicit visitors!

1. We gain Java affinity which is important. Visitor objects
   are just objects and traversal modification
   is just argument addition to a traversal method.
   This should make it easy for Java and C++ programmers
   to understand adaptive programs. 

2. We can build behavior modifications using the familiar principles
   of object-oriented programming: classes with parts and subclasses. 
   We may subclass visitor classes and have visitor objects
   nested in other visitor objects.

3. We get the potential of reuse of visitor objects, especially
   when Java supports a template mechanism so that we can
   do substituitions. We can build Java packages of
   visitor classes for specific domains.

4. We can compose visitor objects without the danger of
   name conflicts. Transportation pattern  composition concatenates
   the code which can lead to naming conflicts.


Edge visitors:

Adaptive programming extends object-oriented programming
with a traversal specification language and with an extension
to the concept of a class. The extended classes are called visitor classes.

A visitor class is like an ordinary class, except that it contains
additional code for other classes. This code comes in two forms:
a coarse-grained and a fine-grained form. The coarse-grained
form is about calling additional behavior when an object
is entered or left, independent how the object was reached.
The fine-grained form is about calling additional behavior
before an object is entered or left through a specific relationship.

The coarse-grained form is also called vertex visitors;
the fine-grained form is called edge visitors.

Edge visitors can be attached to construction edges.
An example of an edge visitor is the following powerful debug statement

before -> *,*,* (@ System.out.println(" going through edge from "
  + source.getClass().getName() + " to "
    + dest.getClass().getName() + " labeled "
      + edge); @)

When put into a visitor, and used with a traversal, it will report
in detail how the object is traversed. In the body of an edge
visitor, you can talk about the source object using "source",
about the destination object, using "dest" and even about the 
edge label using "edge".

A discussion of vertex and edge wrappers and their expressiveness is
in chapter 8.6 of the AP book.

Execution of edge wrappers is discussed in chapter 9 of the AP book.


Chapter tour 
==========================================

We go through the chapters and show the examples in the new
notation.

The Conglomerate example
(Chapters 1 and 3)

starts on page 11, Figure 1.7:

Conglomerate {
  (@
    int addSalaries() {
      // create a visitor of class
      // SummationVisitor = <total> Integer.
      // and set total to 0
      SummationVisitor s = new SummationVisitor(new Integer(0));
      // call traversal function
      // s modifies the behavior of the traversal
      this.allSalaries(s);
      return s.get_total().intValue(); }
  @)
  //define traversal function
  traversal allSalaries(SummationVisitor s) {
    to Salary;}
}

SummationVisitor {
  before Salary (@ 
    total = 
      new Integer(total.intValue() + host.get_v().intValue()); @)
}


Main {
(@
  static public void main(String args[]) throws Exception {
    Conglomerate c = Conglomerate.parse(System.in);

    int r = c.addSalaries();

    System.out.println("done" + " total salaries " + r); 
  }
@)
}

--------------------
Note: DemeterJ allows to write such programs more succinctly
by defining an init and return method for the SummationVisitor.
Then the addSalaries has a simple definition:

int addSalaries() = allSalaries(SummationVisitor);

The visitor will be instantiated automatically, initialized and the
result returned.
--------------------

The class dictionary:

Conglomerate = "Conglomerate" ":" <name>  Ident 
                "Head" "Office" ":" <head> Company .

Subsidiary : WhollyOwned | PartiallyOwned 
                *common* <company> Company.

WhollyOwned = "Wholly" "owned".
PartiallyOwned = "Partially"  "owned" "stake" "=" <stake> Integer.

Company = <name> String 
        "Registered" "Office" <location> Address 
        "Turnover" ":" <turnover> String 
        "Officers" ":" <officers> List(Employee)
        ["Other" "Employees" ":" <employees> List(Employee)]
          // List(Employee) is an instantiation
          // of parameterized class List defined below
        ["Subsidiaries"  "{" <subsidiaries> List(Subsidiary) "}" ]. 

Address = "Street" "-" <street > String
          "City" "-" <city> String
          "State" "-" <state> Ident
          "Country" "-" <country> Ident ".". 

Employee : Shareholding_Employee | Ordinary_Employee *common*
                "Name" "-" <name> String
                "Title" "-" <title>  String
                "Salary" "-" <salary> Salary "." .

Salary = <v> Integer.

Shareholding_Employee = "Shareholder" <share_percentage> Integer
                "percent" "control".

Ordinary_Employee  = "Ordinary".
List(S) ~ { S }.  // parameterized repetition class

SummationVisitor = <total> Integer.

Main = .


The generated Java program:
// this is a bit dated. To see the code generated by the current system,
// please run DemeterJ yourself on this example.

import demeter.*;
final class Conglomerate {
  private Ident name;
  public Ident get_name() { return name; }
  public Ident set_name(Ident name)
  { 
    Ident old_name = this.name;
    this.name = name;
    return old_name;
  }
  private Company head;
  public Company get_head() { return head; }
  public Company set_head(Company head)
  { 
    Company old_head = this.head;
    this.head = head;
    return old_head;
  }
  Conglomerate() { }
  public Conglomerate(Ident name , Company head )
  {
    super();
    set_name(name);
    set_head(head);
  }
  public static Conglomerate parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Conglomerate) p.parse(in, sym.Start_Conglomerate);
  }
  public static Conglomerate parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }

    int addSalaries() {
      // create a visitor of class
      // SummationVisitor = <total> Integer.
      // and set total to 0
      SummationVisitor s = new SummationVisitor(new Integer(0));
      // call traversal function
      // s modifies the behavior of the traversal
      this.allSalaries(s);
      return s.get_total().intValue(); }
    public void allSalaries( SummationVisitor s ) 
  {
    this.allSalaries_traverse(s);
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    head.allSalaries_traverse(s);
  }
}

abstract class Subsidiary {
  private Company company;
  public Company get_company() { return company; }
  public Company set_company(Company company)
  { 
    Company old_company = this.company;
    this.company = company;
    return old_company;
  }
  Subsidiary() { }
  public Subsidiary(Company company )
  {
    super();
    set_company(company);
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    company.allSalaries_traverse(s);
  }
}

final class WhollyOwned extends Subsidiary 
{
  WhollyOwned() { }
  public WhollyOwned(Company company )
  {
    super(company);
  }
  public static WhollyOwned parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (WhollyOwned) p.parse(in, sym.Start_WhollyOwned);
  }
  public static WhollyOwned parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
}

final class PartiallyOwned extends Subsidiary 
{
  private Integer stake;
  public Integer get_stake() { return stake; }
  public Integer set_stake(Integer stake)
  { 
    Integer old_stake = this.stake;
    this.stake = stake;
    return old_stake;
  }
  PartiallyOwned() { }
  public PartiallyOwned(Company company , Integer stake )
  {
    super(company);
    set_stake(stake);
  }
  public static PartiallyOwned parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (PartiallyOwned) p.parse(in, sym.Start_PartiallyOwned);
  }
  public static PartiallyOwned parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
}

final class Company {
  private String name;
  public String get_name() { return name; }
  public String set_name(String name)
  { 
    String old_name = this.name;
    this.name = name;
    return old_name;
  }
  private Address location;
  public Address get_location() { return location; }
  public Address set_location(Address location)
  { 
    Address old_location = this.location;
    this.location = location;
    return old_location;
  }
  private String turnover;
  public String get_turnover() { return turnover; }
  public String set_turnover(String turnover)
  { 
    String old_turnover = this.turnover;
    this.turnover = turnover;
    return old_turnover;
  }
  private Employee_List officers;
  public Employee_List get_officers() { return officers; }
  public Employee_List set_officers(Employee_List officers)
  { 
    Employee_List old_officers = this.officers;
    this.officers = officers;
    return old_officers;
  }
  private Employee_List employees;
  public Employee_List get_employees() { return employees; }
  public Employee_List set_employees(Employee_List employees)
  { 
    Employee_List old_employees = this.employees;
    this.employees = employees;
    return old_employees;
  }
  private Subsidiary_List subsidiaries;
  public Subsidiary_List get_subsidiaries() { return subsidiaries; }
  public Subsidiary_List set_subsidiaries(Subsidiary_List subsidiaries)
  { 
    Subsidiary_List old_subsidiaries = this.subsidiaries;
    this.subsidiaries = subsidiaries;
    return old_subsidiaries;
  }
  Company() { }
  public Company(String name , Address location , String turnover , Employee_List officers , Employee_List employees , Subsidiary_List subsidiaries )
  {
    super();
    set_name(name);
    set_location(location);
    set_turnover(turnover);
    set_officers(officers);
    set_employees(employees);
    set_subsidiaries(subsidiaries);
  }
  public static Company parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Company) p.parse(in, sym.Start_Company);
  }
  public static Company parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    officers.allSalaries_traverse(s);
    if (employees != null)
      employees.allSalaries_traverse(s);
    if (subsidiaries != null)
      subsidiaries.allSalaries_traverse(s);
  }
}

final class Address {
  private String street;
  public String get_street() { return street; }
  public String set_street(String street)
  { 
    String old_street = this.street;
    this.street = street;
    return old_street;
  }
  private String city;
  public String get_city() { return city; }
  public String set_city(String city)
  { 
    String old_city = this.city;
    this.city = city;
    return old_city;
  }
  private Ident state;
  public Ident get_state() { return state; }
  public Ident set_state(Ident state)
  { 
    Ident old_state = this.state;
    this.state = state;
    return old_state;
  }
  private Ident country;
  public Ident get_country() { return country; }
  public Ident set_country(Ident country)
  { 
    Ident old_country = this.country;
    this.country = country;
    return old_country;
  }
  Address() { }
  public Address(String street , String city , Ident state , Ident country )
  {
    super();
    set_street(street);
    set_city(city);
    set_state(state);
    set_country(country);
  }
  public static Address parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Address) p.parse(in, sym.Start_Address);
  }
  public static Address parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
}

abstract class Employee {
  private String name;
  public String get_name() { return name; }
  public String set_name(String name)
  { 
    String old_name = this.name;
    this.name = name;
    return old_name;
  }
  private String title;
  public String get_title() { return title; }
  public String set_title(String title)
  { 
    String old_title = this.title;
    this.title = title;
    return old_title;
  }
  private Salary salary;
  public Salary get_salary() { return salary; }
  public Salary set_salary(Salary salary)
  { 
    Salary old_salary = this.salary;
    this.salary = salary;
    return old_salary;
  }
  Employee() { }
  public Employee(String name , String title , Salary salary )
  {
    super();
    set_name(name);
    set_title(title);
    set_salary(salary);
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    salary.allSalaries_traverse(s);
  }
}

final class Salary {
  private Integer v;
  public Integer get_v() { return v; }
  public Integer set_v(Integer v)
  { 
    Integer old_v = this.v;
    this.v = v;
    return old_v;
  }
  Salary() { }
  public Salary(Integer v )
  {
    super();
    set_v(v);
  }
  public static Salary parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Salary) p.parse(in, sym.Start_Salary);
  }
  public static Salary parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    s.before(this);
  }
}

final class Shareholding_Employee extends Employee 
{
  private Integer share_percentage;
  public Integer get_share_percentage() { return share_percentage; }
  public Integer set_share_percentage(Integer share_percentage)
  { 
    Integer old_share_percentage = this.share_percentage;
    this.share_percentage = share_percentage;
    return old_share_percentage;
  }
  Shareholding_Employee() { }
  public Shareholding_Employee(String name , String title , Salary salary , Integer share_percentage )
  {
    super(name, title, salary);
    set_share_percentage(share_percentage);
  }
  public static Shareholding_Employee parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Shareholding_Employee) p.parse(in, sym.Start_Shareholding_Employee);
  }
  public static Shareholding_Employee parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
}

final class Ordinary_Employee extends Employee 
{
  Ordinary_Employee() { }
  public Ordinary_Employee(String name , String title , Salary salary )
  {
    super(name, title, salary);
  }
  public static Ordinary_Employee parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Ordinary_Employee) p.parse(in, sym.Start_Ordinary_Employee);
  }
  public static Ordinary_Employee parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
}

final class SummationVisitor {
  private Integer total;
  public Integer get_total() { return total; }
  public Integer set_total(Integer total)
  { 
    Integer old_total = this.total;
    this.total = total;
    return old_total;
  }
  SummationVisitor() { }
  public SummationVisitor(Integer total )
  {
    super();
    set_total(total);
  }
  public static SummationVisitor parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (SummationVisitor) p.parse(in, sym.Start_SummationVisitor);
  }
  public static SummationVisitor parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void before(Salary host) { 
    total = 
      new Integer(total.intValue() + host.get_v().intValue()); }
}

final class Main {
  public Main()
  {
    super();
  }
  public static Main parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Main) p.parse(in, sym.Start_Main);
  }
  public static Main parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }

  static public void main(String args[]) throws Exception {
    Conglomerate c = Conglomerate.parse(System.in);

    int r = c.addSalaries();

    System.out.println("done" + " total salaries " + r); 
  }
}

final class Employee_List {
  private Nonempty_Employee_List first;
  public Nonempty_Employee_List get_first() { return first; }
  public Nonempty_Employee_List set_first(Nonempty_Employee_List first)
  { 
    Nonempty_Employee_List old_first = this.first;
    this.first = first;
    return old_first;
  }
  Employee_List() { }
  public Employee_List(Nonempty_Employee_List first )
  {
    super();
    set_first(first);
  }
  public static Employee_List parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Employee_List) p.parse(in, sym.Start_Employee_List);
  }
  public static Employee_List parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    if (first != null)
      first.allSalaries_traverse(s);
  }
}

final class Subsidiary_List {
  private Nonempty_Subsidiary_List first;
  public Nonempty_Subsidiary_List get_first() { return first; }
  public Nonempty_Subsidiary_List set_first(Nonempty_Subsidiary_List first)
  { 
    Nonempty_Subsidiary_List old_first = this.first;
    this.first = first;
    return old_first;
  }
  Subsidiary_List() { }
  public Subsidiary_List(Nonempty_Subsidiary_List first )
  {
    super();
    set_first(first);
  }
  public static Subsidiary_List parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Subsidiary_List) p.parse(in, sym.Start_Subsidiary_List);
  }
  public static Subsidiary_List parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    if (first != null)
      first.allSalaries_traverse(s);
  }
}

final class Nonempty_Employee_List {
  private Employee it;
  public Employee get_it() { return it; }
  public Employee set_it(Employee it)
  { 
    Employee old_it = this.it;
    this.it = it;
    return old_it;
  }
  private Nonempty_Employee_List next;
  public Nonempty_Employee_List get_next() { return next; }
  public Nonempty_Employee_List set_next(Nonempty_Employee_List next)
  { 
    Nonempty_Employee_List old_next = this.next;
    this.next = next;
    return old_next;
  }
  Nonempty_Employee_List() { }
  public Nonempty_Employee_List(Employee it , Nonempty_Employee_List next )
  {
    super();
    set_it(it);
    set_next(next);
  }
  public static Nonempty_Employee_List parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Nonempty_Employee_List) p.parse(in, sym.Start_Nonempty_Employee_List);
  }
  public static Nonempty_Employee_List parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    it.allSalaries_traverse(s);
    if (next != null)
      next.allSalaries_traverse(s);
  }
}

final class Nonempty_Subsidiary_List {
  private Subsidiary it;
  public Subsidiary get_it() { return it; }
  public Subsidiary set_it(Subsidiary it)
  { 
    Subsidiary old_it = this.it;
    this.it = it;
    return old_it;
  }
  private Nonempty_Subsidiary_List next;
  public Nonempty_Subsidiary_List get_next() { return next; }
  public Nonempty_Subsidiary_List set_next(Nonempty_Subsidiary_List next)
  { 
    Nonempty_Subsidiary_List old_next = this.next;
    this.next = next;
    return old_next;
  }
  Nonempty_Subsidiary_List() { }
  public Nonempty_Subsidiary_List(Subsidiary it , Nonempty_Subsidiary_List next )
  {
    super();
    set_it(it);
    set_next(next);
  }
  public static Nonempty_Subsidiary_List parse(java.io.InputStream in)
    throws Exception
  {
    parser p = new parser();
    return (Nonempty_Subsidiary_List) p.parse(in, sym.Start_Nonempty_Subsidiary_List);
  }
  public static Nonempty_Subsidiary_List parse(String str)
    throws Exception
  {
    return parse(new java.io.StringBufferInputStream(str));
  }
  public void allSalaries_traverse ( SummationVisitor s ) 
  {
    it.allSalaries_traverse(s);
    if (next != null)
      next.allSalaries_traverse(s);
  }
}

The input:

Conglomerate : TransGlobal
        Head Office : "TransGlobal Illumination"
        Registered Office
                Street - "23 Rue du Lac" City - "Geneva"
                State - GE Country - Switzerland.
        Turnover : "4bn" 
        Officers :
                Shareholder 60 percent control
                Name - "Karl Soller"
                Title - "Chief Executive Officer and President"
                Salary - 200000 .

                Shareholder 30 percent control

                Name - "Jim Miller"
                Title - "Chief Financial Officer" Salary - 150000 .

                Ordinary
                Name - "Guy Jenny"
                Title - "Secretary" Salary - 100000 .
        Subsidiaries {
                Wholly owned "TransGlobal Adventures"
                Registered Office       
                        Street - "12 Borisinsky Way"
                        City - "Moscow" State - Russia
                        Country - USSR .
                Turnover : "2bn"
                Officers :
                        Shareholder 80 percent control
                        Name - "Boris Kasparov"
                        Title - "Chief Executive Officer"
                        Salary - 200000 .

                        Shareholder 5 percent control
                        Name - "Ivan Spassky"
                        Title - "President" Salary - 150000 .

                        Ordinary
                        Name - "Georg Giezendanner"
                        Title - "Secretary" Salary - 100000 .
                        }


// solves triples problem (simplified) from page 322 of my book
Company {
  traversal allProducers(
    SameLocationV slv,
    CustomerTV ctv,
    ProducerTV ptv
    ){
    to Producer;}

// allProducers
// Host/Visitor interaction
//		slv		ctv		ptv
//          -----------------------------------------
//  before			?,!ctv
//Customer		
//Item	 			
//  after	?ctv,?ptv
//  before					?,!ptv
//Producer	
//          -----------------------------------------
//Legend:
//  ?		read from host
//  ?ctv	read from visitor ctv
//  !		write to host
//  !ctv	write to visitor ctv

  (@
  // finds items for which customer and producer live
  // in the same location
  void same_location() {
    CustomerTV ctv = new CustomerTV();
    ProducerTV ptv = new ProducerTV();
    SameLocationV slv = new SameLocationV(ctv,ptv);
    this.allProducers(slv, ctv, ptv);
  } @) }
// customer transportation visitor
CustomerTV {
  before Customer (@
    name = host.get_name();
    location = host.get_location();
  @) }
// producer transportation visitor
ProducerTV {
  before Producer (@
    name = host.get_name();
    location = host.get_location();
  @) }
SameLocationV {
  after Item (@
    if (ctv.get_location().equals(ptv.get_location())) {
      System.out.println(
	" ctv= " +  ctv.get_name() + 
	" ptv= " +  ptv.get_name() + 
	" current item= " + host.get_name()); 
    }
  @) }


Main {
(@
  static public void main(String args[]) throws Exception {

    Runtime rt = Runtime.getRuntime();
    rt.traceMethodCalls(true);

    Company a = Company.parse(System.in);

    a.same_location();

    System.out.println("done ");
  }
@)
}
// simplified cd for Triples transportation pattern example
// pages 320-325 in AP book.
Company = <customers> List(Customer).
Customer = "customer"
  <orders> List(Item)
  <name> String
  <location> String.
Item = "item"
  <made_by> Producer
  <name> String.
Producer = "producer"
  <name> String
  <location> String.
List(S) ~  {S} .

CustomerTV = 
  <name> String
  <location> String.
ProducerTV = 
  <name> String
  <location> String.
SameLocationV =
  <ctv> CustomerTV
  <ptv> ProducerTV.

Main = .
customer
  item
     producer
     "Novartis"
     "Basel"
   "xyz1"
  "Huber"
  "Basel"
customer
  item
     producer
     "Novartis"
     "Basel"
   "xyz2"
  "Huber"
  "Geneva"
customer
  item
    producer
      "Novartis"
      "Basel"
  "xyz3"
  item
    producer
      "NovartisB"
      "Basel"
  "xyz4"
"HuberB"
"Basel"



/proj/asl/lieber/java/java-envs/j-triples