docs: private static List<List<XYZPoint>> loopsFromWkt(String wkt) throws IllegalArgumentException {
          final String msgPrefix = "Improperly formatted WKT for polygon: ";
  
          StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(wkt));
          tokenizer.lowerCaseMode(true);
          tokenizer.eolIsSignificant(false);
  
          List<XYZPoint> currentLoop = null;
          List<List<XYZPoint>> loops = new ArrayList<>();
          boolean is_shell = true;
          try {
              int token = tokenizer.nextToken();
              if (token != StreamTokenizer.TT_WORD
                      || ! tokenizer.sval.equals("polygon")) {
                  throw new IllegalArgumentException(msgPrefix + "expected WKT to start with POLYGON");
              }
  
              token = tokenizer.nextToken();
              if (token != '(') {
                  throw new IllegalArgumentException(msgPrefix + "expected left parenthesis after POLYGON");
              }
  
              boolean polygonOpen = true;
  
              while (polygonOpen) {
  
                  token = tokenizer.nextToken();
                  switch (token) {
                  case '(':
                      if (currentLoop != null) {
                          throw new IllegalArgumentException(msgPrefix + "missing closing parenthesis");
                      }
                      currentLoop = new ArrayList<>();
                      break;
                  case StreamTokenizer.TT_NUMBER:
                      if (currentLoop == null) {
                          throw new IllegalArgumentException(msgPrefix + "missing opening parenthesis");
                      }
  
                      double lng = tokenizer.nval;
                      token = tokenizer.nextToken();
                      if (token != StreamTokenizer.TT_NUMBER) {
                          throw new IllegalArgumentException(msgPrefix + "missing latitude in long lat pair");
                      }
                      double lat = tokenizer.nval;
                      currentLoop.add(XYZPoint.fromGeographyPointValue(new GeographyPointValue(lng, lat)));
  
                      token = tokenizer.nextToken();
                      if (token != ',') {
                          if (token != ')') {
                              throw new IllegalArgumentException(msgPrefix + "missing comma between long lat pairs");
                          }
                          tokenizer.pushBack();
                      }
                      break;
                  case ')':
                      // perform basic validation of loop
                      diagnoseLoop(currentLoop, msgPrefix);
                      // Following the OGC standard, the first loop should be CCW, and subsequent loops
                      // should be CW.  But we will be building the S2 polygon here,
                      // and S2 wants everything to be CCW.  So, we need to
                      // reverse all but the first loop.
                      //
                      // Note also that we don't want to touch the vertex at index 0, and we want
                      // to remove the vertex at index currentLoop.size() - 1.  We want to hold the first
                      // vertex invariant.  The vertex at currentLoop.size() - 1 should be a duplicate
                      // of the vertex at index 0, and should be removed before pushing it into the
                      // list of loops.
                      //
                      // We are also allowed to swap these out, because they have been
                      // created and are owned by us.
                      //
                      currentLoop.remove(currentLoop.size() - 1);
                      if (!is_shell) {
                          for (int fidx = 1, lidx = currentLoop.size() - 1; fidx < lidx; ++fidx, --lidx) {
                              Collections.swap(currentLoop, fidx, lidx);
                          }
                      }
                      is_shell = false;
                      loops.add(currentLoop);
                      currentLoop = null;
  
                      token = tokenizer.nextToken();
                      if (token == ')') {
                          polygonOpen = false;
                      }
                      else if (token != ',') {
                          throw new IllegalArgumentException(msgPrefix + "unrecognized token in WKT: " + Character.toString((char)token));
                      }
  
                      break;
  
                  case StreamTokenizer.TT_EOF:
                      throw new IllegalArgumentException(msgPrefix + "premature end of input");
  
                  default:
                      throw new IllegalArgumentException(msgPrefix + "unrecognized token in WKT: " + Character.toString((char)token));
                  }
              }
  
              token = tokenizer.nextToken();
              if (token != StreamTokenizer.TT_EOF) {
                  throw new IllegalArgumentException(msgPrefix + "unrecognized input after WKT");
              }
          } catch (IOException e) {
              throw new IllegalArgumentException(msgPrefix + "error tokenizing string");
          }
  
          return loops;
      }