@Override
  public boolean isSoftWrappingEnabled() {
    if (!myUseSoftWraps
        || (!myEditor.myUseNewRendering && myEditor.isOneLineMode())
        || myEditor.isPurePaintingMode()) {
      return false;
    }

    // We check that current thread is EDT because attempt to retrieve information about visible
    // area width may fail otherwise
    Application application = ApplicationManager.getApplication();
    Thread lastEdt = myLastEdt.get();
    Thread currentThread = Thread.currentThread();
    if (lastEdt != currentThread) {
      if (application.isDispatchThread()) {
        myLastEdt = new SoftReference<Thread>(currentThread);
      } else {
        myLastEdt = new SoftReference<Thread>(null);
        return false;
      }
    }

    Rectangle visibleArea = myEditor.getScrollingModel().getVisibleArea();
    return visibleArea.width > 0 && visibleArea.height > 0;
  }
 @Nullable
 private TIntIntHashMap getNewToOldLineMapping(final long date) {
   if (myNewToOldLines == null) {
     myNewToOldLines = doGetLineMapping(date, false);
     if (myNewToOldLines == null) return null;
   }
   return myNewToOldLines.get();
 }
 @Nullable
 private TIntIntHashMap getOldToNewLineMapping(final long date) {
   if (myOldToNewLines == null) {
     myOldToNewLines = doGetLineMapping(date, true);
     if (myOldToNewLines == null) return null;
   }
   return myOldToNewLines.get();
 }
  public static PsiExpression getOrCreatePisExpression(GrExpression expr) {
    if (expr == null) return null;

    final SoftReference<PsiExpression> ref = expr.getUserData(PSI_EXPRESSION);
    final PsiExpression element = ref == null ? null : ref.get();
    if (element != null) return element;
    final GrSyntheticExpression newExpr = new GrSyntheticExpression(expr);
    expr.putUserData(PSI_EXPRESSION, new SoftReference<PsiExpression>(newExpr));
    return newExpr;
  }
  public static PsiTypeElement getOrCreateTypeElement(GrTypeElement typeElement) {
    if (typeElement == null) return null;

    final SoftReference<PsiTypeElement> ref = typeElement.getUserData(PSI_TYPE_ELEMENT);
    final PsiTypeElement element = ref == null ? null : ref.get();
    if (element != null) return element;
    final GrSyntheticTypeElement newTypeElement = new GrSyntheticTypeElement(typeElement);
    typeElement.putUserData(PSI_TYPE_ELEMENT, new SoftReference<PsiTypeElement>(newTypeElement));
    return newTypeElement;
  }
  public static PsiCodeBlock getOrCreatePsiCodeBlock(GrOpenBlock block) {
    if (block == null) return null;

    final SoftReference<PsiCodeBlock> ref = block.getUserData(PSI_CODE_BLOCK);
    final PsiCodeBlock body = ref == null ? null : ref.get();
    if (body != null) return body;
    final GrSyntheticCodeBlock newBody = new GrSyntheticCodeBlock(block);
    block.putUserData(PSI_CODE_BLOCK, new SoftReference<PsiCodeBlock>(newBody));
    return newBody;
  }
 @Nullable
 public AndroidTargetData getTargetData(@NotNull IAndroidTarget target) {
   final SoftReference<AndroidTargetData> targetDataRef = myTargetDatas.get(target);
   AndroidTargetData targetData = targetDataRef != null ? targetDataRef.get() : null;
   if (targetData == null) {
     targetData = new AndroidTargetData(this, target);
     myTargetDatas.put(target, new SoftReference<AndroidTargetData>(targetData));
   }
   return targetData;
 }
  @Nullable
  private SoftReference<TIntIntHashMap> doGetLineMapping(final long date, boolean oldToNew) {
    final VirtualFile f = getVirtualFile();
    final byte[] oldContent;
    synchronized (LOCK) {
      if (myOldContent == null) {
        if (ApplicationManager.getApplication().isDispatchThread()) return null;
        final LocalHistory localHistory = LocalHistory.getInstance();
        byte[] byteContent =
            localHistory.getByteContent(
                f,
                new FileRevisionTimestampComparator() {
                  public boolean isSuitable(long revisionTimestamp) {
                    return revisionTimestamp < date;
                  }
                });

        if (byteContent == null && f.getTimeStamp() > date) {
          byteContent = loadFromVersionControl(date, f);
        }
        myOldContent = new SoftReference<byte[]>(byteContent);
      }
      oldContent = myOldContent.get();
    }

    if (oldContent == null) return null;
    String[] coveredLines = getCoveredLines(oldContent, f);
    final Document document = myDocument;
    if (document == null) return null;
    String[] currentLines = getUpToDateLines(document);

    String[] oldLines = oldToNew ? coveredLines : currentLines;
    String[] newLines = oldToNew ? currentLines : coveredLines;

    Diff.Change change;
    try {
      change = Diff.buildChanges(oldLines, newLines);
    } catch (FilesTooBigForDiffException e) {
      LOG.info(e);
      return null;
    }
    return new SoftReference<TIntIntHashMap>(
        getCoverageVersionToCurrentLineMapping(change, oldLines.length));
  }