private boolean checkLastImage() {
    File file = new File(DesignerApplicationManager.APP_DIR, LAST_PREVIEW_IMAGE_FILE_NAME);
    if (!file.exists()) {
      return false;
    }

    try {
      final VirtualFile virtualFile = toolWindowForm.getFile();
      BufferedImage image =
          IOUtil.readImage(
              file,
              new Processor<DataInputStream>() {
                @Override
                public boolean process(DataInputStream in) {
                  try {
                    return in.readLong() == virtualFile.getTimeStamp()
                        && in.readUTF().equals(virtualFile.getUrl());
                  } catch (IOException e) {
                    throw new RuntimeException(e);
                  }
                }
              });
      if (image != null) {
        toolWindowForm.getPreviewPanel().setImage(image);
        return true;
      }
    } catch (IOException e) {
      LogMessageUtil.LOG.warn("Can't read image for last document", e);
    }

    return false;
  }
  @Override
  public void projectClosed() {
    if (toolWindowForm == null) {
      return;
    }

    try {
      VirtualFile file = toolWindowForm.getFile();
      if (file != null) {
        saveLastImage(file);
      }
    } finally {
      Disposer.dispose(toolWindowForm.getPreviewPanel());
      toolWindowForm = null;
      toolWindow = null;
      toolWindowVisible = false;
    }
  }
 private void saveLastImage(final VirtualFile file) {
   BufferedImage image = toolWindowForm.getPreviewPanel().getImage();
   if (image != null) {
     try {
       IOUtil.saveImage(
           toolWindowForm.getPreviewPanel().getImage(),
           new File(DesignerApplicationManager.APP_DIR, LAST_PREVIEW_IMAGE_FILE_NAME),
           new Consumer<DataOutputStream>() {
             @Override
             public void consume(DataOutputStream out) {
               try {
                 out.writeLong(file.getTimeStamp());
                 out.writeUTF(file.getUrl());
               } catch (IOException e) {
                 throw new RuntimeException(e);
               }
             }
           });
     } catch (Throwable e) {
       LogMessageUtil.LOG.warn("Can't save image for last document", e);
     }
   }
 }
 @Nullable
 public VirtualFile getServedFile() {
   return toolWindowVisible && toolWindowForm != null ? toolWindowForm.getFile() : null;
 }
  private void render(final boolean isSlow, final boolean clearPreviousOnError) {
    if (!toolWindowVisible) {
      return;
    }

    final VirtualFile file = toolWindowForm.getFile();
    if (file == null) {
      return;
    }

    toolWindowForm.getPreviewPanel().clearCannotRender();

    if (isSlow) {
      toolWindowForm.getPreviewPanel().getLoadingDecorator().startLoading(false);
      loadingDecoratorStarted++;
    }

    toolWindowForm.waitingForGetDocument = true;
    XmlFile xmlFile = (XmlFile) PsiManager.getInstance(project).findFile(file);
    LogMessageUtil.LOG.assertTrue(xmlFile != null);
    AsyncResult<BufferedImage> result =
        DesignerApplicationManager.getInstance().getDocumentImage(xmlFile);
    result.doWhenDone(
        new QueuedAsyncResultHandler<BufferedImage>() {
          @Override
          protected boolean isExpired() {
            return toolWindowForm == null || !file.equals(toolWindowForm.getFile());
          }

          @Override
          public void process(final BufferedImage image) {
            UIUtil.invokeLaterIfNeeded(
                new Runnable() {
                  @Override
                  public void run() {
                    toolWindowForm.getPreviewPanel().setImage(image);
                  }
                });
          }
        });

    result.doWhenProcessed(
        new Runnable() {
          @Override
          public void run() {
            toolWindowForm.waitingForGetDocument = false;
            if (isSlow && --loadingDecoratorStarted == 0 && toolWindowForm != null) {
              toolWindowForm.getPreviewPanel().getLoadingDecorator().stopLoading();
            }
          }
        });

    result.doWhenRejected(
        new Runnable() {
          @Override
          public void run() {
            if (clearPreviousOnError) {
              toolWindowForm.getPreviewPanel().setImage(null);
            }
            UIUtil.invokeLaterIfNeeded(
                new Runnable() {
                  @Override
                  public void run() {
                    toolWindowForm.getPreviewPanel().showCannotRender();
                  }
                });
          }
        });
  }
  private void initToolWindow() {
    toolWindowForm = new MxmlPreviewToolWindowForm();
    String toolWindowId = FlashUIDesignerBundle.message("mxml.preview.tool.window.title");
    toolWindow =
        ToolWindowManager.getInstance(project)
            .registerToolWindow(toolWindowId, false, ToolWindowAnchor.RIGHT, project, false);
    toolWindow.setIcon(PlatformIcons.UI_FORM_ICON);

    PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(project);
    toolWindowVisible = propertiesComponent.getBoolean(SETTINGS_TOOL_WINDOW_VISIBLE);
    if (toolWindowVisible) {
      toolWindow.show(null);
    } else {
      toolWindow.hide(null);
    }

    ((ToolWindowManagerEx) ToolWindowManager.getInstance(project))
        .addToolWindowManagerListener(
            new ToolWindowManagerAdapter() {
              @Override
              public void stateChanged() {
                if (project.isDisposed() || toolWindow == null || !toolWindow.isAvailable()) {
                  return;
                }

                final boolean currentVisible = toolWindow.isVisible();
                if (currentVisible == toolWindowVisible) {
                  return;
                }

                toolWindowVisible = currentVisible;

                PropertiesComponent propertiesComponent = PropertiesComponent.getInstance(project);
                if (currentVisible) {
                  propertiesComponent.setValue(SETTINGS_TOOL_WINDOW_VISIBLE, true);

                  if (!lastPreviewChecked) {
                    lastPreviewChecked = true;
                    if (checkLastImage()) {
                      return;
                    }
                  }

                  render(true, false);
                } else {
                  propertiesComponent.unsetValue(SETTINGS_TOOL_WINDOW_VISIBLE);
                }
              }
            });

    JPanel contentPanel = toolWindowForm.getContentPanel();
    ContentManager contentManager = toolWindow.getContentManager();
    Content content = contentManager.getFactory().createContent(contentPanel, null, false);
    content.setCloseable(false);
    content.setPreferredFocusableComponent(contentPanel);
    contentManager.addContent(content);
    contentManager.setSelectedContent(content, true);

    MessageBusConnection connection =
        ApplicationManager.getApplication().getMessageBus().connect(project);
    connection.subscribe(
        DesignerApplicationManager.MESSAGE_TOPIC,
        new DocumentRenderedListener() {
          private boolean isApplicable(DocumentFactoryManager.DocumentInfo info) {
            return toolWindowVisible
                && toolWindowForm.getFile() != null
                && info.equals(
                    DocumentFactoryManager.getInstance().getNullableInfo(toolWindowForm.getFile()));
          }

          @Override
          public void documentRendered(DocumentFactoryManager.DocumentInfo info) {
            if (isApplicable(info) && !toolWindowForm.waitingForGetDocument) {
              UIUtil.invokeLaterIfNeeded(
                  new Runnable() {
                    @Override
                    public void run() {
                      render(false, false);
                    }
                  });
            }
          }

          @Override
          public void errorOccurred() {}
        });
  }