class ExtendedFactoryOuter extends FactoryOuter {

  public ExtendedFactoryOuter(int x) { super(x); }

  public void addExtendedInner(int y) {
    if (lastIndex < fi.length) {
      fi[lastIndex++] = new ExtendedFactoryInner(y);
    } 
    else throw new RuntimeException("FactoryInner array full");
  }

  public void addDirectlyExtendedInner(int y) {
    if (lastIndex < fi.length) {
      fi[lastIndex++] = new DirectlyExtendedFactoryInner(this, y);
    } 
    else throw new RuntimeException("FactoryInner array full");
  }

  public class ExtendedFactoryInner extends FactoryInner {

    public ExtendedFactoryInner(int y) { super(y); }

    public void display() {
      System.out.println("ExtendedFactoryInner x =  " + getX());
    }
  }

}

class DirectlyExtendedFactoryInner extends FactoryOuter.FactoryInner {

  FactoryOuter owner;

  //public DirectlyExtendedFactoryInner (int y) { super(y); } // won't work

  public DirectlyExtendedFactoryInner (FactoryOuter owner, int y) { owner.super(y); this.owner = owner; }
  
  public void display() {
    System.out.println("DirectlyExtendedFactoryInner x =  " + owner.getX());
  }

}

public class InnerClassInheritance {
  public static void main(String[] args) {
    ExtendedFactoryOuter efo = new ExtendedFactoryOuter(1);

    //efo.addInner(101); System.out.println(101);
    efo.addInner(102); System.out.println(101);
    efo.addExtendedInner(103); System.out.println(103);
    efo.addDirectlyExtendedInner(104); System.out.println(104);
    efo.list();
  }
}