@Override
  public boolean performFinish() {

    IFile file = null;
    try {
      IWorkspace workspace = ResourcesPlugin.getWorkspace();
      File afile = new File(page.getAbsoluteFilePath());
      IPath location = Path.fromOSString(afile.getAbsolutePath());
      file = workspace.getRoot().getFileForLocation(location);

      final IWorkbenchPart part = EclipseUtils.getPage().getActivePart();
      final IPlottingSystem system = getPlottingSystem();
      final IFunctionService funcService =
          (IFunctionService) part.getAdapter(IFunctionService.class);

      final IFile finalFile = file;
      getContainer()
          .run(
              true,
              true,
              new IRunnableWithProgress() {

                @Override
                public void run(IProgressMonitor monitor)
                    throws InvocationTargetException, InterruptedException {

                  IPersistentFile file = null;
                  try {
                    IPersistenceService service = ServiceLoader.getPersistenceService();
                    String savePath;
                    if (finalFile != null) savePath = finalFile.getLocation().toOSString();
                    else savePath = page.getAbsoluteFilePath();
                    final File ioFile = new File(savePath);
                    if (ioFile.exists()) ioFile.delete();
                    file = service.createPersistentFile(savePath);

                    final int length = getTotalWork(options, system, funcService);
                    monitor.beginTask("Export", length);
                    final IMonitor mon = new ProgressMonitorWrapper(monitor);

                    // Save things.
                    if (options.is(PersistWizardConstants.ORIGINAL_DATA)) {
                      Collection<ITrace> traces = system.getTraces();
                      for (ITrace trace : traces) {
                        monitor.worked(1);
                        Dataset data = (Dataset) trace.getData();
                        if (trace.getName() != null) data.setName(trace.getName());
                        file.setData(data);
                        if (trace instanceof IImageTrace) {
                          final List<IDataset> iaxes = ((IImageTrace) trace).getAxes();
                          if (iaxes != null) file.setAxes(iaxes);
                        } else if (trace instanceof ILineTrace) {
                          IDataset xData = ((ILineTrace) trace).getXData();
                          if (xData != null)
                            file.setAxes(Arrays.asList(new IDataset[] {xData, null}));
                        }
                      }
                    }
                    if (options.is(PersistWizardConstants.IMAGE_HIST)) {
                      final IToolPageSystem tsystem =
                          (IToolPageSystem) system.getAdapter(IToolPageSystem.class);
                      final IToolPage tool = tsystem.getActiveTool();
                      if (tool != null
                          && tool.getToolId()
                              .equals("org.dawb.workbench.plotting.tools.imageCompareTool")) {
                        final Map<String, IDataset> data =
                            (Map<String, IDataset>) tool.getToolData();
                        if (data != null && !data.isEmpty()) {
                          file.setHistory(data.values().toArray(new IDataset[data.size()]));
                          monitor.worked(1);
                        }
                      }
                    }

                    final ITrace trace = system.getTraces().iterator().next();
                    if (options.is(PersistWizardConstants.MASK) && trace instanceof IImageTrace) {
                      IImageTrace image = (IImageTrace) trace;
                      final String name = options.getString(PersistWizardConstants.MASK);
                      if (image.getMask() != null) {
                        file.addMask(name, (BooleanDataset) image.getMask(), mon);
                        monitor.worked(1);
                      }
                    }

                    final Collection<IRegion> regions = system.getRegions();
                    if (options.is(PersistWizardConstants.REGIONS)
                        && regions != null
                        && !regions.isEmpty()) {
                      for (IRegion iRegion : regions) {
                        monitor.worked(1);
                        if (!file.isRegionSupported(iRegion.getROI())) {
                          logger.debug(
                              "Region "
                                  + iRegion.getName()
                                  + " of type "
                                  + iRegion.getClass().getName()
                                  + " is not supported");
                          continue;
                        }
                        file.addROI(iRegion.getName(), iRegion.getROI());
                        file.setRegionAttribute(
                            iRegion.getName(), "Region Type", iRegion.getRegionType().getName());
                        if (iRegion.getUserObject() != null) {
                          file.setRegionAttribute(
                              iRegion.getName(), "User Object", iRegion.getUserObject().toString());
                        }
                      }
                    }

                    if (options.is(PersistWizardConstants.DIFF_META)) {
                      if (trace != null
                          && trace instanceof IImageTrace
                          && trace.getData() != null) {
                        IMetadata meta = trace.getData().getMetadata();
                        if (meta == null || meta instanceof IDiffractionMetadata) {
                          monitor.worked(1);
                          file.setDiffractionMetadata((IDiffractionMetadata) meta);
                        }
                      }
                    }

                    if (options.is(PersistWizardConstants.FUNCTIONS)) {
                      if (funcService != null) {
                        Map<String, IFunction> functions = funcService.getFunctions();
                        if (functions != null) {
                          monitor.worked(functions.size());
                          file.setFunctions(functions);
                        }
                      }
                    }

                  } catch (Exception e) {
                    throw new InvocationTargetException(e);
                  } finally {
                    if (file != null) file.close();
                  }
                }
              });
    } catch (Throwable ne) {
      if (ne instanceof InvocationTargetException
          && ((InvocationTargetException) ne).getCause() != null) {
        ne = ((InvocationTargetException) ne).getCause();
      }
      String message = null;
      if (file != null) {
        message = "Cannot export '" + file.getName() + "' ";
      } else {
        message = "Cannot export file.";
      }
      logger.error("Cannot export file!", ne);
      ErrorDialog.openError(
          Display.getDefault().getActiveShell(),
          "Export failure",
          message,
          new Status(IStatus.WARNING, "org.dawb.common.ui", ne.getMessage(), ne));
      return true;
    } finally {
      try {
        if (file != null)
          file.getParent().refreshLocal(IResource.DEPTH_ONE, new NullProgressMonitor());
      } catch (CoreException e) {
        logger.error("Cannot refresh dir " + file, e);
      }
    }

    containerFullPath = Path.fromOSString(page.getAbsoluteFilePath());
    staticFileName = page.getFileLabel();

    return true;
  }
  public boolean canFinish() {
    if (page.isPageComplete() && getContainer().getCurrentPage() == page) {
      options.setDescription("Please choose the things to save in '" + page.getPath() + "'.");
      options.setOptionEnabled(PersistWizardConstants.ORIGINAL_DATA, false);
      options.setOptionEnabled(PersistWizardConstants.IMAGE_HIST, false);
      options.setOptionEnabled(PersistWizardConstants.MASK, false);
      options.setOptionEnabled(PersistWizardConstants.REGIONS, false);
      options.setOptionEnabled(PersistWizardConstants.DIFF_META, false);
      options.setOptionEnabled(PersistWizardConstants.FUNCTIONS, false);

      File file = null;
      IPersistentFile pf = null;

      PERSIST_BLOCK:
      try {
        IPersistenceService service = ServiceLoader.getPersistenceService();
        file = new File(page.getAbsoluteFilePath());
        if (!file.exists()) break PERSIST_BLOCK;
        pf = service.getPersistentFile(file.getAbsolutePath());
        final List<String> names = pf.getMaskNames(null);
        if (names != null && !names.isEmpty()) {
          options.setStringValue(PersistWizardConstants.MASK, names.get(0));
        }

      } catch (Throwable ne) {
        logger.error("Cannot read persistence file at " + file);
      } finally {
        if (pf != null) pf.close();
      }

      final IPlottingSystem system = getPlottingSystem();
      if (system != null) {
        if (system != null) {
          ITrace trace = system.getTraces().iterator().next();
          if (trace != null) {

            options.setOptionEnabled(PersistWizardConstants.ORIGINAL_DATA, true);

            if (trace instanceof IImageTrace && ((IImageTrace) trace).getMask() != null) {
              options.setOptionEnabled(PersistWizardConstants.MASK, true);
            }
          }

          boolean requireHistory = false;
          final IToolPageSystem tsystem =
              (IToolPageSystem) system.getAdapter(IToolPageSystem.class);
          final IToolPage tool = tsystem.getActiveTool();
          if (tool != null
              && tool.getToolId().equals("org.dawb.workbench.plotting.tools.imageCompareTool")) {
            final Map<String, IDataset> data = (Map<String, IDataset>) tool.getToolData();
            if (data != null && !data.isEmpty()) requireHistory = true;
          }
          options.setOptionEnabled(PersistWizardConstants.IMAGE_HIST, requireHistory);

          final Collection<IRegion> regions = system.getRegions();
          if (regions != null && !regions.isEmpty()) {
            options.setOptionEnabled(PersistWizardConstants.REGIONS, true);
          }

          if (trace != null && trace instanceof IImageTrace && trace.getData() != null) {
            IMetadata meta = ((Dataset) trace.getData()).getMetadata();
            if (meta != null && (meta instanceof IDiffractionMetadata)) {
              options.setOptionEnabled(PersistWizardConstants.DIFF_META, true);
            }
          }

          final IWorkbenchPart part = EclipseUtils.getPage().getActivePart();
          if (part != null) {
            final IFunctionService funcService =
                (IFunctionService) part.getAdapter(IFunctionService.class);
            if (funcService != null) {
              options.setOptionEnabled(PersistWizardConstants.FUNCTIONS, true);
            }
          }
        }
      }
    }
    return super.canFinish();
  }