// evaluate the current value of the arithmetic tree
  protected final void compute() {
    // get resulting list of ExpressionNodes
    ExpressionValue evlist = root.evaluate();
    MyList myList = (evlist instanceof MyList) ? (MyList) evlist : ((GeoList) evlist).getMyList();

    int evalListSize = myList.size();
    int cachedListSize = list.getCacheSize();

    list.clear();
    for (int i = 0; i < evalListSize; i++) {
      ExpressionValue element = myList.getListElement(i).evaluate();
      GeoElement geo = null;

      // number result
      if (element.isNumberValue()) {
        double val = ((NumberValue) element).getDouble();

        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a number: set value
          if (cachedGeo.isGeoNumeric()) {
            ((GeoNumeric) cachedGeo).setValue(val);
            geo = cachedGeo;
          }
        }

        // no cached number: create new one
        if (geo == null) {
          geo = new GeoNumeric(cons, val);
        }

        // add number to list
        list.add(geo);
      }

      // point
      else if (element.isVectorValue()) {
        GeoVec2D vec = ((VectorValue) element).getVector();

        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoPoint()) {
            ((GeoPoint) cachedGeo).setCoords(vec);
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoPoint point = new GeoPoint(cons);
          point.setCoords(vec);
          geo = point;
        }

        // add point to list
        list.add(geo);
      }

      // needed for matrix multiplication
      // eg {{1,3,5},{2,4,6}}*{{11,14},{12,15},{13,a}}
      else if (element instanceof MyList) {
        MyList myList2 = (MyList) element;
        GeoList list2 = new GeoList(cons);
        list2.clear();

        /* removed Michael Borcherds 20080602
         * bug: 9PointCubic.ggb (matrix multiplication)
        // try to use cached element of  type GeoList
        GeoList list2 = null;
        if (i < cachedListSize) {
        	GeoElement cachedGeo = list.getCached(i);

        	// the cached element is a number: set value
        	if (cachedGeo.isGeoList()) {
        		list2 = (GeoList) cachedGeo;
        	}
        }

        if (list2 == null) {
        	list2 = new GeoList(cons);
        } */

        for (int j = 0; j < myList2.size(); j++) {
          ExpressionValue en = myList2.getListElement(j);
          ExpressionValue ev = en.evaluate();

          if (ev instanceof MyDouble) {
            GeoNumeric geo2 = new GeoNumeric(cons);
            geo2.setValue(((NumberValue) ev).getDouble());
            list2.add(geo2);
          }
        }

        list.add(list2);
      } else if (element instanceof MyStringBuffer) {
        MyStringBuffer str = (MyStringBuffer) element;
        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoText()) {
            ((GeoText) cachedGeo).setTextString(str.toValueString());
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoText text = new GeoText(cons);
          text.setTextString(str.toValueString());
          geo = text;
        }

        // add point to list
        list.add(geo);
      } else if (element instanceof MyBoolean) {
        MyBoolean bool = (MyBoolean) element;
        // try to use cached element of same type
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoBoolean()) {
            ((GeoBoolean) cachedGeo).setValue(bool.getBoolean());
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoBoolean geoBool = new GeoBoolean(cons);
          geoBool.setValue(bool.getBoolean());
          geo = geoBool;
        }

        // add point to list
        list.add(geo);
      } else if (element instanceof GeoFunction) {
        GeoFunction fun = (GeoFunction) element;
        if (i < cachedListSize) {
          GeoElement cachedGeo = list.getCached(i);

          // the cached element is a point: set value
          if (cachedGeo.isGeoFunction()) {
            ((GeoFunction) cachedGeo).set(fun);
            geo = cachedGeo;
          }
        }

        // no cached point: create new one
        if (geo == null) {
          GeoFunction geoFun = new GeoFunction(cons);
          geoFun.set(fun);
          geo = geoFun;
        }
        list.add(geo);

      } else {
        Application.debug("unsupported list addition: " + element.getClass() + "");
      }
    }
  }
  /** Fills the list of default geos */
  protected void createDefaultGeoElements() {
    defaultGeoElements = new HashMap<Integer, GeoElement>();

    // free point
    GeoPoint freePoint = new GeoPoint(cons);
    //		freePoint.setLocalVariableLabel(app.getPlain("Point") + strFree);
    freePoint.setPointSize(EuclidianView.DEFAULT_POINT_SIZE);
    freePoint.setPointStyle(EuclidianView.POINT_STYLE_DOT);
    freePoint.setLocalVariableLabel("Point" + strFree);
    freePoint.setObjColor(colPoint);
    freePoint.setPointSize(pointSize);
    defaultGeoElements.put(DEFAULT_POINT_FREE, freePoint);

    // dependent point
    GeoPoint depPoint = new GeoPoint(cons);
    //		depPoint.setLocalVariableLabel(app.getPlain("Point") + strDependent);
    depPoint.setPointSize(EuclidianView.DEFAULT_POINT_SIZE);
    depPoint.setPointStyle(EuclidianView.POINT_STYLE_DOT);
    depPoint.setLocalVariableLabel("Point" + strDependent);
    depPoint.setObjColor(colDepPoint);
    depPoint.setPointSize(pointSize);
    defaultGeoElements.put(DEFAULT_POINT_DEPENDENT, depPoint);

    // point on path
    GeoPoint pathPoint = new GeoPoint(cons);
    //		pathPoint.setLocalVariableLabel(app.getPlain("PointOn"));
    pathPoint.setPointSize(EuclidianView.DEFAULT_POINT_SIZE);
    pathPoint.setPointStyle(EuclidianView.POINT_STYLE_DOT);
    pathPoint.setLocalVariableLabel("PointOn");
    pathPoint.setObjColor(colPathPoint);
    pathPoint.setPointSize(pointSize);
    defaultGeoElements.put(DEFAULT_POINT_ON_PATH, pathPoint);

    // point in region
    GeoPoint regionPoint = new GeoPoint(cons);
    //		regionPoint.setLocalVariableLabel(app.getPlain("PointOn"));
    regionPoint.setPointSize(EuclidianView.DEFAULT_POINT_SIZE);
    regionPoint.setPointStyle(EuclidianView.POINT_STYLE_DOT);
    regionPoint.setLocalVariableLabel("PointInRegion");
    regionPoint.setObjColor(colRegionPoint);
    defaultGeoElements.put(DEFAULT_POINT_IN_REGION, regionPoint);

    // complex number (handled like a point)
    GeoPoint complexPoint = new GeoPoint(cons);
    complexPoint.setPointSize(EuclidianView.DEFAULT_POINT_SIZE);
    complexPoint.setPointStyle(EuclidianView.POINT_STYLE_DOT);
    complexPoint.setLocalVariableLabel("PointOn");
    complexPoint.setObjColor(colComplexPoint);
    complexPoint.setPointSize(pointSize);
    defaultGeoElements.put(DEFAULT_POINT_COMPLEX, complexPoint);

    // line
    GeoLine line = new GeoLine(cons);
    //		line.setLocalVariableLabel(app.getPlain("Line"));
    line.setLocalVariableLabel("Line");
    line.setObjColor(colLine);
    defaultGeoElements.put(DEFAULT_LINE, line);

    GeoFunctionNVar inequality = new GeoFunctionNVar(cons, null);
    // inequality.setLocalVariableLabel("Inequality");
    inequality.setObjColor(colInequality);
    inequality.setAlphaValue(DEFAULT_INEQUALITY_ALPHA);
    defaultGeoElements.put(DEFAULT_INEQUALITY, inequality);

    GeoFunction inequality1var = new GeoFunction(cons);
    // inequality.setLocalVariableLabel("Inequality");
    inequality1var.setObjColor(colInequality);
    inequality1var.setAlphaValue(DEFAULT_INEQUALITY_ALPHA);
    defaultGeoElements.put(DEFAULT_INEQUALITY_1VAR, inequality1var);

    // vector
    GeoVector vector = new GeoVector(cons);
    vector.setLocalVariableLabel("Vector");
    vector.setObjColor(colLine);
    defaultGeoElements.put(DEFAULT_VECTOR, vector);

    // polygon
    GeoPolygon polygon = new GeoPolygon(cons, null);
    //		polygon.setLocalVariableLabel(app.getPlain("Polygon"));
    polygon.setLocalVariableLabel("Polygon");
    polygon.setObjColor(colPolygon);
    polygon.setAlphaValue(DEFAULT_POLYGON_ALPHA);
    defaultGeoElements.put(DEFAULT_POLYGON, polygon);

    // conic
    GeoConic conic = new GeoConic(cons);
    //		conic.setLocalVariableLabel(app.getPlain("Conic"));
    conic.setLocalVariableLabel("Conic");
    conic.setObjColor(colConic);
    defaultGeoElements.put(DEFAULT_CONIC, conic);

    // conic sector
    GeoConicPart conicSector = new GeoConicPart(cons, GeoConicPart.CONIC_PART_SECTOR);
    //		conicSector.setLocalVariableLabel(app.getPlain("Sector"));
    conicSector.setLocalVariableLabel("Sector");
    conicSector.setObjColor(colPolygon);
    conicSector.setAlphaValue(DEFAULT_POLYGON_ALPHA);
    defaultGeoElements.put(DEFAULT_CONIC_SECTOR, conicSector);

    // number
    GeoNumeric number = new GeoNumeric(cons);
    //		number.setLocalVariableLabel(app.getPlain("Numeric"));
    number.setLocalVariableLabel("Numeric");
    number.setSliderFixed(true);
    number.setLabelMode(GeoElement.LABEL_NAME_VALUE);
    /*we have to set min/max/increment/speed here because
    SetEuclideanVisible takes these from default geo*/
    number.setIntervalMax(GeoNumeric.DEFAULT_SLIDER_MAX);
    number.setIntervalMin(GeoNumeric.DEFAULT_SLIDER_MIN);
    number.setAnimationStep(GeoNumeric.DEFAULT_SLIDER_INCREMENT);
    number.setAnimationSpeed(GeoNumeric.DEFAULT_SLIDER_SPEED);
    defaultGeoElements.put(DEFAULT_NUMBER, number);

    // angle
    GeoAngle angle = new GeoAngle(cons);
    //		angle.setLocalVariableLabel(app.getPlain("Angle"));
    angle.setLocalVariableLabel("Angle");
    angle.setSliderFixed(true);
    angle.setObjColor(colAngle);
    angle.setAlphaValue(DEFAULT_ANGLE_ALPHA);
    angle.setArcSize(angleSize);
    /*we have to set min/max/increment/speed here because
    SetEuclideanVisible takes these from default geo*/
    angle.setIntervalMax(GeoAngle.DEFAULT_SLIDER_MAX);
    angle.setIntervalMin(GeoAngle.DEFAULT_SLIDER_MIN);
    angle.setAnimationStep(GeoAngle.DEFAULT_SLIDER_INCREMENT);
    angle.setAnimationSpeed(GeoAngle.DEFAULT_SLIDER_SPEED);
    defaultGeoElements.put(DEFAULT_ANGLE, angle);

    // function
    GeoFunction function = new GeoFunction(cons);
    //		function.setLocalVariableLabel(app.getPlain("Function"));
    function.setLocalVariableLabel("Function");
    function.setObjColor(colFunction);
    defaultGeoElements.put(DEFAULT_FUNCTION, function);

    // locus
    GeoLocus locus = new GeoLocus(cons);
    //		locus.setLocalVariableLabel(app.getPlain("Locus"));
    locus.setLocalVariableLabel("Locus");
    locus.setObjColor(colLocus);
    locus.setLabelVisible(false);
    defaultGeoElements.put(DEFAULT_LOCUS, locus);

    // text
    GeoText text = new GeoText(cons);
    //		text.setLocalVariableLabel(app.getPlain("Text"));
    text.setLocalVariableLabel("Text");
    defaultGeoElements.put(DEFAULT_TEXT, text);

    // image
    GeoImage img = new GeoImage(cons);
    //		img.setLocalVariableLabel(app.getPlain("Image"));
    img.setLocalVariableLabel("Image");
    defaultGeoElements.put(DEFAULT_IMAGE, img);

    // boolean
    GeoBoolean bool = new GeoBoolean(cons);
    //		bool.setLocalVariableLabel(app.getPlain("Boolean"));
    bool.setLocalVariableLabel("Boolean");
    defaultGeoElements.put(DEFAULT_BOOLEAN, bool);

    // list
    GeoList list = new GeoList(cons);
    //		list.setLocalVariableLabel(app.getPlain("List"));
    list.setShowAllProperties(true); // show all properties in the defaults dialog
    list.setLocalVariableLabel("List");
    list.setObjColor(colList);
    list.setAlphaValue(-1); // wait until we have an element in the list
    // then we will use the alphaValue of the first element in the list
    // see GeoList.setAlphaValue() and getAlphaValue()
    defaultGeoElements.put(DEFAULT_LIST, list);
  }