public void setValue(final String elementName, final String newValue) {

    try {
      final NodeList nl = doc.getElementsByTagName(elementName);
      final Element element = (Element) nl.item(0);
      if (element == null || newValue == null) {
        ShowGUIMessage.showGUIMessage(
            "The property "
                + elementName
                + " was either not found in the properties file or the value "
                + newValue
                + " was not set.",
            "Property not found.");
      } else {
        element.setAttribute("value", newValue);
      }

    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " setting value in properties file");
    }
  }
  private void addChildElements(final NodeList tree, final Element menu) {

    if (!properties[position].equals("ENDCHILDREN")) {

      final int containsNode = checkNodelistForValue(tree, properties[position + 1], false);
      final int containsComment = checkNodelistForValue(tree, properties[position], true);

      if (containsNode == -1) {

        menu.appendChild(doc.createComment(properties[position]));
        position++;

        final Element property = doc.createElement(properties[position]);

        // Increment to property value
        position++;

        property.setAttribute("value", properties[position]);
        menu.appendChild(property);

      } else {
        if (containsComment == -1) {
          menu.insertBefore(doc.createComment(properties[position]), tree.item(containsNode));
        }
        position++;
        // Check version number for refactoring and updating
        if (properties[position].equals("currentversion")) {

          // Get store value for the current version
          final NodeList nl = doc.getElementsByTagName(properties[position]);
          final Element element = (Element) nl.item(0);

          if (element == null) {
            // Element not found in tree, should never happen
            ShowGUIMessage.showGUIMessage(
                "The property "
                    + properties[position]
                    + " was either not found in the properties file.",
                "Property not found.");
          } else {

            // Is it running in the IDE
            if (properties[position + 1].equals("6.9.29")) {
              // Do nothing as we are in the IDE
              // Refactor for testing purposes
              // refactorProperties  = true;
              //							isTest=true;

            } else { // Check versions of released jar

              // Program Version
              final float progVersion = Float.parseFloat(PdfDecoderInt.version.substring(0, 4));

              // Ensure properties is a valid value
              String propVer = "0";
              final String version = element.getAttribute("value");
              if (version.length() > 3) {
                propVer = version.substring(0, 4);
              }

              // Properties Version
              final float propVersion = Float.parseFloat(propVer);

              // compare version, only update on newer version
              if (progVersion > propVersion) {
                element.setAttribute("value", PdfDecoderInt.version);
              }
            }
          }
        }

        // Increment passed value to next property
        position++;
      }
    } else {
      endMenu = true;
    }
    position++;
  }
  /** create the actual shape */
  @Override
  public void createPaths(
      final int[] pX,
      final int[] pY,
      final boolean[] onCurve,
      final boolean[] endOfContour,
      final int endIndex) {

    // allow for bum data
    if (endOfContour == null) {
      return;
    }

    /*
     * scan data and adjust glyfs after first if do not end in contour
     */

    final int ptCount = endOfContour.length;

    int start = 0, firstPt = -1;
    for (int ii = 0; ii < ptCount; ii++) {

      if (endOfContour[ii]) {

        if (firstPt != -1
            && (!onCurve[start]
                || !onCurve[ii])) { // last point not on curve and we have a first point

          final int diff = firstPt - start;
          int newPos;

          // make a deep copy of values
          final int pXlength = pX.length;
          final int[] old_pX = new int[pXlength];
          System.arraycopy(pX, 0, old_pX, 0, pXlength);

          final int[] old_pY = new int[pXlength];
          System.arraycopy(pY, 0, old_pY, 0, pXlength);

          final boolean[] old_onCurve = new boolean[pXlength];
          System.arraycopy(onCurve, 0, old_onCurve, 0, pXlength);

          // rotate values to ensure point at start
          for (int oldPos = start; oldPos < ii + 1; oldPos++) {

            newPos = oldPos + diff;
            if (newPos > ii) {
              newPos -= (ii - start + 1);
            }
            pX[oldPos] = old_pX[newPos];
            pY[oldPos] = old_pY[newPos];
            onCurve[oldPos] = old_onCurve[newPos];
          }
        }

        // reset values
        start = ii + 1;
        firstPt = -1;

      } else if (onCurve[ii] && firstPt == -1) { // track first point
        firstPt = ii;
      }
    }

    boolean isFirstDraw = true;

    final GeneralPath current_path = new GeneralPath(GeneralPath.WIND_NON_ZERO);

    final int c = pX.length;
    int fc = -1;

    // find first end contour
    for (int jj = 0; jj < c; jj++) {
      if (endOfContour[jj]) {
        fc = jj + 1;
        jj = c;
      }
    }

    int x1, y1, x2 = 0, y2 = 0, x3 = 0, y3 = 0;

    x1 = pX[0];
    y1 = pY[0];

    if (debug) {
      System.out.println(pX[0] + " " + pY[0] + " move to x1,y1=" + x1 + ' ' + y1);
    }

    current_path.moveTo(x1, y1);

    if (debug) {
      System.out.println(
          "first contour=" + fc + "====================================" + pX[0] + ' ' + pY[0]);
      // System.out.println("start="+x1+ ' ' +y1+" unitsPerEm="+unitsPerEm);
      // for (int i = 0; i <c-2; i++)
      // System.out.println(i+" "+convertX(pX[i],pY[i])+ ' ' +convertY(pX[i],pY[i])+ ' '
      // +onCurve[i]+ ' ' +endOfContour[i]+" raw="+pX[i]+ ' ' +pY[i]);

      // System.out.println("Move to "+x1+ ' ' +y1);

    }

    int xs = 0, ys = 0, lc = 0;
    boolean isEnd = false;

    for (int j = 0; j < endIndex; j++) {

      final int p = j % fc;
      int p1 = (j + 1) % fc;
      int p2 = (j + 2) % fc;
      int pm1 = (j - 1) % fc;

      /* special cases
       *
       *round up to last point at end
       *First point
       */
      if (j == 0) {
        pm1 = fc - 1;
      }
      if (p1 < lc) {
        p1 += lc;
      }
      if (p2 < lc) {
        p2 += lc;
      }

      if (debug) {
        System.out.println(
            "points="
                + lc
                + '/'
                + fc
                + ' '
                + pm1
                + ' '
                + p
                + ' '
                + p1
                + ' '
                + p2
                + " j="
                + j
                + " endOfContour[j]="
                + endOfContour[j]);
      }

      // allow for wrap around on contour
      if (endOfContour[j]) {
        isEnd = true;

        if (onCurve[fc]) {
          xs = pX[fc];
          ys = pY[fc];
        } else {
          xs = pX[j + 1];
          ys = pY[j + 1];
        }

        // remember start point
        lc = fc;
        // find next contour
        for (int jj = j + 1; jj < c; jj++) {
          if (endOfContour[jj]) {
            fc = jj + 1;
            jj = c;
          }
        }

        if (debug) {
          System.out.println("End of contour. next=" + j + ' ' + fc + ' ' + lc);
        }
      }

      if (debug) {
        if (j > 0) {
          System.out.println(
              "curves="
                  + onCurve[p]
                  + ' '
                  + onCurve[p1]
                  + ' '
                  + onCurve[p2]
                  + " EndOfContour j-1="
                  + endOfContour[j - 1]
                  + " j="
                  + endOfContour[j]
                  + " j+1="
                  + endOfContour[j + 1]);
        } else {
          System.out.println(
              "curves="
                  + onCurve[p]
                  + ' '
                  + onCurve[p1]
                  + ' '
                  + onCurve[p2]
                  + " EndOfContour j="
                  + endOfContour[j]
                  + " j+1="
                  + endOfContour[j + 1]);
        }
      }

      if (lc == fc && onCurve[p]) {
        j = c;
        if (debug) {
          System.out.println("last 2 match");
        }
      } else {

        if (debug) {
          System.out.println(fc + " " + pm1 + ' ' + p + ' ' + p1 + ' ' + p2);
        }

        if (onCurve[p] && onCurve[p1]) { // straight line
          x3 = pX[p1];
          y3 = pY[p1];
          current_path.lineTo(x3, y3);
          if (debug) {
            System.out.println(p + " pt,pt " + x3 + ' ' + y3 + " (lineTo)");
          }

          isFirstDraw = false;
          // curves
        } else if (j < (c - 3) && ((fc - lc) > 1 || fc == lc)) {
          boolean checkEnd = false;
          if (onCurve[p] && !onCurve[p1] && onCurve[p2]) { // 2 points + control

            x1 = pX[p];
            y1 = pY[p];
            x2 = pX[p1];
            y2 = pY[p1];
            x3 = pX[p2];
            y3 = pY[p2];
            j++;
            checkEnd = true;
            if (debug) {
              System.out.println(
                  p + " pt,cv,pt " + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' ' + x3 + ' ' + y3);
            }

          } else if (onCurve[p] && !onCurve[p1] && !onCurve[p2]) { // 1 point + 2 control

            x1 = pX[p];
            y1 = pY[p];
            x2 = pX[p1];
            y2 = pY[p1];
            x3 = midPt(pX[p1], pX[p2]);
            y3 = midPt(pY[p1], pY[p2]);
            j++;

            checkEnd = true;

            if (debug) {
              System.out.println(
                  p + " pt,cv,cv " + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' ' + x3 + ' ' + y3);
            }

          } else if (!onCurve[p]
              && !onCurve[p1]
              && (!endOfContour[p2]
                  || fc - p2
                      == 1)) { // 2 control + 1 point (final check allows for last point to complete
            // loop

            x1 = midPt(pX[pm1], pX[p]);
            y1 = midPt(pY[pm1], pY[p]);
            x2 = pX[p];
            y2 = pY[p];

            x3 = midPt(pX[p], pX[p1]);
            y3 = midPt(pY[p], pY[p1]);
            if (debug) {
              System.out.println(
                  p + " cv,cv1 " + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' ' + x3 + ' ' + y3);
            }

          } else if (!onCurve[p] && onCurve[p1]) { // 1 control + 2 point

            x1 = midPt(pX[pm1], pX[p]);
            y1 = midPt(pY[pm1], pY[p]);
            x2 = pX[p];
            y2 = pY[p];
            x3 = pX[p1];
            y3 = pY[p1];
            if (debug) {
              System.out.println(
                  p + " cv,pt " + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' ' + x3 + ' ' + y3);
            }
          }

          if (isFirstDraw) {
            current_path.moveTo(x1, y1);
            isFirstDraw = false;

            if (debug) {
              System.out.println("first draw move to " + x1 + ' ' + y1);
            }
          }

          if (!(endOfContour[p] && p > 0 && endOfContour[p - 1])) {
            hasEndCurve = true;
            current_path.curveTo(x1, y1, x2, y2, x3, y3);
          }

          if (debug) {
            System.out.println(
                "curveto " + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' ' + x3 + ' ' + y3);
          }

          /* if end after curve, roll back so we pick up the end*/
          if (checkEnd && endOfContour[j]) {

            isEnd = true;

            xs = pX[fc];
            ys = pY[fc];
            // remmeber start point
            lc = fc;
            // find next contour
            for (int jj = j + 1; jj < c; jj++) {
              if (endOfContour[jj]) {
                fc = jj + 1;
                jj = c;
              }
            }

            if (debug) {
              System.out.println("Curve");
            }
          }
        }

        if (endOfContour[p]) {
          current_path.closePath();
        }

        if (debug) {
          System.out.println("x2 " + xs + ' ' + ys + ' ' + isEnd);
        }

        if (isEnd) {
          current_path.moveTo(xs, ys);
          isEnd = false;
          if (debug) {
            System.out.println("Move to " + xs + ' ' + ys);
          }
        }

        if (debug) {
          try {
            if (img == null) {
              img =
                  new java.awt.image.BufferedImage(
                      800, 800, java.awt.image.BufferedImage.TYPE_INT_ARGB);
            }

            final Graphics2D g2 = img.createGraphics();
            g2.setColor(java.awt.Color.green);
            g2.draw(current_path);

            final String key = String.valueOf(p);

            org.jpedal.gui.ShowGUIMessage.showGUIMessage(key, img, key);

          } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
          }
        }
      }
    }

    /*
     * store so we can draw glyf as set of paths
     */
    paths.addElement(current_path);

    if (debug) {
      System.out.println(
          "Ends at "
              + x1
              + ' '
              + y1
              + " x="
              + minX
              + ','
              + maxX
              + " y="
              + minY
              + ','
              + maxY
              + " glyph x="
              + compMinX
              + ','
              + compMaxX
              + " y="
              + compMinY
              + ','
              + compMaxY);
    }
  }