public String build() {
    final TypeEvalContext context =
        TypeEvalContext.userInitiated(myElement.getProject(), myElement.getContainingFile());
    final PsiElement outerElement =
        myOriginalElement != null ? myOriginalElement.getParent() : null;

    final PsiElement elementDefinition = resolveToDocStringOwner();
    final boolean isProperty = buildFromProperty(elementDefinition, outerElement, context);

    if (myProlog.isEmpty() && !isProperty && !isAttribute()) {
      myProlog.add(myReassignmentChain);
    }

    if (elementDefinition instanceof PyDocStringOwner) {
      buildFromDocstring(elementDefinition, isProperty);
    } else if (isAttribute()) {
      buildFromAttributeDoc();
    } else if (elementDefinition instanceof PyNamedParameter) {
      buildFromParameter(context, outerElement, elementDefinition);
    } else if (elementDefinition != null && outerElement instanceof PyReferenceExpression) {
      myBody.addItem(combUp("\nInferred type: "));
      PythonDocumentationProvider.describeExpressionTypeWithLinks(
          myBody, (PyReferenceExpression) outerElement, context);
    }

    if (elementDefinition != null
        && PythonDialectsTokenSetProvider.INSTANCE
            .getKeywordTokens()
            .contains(elementDefinition.getNode().getElementType())) {
      buildForKeyword(elementDefinition.getText());
    }
    if (myBody.isEmpty() && myEpilog.isEmpty()) {
      return null; // got nothing substantial to say!
    } else {
      return myResult.toString();
    }
  }