gt:         if( _oldVMToolFolder == null ) {
context: /*
  * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
  *
  * This program and the accompanying materials are made available
  * under the terms of the Eclipse Public License, Version 1.0,
  * which accompanies this distribution and is available at
  *
  * http://www.eclipse.org/legal/epl-v10.html
  *
  */
  package net.rim.ejde.internal.util;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.URL;
  import java.util.Properties;
  
  import net.rim.ejde.internal.core.ContextManager;
  import net.rim.ejde.internal.core.IConstants;
  import net.rim.ejde.internal.model.BlackBerryVMInstallType;
  import net.rim.ejde.internal.ui.dialogs.VCWarningDialog;
  import net.rim.ejde.internal.ui.preferences.PreferenceConstants;
  import net.rim.ide.OSUtils;
  
  import org.apache.log4j.Logger;
  import org.eclipse.core.runtime.FileLocator;
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.core.runtime.Path;
  import org.eclipse.core.runtime.Platform;
  import org.eclipse.core.runtime.preferences.IEclipsePreferences;
  import org.eclipse.core.runtime.preferences.InstanceScope;
  import org.eclipse.jdt.launching.IVMInstall;
  import org.eclipse.jdt.launching.LibraryLocation;
  import org.eclipse.osgi.util.NLS;
  import org.eclipse.swt.widgets.Display;
  import org.osgi.framework.Bundle;
  
  /**
   * The Class is used to manage VM tools. It copies the tools (e.g. SignatureTool.jar, JavaLoader.exe, etc) from the highest
   * version of the VM installed into a local cache. If the VM is uninstalled, the local cache will be removed.
   *
   * @author jheifetz
   */
  public class VMToolsUtils {
  
      static private final Logger _log = Logger.getLogger( VMToolsUtils.class );
      private static IPath _storedVMToolFolder;
      private static IPath _oldVMToolFolder;
  
      /**
       * Gets the VM tools folder name.
       *
       * @return the VM tools folder name
       */
      public static String getVMToolsFolderName() {
          return ContextManager.getDefault().getPreferenceStore().getString( IConstants.VMTOOLS_LOCATION_KEY );
      }
  
      /**
       * Gets the bundle data folder name.
       *
       * @return the bundle data folder name
       */
      public static String getBundleDataFolderName() {
          return ContextManager.getDefault().getPreferenceStore().getString( IConstants.BUNDLE_DATA_LOCATION_KEY );
      }
  
      /**
       * Gets the VM tools folder path.
       *
       * @return the VM tools folder path
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getVMToolsFolderPath() throws IOException {
          if( _storedVMToolFolder == null ) {
              Bundle bundle = Platform.getBundle( ContextManager.PLUGIN_ID );
              FileLocator.resolve( FileLocator.find( bundle, Path.ROOT, null ) );
              URL bundleURL = FileLocator.resolve( FileLocator.find( bundle, Path.ROOT, null ) );
              String bundlePath = bundleURL.getFile();
              bundlePath = bundlePath.substring( bundlePath.indexOf( IPath.SEPARATOR ) + 1 );
              _storedVMToolFolder = new Path( bundlePath ).removeLastSegments( 1 ).append(
                      VMToolsUtils.getBundleDataFolderName() + IPath.SEPARATOR + VMToolsUtils.getVMToolsFolderName() );
          }
          return _storedVMToolFolder;
      }
  
      /**
       * Gets the Signature tools path.
       *
       * @return the Signature tool path
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getSignatureToolPath() throws IOException {
          return VMToolsUtils.getVMToolsFolderPath().append( IPath.SEPARATOR + IConstants.SIGNATURE_TOOL_FILE_NAME );
      }
  
      /**
       * Gets the JavaLoader path.
       *
       * @return the JavaLoader path
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getJavaLoaderPath() throws IOException {
          return VMToolsUtils.getVMToolsFolderPath().append( IPath.SEPARATOR + IConstants.JAVA_LOADER_FILE_NAME );
      }
  
      /**
       * Gets the version file path.
       *
       * @return the version path
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getVersionFilePath() throws IOException {
          return VMToolsUtils.getVMToolsFolderPath().append( IPath.SEPARATOR + IConstants.VERSION_PROPERTY_FILE_NAME );
      }
  
      /**
       * Gets the path for the given tool.
       *
       * @param name
       *            The tool name
       * @return the tool path
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getToolPath( String name ) throws IOException {
          return VMToolsUtils.getVMToolsFolderPath().append( IPath.SEPARATOR + name );
      }
  
      /**
       * Gets the fledgehook path.
       *
       * @param file
       *            name. i.e fledgehook.exe or fledgehook.dll the vm that has been added.
       *
       * @return the fledgehook path
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getFledgeHookPath( String name ) throws IOException {
          return VMToolsUtils.getVMToolsFolderPath().append( IPath.SEPARATOR + name );
      }
  
      /**
       * Updates the VM tools on the addition of a VM. If the VM version is greater than the stored version, it is copied. If not,
       * nothing happens
       *
       * VMs are compared based on modification stamp of the Jar.
       *
       * @param vm
       *            the vm that has been added.
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static void addVMTools( IVMInstall vm ) throws IOException {
          if( ( null == vm ) || !BlackBerryVMInstallType.VM_ID.equals( vm.getVMInstallType().getId() ) ) {
              return;
          }
          // check source attachment
          LibraryLocation[] libraryLocations = vm.getLibraryLocations();
          IPath sourcePath;
          if( libraryLocations != null ) {
              for( int i = 0; i < libraryLocations.length; i++ ) {
                  sourcePath = libraryLocations[ i ].getSystemLibrarySourcePath();
                  if( sourcePath == null || sourcePath.isEmpty() ) {
                      sourcePath = ImportUtils.getSourceJarPath( libraryLocations[ i ].getSystemLibraryPath() );
                      if( sourcePath.toFile().exists() ) {
                          _log.trace( "Source has been attached to library jar "
                                  + libraryLocations[ i ].getSystemLibraryPath().lastSegment() + " in JRE " + vm.getName() );
                          libraryLocations[ i ].setSystemLibrarySource( sourcePath );
                      }
                  }
              }
          }
          IPath sigToolPath = new Path( vm.getInstallLocation().getAbsolutePath() + IPath.SEPARATOR + IConstants.BIN_FOLD_NAME
                  + IPath.SEPARATOR + IConstants.SIGNATURE_TOOL_FILE_NAME );
          File sigToolFile = sigToolPath.toFile();
          if( !sigToolFile.exists() ) {
              throw new IOException( "Cannot Find Signature Tool At: " + sigToolPath.toString() );
          }
          IPath javaLoaderPath = new Path( vm.getInstallLocation().getAbsolutePath() + IPath.SEPARATOR + IConstants.BIN_FOLD_NAME
                  + IPath.SEPARATOR + IConstants.JAVA_LOADER_FILE_NAME );
          File javaLoaderFile = javaLoaderPath.toFile();
          if( !javaLoaderFile.exists() ) {
              throw new IOException( "Cannot Find JavaLoader.exe At: " + javaLoaderPath.toString() );
          }
  
          // if()
          // copyFledgeHookFile();
          File fledgeHookFile = null;
          File fledgeHookDllFile = null;
          if( OSUtils.isWindows() ) {
              IPath fledgeHookPath = new Path( vm.getInstallLocation().getAbsolutePath() + IPath.SEPARATOR
                      + IConstants.BIN_FOLD_NAME + IPath.SEPARATOR + IConstants.FLEDGE_HOOK_FILE_NAME );
              fledgeHookFile = fledgeHookPath.toFile();
  
              IPath fledgeHookDllPath = new Path( vm.getInstallLocation().getAbsolutePath() + IPath.SEPARATOR
                      + IConstants.BIN_FOLD_NAME + IPath.SEPARATOR + IConstants.FLEDGE_HOOK_DLL_FILE_NAME );
              fledgeHookDllFile = fledgeHookDllPath.toFile();
          }
          File storedSigTool = VMToolsUtils.getSignatureToolPath().toFile();
          File storedJavaLoader = VMToolsUtils.getJavaLoaderPath().toFile();
          File storedVersionFile = VMToolsUtils.getVersionFilePath().toFile();
          File storedFledgeHookFile = null;
          File storedFledgeHookDllFile = null;
          if( OSUtils.isWindows() ) {
              storedFledgeHookFile = VMToolsUtils.getFledgeHookPath( IConstants.FLEDGE_HOOK_FILE_NAME ).toFile();
              storedFledgeHookDllFile = VMToolsUtils.getFledgeHookPath( IConstants.FLEDGE_HOOK_DLL_FILE_NAME ).toFile();
          }
          // Compare the VM version against the stored version, if it is greater, copy the tools to the stored folder.
          // If the version file does not exist, just copy the tools and create the version file.
          boolean checkFlag = false;
          if( OSUtils.isWindows() ) {
              checkFlag = !storedFledgeHookFile.exists() || !storedFledgeHookDllFile.exists();
          }
          if( ( !storedVersionFile.exists() ) || ( VMUtils.getVMVersion( vm ).compareTo( getStoredVersion() ) > 0 )
                  || !storedSigTool.exists() || !storedJavaLoader.exists() || checkFlag ) {
              FileUtils.copyOverwrite( sigToolFile, storedSigTool );
              FileUtils.copyOverwrite( javaLoaderFile, storedJavaLoader );
              if( !storedJavaLoader.canExecute() ) {
                  storedJavaLoader.setExecutable( true );
              }
              setStoredVersion( VMUtils.getVMVersion( vm ) );
              if( OSUtils.isWindows() ) {
                  if( fledgeHookFile.exists() && fledgeHookDllFile.exists() ) {
                      // copy from new cp/bin to vmTools
                      FileUtils.copyOverwrite( fledgeHookFile, storedFledgeHookFile );
                      FileUtils.copyOverwrite( fledgeHookDllFile, storedFledgeHookDllFile );
                  } else {// force copy from bundle to vmTools
                      copyFledgeHookFile();
                  }
              }
          }
  
          if( !OSUtils.isWindows() ) {
              // For non windows environments
              File jnilibFileInCP = new Path( vm.getInstallLocation().getAbsolutePath() + IPath.SEPARATOR
                      + IConstants.BIN_FOLD_NAME + IPath.SEPARATOR + IConstants.CP_JNI_LIB_2_FILE_NAME ).toFile();
              // Currently we do not copy the libRIMUsbJni.jnilib file into the VMTools directory
              // but in this code blog we make sure if such file exists then it has the executable permission.
              File storedJniLibFile = VMToolsUtils.getToolPath( IConstants.CP_JNI_LIB_2_FILE_NAME ).toFile();
              if( storedJniLibFile.exists() && ( !storedJniLibFile.canExecute() ) ) {
                  storedJniLibFile.setExecutable( true );// In VMTools directory
              } else if( jnilibFileInCP.exists() && ( !jnilibFileInCP.canExecute() ) ) {
                  jnilibFileInCP.setExecutable( true );// In CP
              }
          }
  
          // Copy csk and db file from old vm tool folder (i.e signTool) if it exists to new location
          File cskFile = VMToolsUtils.getToolPath( IConstants.CSK_FILE_NAME ).toFile();
          File dbFile = VMToolsUtils.getToolPath( IConstants.DB_FILE_NAME ).toFile();
          if( !cskFile.exists() || !dbFile.exists() ) {
              // try to copy the files from old signTool folder if there is
              File oldCskFile = new File( VMToolsUtils.getOldVMToolsFolderPath() + File.separator + IConstants.CSK_FILE_NAME );
              File oldDbFile = new File( VMToolsUtils.getOldVMToolsFolderPath() + File.separator + IConstants.DB_FILE_NAME );
              if( oldCskFile.exists() && oldDbFile.exists() ) {
                  FileUtils.copyOverwrite( oldCskFile, cskFile );
                  FileUtils.copyOverwrite( oldDbFile, dbFile );
                  _log.info( Messages.CodeSigningPrefsPage_MessageDialogMsg8 );
              }
          }
  
          // show BlackBerry getting started page upon first-time Eclipse launch.
          showStartupPage();
  
          String eeVersion = VMUtils.getVMVersion( vm );
          if( OSUtils.isWindows() && is6OrLater( eeVersion ) && ( !WindowsRegistryReader.isVC2008RuntimeInstalled() ) ) {
              _log.debug( "Using 6.0+ but missing key FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4" );
              warnMissingVC2008( eeVersion );
          }
      }
  
      /**
       * Updates the VM tools on the removal of a VM. If the VM version is the same as the stored version, it is removed, and all
       * VMs are re-scanned. If not, nothing happens
       *
       * @param vm
       *            the vm that has been removed.
       *
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static void removeVMTools( IVMInstall vm ) throws IOException {
          if( ( null == vm ) || !BlackBerryVMInstallType.VM_ID.equals( vm.getVMInstallType().getId() ) ) {
              return;
          }
          String vmVersion = VMUtils.getVMVersion( vm );
          String storedVersion = getStoredVersion();
          if( vmVersion.equals( storedVersion ) ) {
              File storedSigTool = VMToolsUtils.getSignatureToolPath().toFile();
              storedSigTool.delete();
              File storedJavaLoader = VMToolsUtils.getJavaLoaderPath().toFile();
              storedJavaLoader.delete();
              File storedVersionFile = VMToolsUtils.getVersionFilePath().toFile();
              boolean deleted = storedVersionFile.delete();
              System.out.println( deleted );
              for( IVMInstall otherVMs : VMUtils.getInstalledBBVMs() ) {
                  if( !otherVMs.equals( vm ) ) {
                      VMToolsUtils.addVMTools( otherVMs );
                  }
              }
          }
      }
  
      public static String getStoredVersion() {
          String version = IConstants.DEFAULT_VM_VERSION;
          FileInputStream fis = null;
          try {
              String fileName = getVersionFilePath().toOSString();
              Properties properties = new Properties();
              fis = new FileInputStream( fileName );
              properties.load( fis );
              version = properties.getProperty( IConstants.VM_VERSION );
          } catch( IOException e ) {
              _log.error( e );
          } finally {
              if( fis != null ) {
                  try {
                      fis.close();
                  } catch( IOException e ) {
                  }
              }
          }
          return version;
      }
  
      private static void setStoredVersion( String version ) throws IOException {
          Properties properties = new Properties();
          properties.setProperty( IConstants.VM_VERSION, version );
          String fileName = getVersionFilePath().toOSString();
          FileOutputStream fos = null;
          try {
              fos = new FileOutputStream( fileName );
              properties.store( fos, null );
          } finally {
              if( fos != null ) {
                  try {
                      fos.close();
                  } catch( IOException e ) {
                  }
              }
          }
      }
  
      /**
       * Checks if all the vm tools are valid.
       *
       * @return
       * @throws IOException
       */
      static public final boolean isVMToolValid() throws IOException {
          IPath javaLoaderPath = getJavaLoaderPath();
          IPath signatureToolPath = getSignatureToolPath();
          if( !javaLoaderPath.toFile().exists() || !signatureToolPath.toFile().exists() ) {
              addVMTools( VMUtils.getLatestSDK() );
          }
          if( !javaLoaderPath.toFile().exists() || !signatureToolPath.toFile().exists() ) {
              return false;
          }
          return true;
      }
  
      /**
       * Checks if the signature tool is valid to be used.
       *
       * @return
       * @throws IOException
       */
      static public final boolean isSignatureToolValid() throws IOException {
          IPath signatureToolPath = getSignatureToolPath();
          // check if the signaturetool.jar is there
          if( !signatureToolPath.toFile().exists() ) {
              addVMTools( VMUtils.getLatestSDK() );
          }
          if( !signatureToolPath.toFile().exists() ) {
              return false;
          }
          // check if there is any csk and db file
          File cskFile = new File( VMToolsUtils.getVMToolsFolderPath() + File.separator + IConstants.CSK_FILE_NAME );
          File dbFile = new File( VMToolsUtils.getVMToolsFolderPath() + File.separator + IConstants.DB_FILE_NAME );
          if( ( !cskFile.exists() ) && ( !dbFile.exists() ) ) {
              return false;
          }
          return true;
      }
  
      /**
       * Copy FledgeHook.exe to the vm tools folder.
       *
       * @throws IOException
       */
      static private void copyFledgeHookFile() throws IOException {
          String[] names = { IConstants.FLEDGE_HOOK_FILE_NAME, IConstants.FLEDGE_HOOK_DLL_FILE_NAME };
  
          IPath location = new Path( VMToolsUtils.getVMToolsFolderPath() + File.separator );
  
          InputStream inputStream;
          OutputStream outputStream;
          File fledgeFile;
          byte[] buf;
          int numbytes;
          URL bundUrl;
  
          for( String fledgeFileName : names ) {
              inputStream = null;
              outputStream = null;
  
              try {
                  fledgeFile = location.append( fledgeFileName ).toFile();
                  Bundle bundle = Platform.getBundle( ContextManager.PLUGIN_ID );
                  if( fledgeFile.exists() ) {
                      if( !fledgeFile.delete() ) {
                          _log.warn( "Could not replace file " + fledgeFile ); //$NON-NLS-1$
                          return;
                      }
                  }
  
                  bundUrl = bundle.getResource( fledgeFileName );
  
                  if( bundUrl == null )
                      continue;
  
                  inputStream = bundUrl.openStream();
                  outputStream = new FileOutputStream( fledgeFile );
                  buf = new byte[ 4096 ];
                  numbytes = 0;
  
                  while( ( numbytes = inputStream.read( buf ) ) > 0 )
                      outputStream.write( buf, 0, numbytes );
  
              } catch( IOException t ) {
                  _log.error( t.getMessage(), t );
              } finally {
                  try {
                      if( inputStream != null )
                          inputStream.close();
  
                      if( outputStream != null )
                          outputStream.close();
                  } catch( IOException t ) {
                      _log.error( t.getMessage(), t );
                  }
              }
          }
      }
  
      /**
       * Gets old VM tools (i.e. signTool) folder path.
       *
       * @return the old VM tools folder path
       * @throws IOException
       *             Signals that an I/O exception has occurred.
       */
      public static IPath getOldVMToolsFolderPath() throws IOException {
  