@Override
 protected void moveOffsetAfter(boolean success) {
   if (success && (myPanel != null && myPanel.getInitPlace() != InitPlace.SAME_METHOD)
       || myOperation.getInplaceInitPlace() != InitPlace.SAME_METHOD) {
     final AccessToken accessToken =
         ApplicationManager.getApplication().acquireWriteActionLock(getClass());
     try {
       final PyAssignmentStatement initializer =
           PsiTreeUtil.getParentOfType(myTarget, PyAssignmentStatement.class);
       assert initializer != null;
       final Function<String, PyStatement> callback =
           FunctionUtil.<String, PyStatement>constant(initializer);
       final PyClass pyClass = PyUtil.getContainingClassOrSelf(initializer);
       InitPlace initPlace =
           myPanel != null ? myPanel.getInitPlace() : myOperation.getInplaceInitPlace();
       if (initPlace == InitPlace.CONSTRUCTOR) {
         AddFieldQuickFix.addFieldToInit(myProject, pyClass, "", callback);
       } else if (initPlace == InitPlace.SET_UP) {
         addFieldToSetUp(pyClass, callback);
       }
       if (myOperation.getOccurrences().size() > 0) {
         initializer.delete();
       } else {
         final PyExpression copy =
             PyElementGenerator.getInstance(myProject)
                 .createExpressionFromText(
                     LanguageLevel.forElement(myTarget), myTarget.getText());
         initializer.replace(copy);
       }
       initializer.delete();
     } finally {
       accessToken.finish();
     }
   }
 }
 public void invoke(
     @NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
   final IntroduceOperation operation = new IntroduceOperation(project, editor, file, null);
   operation.addAvailableInitPlace(InitPlace.CONSTRUCTOR);
   if (isTestClass(file, editor)) {
     operation.addAvailableInitPlace(InitPlace.SET_UP);
   }
   performAction(operation);
 }
 @Override
 protected void performInplaceIntroduce(IntroduceOperation operation) {
   final PsiElement statement = performRefactoring(operation);
   // put caret on identifier after "self."
   if (statement instanceof PyAssignmentStatement) {
     final List<PsiElement> occurrences = operation.getOccurrences();
     final PsiElement occurrence = findOccurrenceUnderCaret(occurrences, operation.getEditor());
     PyTargetExpression target =
         (PyTargetExpression) ((PyAssignmentStatement) statement).getTargets()[0];
     putCaretOnFieldName(operation.getEditor(), occurrence != null ? occurrence : target);
     final InplaceVariableIntroducer<PsiElement> introducer =
         new PyInplaceFieldIntroducer(target, operation, occurrences);
     introducer.performInplaceRefactoring(new LinkedHashSet<>(operation.getSuggestedNames()));
   }
 }
 @Override
 protected PsiElement replaceExpression(
     PsiElement expression, PyExpression newExpression, IntroduceOperation operation) {
   if (operation.getInitPlace() != InitPlace.SAME_METHOD) {
     return PyReplaceExpressionUtil.replaceExpression(expression, newExpression);
   }
   return super.replaceExpression(expression, newExpression, operation);
 }
 public PyInplaceFieldIntroducer(
     PyTargetExpression target, IntroduceOperation operation, List<PsiElement> occurrences) {
   super(
       target,
       operation.getEditor(),
       operation.getProject(),
       "Introduce Field",
       occurrences.toArray(new PsiElement[occurrences.size()]),
       null);
   myTarget = target;
   myOperation = operation;
   if (operation.getAvailableInitPlaces().size() > 1) {
     myPanel = new PyIntroduceFieldPanel(myProject, operation.getAvailableInitPlaces());
   } else {
     myPanel = null;
   }
 }
 @Nullable
 @Override
 protected PsiElement addDeclaration(
     @NotNull PsiElement expression,
     @NotNull PsiElement declaration,
     @NotNull IntroduceOperation operation) {
   final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent();
   PsiElement anchor = PyUtil.getContainingClassOrSelf(expr);
   assert anchor instanceof PyClass;
   final PyClass clazz = (PyClass) anchor;
   final Project project = anchor.getProject();
   if (operation.getInitPlace() == InitPlace.CONSTRUCTOR && !inConstructor(expression)) {
     return AddFieldQuickFix.addFieldToInit(
         project, clazz, "", new AddFieldDeclaration(declaration));
   } else if (operation.getInitPlace() == InitPlace.SET_UP) {
     return addFieldToSetUp(clazz, new AddFieldDeclaration(declaration));
   }
   return PyIntroduceVariableHandler.doIntroduceVariable(
       expression, declaration, operation.getOccurrences(), operation.isReplaceAll());
 }
 @Override
 protected boolean checkEnabled(IntroduceOperation operation) {
   if (PyUtil.getContainingClassOrSelf(operation.getElement()) == null) {
     CommonRefactoringUtil.showErrorHint(
         operation.getProject(),
         operation.getEditor(),
         "Cannot introduce field: not in class",
         myDialogTitle,
         getHelpId());
     return false;
   }
   if (dependsOnLocalScopeValues(operation.getElement())) {
     operation.removeAvailableInitPlace(InitPlace.CONSTRUCTOR);
     operation.removeAvailableInitPlace(InitPlace.SET_UP);
   }
   return true;
 }