docs: private static OperationType buildQueryModelFromMethodName(String methodName, StringBuilder sb) {
          String queryString;
          OperationType operationType;
  
          if (methodName.startsWith("findBy")) {
              queryString = methodName.substring("findBy".length(), methodName.length() - (methodName.endsWith("As") ? "As".length() : 0));
              operationType = OperationType.Read;
          } else if (methodName.startsWith("countBy")) {
              sb.append("    queryModel.setProjection(buildProjection(\"\", org.iternine.jeppetto.dao.ProjectionType.RowCount, argsIterator));\n\n");
  
              queryString = methodName.substring("countBy".length(), methodName.length() - (methodName.endsWith("As") ? "As".length() : 0));
              operationType = OperationType.Read;
          } else if (methodName.startsWith("updateBy")) {
              queryString = methodName.substring("updateBy".length(), methodName.length() - (methodName.endsWith("As") ? "As".length() : 0));
              operationType = OperationType.Update;
              sb.append("    org.iternine.jeppetto.dao.updateobject.UpdateObject updateObject = (org.iternine.jeppetto.dao.updateobject.UpdateObject) argsIterator.next();\n\n");
          } else if (methodName.startsWith("deleteBy")) {
              queryString = methodName.substring("deleteBy".length(), methodName.length() - (methodName.endsWith("As") ? "As".length() : 0));
              operationType = OperationType.Delete;
          } else {
              throw new UnsupportedOperationException("Don't know how to handle '" + methodName + "'");
          }
  
          int orderByIndex = queryString.indexOf("OrderBy");
          boolean limitResults;
          boolean skipResults;
  
          if (skipResults = queryString.endsWith("AndSkip")) {
              queryString = queryString.substring(0, queryString.length() - "AndSkip".length());
          }
  
          if (limitResults = queryString.endsWith("AndLimit")) {
              queryString = queryString.substring(0, queryString.length() - "AndLimit".length());
          }
  
          String[] queryParts;
          String orderParts;
  
          if (orderByIndex == -1) {
              queryParts = queryString.split("Having");
              orderParts = null;
          } else {
              queryParts = queryString.substring(0, orderByIndex).split("Having");
              orderParts = queryString.substring(orderByIndex + "OrderBy".length());
          }
  
          if (queryParts[0] != null) {
              if (queryParts[0].length() > 0) {
                  String[] conditionStrings = queryParts[0].split("And");
  
                  for (String conditionString : conditionStrings) {
                      String conditionName = getConditionNameFromString(conditionString);
  
                      sb.append(String.format("    queryModel.addCondition(buildCondition(\"%s\", org.iternine.jeppetto.dao.ConditionType.%s, argsIterator));\n",
                                              pruneFieldNameFromString(conditionString, conditionName), conditionName));
                  }
  
                  sb.append('\n');
              }
  
              for (int i = 1; i < queryParts.length; i++) {
                  String associationString = queryParts[i];
                  int withIndex = associationString.indexOf("With");  // If -1, exception.  Okay.
                  String[] conditionStrings = associationString.substring(withIndex + 4, associationString.length()).split("And");
  
                  for (String conditionString : conditionStrings) {
                      String conditionName = getConditionNameFromString(conditionString);
  
                      sb.append(String.format("    queryModel.addAssociationCondition(\"%s\", buildCondition(\"%s\", org.iternine.jeppetto.dao.ConditionType.%s, argsIterator));\n",
                                              Character.toLowerCase(associationString.charAt(0)) + associationString.substring(1, withIndex),
                                              pruneFieldNameFromString(conditionString, conditionName), conditionName));
                  }
  
                  sb.append('\n');
              }
          }
  
          if (orderParts != null && operationType == OperationType.Read) {
              for (String orderPart : orderParts.split("And")) {
                  SortDirection sortDirection;
                  String fieldName;
  
                  if (orderPart.endsWith("Desc")) {
                      sortDirection = SortDirection.Descending;
                      fieldName = pruneFieldNameFromString(orderPart, "Desc");
                  } else {
                      sortDirection = SortDirection.Ascending;
                      fieldName = pruneFieldNameFromString(orderPart, "Asc");
                  }
  
                  sb.append(String.format("    queryModel.addSort(org.iternine.jeppetto.dao.SortDirection.%s, \"%s\");\n",
                                          sortDirection.name(), fieldName));
              }
  
              sb.append('\n');
          }
  
          if (limitResults) {
              sb.append("    queryModel.setMaxResults(((Integer) argsIterator.next()).intValue());\n\n");
          }
  
          if (skipResults) {
              sb.append("    queryModel.setFirstResult(((Integer) argsIterator.next()).intValue());\n\n");
          }
  
          return operationType;
      }