docs: protected void parseNumbersString(String numberString, int componentType,
                                      int componentCount) {
          //preprocessing to get rid of 'e' or 'E' exponent
          // otherwise the SAX parser splits 3e-2 (which is .03) into two
          // number, 3 and -2.
          if ( (numberString.indexOf('e') != -1) || (numberString.indexOf('E') != -1) ) {
              int stringPos = 0;
              String newReplacementString = "";
              // we do assume the numberString won't be mixing 'e' and 'E'
              // but we want to handle any either character
              char eChar = 'e';
              if ( numberString.indexOf('E') != -1 ) eChar = 'E';
              while (numberString.indexOf(eChar, stringPos) != -1)  {
                  int ePos = numberString.indexOf(eChar, stringPos);
                  // check for the first space or comma before 'e'.
                  int prevSpaceBefore_e = Math.max( (numberString.lastIndexOf(' ', ePos)), (numberString.lastIndexOf(',', ePos)) );
                  prevSpaceBefore_e++;
                  // Copy from the current position until the comma or space before the 'e'
                  newReplacementString += numberString.substring(stringPos, prevSpaceBefore_e);
                  // check for the next space or comma after 'e'.
                  // Otherwise, we might be at the end of the string.
                  int nextSpaceAfter_e = Math.min( (numberString.indexOf(' ', ePos)), (numberString.indexOf(',', ePos)) );
                  if (nextSpaceAfter_e == -1) {
                      // at the end of the original string, find the last space, comma or EOL of the string
                      nextSpaceAfter_e = Math.max( (numberString.indexOf(' ', ePos)), (numberString.indexOf(',', ePos)) );
                      if (nextSpaceAfter_e == -1) nextSpaceAfter_e = Math.max( nextSpaceAfter_e, numberString.length() );
                  }
                  String exponentString = numberString.substring(ePos+1, nextSpaceAfter_e);
                  try {
                      double newReplacementNumber =
                              ( (float) (new Float( numberString.substring(prevSpaceBefore_e, ePos) )) )
                                      * Math.pow(10, (int) (new Integer(exponentString)) );
                      // At < 1/1000th, it might be more efficient as 0.
                      if ( Math.abs(newReplacementNumber) < .001 ) newReplacementNumber = 0;
                      newReplacementString += " " + newReplacementNumber + " ";
                  }
                  catch (java.lang.NumberFormatException exception) {
                      Log.e(TAG, "NumberFormatException in " + numberString.substring(prevSpaceBefore_e, nextSpaceAfter_e) + "; " + exception);
                  }
                  catch (Exception exception) {
                      Log.e(TAG, "Exception in " + numberString.substring(prevSpaceBefore_e, nextSpaceAfter_e) + "; " + exception);
                  }
                  stringPos = nextSpaceAfter_e;
              }
              // Add any remainder of a string
              numberString = newReplacementString + numberString.substring(stringPos, numberString.length());
          }
          StringReader sr = new StringReader(numberString);
          StreamTokenizer st = new StreamTokenizer(sr);
          st.parseNumbers();
          int tokenType;
          short componentShort[] = new short[componentCount];
          float componentFloat[] = new float[componentCount];
          try {
              int index = 0;
              while ((tokenType = st.nextToken()) != StreamTokenizer.TT_EOF) {
                  if (tokenType == StreamTokenizer.TT_NUMBER) {
  
                      // first componentType's parse for short values
                      // (integers) and will have no exponents
  
                      if (componentType == indexedFaceSetComponent) {
                          if ((int) st.nval != -1) {
                              meshCreator.addPositionIndex((int) st.nval);
                              index++;
                              if (index == componentCount) {
                                  index = 0;
                              }
                          }
                      } else if (componentType == textureIndexComponent) {
                          if ((int) st.nval != -1) {
                              meshCreator.addTexcoordIndex((int) st.nval);
                              index++;
                              if (index == componentCount) {
                                  index = 0;
                              }
                          }
                      } else if (componentType == normalIndexComponent) {
                          if ((int) st.nval != -1) {
                              meshCreator.addNormalIndex((int) st.nval);
                              index++;
                              if (index == componentCount) {
                                  index = 0;
                              }
                          }
                      }
  
                      // The rest of these will be parsing floats that could
                      // have 'e' exponent value.  3DSMax will export X3D/VRML
                      // with the 'e' exponent
                      //TODO: check for 'e' exponent values.
  
                      else if (componentType == verticesComponent) {
                          componentFloat[index] = (float) (st.nval);
                          index++;
                          if (index == componentCount) {
                              meshCreator.addInputPosition(componentFloat);
                              index = 0;
                          }
                      } else if (componentType == textureCoordComponent) {
                          componentFloat[index] = (float) st.nval;
                          index++;
                          if (index == componentCount) {
                              meshCreator.addInputTexcoord(componentFloat);
                              index = 0;
                          }
                      } else if (componentType == normalsComponent) {
                          componentFloat[index] = (float) st.nval;
                          index++;
                          if (index == componentCount) {
                              meshCreator.addInputNormal(componentFloat);
                              index = 0;
                          }
                      } else if (componentType == interpolatorKeyComponent) {
                          componentFloat[index] = (float) st.nval;
                          index++;
                          if (index == componentCount) {
                              mX3DObject.AddKeys(componentFloat[0]);
                              index = 0;
                          }
                      } else if (componentType == interpolatorKeyValueComponent) {
                          componentFloat[index] = (float) st.nval;
                          index++;
                          if (index == componentCount) {
                              mX3DObject.AddKeyValues(componentFloat);
                              index = 0;
                          }
                      } else if (componentType == LODComponent) {
                          componentFloat[index] = (float) st.nval;
                          mX3DObject.AddKeys(componentFloat[0]);
                      } else if (componentType == elevationGridHeight) {
                          // Elevation Grid not currently supported
                          mX3DObject.floatArray.add(new Float((float) st.nval));
                      }
  
                  } // end if token = number
              } // end while loop
          } // end try statement
          catch (IOException e) {
              Log.e(TAG, "Error: parseNumbersString - " + e);
          }
      }