@Override
  protected void updateUsages(@NotNull Collection<String> newParamNames, UsageInfo @NotNull [] usages) {
    // Field usages
    for (String attrName : myAttributeReferences.keySet()) {
      final Collection<PyReferenceExpression> reads = myAttributeReferences.get(attrName);
      final String paramName = myAttributeToParameterName.get(attrName);
      if (!attrName.equals(paramName)) {
        for (PyReferenceExpression read : reads) {
          read.replace(myGenerator.createExpressionFromText(LanguageLevel.forElement(read), paramName));
        }
      }
      else {
        for (PyReferenceExpression read : reads) {
          removeQualifier(read);
        }
      }
    }

    // Function usages
    final Collection<String> attrNames = myAttributeToParameterName.keySet();
    for (UsageInfo usage : usages) {
      final PsiElement usageElem = usage.getElement();
      if (usageElem == null) {
        continue;
      }

      if (usageElem instanceof PyReferenceExpression) {
        final PyExpression qualifier = ((PyReferenceExpression)usageElem).getQualifier();
        final PyCallExpression callExpr = as(usageElem.getParent(), PyCallExpression.class);
        if (qualifier != null && callExpr != null && callExpr.getArgumentList() != null) {
          PyExpression instanceExpr = qualifier;
          final PyArgumentList argumentList = callExpr.getArgumentList();

          // Class.method(instance) -> method(instance.attr)
          if (resolvesToClass(qualifier)) {
            final PyExpression[] arguments = argumentList.getArguments();
            if (arguments.length > 0) {
              instanceExpr = arguments[0];
              instanceExpr.delete();
            }
            else {
              // It's not clear how to handle usages like Class.method(), since there is no suitable instance
              instanceExpr = null;
            }
          }

          if (instanceExpr != null) {
            // module.inst.method() -> method(module.inst.foo, module.inst.bar)
            if (isPureReferenceExpression(instanceExpr)) {
              // recursive call inside the method
              if (myReadsOfSelfParam.contains(instanceExpr)) {
                addArguments(argumentList, newParamNames);
              }
              else {
                final String instanceExprText = instanceExpr.getText();
                addArguments(argumentList, ContainerUtil.map(attrNames, attribute -> instanceExprText + "." + attribute));
              }
            }
            // Class().method() -> method(Class().foo)
            else if (newParamNames.size() == 1) {
              addArguments(argumentList, Collections.singleton(instanceExpr.getText() + "." + ContainerUtil.getFirstItem(attrNames)));
            }
            // Class().method() -> inst = Class(); method(inst.foo, inst.bar)
            else if (!newParamNames.isEmpty()) {
              final PyStatement anchor = PsiTreeUtil.getParentOfType(callExpr, PyStatement.class);
              //noinspection ConstantConditions
              final String className = StringUtil.notNullize(myFunction.getContainingClass().getName(), PyNames.OBJECT);
              final String targetName = PyRefactoringUtil.selectUniqueNameFromType(className, usageElem);
              final String assignmentText = targetName + " = " + instanceExpr.getText();
              final PyAssignmentStatement assignment = myGenerator.createFromText(LanguageLevel.forElement(callExpr),
                                                                                  PyAssignmentStatement.class,
                                                                                  assignmentText);
              //noinspection ConstantConditions
              anchor.getParent().addBefore(assignment, anchor);
              addArguments(argumentList, ContainerUtil.map(attrNames, attribute -> targetName + "." + attribute));
            }
          }
        }

        // Will replace/invalidate entire expression
        removeQualifier((PyReferenceExpression)usageElem);
      }
    }
  }
@Override
  protected void updateUsages(@NotNull Collection<String> newParamNames, UsageInfo @NotNull [] usages)