private static @NotNull Map<String, PsiMember> prepareWritableProperties(@NotNull PsiClass psiClass) {
    // todo search for setter in corresponding builder class, e.g. MyDataBuilder.setText() + MyData.getText(), reuse logic from hasBuilder()
    final Map<String, PsiMember> acceptableMembers = new HashMap<>();
    for (String propertyName : prepareConstructorNamedArgProperties(psiClass)) {
      if (!acceptableMembers.containsKey(propertyName)) {
        final PsiField field = psiClass.findFieldByName(propertyName, true);
        if (field != null && !field.hasModifierProperty(PsiModifier.STATIC)) {
          acceptableMembers.put(propertyName, field);
        }
      }
    }
    for (PsiMethod method : psiClass.getAllMethods()) {
      if (method.hasModifierProperty(PsiModifier.STATIC) || !method.hasModifierProperty(PsiModifier.PUBLIC)) continue;
      if (PropertyUtilBase.isSimplePropertyGetter(method)) {
        PsiMember acceptableMember = method;
        final String propertyName = PropertyUtilBase.getPropertyName(method);
        assert propertyName != null;

        PsiMethod setter = findInstancePropertySetter(psiClass, propertyName);
        if (setter != null) {
          final PsiType setterArgType = setter.getParameterList().getParameters()[0].getType();
          final PsiField field = psiClass.findFieldByName(propertyName, true);
          if (field != null && !field.hasModifierProperty(PsiModifier.STATIC)) {
            final PsiType fieldType = getWritablePropertyType(psiClass, field);
            if (fieldType == null || setterArgType.isConvertibleFrom(fieldType)) {
              acceptableMember = field;
            }
          }
        }
        else {
          final PsiType returnType = method.getReturnType();
          if (returnType != null && isWritablePropertyType(psiClass, returnType)) {
            final PsiField field = psiClass.findFieldByName(propertyName, true);
            if (field != null && !field.hasModifierProperty(PsiModifier.STATIC)) {
              final PsiType fieldType = getWritablePropertyType(psiClass, field);
              if (fieldType == null || returnType.isAssignableFrom(fieldType)) {
                acceptableMember = field;
              }
            }
          }
          else {
            acceptableMember = null;
          }
        }
        if (acceptableMember != null) acceptableMembers.put(propertyName, acceptableMember);
      }
    }
    return acceptableMembers;
  }
private static @NotNull Map<String, PsiMember> prepareWritableProperties(@NotNull PsiClass psiClass)