class Spoon extends ApplicationWindow implements AddUndoPositionInterface, TabListener, SpoonInterface,
  OverwritePrompter, PDIObserver, LifeEventHandler, XulEventSource, XulEventHandler, PartitionSchemasProvider {

  public boolean saveToFile( EngineMetaInterface meta ) throws KettleException {
    if ( meta == null ) {
      return false;
    }

    boolean saved = false;

    ( (AbstractMeta) meta ).setRepository( rep );
    ( (AbstractMeta) meta ).setMetaStore( metaStore );

    if ( getLog().isDetailed() ) {
      // "Save to file or repository...
      getLog().logDetailed( BaseMessages.getString( PKG, "Spoon.Log.SaveToFileOrRepository" ) );
    }

    SpoonPerspective activePerspective = SpoonPerspectiveManager.getInstance().getActivePerspective();

    // In case the perspective wants to handle open/save itself, let it...
    //
    if ( activePerspective instanceof SpoonPerspectiveOpenSaveInterface ) {
      return ( (SpoonPerspectiveOpenSaveInterface) activePerspective ).save( meta );
    }

    String activePerspectiveId = activePerspective.getId();
    boolean etlPerspective = activePerspectiveId.equals( MainSpoonPerspective.ID );
    if ( rep != null && etlPerspective ) {
      if ( meta.getObjectId() == null ) {
        meta.setFilename( null );
      }
      saved = saveToRepository( meta );
    } else {
      if ( meta.getFilename() != null ) {
        saved = save( meta, meta.getFilename(), false );
      } else {
        if ( meta.canSave() ) {
          saved = saveFileAs( meta );
        }
      }
    }

    meta.saveSharedObjects(); // throws Exception in case anything goes wrong

    try {
      if ( props.useDBCache() && meta instanceof TransMeta ) {
        ( (TransMeta) meta ).getDbCache().saveCache();
      }
    } catch ( KettleException e ) {
      new ErrorDialog(
        shell, BaseMessages.getString( PKG, "Spoon.Dialog.ErrorSavingDatabaseCache.Title" ),
        // "An error occurred saving the database cache to disk"
        BaseMessages.getString( PKG, "Spoon.Dialog.ErrorSavingDatabaseCache.Message" ), e );
    }

    // rename the tab only if the meta was successfully saved
    if ( saved ) {
      delegates.tabs.renameTabs(); // filename or name of transformation might have changed.
    }
    refreshTree();

    // Update menu status for the newly saved object
    enableMenus();

    return saved;
  }

  private  Spoon();
  private  Spoon( Repository rep );

}