this.customPreprocessors.add( customProcessor );
	public void initProject() {		// find out where J2ME Polish has been installed to:		this.polishHomePath = getProject().getProperty( "polish.home" );		if (this.polishHomePath != null) {			File dir = new File( this.polishHomePath );			if (!dir.isAbsolute()) {				dir = new File( getProject().getBaseDir(), this.polishHomePath );				this.polishHomePath = dir.getAbsolutePath();			}			this.polishHomePath += File.separatorChar;			this.polishHomeDir = new File( this.polishHomePath );		} else {			this.polishHomeDir = new File( "." );		}				try {			// load extensions:			this.extensionManager = new ExtensionManager( getProject(), this.buildSetting.openExtensions() );			this.extensionManager.loadCustomDefinitions( this.buildSetting.getCustomExtensions() );		} catch (Exception e) {			e.printStackTrace();			throw new BuildException("Unable to load extensions.xml - please report this error to j2mepolish@enough.de.");		}				// create environment		this.environment = new Environment( this.extensionManager, getProject(), this );		this.environment.setBuildSetting( this.buildSetting );				// create debug manager:		boolean isDebugEnabled = this.buildSetting.isDebugEnabled(); 		DebugManager debugManager = null;		if (isDebugEnabled) {			try {				debugManager = new DebugManager( this.buildSetting.getDebugSetting(), this.extensionManager, this.environment );			} catch (BuildException e) {				throw new BuildException( e.getMessage(), e );			}		}				// create project settings:		this.polishProject = new PolishProject( this.buildSetting.usePolishGui(), isDebugEnabled, debugManager );		this.polishProject.addDirectCapability("polish.buildVersion", VERSION);		this.polishProject.addDirectFeature( "polish.active" );		if (debugManager != null && debugManager.isVerbose()) {			this.polishProject.addFeature("debugVerbose");			this.polishProject.addFeature("debug.verbose");			this.polishProject.addDirectCapability("polish.debug.Verbose", "enabled");		}		if (debugManager != null && this.buildSetting.getDebugSetting().showLogOnError()) {			this.polishProject.addFeature("showLogOnError");		}		this.polishProject.addCapability("license", this.infoSetting.getlicense() );		if (isDebugEnabled) {			this.polishProject.addFeature("debugEnabled");		}		// specify some preprocessing symbols depending on the selected features:		this.polishProject.addFeature(this.buildSetting.getImageLoadStrategy());		// this is actually outdated and only kept for backwards-compatibility:		if (debugManager != null && this.buildSetting.getDebugSetting().useGui()) {			this.polishProject.addFeature("useDebugGui");		}		// add all ant properties if desired: 		if (this.buildSetting.includeAntProperties()) {			Hashtable antProperties = getProject().getProperties();			Set keySet = antProperties.keySet();			for (Iterator iter = keySet.iterator(); iter.hasNext();) {				String key = (String) iter.next();				this.polishProject.addDirectCapability( key, (String) antProperties.get(key) );			}		}		// add all variables from the build.xml:		/*		Variable[] variables = this.buildSetting.getVariables();		if (variables != null) {			ArrayList conditionalVarsList = new ArrayList();			for (int i = 0; i < variables.length; i++) {				Variable var = variables[i];				if (var.hasCondition()) {					conditionalVarsList.add( var );				} else {					//System.out.println("adding variable [" + var.getName() + "]." );					this.polishProject.addDirectCapability( var );				}			}			this.conditionalVariables = (Variable[]) conditionalVarsList.toArray( new Variable[ conditionalVarsList.size() ]); 		}		*/		this.variables = this.buildSetting.getVariables();		Variable[] unconditionalVars = this.variables.getUnconditionalVariables();		for (int i = 0; i < unconditionalVars.length; i++) {			Variable variable = unconditionalVars[i];			this.polishProject.addDirectCapability( variable );		}				// add all symbols from the build.xml:		String symbolDefinition = this.buildSetting.getSymbols();		if (symbolDefinition != null) {			String[] symbols = StringUtil.splitAndTrim( symbolDefinition, ',' );			for (int i = 0; i < symbols.length; i++) {				this.polishProject.addDirectFeature( symbols[i] );			}		}				// add primary midlet-class-definition:		String[] midletClassNames = this.buildSetting.getMidletClassNames();		this.polishProject.addDirectCapability("polish.midlet.class", midletClassNames[0] );		for (int i = 0; i < midletClassNames.length; i++) {			this.polishProject.addDirectCapability("polish.classes.midlet-" + (i+1), midletClassNames[i] );					}				// load CSS attributes:		// create CSS attributes manager:		if (this.buildSetting.usePolishGui()) {			this.cssAttributesManager = new CssAttributesManager( this.buildSetting.openStandardCssAttributes() );			InputStream is = this.buildSetting.openCustomCssAttributes();			if (is != null) {				this.cssAttributesManager.addCssAttributes(is);			}			boolean allowAllCssAttributes = "true".equals( this.polishProject.getCapability("polish.css.allowAllAttributes") );			if (allowAllCssAttributes) {				CssAttribute[] attributes = this.cssAttributesManager.getAttributes();				for (int i = 0; i < attributes.length; i++) {					CssAttribute attribute = attributes[i];					String name = attribute.getName();					String feature = "polish.css." + name;					this.polishProject.addDirectFeature( feature );				}			}		}		// create device database:		this.deviceDatabase = new DeviceDatabase( getProject().getProperties(), this.polishHomeDir, getProject().getBaseDir(),				this.buildSetting.getApiDir(), this.polishProject, this.buildSetting.getDeviceDatabaseInputStreams(), this.buildSetting.getDeviceDatabaseFiles() );				this.libraryManager = this.deviceDatabase.getLibraryManager();		this.environment.setLibraryManager(this.libraryManager);				// create capability/vendor/group/device manager:		this.deviceManager = this.deviceDatabase.getDeviceManager();						// create preprocessor:		boolean replacePropertiesWithoutDirective = false;		if (this.variables != null) {			replacePropertiesWithoutDirective = this.variables.replacePropertiesWithoutDirective();		}		if (!replacePropertiesWithoutDirective) {			replacePropertiesWithoutDirective = this.buildSetting.replacePropertiesWithoutDirective();		}		this.preprocessor = new Preprocessor( this.polishProject, this.environment, null, false, true, replacePropertiesWithoutDirective, null );		this.preprocessor.setUseDefaultPackage( this.buildSetting.useDefaultPackage() );		this.preprocessor.setCssAttributesManager( this.cssAttributesManager );		// init custom preprocessors:		this.customPreprocessors = new ArrayList();		PreprocessorSetting[] settings = this.buildSetting.getPreprocessors();		//CustomPreprocessor[] processors = new CustomPreprocessor[ settings.length + 1];		// add the polish custom processor:		// new PolishPreprocessor();		PreprocessorSetting preprocessorSetting = new PreprocessorSetting();		preprocessorSetting.setName("polish");		CustomPreprocessor customProcessor = CustomPreprocessor.getInstance(preprocessorSetting, this.preprocessor, this.extensionManager, this.environment );		//customProcessor.init(this.preprocessor, null);		this.customPreprocessors.add( customProcessor );		//processors[0] = customProcessor;		for (int i = 0; i < settings.length; i++) {			preprocessorSetting = settings[i];			customProcessor = CustomPreprocessor.getInstance(preprocessorSetting, this.preprocessor, this.extensionManager, this.environment );			this.customPreprocessors.add( customProcessor );		}				//	initialise the preprocessing-source-directories:		DirectoryScanner dirScanner = new DirectoryScanner();		dirScanner.setIncludes( new String[]{"**/*.java"} );		this.sourceSettings = this.buildSetting.getSourceSettings();		//File[] dirs = this.buildSetting.getSourceDirs();		//this.sourceDirs = new File[ dirs.length];		this.sourceFiles = new TextFile[ this.sourceSettings.length][];		TextFileManager textFileManager = new TextFileManager();		this.preprocessor.setTextFileManager(textFileManager);		if (this.buildSetting.getPolishDir() != null) {			// there is an explicit J2ME Polish directory:			this.polishSourceDir = this.buildSetting.getPolishDir();			dirScanner.setBasedir(this.polishSourceDir);			dirScanner.scan();			this.polishSourceFiles = getTextFiles( this.polishSourceDir,  dirScanner.getIncludedFiles(), textFileManager );		} else {			// the J2ME Polish sources need to be loaded from the jar-file:			long lastModificationTime = 0;			File jarFile = new File( this.buildSetting.getApiDir().getAbsolutePath() 					+ File.separator + "enough-j2mepolish-build.jar");			if (jarFile.exists()) {				lastModificationTime = jarFile.lastModified();			} else {				jarFile = new File("import/enough-j2mepolish-build.jar");				if (jarFile.exists()) {					lastModificationTime = jarFile.lastModified();				}			}			this.polishSourceDir = new File("src");			try {				String[] fileNames = this.resourceUtil.readTextFile( ".", "build/j2mepolish.index.txt");				this.polishSourceFiles = getTextFiles( "src", fileNames, lastModificationTime, textFileManager );			} catch (IOException e) {				throw new BuildException("Unable to load the J2ME source files from enough-j2mepolish-build.jar: " + e.getMessage(), e );			}		}				// load the normal source files:		for (int i = 0; i < this.sourceSettings.length; i++) {			SourceSetting setting = this.sourceSettings[i];			File dir = setting.getDir();			if (!dir.exists()) {				throw new BuildException("The source-directory [" + dir.getAbsolutePath() + "] does not exist. Please check your settings in the [sourceDir] attribute of the <build> element.");			}			//this.sourceDirs[i] = dir; 			dirScanner.setBasedir(dir);			dirScanner.scan();			this.sourceFiles[i] = getTextFiles( dir,  dirScanner.getIncludedFiles(), textFileManager );		}		if (this.buildSetting.usePolishGui() && this.styleSheetSourceFile == null) {			throw new BuildException("Did not find the file [StyleSheet.java] of the J2ME Polish GUI framework. Please adjust the [polishDir] attribute of the <build> element in the [build.xml] file. The [polishDir]-attribute should point to the directory which contains the J2ME Polish-Java-sources.");		}				// load third party binary libraries, if any.		// When there are third party libraries, they will all be extracted		// and copied to the build/binary folder for easier integration:		this.binaryLibraries = this.buildSetting.getBinaryLibraries();		if (this.binaryLibraries != null) {			File binaryBaseDir = new File( this.buildSetting.getWorkDir(), "binary");			try {				this.binaryLibrariesUpdated = this.binaryLibraries.copyToCache( binaryBaseDir );			} catch (IOException e) {				e.printStackTrace();				throw new BuildException("Unable to copy the binary libraries to the internal cache [" + binaryBaseDir.getAbsolutePath() + "]: " + e.toString(), e );			}		} // done preparing of binary libraries.				// init boot class path:		this.midp1BootClassPath = new Path( getProject(), this.buildSetting.getMidp1Path().getAbsolutePath());		this.midp2BootClassPath = new Path( getProject(), this.buildSetting.getMidp2Path().getAbsolutePath());		this.midp2Cldc11BootClassPath = new Path( getProject(), this.buildSetting.getMidp2Cldc11Path().getAbsolutePath());				// init postcompilers:		if (this.buildSetting.doPostCompile()) {			this.doPostCompile = true;			PostCompilerSetting[] postCompilerSettings = this.buildSetting.getPostCompilers();			this.postCompilers = new PostCompiler[ postCompilerSettings.length ];			for (int i = 0; i < postCompilerSettings.length; i++) {				PostCompilerSetting setting = postCompilerSettings[i];				this.postCompilers[i] = PostCompiler.getInstance(setting, this.extensionManager, this.environment);			}		}								// init obfuscators:		if (this.buildSetting.doObfuscate()) {			ObfuscatorSetting[] obfuscatorSettings = this.buildSetting.getObfuscatorSettings();			ArrayList obfuscatorsList = new ArrayList();			String[] keepClasses = null;			for (int i = 0; i < obfuscatorSettings.length; i++) {				ObfuscatorSetting obfuscatorSetting = obfuscatorSettings[i];				if (keepClasses == null && 						obfuscatorSetting.hasKeepDefinitions()) {					keepClasses = obfuscatorSetting.getPreserveClassNames();				}				if ((obfuscatorSetting.isEnabled())) {					Obfuscator obfuscator;					try {						obfuscator = Obfuscator.getInstance( obfuscatorSetting, getProject(), this.extensionManager, this.environment );					} catch (BuildException e) {						throw e;					} catch (Exception e) {						e.printStackTrace();						throw new BuildException("Unable to initialize the obfuscator [" + obfuscatorSetting.getName() + "/" + obfuscatorSetting.getClassName() + "]: " + e.toString() );					}					obfuscatorsList.add( obfuscator );				}							}			this.doObfuscate = (obfuscatorsList.size() > 0);			if (this.doObfuscate) {				this.obfuscators = (Obfuscator[]) obfuscatorsList.toArray( new Obfuscator[ obfuscatorsList.size() ] );				this.useDefaultPackage = this.buildSetting.useDefaultPackage();								String[] midletClasses = this.buildSetting.getMidletClassNames();				if (keepClasses == null) {					keepClasses = new String[0];				}				this.preserveClasses = new String[ keepClasses.length + midletClasses.length ];				System.arraycopy( keepClasses, 0, this.preserveClasses, 0,  keepClasses.length );				System.arraycopy( midletClasses, 0, this.preserveClasses, keepClasses.length, midletClasses.length  );			}		}				// init import manager:		this.importConverter = new ImportConverter();				// init base style sheet:		if (this.buildSetting.usePolishGui()) {			ResourceSetting resourceSetting = this.buildSetting.getResourceSetting();			File cssFile = new File( resourceSetting.getDir().getAbsolutePath() + File.separatorChar + "polish.css");			if (!cssFile.exists()) {				log("Unable to find polish.css at [" + cssFile.getAbsolutePath() + "] - you should create this file when you want to make most of the J2ME Polish GUI.", Project.MSG_WARN );				this.styleSheet = new StyleSheet();			} else {				CssReader cssReader = new CssReader();				try {					cssReader.add(cssFile);				} catch (IOException e) {					throw new BuildException("Unable to load polish.css: " + e.getMessage(), e );				}				this.styleSheet = cssReader.getStyleSheet();			}		}				// set the names of the midlets:		this.midletClassesByName = new HashMap();		String[] midletClasses = this.buildSetting.getMidletClassNames();		for (int i = 0; i < midletClasses.length; i++) {			this.midletClassesByName.put( midletClasses[i], Boolean.TRUE );					}				// get the java-extension:		this.javaExtensions = this.buildSetting.getJavaExtensions();				// get the javac-settings:		this.javacTarget = this.buildSetting.getJavacTarget();				// get the resource manager:		this.resourceManager = new ResourceManager( this.buildSetting.getResourceSetting(), this.extensionManager, this.environment );		Locale[] localizations = this.resourceManager.getLocales();		if (localizations != null) {			this.localizationSetting = this.buildSetting.getResourceSetting().getLocalizationSetting();			if (this.localizationSetting.isDynamic()) {				this.supportedLocales = null;			} else {				this.supportedLocales = localizations;			}			// add the preprocessor for translations:			String className;			if (this.localizationSetting != null) {				className = this.localizationSetting.getPreprocessorClassName();			} else {				className = "de.enough.polish.preprocess.custom.TranslationPreprocessor";			}			PreprocessorSetting setting = new PreprocessorSetting();			setting.setClass( className );			this.translationPreprocessor = (TranslationPreprocessor) CustomPreprocessor.getInstance(setting, this.preprocessor,  this.extensionManager, this.environment );			this.customPreprocessors.add( this.translationPreprocessor );			if (this.localeSourceFile == null) {				throw new BuildException("Unable to find [de.enough.polish.util.Locale.java] in the path, please set the \"polishDir\"-attribute of the <build>-element correctly.");			}		}				try {			// get the packager for creating the final jar-file:			this.extensionManager.registerExtensions( ExtensionManager.TYPE_PACKAGER, this.buildSetting.getPackageSettings(), this.environment );		} catch (Exception e) {			e.printStackTrace();			throw new BuildException("Unable to initialize packager: " + e.toString() );		}				// check if there has been an error at the last run:		this.errorLock = new File( this.buildSetting.getWorkDir().getAbsolutePath()				+ File.separator + "error.lock");		if (this.errorLock.exists()) {			this.lastRunFailed = true;		} else {			this.lastRunFailed = false;			try {				this.errorLock.createNewFile();			} catch (IOException e) {				System.err.println("Warning: unable to create temporary lock file: " + e.toString() );			}		}				// set J2ME Polish specific logger,		// this logger will show the original source-code positions		// and remove some verbose logging from ProGuard etc:		Vector buildListeners = getProject().getBuildListeners();		BuildLogger logger = null;		for (Iterator iter = buildListeners.iterator(); iter.hasNext();) {			BuildListener listener = (BuildListener) iter.next();			if (listener instanceof BuildLogger) {				logger = (BuildLogger) listener;				break;			}					}		if (logger != null) {			// prepare the classPathTranslations-Map:			HashMap classPathTranslationsMap = new HashMap(); 			for (int i=0; i < this.sourceFiles.length; i++) {				TextFile[] files = this.sourceFiles[i];				for (int j = 0; j < files.length; j++) {					TextFile file = files[j];					classPathTranslationsMap.put( file.getFilePath(), file.getFile().getAbsolutePath() );				}			}			this.polishLogger = new PolishLogger(logger, classPathTranslationsMap );			getProject().addBuildListener( this.polishLogger );			getProject().removeBuildListener(logger);		} else {			System.err.println("Warning: unable to replace Ant-logger. Compile errors will point to the preprocessed files instead of the original sources.");		}	}