docs: @SuppressWarnings("unchecked")
      private List<PropertyDescriptor> introspectProperties(Method[] methodDescriptors) {
  
          // Get the list of public non-static methods into an array
          if (methodDescriptors == null) {
              return null;
          }
  
          HashMap<String, HashMap> propertyTable = new HashMap<>(methodDescriptors.length);
  
          // Search for methods that either get or set a Property
          for (Method methodDescriptor : methodDescriptors) {
              introspectGet(methodDescriptor, propertyTable);
              introspectSet(methodDescriptor, propertyTable);
          }
  
          // fix possible getter & setter collisions
          fixGetSet(propertyTable);
  
          // Put the properties found into the PropertyDescriptor array
          ArrayList<PropertyDescriptor> propertyList = new ArrayList<>();
  
          for (Map.Entry<String, HashMap> entry : propertyTable.entrySet()) {
              String propertyName = entry.getKey();
              HashMap table = entry.getValue();
              if (table == null) {
                  continue;
              }
              String normalTag = (String) table.get(STR_NORMAL);
  
              if ((normalTag == null)) {
                  continue;
              }
  
              Method get = (Method) table.get(STR_NORMAL + PREFIX_GET);
              Method set = (Method) table.get(STR_NORMAL + PREFIX_SET);
  
              PropertyDescriptor propertyDesc = new PropertyDescriptor(propertyName, get, set);
              propertyList.add(propertyDesc);
          }
  
          return Collections.unmodifiableList(propertyList);
      }