Changes:
authorkhartlage <khartlage>
Sat, 11 Oct 2003 12:45:34 +0000 (12:45 +0000)
committerkhartlage <khartlage>
Sat, 11 Oct 2003 12:45:34 +0000 (12:45 +0000)
- Smarty syntax highlighting
- new templates for Smarty
- Improved code completion
- Encoding can be set now
- Organized Imports

264 files changed:
net.sourceforge.phpeclipse/plugin.properties
net.sourceforge.phpeclipse/plugin.xml
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestorAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ElementChangedEvent.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IBufferFactory.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompletionRequestor.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IElementChangedListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElementDelta.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaModel.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMethod.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IOpenable.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IParent.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IProblemRequestor.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IRegion.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceRange.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceReference.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaCore.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/compiler/ITerminalSymbols.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/dialog/ExternalToolVariableForm.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/ExternalToolsPlugin.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/model/VariableContextManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/program/launchConfigurations/ProgramBuilderTabGroup.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/program/launchConfigurations/ProgramLaunchDelegate.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/program/launchConfigurations/ProgramMainTab.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/program/launchConfigurations/ProgramTabGroup.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/registry/ArgumentVariable.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/registry/ArgumentVariableRegistry.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/registry/ExternalToolVariableRegistry.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/registry/PathLocationVariable.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/registry/RefreshScopeVariable.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/registry/RefreshScopeVariableRegistry.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/ui/FileSelectionDialog.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/ui/MessageLine.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/ui/StatusDialog.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/internal/ui/StatusInfo.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/launchConfigurations/ExternalToolsRefreshTab.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/model/StringMatcher.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/model/ToolUtil.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/variable/ExpandVariableContext.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/variable/IVariableComponent.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/variable/ResourceComponent.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/variable/ResourceExpander.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/variable/SpecificFileResourceComponent.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/externaltools/variable/SpecificFolderResourceComponent.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ConfigurableOption.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AbstractCase.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AbstractPHPComment.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ArrayDeclarator.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ArrayInitializer.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ArrayVariableDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AstNode.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/BinaryExpression.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Block.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/BranchStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/CastExpression.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ClassAccess.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ClassDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ConditionalExpression.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ConstantIdentifier.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Define.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/DoStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/EchoStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Else.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ElseIf.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/EmptyStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/FalseLiteral.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/FieldDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ForStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ForeachStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/FunctionCall.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/GlobalStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/HTMLBlock.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/IfStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/InclusionStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ListExpression.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Literal.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/MethodDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/PHPDocument.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/PHPEchoBlock.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/PrintExpression.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/ReturnStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/StaticStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/StringLiteral.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/SwitchStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/TrueLiteral.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/UnaryExpression.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/VarAssignation.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Variable.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/VariableDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/WhileStatement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/PHPFunctionDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/PHPOutlineInfo.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/PHPVarDeclaration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/Util.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/messages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BatchOperation.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BufferManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElement.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementDelta.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelStatus.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Region.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Util.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/PerThreadObject.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocUtil.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitCompletion.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/HTMLUnitContext.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/PHPTemplateMessages.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/PHPUnitContext.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUIMessages.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/PHPUiImages.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/SelectionDispatchAction.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/WorkbenchRunnableAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/dialog/StatusUtil.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.java [copied from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/ObfuscatorMessages.java with 54% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/CodeFormatterPreferencePage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/AbstractJavaScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaAnnotationHover.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaColorManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/LineBreakingReader.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPAnnotationHover.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPAnnotationHover.java with 99% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IProblemRequestorExtension.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaFormattingStrategy.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/BuiltInProposal.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/StreamUtil.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/TableLayoutComposite.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewClassCreationWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewElementWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.java [copied from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/ObfuscatorMessages.java with 54% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/CheckedListDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ComboDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/DialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IDialogFieldListener.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IListAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IStringButtonAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ITreeListAdapter.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/LayoutUtil.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ListDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogFieldGroup.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/Separator.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonStatusDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/TreeListDialogField.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/IColorManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewClassWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewElementWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewTypeWizardPage.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/IPreferenceConstants.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPCore.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPEclipseParserPreferencePage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPPerspectiveFactory.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPSyntaxEditorPreferencePage.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPeclipsePlugin.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPEclipseShowAction.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPExternalParserAction.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPObfuscatorAction.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ExternalEditorInput.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/ExternalStorageDocumentProvider.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/FileStorage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/PHPIdentifierLocation.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/CopyMover.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DefaultFilter.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DefaultMover.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DirectoryWalker.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/IFilter.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/IMover.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/PHPFilter.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/default-obfuscator.xml [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_DE.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_FR.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_en_GB.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/newPHPPreferencesMessages_es_ES.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnoreSet.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/ObfuscatorIgnoreSet.java with 99% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorIgnores.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/ObfuscatorIgnores.java with 98% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/ObfuscatorMessages.java with 95% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorMessages.properties [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/ObfuscatorMessages.properties with 100% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass1Exporter.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/PHPAnalyzer.java with 59% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/ObfuscatorPass2Exporter.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/PHPObfuscatorMover.java with 61% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/PHPIdentifier.java [moved from net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/PHPIdentifier.java with 87% similarity]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/default-obfuscator.xml [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportOperation.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportWizard.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/WizardObfuscatorResourceExportPage1.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/messages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/AnnotationType.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/IJavaAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationIterator.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaMarkerAnnotation.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRuler.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRulerHoverManager.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPActionContributor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParserAction.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSyntaxRdr.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PaintManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PrintMarginPainter.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/ProblemAnnotationIterator.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/TogglePresentationAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormatter.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormattingStrategy.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLCompletionProcessor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/IPHPPartitionScannerConstants.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartition.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/Partition.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PartitionStack.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyDocCodeScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/resourcesview/MainActionGroup.java
net.sourceforge.phpeclipse/src/test/PHPParserManager.java
net.sourceforge.phpeclipse/src/test/PHPParserSuperclass.java
net.sourceforge.phpeclipse/src/test/PHPParserTokenManager.java
net.sourceforge.phpeclipse/src/test/PHPVar.java

index 6154c8e..97666be 100644 (file)
@@ -12,6 +12,11 @@ viewPHPResources.name=PHP Resources
 newWizardCategory.name=PHP
 newWizardPHPProject.name=PHP Project
 newWizardPHPFile.name=PHP File
+NewPHPClass.label= Class
+NewPHPClass.description=Create a PHP class
+
+ExportWizards.Obfuscator = Obfuscate PHP Project to File system
+ExportWizards.ObfuscatorDescription = Obfuscate PHP resources to the local file system
 
 propertyPagePHPProject.name=PHP Project Properties
 
@@ -28,6 +33,7 @@ phtmlFileExtension=phtml
 htmlFileExtension=html
 htmFileExtension=htm
 xmlFileExtension=xml
+tplFileExtension=tpl
 #
 # Action sets
 #
index 1d9e23f..801f657 100644 (file)
@@ -19,6 +19,7 @@
       <import plugin="org.eclipse.swt"/>
       <import plugin="org.eclipse.debug.core"/>
       <import plugin="org.eclipse.debug.ui"/>
+      <import plugin="org.eclipse.search"/>
       <import plugin="org.apache.xerces"/>
       <import plugin="org.eclipse.update.ui"/>
    </requires>
             type="text"
             extension="xml">
       </fileTypes>
+      <fileTypes
+            type="text"
+            extension="tpl">
+      </fileTypes>
    </extension>
    <extension
          point="org.eclipse.ui.perspectives">
             name="%newWizardCategory.name"
             id="net.sourceforge.phpeclipse.wizards.NewWizardCategoryPHP">
       </category>
-<!--    
-Temporarily replaced until errors can be ironed out...
--->
       <wizard
             name="%newWizardPHPProject.name"
             icon="icons/obj16/php.gif"
@@ -111,6 +113,15 @@ Temporarily replaced until errors can be ironed out...
             Create a new PHP project.
          </description>
       </wizard>
+<!--   <wizard
+               id="net.sourceforge.phpdt.internal.ui.wizards.NewClassCreationWizard"
+               name="%NewPHPClass.label"
+               class="net.sourceforge.phpdt.internal.ui.wizards.NewClassCreationWizard"
+               category="net.sourceforge.phpeclipse.wizards.NewWizardCategoryPHP"
+               icon="icons/ctool16/newclass_wiz.gif">
+               <description>%NewPHPClass.description</description>
+       </wizard>      
+      -->
 <!--
 <this wizard replaces it as it works - maybe not as pretty but still>
 
@@ -148,6 +159,15 @@ Temporarily replaced until errors can be ironed out...
          </description>
       </wizard>
    </extension>
+   <extension point="org.eclipse.ui.exportWizards">
+     <wizard name="%ExportWizards.Obfuscator" 
+             icon="icons/ctool16/exportdir_wiz.gif" 
+             class="net.sourceforge.phpeclipse.obfuscator.export.ObfuscatorExportWizard" 
+             id="net.sourceforge.phpeclipse.obfuscator.export.ObfuscatorExportWizard">
+     <description>%ExportWizards.ObfuscatorDescription</description> 
+     <selection class="org.eclipse.core.resources.IResource" /> 
+     </wizard>
+  </extension>
    <extension
          point="org.eclipse.ui.projectNatureImages">
       <image
@@ -262,6 +282,15 @@ Temporarily replaced until errors can be ironed out...
             class="net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor"
             id="net.sourceforge.phpeclipse.PHPUnitEditor">
       </editor>
+      <editor
+            name="%phpEditorName"
+            default="true"
+            icon="icons/obj16/htmledit.gif"
+            extensions="tpl"
+            contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
+            class="net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor"
+            id="net.sourceforge.phpeclipse.PHPUnitEditor">
+      </editor>
    </extension>
    <extension
          point="org.eclipse.ui.actionSets">
@@ -419,16 +448,6 @@ Temporarily replaced until errors can be ironed out...
    <extension
          point="org.eclipse.ui.popupMenus">
       <objectContribution
-            objectClass="org.eclipse.core.resources.IResource"
-            id="net.sourceforge.phpeclipse.actions.obfuscator">
-         <action
-               label="PHP Obfuscator"
-               class="net.sourceforge.phpeclipse.actions.PHPObfuscatorAction"
-               menubarPath="additions"
-               id="net.sourceforge.phpeclipse.actions.obfuscatorAction">
-         </action>
-      </objectContribution>
-      <objectContribution
             objectClass="org.eclipse.core.resources.IFile"
             nameFilter="*.php"
             id="net.sourceforge.phpeclipse.actions.externalParserAction">
@@ -730,6 +749,14 @@ Temporarily replaced until errors can be ironed out...
       </provider>
    </extension>
    <extension
+         point="org.eclipse.ui.documentProviders">
+      <provider
+            extensions="%tplFileExtension"
+            class="net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider"
+            id="net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider">
+      </provider>
+   </extension>
+   <extension
          point="org.eclipse.ui.views">
       <view
             name="%phpConsoleView"
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestorAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestorAdapter.java
new file mode 100644 (file)
index 0000000..c473feb
--- /dev/null
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import net.sourceforge.phpdt.core.compiler.IProblem;
+
+
+/**
+ * Adapter of the requestor interface <code>ICompletionRequestor</code>.
+ * <p>
+ * This class is intended to be instanciated and subclassed by clients.
+ * </p>
+ *
+ * @see ICompletionRequestor
+ * @since 2.0
+ */
+public class CompletionRequestorAdapter implements ICompletionRequestor {
+
+       /*
+        * @see ICompletionRequestor#acceptAnonymousType(char[], char[], char[][], char[][], char[][], char[], int, int, int)
+        */
+       public void acceptAnonymousType(
+               char[] superTypePackageName,
+               char[] superTypeName,
+               char[][] parameterPackageNames,
+               char[][] parameterTypeNames,
+               char[][] parameterNames,
+               char[] completionName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptClass(char[], char[], char[], int, int, int)
+        */
+       public void acceptClass(
+               char[] packageName,
+               char[] className,
+               char[] completionName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptError(IProblem)
+        */
+       public void acceptError(IProblem error) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptField(char[], char[], char[], char[], char[], char[], int, int, int)
+        */
+       public void acceptField(
+               char[] declaringTypePackageName,
+               char[] declaringTypeName,
+               char[] name,
+               char[] typePackageName,
+               char[] typeName,
+               char[] completionName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptInterface(char[], char[], char[], int, int, int)
+        */
+       public void acceptInterface(
+               char[] packageName,
+               char[] interfaceName,
+               char[] completionName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptKeyword(char[], int, int)
+        */
+       public void acceptKeyword(
+               char[] keywordName,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptLabel(char[], int, int)
+        */
+       public void acceptLabel(
+               char[] labelName,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptLocalVariable(char[], char[], char[], int, int, int)
+        */
+       public void acceptLocalVariable(
+               char[] name,
+               char[] typePackageName,
+               char[] typeName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptMethod(char[], char[], char[], char[][], char[][], char[][], char[], char[], char[], int, int, int)
+        */
+       public void acceptMethod(
+               char[] declaringTypePackageName,
+               char[] declaringTypeName,
+               char[] selector,
+               char[][] parameterPackageNames,
+               char[][] parameterTypeNames,
+               char[][] parameterNames,
+               char[] returnTypePackageName,
+               char[] returnTypeName,
+               char[] completionName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptMethodDeclaration(char[], char[], char[], char[][], char[][], char[][], char[], char[], char[], int, int, int)
+        */
+       public void acceptMethodDeclaration(
+               char[] declaringTypePackageName,
+               char[] declaringTypeName,
+               char[] selector,
+               char[][] parameterPackageNames,
+               char[][] parameterTypeNames,
+               char[][] parameterNames,
+               char[] returnTypePackageName,
+               char[] returnTypeName,
+               char[] completionName,
+               int modifiers,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptModifier(char[], int, int)
+        */
+       public void acceptModifier(
+               char[] modifierName,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptPackage(char[], char[], int, int)
+        */
+       public void acceptPackage(
+               char[] packageName,
+               char[] completionName,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptType(char[], char[], char[], int, int)
+        */
+       public void acceptType(
+               char[] packageName,
+               char[] typeName,
+               char[] completionName,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptVariableName(char[], char[], char[], char[], int, int)
+        */
+       public void acceptVariableName(
+               char[] typePackageName,
+               char[] typeName,
+               char[] name,
+               char[] completionName,
+               int completionStart,
+               int completionEnd,
+               int relevance) {
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ElementChangedEvent.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ElementChangedEvent.java
new file mode 100644 (file)
index 0000000..9c16bea
--- /dev/null
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import java.util.EventObject;
+
+/**
+ * An element changed event describes a change to the structure or contents
+ * of a tree of Java elements. The changes to the elements are described by
+ * the associated delta object carried by this event.
+ * <p>
+ * This class is not intended to be instantiated or subclassed by clients.
+ * Instances of this class are automatically created by the Java model.
+ * </p>
+ *
+ * @see IElementChangedListener
+ * @see IJavaElementDelta
+ */
+public class ElementChangedEvent extends EventObject {
+       
+       /**
+        * Event type constant (bit mask) indicating an after-the-fact 
+        * report of creations, deletions, and modifications
+        * to one or more Java element(s) expressed as a hierarchical
+        * java element delta as returned by <code>getDelta()</code>.
+        *
+        * Note: this notification occurs during the corresponding POST_CHANGE
+        * resource change notification, and contains a full delta accounting for
+        * any JavaModel operation  and/or resource change.
+        *
+        * @see IJavaElementDelta
+        * @see org.eclipse.core.resources.IResourceChangeEvent
+        * @see #getDelta()
+        * @since 2.0
+        */
+       public static final int POST_CHANGE = 1;
+
+       /**
+        * Event type constant (bit mask) indicating an after-the-fact 
+        * report of creations, deletions, and modifications
+        * to one or more Java element(s) expressed as a hierarchical
+        * java element delta as returned by <code>getDelta</code>.
+        *
+        * Note: this notification occurs during the corresponding PRE_AUTO_BUILD
+        * resource change notification. The delta, which is notified here, only contains
+        * information relative to the previous JavaModel operations (in other words, 
+        * it ignores the possible resources which have changed outside Java operations). 
+        * In particular, it is possible that the JavaModel be inconsistent with respect to
+        * resources, which got modified outside JavaModel operations (it will only be
+        * fully consistent once the POST_CHANGE notification has occurred).
+        * 
+        * @see IJavaElementDelta
+        * @see org.eclipse.core.resources.IResourceChangeEvent
+        * @see #getDelta()
+        * @since 2.0
+        */
+       public static final int PRE_AUTO_BUILD = 2;
+
+       /**
+        * Event type constant (bit mask) indicating an after-the-fact 
+        * report of creations, deletions, and modifications
+        * to one or more Java element(s) expressed as a hierarchical
+        * java element delta as returned by <code>getDelta</code>.
+        *
+        * Note: this notification occurs as a result of a working copy reconcile
+        * operation.
+        *
+        * @see IJavaElementDelta
+        * @see org.eclipse.core.resources.IResourceChangeEvent
+        * @see #getDelta()
+        * @since 2.0
+        */
+       public static final int         POST_RECONCILE = 4;     
+       /*
+        * Event type indicating the nature of this event. 
+        * It can be a combination either:
+        *  - POST_CHANGE
+        *  - PRE_AUTO_BUILD
+        *  - POST_RECONCILE
+        */
+       private int type; 
+       
+       /**
+        * Creates an new element changed event (based on a <code>IJavaElementDelta</code>).
+        *
+        * @param delta the Java element delta.
+        */
+       public ElementChangedEvent(IJavaElementDelta delta, int type) {
+               super(delta);
+               this.type = type;
+       }
+       /**
+        * Returns the delta describing the change.
+        *
+        * @return the delta describing the change
+        */
+       public IJavaElementDelta getDelta() {
+               return (IJavaElementDelta) source;
+       }
+       
+       /**
+        * Returns the type of event being reported.
+        *
+        * @return one of the event type constants
+        * @see #POST_CHANGE
+        * @see #PRE_AUTO_BUILD
+        * @see #POST_RECONCILE
+        * @since 2.0
+        */
+       public int getType() {
+               return this.type;
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java
new file mode 100644 (file)
index 0000000..3fcf33a
--- /dev/null
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import net.sourceforge.phpdt.internal.compiler.env.IConstants;
+
+
+
+/**
+ * Utility class for decoding modifier flags in Java elements.
+ * <p>
+ * This class provides static methods only; it is not intended to be
+ * instantiated or subclassed by clients.
+ * </p>
+ * <p>
+ * Note that the numeric values of these flags match the ones for class files
+ * as described in the Java Virtual Machine Specification. The AST class
+ * <code>Modifier</code> provides the same functionality as this class, only in
+ * the <code>org.eclipse.jdt.core.dom</code> package.
+ * </p>
+ *
+ * @see IMember#getFlags
+ */
+public final class Flags {
+
+       /**
+        * Public access flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+       public static final int AccPublic = IConstants.AccPublic;
+       /**
+        * Private access flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+       public static final int AccPrivate = IConstants.AccPrivate;
+       /**
+        * Protected access flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+       public static final int AccProtected = IConstants.AccProtected;
+       /**
+        * Static access flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+       public static final int AccStatic = IConstants.AccStatic;
+       /**
+        * Final access flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+       public static final int AccFinal = IConstants.AccFinal;
+       /**
+        * Synchronized access flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccSynchronized = IConstants.AccSynchronized;
+       /**
+        * Volatile property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccVolatile = IConstants.AccVolatile;
+       /**
+        * Transient property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccTransient = IConstants.AccTransient;
+       /**
+        * Native property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccNative = IConstants.AccNative;
+       /**
+        * Interface property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccInterface = IConstants.AccInterface;
+       /**
+        * Abstract property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccAbstract = IConstants.AccAbstract;
+       /**
+        * Strictfp property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccStrictfp = IConstants.AccStrictfp;
+       /**
+        * Super property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+       public static final int AccSuper = IConstants.AccSuper;
+       /**
+        * Synthetic property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccSynthetic = IConstants.AccSynthetic;
+       /**
+        * Deprecated property flag. See The Java Virtual Machine Specification for more details.
+        * @since 2.0
+        */
+//     public static final int AccDeprecated = IConstants.AccDeprecated;
+       
+       /**
+        * Not instantiable.
+        */
+       private Flags() {
+       }
+       /**
+        * Returns whether the given integer includes the <code>abstract</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>abstract</code> modifier is included
+        */
+//     public static boolean isAbstract(int flags) {
+//             return (flags & AccAbstract) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the indication that the 
+        * element is deprecated (<code>@deprecated</code> tag in Javadoc comment).
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the element is marked as deprecated
+        */
+//     public static boolean isDeprecated(int flags) {
+//             return (flags & AccDeprecated) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the <code>final</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>final</code> modifier is included
+        */
+       public static boolean isFinal(int flags) {
+               return (flags & AccFinal) != 0;
+       }
+       /**
+        * Returns whether the given integer includes the <code>interface</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>interface</code> modifier is included
+        * @since 2.0
+        */
+//     public static boolean isInterface(int flags) {
+//             return (flags & AccInterface) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the <code>native</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>native</code> modifier is included
+        */
+//     public static boolean isNative(int flags) {
+//             return (flags & AccNative) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the <code>private</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>private</code> modifier is included
+        */
+       public static boolean isPrivate(int flags) {
+               return (flags & AccPrivate) != 0;
+       }
+       /**
+        * Returns whether the given integer includes the <code>protected</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>protected</code> modifier is included
+        */
+       public static boolean isProtected(int flags) {
+               return (flags & AccProtected) != 0;
+       }
+       /**
+        * Returns whether the given integer includes the <code>public</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>public</code> modifier is included
+        */
+       public static boolean isPublic(int flags) {
+               return (flags & AccPublic) != 0;
+       }
+       /**
+        * Returns whether the given integer includes the <code>static</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>static</code> modifier is included
+        */
+       public static boolean isStatic(int flags) {
+               return (flags & AccStatic) != 0;
+       }
+       /**
+        * Returns whether the given integer includes the <code>strictfp</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>strictfp</code> modifier is included
+        */
+//     public static boolean isStrictfp(int flags) {
+//             return (flags & AccStrictfp) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the <code>synchronized</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>synchronized</code> modifier is included
+        */
+//     public static boolean isSynchronized(int flags) {
+//             return (flags & AccSynchronized) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the indication that the 
+        * element is synthetic.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the element is marked synthetic
+        */
+//     public static boolean isSynthetic(int flags) {
+//             return (flags & AccSynthetic) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the <code>transient</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>transient</code> modifier is included
+        */
+//     public static boolean isTransient(int flags) {
+//             return (flags & AccTransient) != 0;
+//     }
+       /**
+        * Returns whether the given integer includes the <code>volatile</code> modifier.
+        *
+        * @param flags the flags
+        * @return <code>true</code> if the <code>volatile</code> modifier is included
+        */
+//     public static boolean isVolatile(int flags) {
+//             return (flags & AccVolatile) != 0;
+//     }
+       /**
+        * Returns a standard string describing the given modifier flags.
+        * Only modifier flags are included in the output; the deprecated and
+        * synthetic flags are ignored if set.
+        * <p>
+        * The flags are output in the following order:
+        * <pre>
+        *   <code>public</code> <code>protected</code> <code>private</code> 
+        *   <code>static</code> 
+        *   <code>abstract</code> <code>final</code> <code>native</code> <code>synchronized</code> <code>transient</code> <code>volatile</code> <code>strictfp</code>
+        * </pre>
+        * This is a compromise between the orders specified in sections 8.1.1,
+        * 8.3.1, 8.4.3, 8.8.3, 9.1.1, and 9.3 of <em>The Java Language 
+        * Specification, Second Edition</em> (JLS2).
+        * </p> 
+        * <p>
+        * Examples results:
+        * <pre>
+        *        <code>"public static final"</code>
+        *        <code>"private native"</code>
+        * </pre>
+        * </p>
+        *
+        * @param flags the flags
+        * @return the standard string representation of the given flags
+        */
+       public static String toString(int flags) {
+               StringBuffer sb = new StringBuffer();
+
+               if (isPublic(flags))
+                       sb.append("public "); //$NON-NLS-1$
+               if (isProtected(flags))
+                       sb.append("protected "); //$NON-NLS-1$
+               if (isPrivate(flags))
+                       sb.append("private "); //$NON-NLS-1$
+               if (isStatic(flags))
+                       sb.append("static "); //$NON-NLS-1$
+//             if (isAbstract(flags))
+//                     sb.append("abstract "); //$NON-NLS-1$
+               if (isFinal(flags))
+                       sb.append("final "); //$NON-NLS-1$
+//             if (isNative(flags))
+//                     sb.append("native "); //$NON-NLS-1$
+//             if (isSynchronized(flags))
+//                     sb.append("synchronized "); //$NON-NLS-1$
+//             if (isTransient(flags))
+//                     sb.append("transient "); //$NON-NLS-1$
+//             if (isVolatile(flags))
+//                     sb.append("volatile "); //$NON-NLS-1$
+//             if (isStrictfp(flags))
+//                     sb.append("strictfp "); //$NON-NLS-1$
+
+               int len = sb.length();
+               if (len == 0)
+                       return ""; //$NON-NLS-1$
+               sb.setLength(len - 1);
+               return sb.toString();
+       }
+}
index 15b61e6..45389b6 100644 (file)
@@ -28,6 +28,6 @@ public interface IBufferFactory {
         * @param owner the owner of the buffer
         * @see IBuffer
         */
-       IBuffer createBuffer(IOpenable owner);
+//     IBuffer createBuffer(IOpenable owner);
 }
 
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompilationUnit.java
new file mode 100644 (file)
index 0000000..94f7f88
--- /dev/null
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+
+/**
+ * Represents an entire Java compilation unit (<code>.java</code> source file).
+ * Compilation unit elements need to be opened before they can be navigated or manipulated.
+ * The children are of type <code>IPackageDeclaration</code>,
+ * <code>IImportContainer</code>, and <code>IType</code>,
+ * and appear in the order in which they are declared in the source.
+ * If a <code>.java</code> file cannot be parsed, its structure remains unknown.
+ * Use <code>IJavaElement.isStructureKnown</code> to determine whether this is 
+ * the case.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface ICompilationUnit extends IJavaElement, IParent, IOpenable {
+//extends IJavaElement, ISourceReference, IParent, IOpenable, IWorkingCopy, ISourceManipulation, ICodeAssist {
+/**
+ * Creates and returns an import declaration in this compilation unit
+ * with the given name.
+ * <p>
+ * Optionally, the new element can be positioned before the specified
+ * sibling. If no sibling is specified, the element will be inserted
+ * as the last import declaration in this compilation unit.
+ * <p>
+ * If the compilation unit already includes the specified import declaration,
+ * the import is not generated (it does not generate duplicates).
+ * Note that it is valid to specify both a single-type import and an on-demand import
+ * for the same package, for example <code>"java.io.File"</code> and
+ * <code>"java.io.*"</code>, in which case both are preserved since the semantics
+ * of this are not the same as just importing <code>"java.io.*"</code>.
+ * Importing <code>"java.lang.*"</code>, or the package in which the compilation unit
+ * is defined, are not treated as special cases.  If they are specified, they are
+ * included in the result.
+ *
+ * @param name the name of the import declaration to add as defined by JLS2 7.5. (For example: <code>"java.io.File"</code> or
+ *  <code>"java.awt.*"</code>)
+ * @param sibling the existing element which the import declaration will be inserted immediately before (if
+ *     <code> null </code>, then this import will be inserted as the last import declaration.
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted import declaration (or the previously existing one in case attempting to create a duplicate)
+ *
+ * @exception JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist or the specified sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The specified sibling is not a child of this compilation unit (INVALID_SIBLING)
+ * <li> The name is not a valid import name (INVALID_NAME)
+ * </ul>
+ */
+//IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Creates and returns a package declaration in this compilation unit
+ * with the given package name.
+ *
+ * <p>If the compilation unit already includes the specified package declaration,
+ * it is not generated (it does not generate duplicates).
+ *
+ * @param name the name of the package declaration to add as defined by JLS2 7.4. (For example, <code>"java.lang"</code>)
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted package declaration (or the previously existing one in case attempting to create a duplicate)
+ *
+ * @exception JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The name is not a valid package name (INVALID_NAME)
+ * </ul>
+ */
+// IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException;   
+/**
+ * Creates and returns a type in this compilation unit with the
+ * given contents. If this compilation unit does not exist, one
+ * will be created with an appropriate package declaration.
+ * <p>
+ * Optionally, the new type can be positioned before the specified
+ * sibling. If <code>sibling</code> is <code>null</code>, the type will be appended
+ * to the end of this compilation unit.
+ *
+ * <p>It is possible that a type with the same name already exists in this compilation unit.
+ * The value of the <code>force</code> parameter effects the resolution of
+ * such a conflict:<ul>
+ * <li> <code>true</code> - in this case the type is created with the new contents</li>
+ * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+ * </ul>
+ *
+ * @param contents the source contents of the type declaration to add.
+ * @param sibling the existing element which the type will be inserted immediately before (if
+ *     <code> null </code>, then this type will be inserted as the last type declaration.
+ * @param force a <code> boolean </code> flag indicating how to deal with duplicates
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted type
+ *
+ * @exception JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li>The specified sibling element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The specified sibling is not a child of this compilation unit (INVALID_SIBLING)
+ * <li> The contents could not be recognized as a type declaration (INVALID_CONTENTS)
+ * <li> There was a naming collision with an existing type (NAME_COLLISION)
+ * </ul>
+ */
+//IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Returns all types declared in this compilation unit in the order
+ * in which they appear in the source. 
+ * This includes all top-level types and nested member types.
+ * It does NOT include local types (types defined in methods).
+ *
+ * @return the array of top-level and member types defined in a compilation unit, in declaration order.
+ * @exception JavaModelException if this element does not exist or if an
+ *             exception occurs while accessing its corresponding resource
+ */
+//IType[] getAllTypes() throws JavaModelException;
+/**
+ * Returns the smallest element within this compilation unit that 
+ * includes the given source position (that is, a method, field, etc.), or
+ * <code>null</code> if there is no element other than the compilation
+ * unit itself at the given position, or if the given position is not
+ * within the source range of this compilation unit.
+ *
+ * @param position a source position inside the compilation unit
+ * @return the innermost Java element enclosing a given source position or <code>null</code>
+ *     if none (excluding the compilation unit).
+ * @exception JavaModelException if the compilation unit does not exist or if an
+ *             exception occurs while accessing its corresponding resource
+ */
+//IJavaElement getElementAt(int position) throws JavaModelException;
+/**
+ * Returns the first import declaration in this compilation unit with the given name.
+ * This is a handle-only method. The import declaration may or may not exist. This
+ * is a convenience method - imports can also be accessed from a compilation unit's
+ * import container.
+ *
+ * @param name the name of the import to find as defined by JLS2 7.5. (For example: <code>"java.io.File"</code> 
+ *     or <code>"java.awt.*"</code>)
+ * @return a handle onto the corresponding import declaration. The import declaration may or may not exist.
+ */
+//IImportDeclaration getImport(String name) ;
+/**
+ * Returns the import container for this compilation unit.
+ * This is a handle-only method. The import container may or
+ * may not exist. The import container can used to access the 
+ * imports.
+ * @return a handle onto the corresponding import container. The 
+ *             import contain may or may not exist.
+ */
+//IImportContainer getImportContainer();
+/**
+ * Returns the import declarations in this compilation unit
+ * in the order in which they appear in the source. This is
+ * a convenience method - import declarations can also be
+ * accessed from a compilation unit's import container.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *             exception occurs while accessing its corresponding resource
+ */
+//IImportDeclaration[] getImports() throws JavaModelException;
+/**
+ * Returns the first package declaration in this compilation unit with the given package name
+ * (there normally is at most one package declaration).
+ * This is a handle-only method. The package declaration may or may not exist.
+ *
+ * @param name the name of the package declaration as defined by JLS2 7.4. (For example, <code>"java.lang"</code>)
+ */
+//IPackageDeclaration getPackageDeclaration(String name);
+/**
+ * Returns the package declarations in this compilation unit
+ * in the order in which they appear in the source.
+ * There normally is at most one package declaration.
+ *
+ * @return an array of package declaration (normally of size one)
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *             exception occurs while accessing its corresponding resource
+ */
+//IPackageDeclaration[] getPackageDeclarations() throws JavaModelException;
+/**
+ * Returns the top-level type declared in this compilation unit with the given simple type name.
+ * The type name has to be a valid compilation unit name.
+ * This is a handle-only method. The type may or may not exist.
+ *
+ * @param name the simple name of the requested type in the compilation unit
+ * @return a handle onto the corresponding type. The type may or may not exist.
+ * @see JavaConventions#validateCompilationUnitName(String name)
+ */
+//IType getType(String name);
+/**
+ * Returns the top-level types declared in this compilation unit
+ * in the order in which they appear in the source.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *             exception occurs while accessing its corresponding resource
+ */
+//IType[] getTypes() throws JavaModelException;
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompletionRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICompletionRequestor.java
new file mode 100644 (file)
index 0000000..acbb1c9
--- /dev/null
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import net.sourceforge.phpdt.core.compiler.IProblem;
+
+/**
+ * A completion requestor accepts results as they are computed and is aware
+ * of source positions to complete the various different results.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @see ICodeAssist
+ * @since 2.0
+ */
+public interface ICompletionRequestor {
+/**
+ * Code assist notification of an anonymous type declaration completion.
+ * @param superTypePackageName Name of the package that contains the super type of this 
+ *             new anonymous type declaration .
+ * 
+ * @param superTypeName Name of the super type of this new anonymous type declaration.
+ * 
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *     Should contain as many elements as parameterTypeNames.
+ * 
+ * @param parameterTypeNames Names of the parameters types. 
+ *             Should contain as many elements as parameterPackageNames.
+ * 
+ * @param completionName The completion for the anonymous type declaration.
+ *             Can include zero, one or two brackets. If the closing bracket is included,
+ *             then the cursor should be placed before it.
+ * 
+ * @param modifiers The modifiers of the constructor.
+ * 
+ * @param completionStart The start position of insertion of the name of this new anonymous type declaration.
+ * 
+ * @param completionEnd The end position of insertion of the name of this new anonymous type declaration.
+ * 
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ * 
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ */
+void acceptAnonymousType(
+       char[] superTypePackageName,
+       char[] superTypeName,
+       char[][] parameterPackageNames,
+       char[][] parameterTypeNames,
+       char[][] parameterNames,
+       char[] completionName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of a class completion.
+ * 
+ * @param packageName Declaring package name of the class.
+ * @param className Name of the class.
+ * @param completionName The completion for the class. Can include ';' for imported classes.
+ * @param modifiers The modifiers of the class.
+ * @param completionStart The start position of insertion of the name of the class.
+ * @param completionEnd The end position of insertion of the name of the class.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptClass(
+       char[] packageName,
+       char[] className,
+       char[] completionName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of a compilation error detected during completion.
+ *  @param error Only problems which are categorized as non-syntax errors are notified to the 
+ *     requestor, warnings are silently ignored.
+ *             In case an error got signalled, no other completions might be available,
+ *             therefore the problem message should be presented to the user.
+ *             The source positions of the problem are related to the source where it was
+ *             detected (might be in another compilation unit, if it was indirectly requested
+ *             during the code assist process).
+ *      Note: the problem knows its originating file name.
+ */
+void acceptError(IProblem error);
+/**
+ * Code assist notification of a field completion.
+ * 
+ * @param declaringTypePackageName Name of the package in which the type that contains this field is declared.
+ * @param declaringTypeName Name of the type declaring this new field.
+ * @param name Name of the field.
+ * @param typePackageName Name of the package in which the type of this field is declared.
+ * @param typeName Name of the type of this field.
+ * @param completionName The completion for the field.
+ * @param modifiers The modifiers of this field.
+ * @param completionStart The start position of insertion of the name of this field.
+ * @param completionEnd The end position of insertion of the name of this field.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ * 
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptField(
+       char[] declaringTypePackageName,
+       char[] declaringTypeName,
+       char[] name,
+       char[] typePackageName,
+       char[] typeName,
+       char[] completionName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of an interface completion.
+ * 
+ * @param packageName Declaring package name of the interface.
+ * @param className Name of the interface.
+ * @param completionName The completion for the interface.     Can include ';' for imported interfaces.
+ * @param modifiers The modifiers of the interface.
+ * @param completionStart The start position of insertion of the name of the interface.
+ * @param completionEnd The end position of insertion of the name of the interface.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptInterface(
+       char[] packageName,
+       char[] interfaceName,
+       char[] completionName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of a keyword completion.
+ * @param keywordName The keyword source.
+ * @param completionStart The start position of insertion of the name of this keyword.
+ * @param completionEnd The end position of insertion of the name of this keyword.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ */
+void acceptKeyword(char[] keywordName, int completionStart, int completionEnd, int relevance);
+/**
+ * Code assist notification of a label completion.
+ * 
+ * @param labelName The label source.
+ * @param completionStart The start position of insertion of the name of this label.
+ * @param completionEnd The end position of insertion of the name of this label.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ */
+void acceptLabel(char[] labelName, int completionStart, int completionEnd, int relevance);
+/**
+ * Code assist notification of a local variable completion.
+ * 
+ * @param name Name of the new local variable.
+ * @param typePackageName Name of the package in which the type of this new local variable is declared.
+ * @param typeName Name of the type of this new local variable.
+ * @param modifiers The modifiers of this new local variable.
+ * @param completionStart The start position of insertion of the name of this new local variable.
+ * @param completionEnd The end position of insertion of the name of this new local variable.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptLocalVariable(
+       char[] name,
+       char[] typePackageName,
+       char[] typeName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of a method completion.
+ * 
+ * @param declaringTypePackageName Name of the package in which the type that contains this new method is declared.
+ * @param declaringTypeName Name of the type declaring this new method.
+ * @param selector Name of the new method.
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *     Should contain as many elements as parameterTypeNames.
+ * @param parameterTypeNames Names of the parameters types.
+ *     Should contain as many elements as parameterPackageNames.
+ * @param returnTypePackageName Name of the package in which the return type is declared.
+ * @param returnTypeName Name of the return type of this new method, should be <code>null</code> for a constructor.
+ * @param completionName The completion for the method. Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it.
+ * @param modifiers The modifiers of this new method.
+ * @param completionStart The start position of insertion of the name of this new method.
+ * @param completionEnd The end position of insertion of the name of this new method.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ */
+void acceptMethod(
+       char[] declaringTypePackageName,
+       char[] declaringTypeName,
+       char[] selector,
+       char[][] parameterPackageNames,
+       char[][] parameterTypeNames,
+       char[][] parameterNames,
+       char[] returnTypePackageName,
+       char[] returnTypeName,
+       char[] completionName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+
+/**
+ * Code assist notification of a method completion.
+ * 
+ * @param declaringTypePackageName Name of the package in which the type that contains this new method is declared.
+ * @param declaringTypeName Name of the type declaring this new method.
+ * @param selector Name of the new method.
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *     Should contain as many elements as parameterTypeNames.
+ * @param parameterTypeNames Names of the parameters types.
+ *     Should contain as many elements as parameterPackageNames.
+ * @param returnTypePackageName Name of the package in which the return type is declared.
+ * @param returnTypeName Name of the return type of this new method, should be <code>null</code> for a constructor.
+ * @param completionName The completion for the method. Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it.
+ * @param modifiers The modifiers of this new method.
+ * @param completionStart The start position of insertion of the name of this new method.
+ * @param completionEnd The end position of insertion of the name of this new method.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ */
+void acceptMethodDeclaration(
+       char[] declaringTypePackageName,
+       char[] declaringTypeName,
+       char[] selector,
+       char[][] parameterPackageNames,
+       char[][] parameterTypeNames,
+       char[][] parameterNames,
+       char[] returnTypePackageName,
+       char[] returnTypeName,
+       char[] completionName,
+       int modifiers,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of a modifier completion.
+ * 
+ * @param modifierName The new modifier.
+ * @param completionStart The start position of insertion of the name of this new modifier.
+ * @param completionEnd The end position of insertion of the name of this new modifier.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ */
+void acceptModifier(char[] modifierName, int completionStart, int completionEnd, int relevance);
+/**
+ * Code assist notification of a package completion.
+ * 
+ * @param packageName The package name.
+ * @param completionName The completion for the package. Can include '.*;' for imports.
+ * @param completionStart The start position of insertion of the name of this new package.
+ * @param completionEnd The end position of insertion of the name of this new package.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    The default package is represented by an empty array.
+ */
+void acceptPackage(
+       char[] packageName,
+       char[] completionName,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+/**
+ * Code assist notification of a type completion.
+ * 
+ * @param packageName Declaring package name of the type.
+ * @param typeName Name of the type.
+ * @param completionName The completion for the type. Can include ';' for imported types.
+ * @param completionStart The start position of insertion of the name of the type.
+ * @param completionEnd The end position of insertion of the name of the type.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptType(
+       char[] packageName,
+       char[] typeName,
+       char[] completionName,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+       
+/**
+ * Code assist notification of a variable name completion.
+ * 
+ * @param typePackageName Name of the package in which the type of this variable is declared.
+ * @param typeName Name of the type of this variable.
+ * @param name Name of the variable.
+ * @param completionName The completion for the variable.
+ * @param completionStart The start position of insertion of the name of this variable.
+ * @param completionEnd The end position of insertion of the name of this variable.
+ * @param relevance The relevance of the completion proposal
+ *             It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ *             This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ *             value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptVariableName(
+       char[] typePackageName,
+       char[] typeName,
+       char[] name,
+       char[] completionName,
+       int completionStart,
+       int completionEnd,
+       int relevance);
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IElementChangedListener.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IElementChangedListener.java
new file mode 100644 (file)
index 0000000..19a3ab8
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * An element changed listener receives notification of changes to Java elements
+ * maintained by the Java model.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ */
+public interface IElementChangedListener {
+       
+/**
+ * Notifies that one or more attributes of one or more Java elements have changed.
+ * The specific details of the change are described by the given event.
+ *
+ * @param event the change event
+ */
+public void elementChanged(ElementChangedEvent event);
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IField.java
new file mode 100644 (file)
index 0000000..10aba92
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * Represents a field declared in a type.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IField extends IMember {
+/**
+ * Returns the constant value associated with this field
+ * or <code>null</code> if this field has none.
+ * Returns either a subclass of <code>Number</code>, or a <code>String</code>,
+ * depending on the type of the field.
+ * For example, if the field is of type <code>short</code>, this returns
+ * a <code>Short</code>.
+ *
+ * @return  the constant value associated with this field or <code>null</code> if this field has none.
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+public Object getConstant() throws JavaModelException;
+/**
+ * Returns the simple name of this field.
+ * @return the simple name of this field.
+ */
+String getElementName();
+/**
+ * Returns the type signature of this field.
+ *
+ * @see Signature
+ * @return the type signature of this field.
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+String getTypeSignature() throws JavaModelException;
+}
index a4160bb..318061a 100644 (file)
@@ -12,7 +12,6 @@ package net.sourceforge.phpdt.core;
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IPath;
 
 /**
  * Common protocol for all elements provided by the Java model.
@@ -130,7 +129,7 @@ public interface IJavaElement extends IAdaptable {
         * @return <code>true</code> if this element exists in the Java model, and
         * <code>false</code> if this element does not exist
         */
-       boolean exists();
+//     boolean exists();
        
        /**
         * Returns the first ancestor of this Java element that has the given type.
@@ -161,7 +160,7 @@ public interface IJavaElement extends IAdaptable {
         * @exception JavaModelException if this element does not exist or if an
         *              exception occurs while accessing its corresponding resource
         */
-       IResource getCorrespondingResource() throws JavaModelException;
+//     IResource getCorrespondingResource() throws JavaModelException;
 
        /**
         * Returns the name of this element. This is a handle-only method.
@@ -197,7 +196,7 @@ public interface IJavaElement extends IAdaptable {
         *
         * @return the Java model
         */
-       // IJavaModel getJavaModel();
+        IJavaModel getJavaModel();
 
        /**
         * Returns the Java project this element is contained in,
@@ -244,7 +243,7 @@ public interface IJavaElement extends IAdaptable {
         * @return the path to the innermost resource enclosing this element
         * @since 2.0
         */
-       IPath getPath();
+//     IPath getPath();
 
        /**
         * Returns the innermost resource enclosing this element. 
@@ -300,5 +299,5 @@ public interface IJavaElement extends IAdaptable {
         * @exception JavaModelException if this element does not exist or if an
         *              exception occurs while accessing its corresponding resource
         */
-       boolean isStructureKnown() throws JavaModelException;
+//     boolean isStructureKnown() throws JavaModelException;
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElementDelta.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaElementDelta.java
new file mode 100644 (file)
index 0000000..f13308f
--- /dev/null
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import org.eclipse.core.resources.IResourceDelta;
+
+/**
+ * A Java element delta describes changes in Java element between two discrete
+ * points in time.  Given a delta, clients can access the element that has 
+ * changed, and any children that have changed.
+ * <p>
+ * Deltas have a different status depending on the kind of change they represent.  
+ * The list below summarizes each status (as returned by <code>getKind</code>)
+ * and its meaning (see individual constants for a more detailled description):
+ * <ul>
+ * <li><code>ADDED</code> - The element described by the delta has been added.</li>
+ * <li><code>REMOVED</code> - The element described by the delta has been removed.</li>
+ * <li><code>CHANGED</code> - The element described by the delta has been changed in some way.  
+ * Specification of the type of change is provided by <code>getFlags</code> which returns the following values:
+ * <ul>
+ * <li><code>F_ADDED_TO_CLASSPATH</code> - A classpath entry corresponding to the element
+ * has been added to the project's classpath. This flag is only valid if the element is an 
+ * <code>IPackageFragmentRoot</code>.</li>
+ * <li><code>F_ARCHIVE_CONTENT_CHANGED</code> - The contents of an archive
+ * has changed in some way. This flag is only valid if the element is an <code>IPackageFragmentRoot</code>
+ * which is an archive.</li>
+ * <li><code>F_CHILDREN</code> - A child of the element has changed in some way.  This flag
+ * is only valid if the element is an <code>IParent</code>.</li>
+ * <li><code>F_CLASSPATH_REORDER</code> - A classpath entry corresponding to the element
+ * has changed position in the project's classpath. This flag is only valid if the element is an 
+ * <code>IPackageFragmentRoot</code>.</li>
+ * <li><code>F_CLOSED</code> - The underlying <code>IProject</code>
+ * has been closed. This flag is only valid if the element is an <code>IJavaProject</code>.</li>
+ * <li><code>F_CONTENT</code> - The contents of the element have been altered.  This flag
+ * is only valid for elements which correspond to files.</li>
+ *<li><code>F_FINE_GRAINED</code> - The delta is a fine-grained delta, that is, an analysis down
+ * to the members level was done to determine if there were structural changes to members of the element.</li>
+ * <li><code>F_MODIFIERS</code> - The modifiers on the element have changed in some way. 
+ * This flag is only valid if the element is an <code>IMember</code>.</li>
+ * <li><code>F_OPENED</code> - The underlying <code>IProject</code>
+ * has been opened. This flag is only valid if the element is an <code>IJavaProject</code>.</li>
+ * <li><code>F_REMOVED_FROM_CLASSPATH</code> - A classpath entry corresponding to the element 
+ * has been removed from the project's classpath. This flag is only valid if the element is an 
+ * <code>IPackageFragmentRoot</code>.</li>
+ * <li><code>F_SOURCEATTACHED</code> - The source attachment path or the source attachment root path
+ * of a classpath entry corresponding to the element was added. This flag is only valid if the element is an 
+ * <code>IPackageFragmentRoot</code>.</li>
+ * <li><code>F_SOURCEDETACHED</code> - The source attachment path or the source attachment root path
+ * of a classpath entry corresponding to the element was removed. This flag is only valid if the element is an 
+ * <code>IPackageFragmentRoot</code>.</li>
+ * <li><code>F_SUPER_TYPES</code> - One of the supertypes of an <code>IType</code> has changed</li>.
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * Move operations are indicated by other change flags, layered on top
+ * of the change flags described above. If element A is moved to become B,
+ * the delta for the  change in A will have status <code>REMOVED</code>,
+ * with change flag <code>F_MOVED_TO</code>. In this case,
+ * <code>getMovedToElement</code> on delta A will return the handle for B.
+ * The  delta for B will have status <code>ADDED</code>, with change flag
+ * <code>F_MOVED_FROM</code>, and <code>getMovedFromElement</code> on delta
+ * B will return the handle for A. (Note, the handle to A in this case represents
+ * an element that no longer exists).
+ * </p>
+ * <p>
+ * Note that the move change flags only describe the changes to a single element, they
+ * do not imply anything about the parent or children of the element.
+ * </p>
+ * <p>
+ * The <code>F_ADDED_TO_CLASSPATH</code>, <code>F_REMOVED_FROM_CLASSPATH</code> and
+ * <code>F_CLASSPATH_REORDER</code> flags are triggered by changes to a project's classpath. They do not mean that
+ * the underlying resource was added, removed or changed. For example, if a project P already contains a folder src, then 
+ * adding a classpath entry with the 'P/src' path to the project's classpath will result in an <code>IJavaElementDelta</code> 
+ * with the <code>F_ADDED_TO_CLASSPATH</code> flag for the <code>IPackageFragmentRoot</code> P/src.
+ * On the contrary, if a resource is physically added, removed or changed and this resource corresponds to a classpath
+ * entry of the project, then an <code>IJavaElementDelta</code> with the <code>ADDED</code>, 
+ * <code>REMOVED</code>, or <code>CHANGED</code> kind will be fired.
+ * </p>
+ * <p>
+ * Note that when a source attachment path or a source attachment root path is changed, then the flags of the delta contain
+ * both <code>F_SOURCEATTACHED</code> and <code>F_SOURCEDETTACHED</code>.
+ * </p>
+ * <p>
+ * No assumptions should be made on whether the java element delta tree is rooted at the <code>IJavaModel</code>
+ * level or not.
+ * </p>
+ * <p>
+ * <code>IJavaElementDelta</code> object are not valid outside the dynamic scope
+ * of the notification.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IJavaElementDelta {
+
+       /**
+        * Status constant indicating that the element has been added.
+        * Note that an added java element delta has no children, as they are all implicitely added.
+        */
+       public int ADDED = 1;
+
+       /**
+        * Status constant indicating that the element has been removed.
+        * Note that a removed java element delta has no children, as they are all implicitely removed.
+        */
+       public int REMOVED = 2;
+
+       /**
+        * Status constant indicating that the element has been changed,
+        * as described by the change flags.
+        * 
+        * @see #getFlags
+        */
+       public int CHANGED = 4;
+
+       /**
+        * Change flag indicating that the content of the element has changed.
+        * This flag is only valid for elements which correspond to files.
+        */
+       public int F_CONTENT = 0x0001;
+
+       /**
+        * Change flag indicating that the modifiers of the element have changed.
+        * This flag is only valid if the element is an <code>IMember</code>. 
+        */
+       public int F_MODIFIERS = 0x0002;
+
+       /**
+        * Change flag indicating that there are changes to the children of the element.
+        * This flag is only valid if the element is an <code>IParent</code>. 
+        */
+       public int F_CHILDREN = 0x0008;
+
+       /**
+        * Change flag indicating that the element was moved from another location.
+        * The location of the old element can be retrieved using <code>getMovedFromElement</code>.
+        */
+       public int F_MOVED_FROM = 0x0010;
+
+       /**
+        * Change flag indicating that the element was moved to another location.
+        * The location of the new element can be retrieved using <code>getMovedToElement</code>.
+        */
+       public int F_MOVED_TO = 0x0020;
+
+       /**
+        * Change flag indicating that a classpath entry corresponding to the element has been added to the project's classpath. 
+        * This flag is only valid if the element is an <code>IPackageFragmentRoot</code>.
+        */
+       public int F_ADDED_TO_CLASSPATH = 0x0040;
+
+       /**
+        * Change flag indicating that a classpath entry corresponding to the element has been removed from the project's 
+        * classpath. This flag is only valid if the element is an <code>IPackageFragmentRoot</code>.
+        */
+       public int F_REMOVED_FROM_CLASSPATH = 0x0080;
+
+       /**
+        * Change flag indicating that a classpath entry corresponding to the element has changed position in the project's 
+        * classpath. This flag is only valid if the element is an <code>IPackageFragmentRoot</code>.
+        * @deprecated Use F_REORDER instead.
+        */
+       public int F_CLASSPATH_REORDER = 0x0100;
+       /**
+        * Change flag indicating that the element has changed position relatively to its siblings. 
+        * If the element is an <code>IPackageFragmentRoot</code>,  a classpath entry corresponding 
+        * to the element has changed position in the project's classpath.
+        * 
+        * @since 2.1
+        */
+       public int F_REORDER = 0x0100;
+
+       /**
+        * Change flag indicating that the underlying <code>IProject</code> has been
+        * opened. This flag is only valid if the element is an <code>IJavaProject</code>. 
+        */
+       public int F_OPENED = 0x0200;
+
+       /**
+        * Change flag indicating that the underlying <code>IProject</code> has been
+        * closed. This flag is only valid if the element is an <code>IJavaProject</code>. 
+        */
+       public int F_CLOSED = 0x0400;
+
+       /**
+        * Change flag indicating that one of the supertypes of an <code>IType</code>
+        * has changed.
+        */
+       public int F_SUPER_TYPES = 0x0800;
+
+       /**
+        * Change flag indicating that the source attachment path or the source attachment root path of a classpath entry 
+        * corresponding to the element was added. This flag is only valid if the element is an 
+        * <code>IPackageFragmentRoot</code>.
+        */
+       public int F_SOURCEATTACHED = 0x1000;   
+
+       /**
+        * Change flag indicating that the source attachment path or the source attachment root path of a classpath entry 
+        * corresponding to the element was removed. This flag is only valid if the element is an 
+        * <code>IPackageFragmentRoot</code>.
+        */
+       public int F_SOURCEDETACHED = 0x2000;   
+       
+       /**
+        * Change flag indicating that this is a fine-grained delta, that is, an analysis down
+        * to the members level was done to determine if there were structural changes to
+        * members.
+        * <p>
+        * Clients can use this flag to find out if a compilation unit 
+     * that have a <code>F_CONTENT</code> change should assume that there are 
+     * no finer grained changes (<code>F_FINE_GRAINED</code> is set) or if 
+     * finer grained changes were not considered (<code>F_FINE_GRAINED</code> 
+     * is not set). 
+     * 
+     * @since 2.0
+        */
+       public int F_FINE_GRAINED = 0x4000;
+
+       /**
+        * Change flag indicating that the element's archive content on the classpath has changed.
+        * This flag is only valid if the element is an <code>IPackageFragmentRoot</code>
+        * which is an archive.
+        * 
+        * @see IPackageFragmentRoot#isArchive
+        * @since 2.0
+        */
+       public int F_ARCHIVE_CONTENT_CHANGED = 0x8000;
+
+       /**
+        * Returns deltas for the children that have been added.
+        * @return deltas for the children that have been added
+        */
+       public IJavaElementDelta[] getAddedChildren();
+
+       /**
+        * Returns deltas for the affected (added, removed, or changed) children.
+        * @return deltas for the affected (added, removed, or changed) children
+        */
+       public IJavaElementDelta[] getAffectedChildren();
+
+       /**
+        * Returns deltas for the children which have changed.
+        * @return deltas for the children which have changed
+        */
+       public IJavaElementDelta[] getChangedChildren();
+
+       /**
+        * Returns the element that this delta describes a change to.
+        * @return the element that this delta describes a change to
+        */
+       public IJavaElement getElement();
+
+       /**
+        * Returns flags that describe how an element has changed. 
+        * Such flags should be tested using the <code>&</code> operand. For example:
+        * <pre>
+        * if ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0) {
+        *      // the delta indicates a content change
+        * }
+        * </pre>
+        *
+        * @return flags that describe how an element has changed
+        */
+       public int getFlags();
+
+       /**
+        * Returns the kind of this delta - one of <code>ADDED</code>, <code>REMOVED</code>,
+        * or <code>CHANGED</code>.
+        * 
+        * @return the kind of this delta
+        */
+       public int getKind();
+
+       /**
+        * Returns an element describing this element before it was moved
+        * to its current location, or <code>null</code> if the
+        * <code>F_MOVED_FROM</code> change flag is not set. 
+        * 
+        * @return an element describing this element before it was moved
+        * to its current location, or <code>null</code> if the
+        * <code>F_MOVED_FROM</code> change flag is not set
+        */
+       public IJavaElement getMovedFromElement();
+
+       /**
+        * Returns an element describing this element in its new location,
+        * or <code>null</code> if the <code>F_MOVED_TO</code> change
+        * flag is not set.
+        * 
+        * @return an element describing this element in its new location,
+        * or <code>null</code> if the <code>F_MOVED_TO</code> change
+        * flag is not set
+        */
+       public IJavaElement getMovedToElement();
+
+       /**
+        * Returns deltas for the children which have been removed.
+        * 
+        * @return deltas for the children which have been removed
+        */
+       public IJavaElementDelta[] getRemovedChildren();
+
+       /**
+        * Returns the collection of resource deltas.
+        * <p>
+        * Note that resource deltas, like Java element deltas, are generally only valid
+        * for the dynamic scope of an event notification. Clients must not hang on to
+        * these objects.
+        * </p>
+        *
+        * @return the underlying resource deltas, or <code>null</code> if none
+        */
+       public IResourceDelta[] getResourceDeltas();
+}
index d745883..a4ff657 100644 (file)
@@ -10,9 +10,7 @@
  *******************************************************************************/
 package net.sourceforge.phpdt.core;
 
-import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.runtime.IProgressMonitor;
 
 /**
  * Represent the root Java element corresponding to the workspace. 
@@ -49,7 +47,7 @@ public interface IJavaModel extends IJavaElement, IOpenable, IParent {
  * @return true if the resource is accessible through the Java model
  * @since 2.1
  */
-boolean contains(IResource resource);
+//boolean contains(IResource resource);
 /**
  * Copies the given elements to the specified container(s).
  * If one container is specified, all elements are copied to that
@@ -96,7 +94,7 @@ boolean contains(IResource resource);
  * <li> A container or element is read-only (<code>READ_ONLY</code>) </li>
  * </ul>
  */
-void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+//void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException;
 /**
  * Deletes the given elements, forcing the operation if necessary and specified.
  *
@@ -112,14 +110,14 @@ void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] sib
  * <li> An element is read-only (<code>READ_ONLY</code>) </li>
  * </ul>
  */
-void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException;
+//void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException;
 /**
  * Returns the Java project with the given name. This is a handle-only method. 
  * The project may or may not exist.
  * 
  * @return the Java project with the given name
  */
-// IJavaProject getJavaProject(String name);
+ IJavaProject getJavaProject(String name);
 /**
  * Returns the Java projects in this Java model, or an empty array if there
  * are none.
@@ -128,7 +126,7 @@ void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) th
  * are none
  * @exception JavaModelException if this request fails.
  */
-// IJavaProject[] getJavaProjects() throws JavaModelException;
+ IJavaProject[] getJavaProjects() throws JavaModelException;
 /**
  * Returns an array of non-Java resources (that is, non-Java projects) in
  * the workspace.
@@ -142,7 +140,7 @@ void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) th
  *             exception occurs while accessing its corresponding resource
  * @since 2.1
  */
-Object[] getNonJavaResources() throws JavaModelException;
+//Object[] getNonJavaResources() throws JavaModelException;
 /**
  * Returns the workspace associated with this Java model.
  * 
@@ -197,7 +195,7 @@ IWorkspace getWorkspace();
  *
  * @exception IllegalArgumentException any element or container is <code>null</code>
  */
-void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+//void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException;
 
 /**
  * Triggers an update of the JavaModel with respect to the referenced external archives.
@@ -225,7 +223,7 @@ void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] sib
  * @see IJavaElementDelta
  * @since 2.0
  */
-void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException;
+//void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException;
 
 /**
  * Renames the given elements as specified.
@@ -251,6 +249,6 @@ void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor moni
  * <li> An element is read-only (<code>READ_ONLY</code>) 
  * </ul>
  */
-void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+//void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean replace, IProgressMonitor monitor) throws JavaModelException;
 
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IJavaProject.java
new file mode 100644 (file)
index 0000000..612ff56
--- /dev/null
@@ -0,0 +1,619 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added getOption(String, boolean), getOptions(boolean) and setOptions(Map)
+ *     IBM Corporation - deprecated getPackageFragmentRoots(IClasspathEntry) and 
+ *                               added findPackageFragmentRoots(IClasspathEntry)
+ *     IBM Corporation - added isOnClasspath(IResource)
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import org.eclipse.core.resources.IProject;
+
+
+/**
+ * A Java project represents a view of a project resource in terms of Java 
+ * elements such as package fragments, types, methods and fields.
+ * A project may contain several package roots, which contain package fragments. 
+ * A package root corresponds to an underlying folder or JAR.
+ * <p>
+ * Each Java project has a classpath, defining which folders contain source code and
+ * where required libraries are located. Each Java project also has an output location,
+ * defining where the builder writes <code>.class</code> files. A project that
+ * references packages in another project can access the packages by including
+ * the required project in a classpath entry. The Java model will present the
+ * source elements in the required project; when building, the compiler will use
+ * the corresponding generated class files from the required project's output
+ * location(s)). The classpath format is a sequence of classpath entries
+ * describing the location and contents of package fragment roots.
+ * </p>
+ * Java project elements need to be opened before they can be navigated or manipulated.
+ * The children of a Java project are the package fragment roots that are 
+ * defined by the classpath and contained in this project (in other words, it
+ * does not include package fragment roots for other projects).
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients. An instance
+ * of one of these handles can be created via 
+ * <code>JavaCore.create(project)</code>.
+ * </p>
+ *
+ * @see JavaCore#create(org.eclipse.core.resources.IProject)
+ * @see IClasspathEntry
+ */
+public interface IJavaProject extends IParent, IJavaElement, IOpenable {
+
+       /**
+        * Returns the <code>IJavaElement</code> corresponding to the given
+        * classpath-relative path, or <code>null</code> if no such 
+        * <code>IJavaElement</code> is found. The result is one of an
+        * <code>ICompilationUnit</code>, <code>IClassFile</code>, or
+        * <code>IPackageFragment</code>. 
+        * <p>
+        * When looking for a package fragment, there might be several potential
+        * matches; only one of them is returned.
+        *
+        * <p>For example, the path "java/lang/Object.java", would result in the
+        * <code>ICompilationUnit</code> or <code>IClassFile</code> corresponding to
+        * "java.lang.Object". The path "java/lang" would result in the
+        * <code>IPackageFragment</code> for "java.lang".
+        * @param path the given classpath-relative path
+        * @exception JavaModelException if the given path is <code>null</code>
+        *  or absolute
+        * @return the <code>IJavaElement</code> corresponding to the given
+        * classpath-relative path, or <code>null</code> if no such 
+        * <code>IJavaElement</code> is found
+        */
+//     IJavaElement findElement(IPath path) throws JavaModelException;
+
+       /**
+        * Returns the first existing package fragment on this project's classpath
+        * whose path matches the given (absolute) path, or <code>null</code> if none
+        * exist.
+        * The path can be:
+        *      - internal to the workbench: "/Project/src"
+        *  - external to the workbench: "c:/jdk/classes.zip/java/lang"
+        * @param path the given absolute path
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        * @return the first existing package fragment on this project's classpath
+        * whose path matches the given (absolute) path, or <code>null</code> if none
+        * exist
+        */
+//     IPackageFragment findPackageFragment(IPath path) throws JavaModelException;
+
+       /**
+        * Returns the existing package fragment root on this project's classpath
+        * whose path matches the given (absolute) path, or <code>null</code> if
+        * one does not exist.
+        * The path can be:
+        *      - internal to the workbench: "/Compiler/src"
+        *      - external to the workbench: "c:/jdk/classes.zip"
+        * @param path the given absolute path
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        * @return the existing package fragment root on this project's classpath
+        * whose path matches the given (absolute) path, or <code>null</code> if
+        * one does not exist
+        */
+//     IPackageFragmentRoot findPackageFragmentRoot(IPath path)
+//             throws JavaModelException;
+       /**
+        * Returns the existing package fragment roots identified by the given entry.
+        * Note that a classpath entry that refers to another project may
+        * have more than one root (if that project has more than on root
+        * containing source), and classpath entries within the current
+        * project identify a single root.
+        * <p>
+        * If the classpath entry denotes a variable, it will be resolved and return
+        * the roots of the target entry (empty if not resolvable).
+        * <p>
+        * If the classpath entry denotes a container, it will be resolved and return
+        * the roots corresponding to the set of container entries (empty if not resolvable).
+        * 
+        * @param entry the given entry
+        * @return the existing package fragment roots identified by the given entry
+        * @see IClasspathContainer
+        * @since 2.1
+        */
+//     IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry);
+       /**
+        * Returns the first type found following this project's classpath 
+        * with the given fully qualified name or <code>null</code> if none is found.
+        * The fully qualified name is a dot-separated name. For example,
+        * a class B defined as a member type of a class A in package x.y should have a 
+        * the fully qualified name "x.y.A.B".
+        * 
+        * Note that in order to be found, a type name (or its toplevel enclosing
+        * type name) must match its corresponding compilation unit name. As a 
+        * consequence, secondary types cannot be found using this functionality.
+        * Secondary types can however be explicitely accessed through their enclosing
+        * unit or found by the <code>SearchEngine</code>.
+        * 
+        * @param fullyQualifiedName the given fully qualified name
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        * @return the first type found following this project's classpath 
+        * with the given fully qualified name or <code>null</code> if none is found
+        * @see IType#getFullyQualifiedName(char)
+        * @since 2.0
+        */
+//     IType findType(String fullyQualifiedName) throws JavaModelException;
+       /**
+        * Returns the first type found following this project's classpath 
+        * with the given package name and type qualified name
+        * or <code>null</code> if none is found.
+        * The package name is a dot-separated name.
+        * The type qualified name is also a dot-separated name. For example,
+        * a class B defined as a member type of a class A should have the 
+        * type qualified name "A.B".
+        * 
+        * Note that in order to be found, a type name (or its toplevel enclosing
+        * type name) must match its corresponding compilation unit name. As a 
+        * consequence, secondary types cannot be found using this functionality.
+        * Secondary types can however be explicitely accessed through their enclosing
+        * unit or found by the <code>SearchEngine</code>.
+        * 
+        * @param packageName the given package name
+        * @param typeQualifiedName the given type qualified name
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        * @return the first type found following this project's classpath 
+        * with the given package name and type qualified name
+        * or <code>null</code> if none is found
+        * @see IType#getTypeQualifiedName(char)
+
+        * @since 2.0
+        */
+//     IType findType(String packageName, String typeQualifiedName) throws JavaModelException;
+
+       /**
+        * Returns all of the existing package fragment roots that exist
+        * on the classpath, in the order they are defined by the classpath.
+        *
+        * @return all of the existing package fragment roots that exist
+        * on the classpath
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        */
+//     IPackageFragmentRoot[] getAllPackageFragmentRoots() throws JavaModelException;
+
+       /**
+        * Returns an array of non-Java resources directly contained in this project.
+        * It does not transitively answer non-Java resources contained in folders;
+        * these would have to be explicitly iterated over.
+        * <p>
+        * Non-Java resources includes other files and folders located in the
+        * project not accounted for by any of it source or binary package fragment
+        * roots. If the project is a source folder itself, resources excluded from the
+        * corresponding source classpath entry by one or more exclusion patterns
+        * are considered non-Java resources and will appear in the result
+        * (possibly in a folder)
+        * </p>
+        * 
+        * @return an array of non-Java resources directly contained in this project
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        */
+//     Object[] getNonJavaResources() throws JavaModelException;
+
+       /**
+        * Helper method for returning one option value only. Equivalent to <code>(String)this.getOptions(inheritJavaCoreOptions).get(optionName)</code>
+        * Note that it may answer <code>null</code> if this option does not exist, or if there is no custom value for it.
+        * <p>
+        * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+        * </p>
+        * 
+        * @param optionName the name of an option
+        * @param inheritJavaCoreOptions - boolean indicating whether JavaCore options should be inherited as well
+        * @return the String value of a given option
+        * @see JavaCore#getDefaultOptions
+        * @since 2.1
+        */
+//     String getOption(String optionName, boolean inheritJavaCoreOptions);
+       
+       /**
+        * Returns the table of the current custom options for this project. Projects remember their custom options,
+        * in other words, only the options different from the the JavaCore global options for the workspace.
+        * A boolean argument allows to directly merge the project options with global ones from <code>JavaCore</code>.
+        * <p>
+        * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+        * </p>
+        * 
+        * @param inheritJavaCoreOptions - boolean indicating whether JavaCore options should be inherited as well
+        * @return table of current settings of all options 
+        *   (key type: <code>String</code>; value type: <code>String</code>)
+        * @see JavaCore#getDefaultOptions
+        * @since 2.1
+        */
+//     Map getOptions(boolean inheritJavaCoreOptions);
+
+       /**
+        * Returns the default output location for this project as a workspace-
+        * relative absolute path.
+        * <p>
+        * The default output location is where class files are ordinarily generated
+        * (and resource files, copied). Each source classpath entry can also
+        * specify an output location for the generated class files (and copied
+        * resource files) corresponding to compilation units under that source
+        * folder. This makes it possible to arrange generated class files for
+        * different source folders in different output folders, and not
+        * necessarily the default output folder. This means that the generated
+        * class files for the project may end up scattered across several folders,
+        * rather than all in the default output folder (which is more standard).
+        * </p>
+        * 
+        * @return the workspace-relative absolute path of the default output folder
+        * @exception JavaModelException if this element does not exist
+        * @see #setOutputLocation
+        * @see IClasspathEntry#getOutputLocation
+        */
+//     IPath getOutputLocation() throws JavaModelException;
+
+       /**
+        * Returns a package fragment root for the JAR at the specified file system path.
+        * This is a handle-only method.  The underlying <code>java.io.File</code>
+        * may or may not exist. No resource is associated with this local JAR
+        * package fragment root.
+        * 
+        * @param jarPath the jars's file system path
+        * @return a package fragment root for the JAR at the specified file system path
+        */
+//     IPackageFragmentRoot getPackageFragmentRoot(String jarPath);
+
+       /**
+        * Returns a package fragment root for the given resource, which
+        * must either be a folder representing the top of a package hierarchy,
+        * or a <code>.jar</code> or <code>.zip</code> file.
+        * This is a handle-only method.  The underlying resource may or may not exist. 
+        * 
+        * @param resource the given resource
+        * @return a package fragment root for the given resource, which
+        * must either be a folder representing the top of a package hierarchy,
+        * or a <code>.jar</code> or <code>.zip</code> file
+        */
+//     IPackageFragmentRoot getPackageFragmentRoot(IResource resource);
+
+       /**
+        * Returns all of the  package fragment roots contained in this
+        * project, identified on this project's resolved classpath. The result
+        * does not include package fragment roots in other projects referenced
+        * on this project's classpath.
+        *
+        * <p>NOTE: This is equivalent to <code>getChildren()</code>.
+        *
+        * @return all of the  package fragment roots contained in this
+        * project, identified on this project's resolved classpath
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        */
+//     IPackageFragmentRoot[] getPackageFragmentRoots() throws JavaModelException;
+
+       /**
+        * Returns the existing package fragment roots identified by the given entry.
+        * Note that a classpath entry that refers to another project may
+        * have more than one root (if that project has more than on root
+        * containing source), and classpath entries within the current
+        * project identify a single root.
+        * <p>
+        * If the classpath entry denotes a variable, it will be resolved and return
+        * the roots of the target entry (empty if not resolvable).
+        * <p>
+        * If the classpath entry denotes a container, it will be resolved and return
+        * the roots corresponding to the set of container entries (empty if not resolvable).
+        * 
+        * @param entry the given entry
+        * @return the existing package fragment roots identified by the given entry
+        * @see IClasspathContainer
+        * @deprecated Use IJavaProject#findPackageFragmentRoots instead
+        */
+//     IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry);
+
+       /**
+        * Returns all package fragments in all package fragment roots contained
+        * in this project. This is a convenience method.
+        *
+        * Note that the package fragment roots corresponds to the resolved
+        * classpath of the project.
+        *
+        * @return all package fragments in all package fragment roots contained
+        * in this project
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        */
+//     IPackageFragment[] getPackageFragments() throws JavaModelException;
+
+       /**
+        * Returns the <code>IProject</code> on which this <code>IJavaProject</code>
+        * was created. This is handle-only method.
+        * 
+        * @return the <code>IProject</code> on which this <code>IJavaProject</code>
+        * was created
+        */
+       IProject getProject();
+
+       /**
+        * Returns the raw classpath for the project, as a list of classpath entries. This corresponds to the exact set
+        * of entries which were assigned using <code>setRawClasspath</code>, in particular such a classpath may contain
+        * classpath variable entries. Classpath variable entries can be resolved individually (see <code>JavaCore#getClasspathVariable</code>),
+        * or the full classpath can be resolved at once using the helper method <code>getResolvedClasspath</code>.
+        * <p>
+        * A classpath variable provides an indirection level for better sharing a classpath. As an example, it allows
+        * a classpath to no longer refer directly to external JARs located in some user specific location. The classpath
+        * can simply refer to some variables defining the proper locations of these external JARs.
+        *  <p>
+        * Note that in case the project isn't yet opened, the classpath will directly be read from the associated <tt>.classpath</tt> file.
+        * <p>
+        * 
+        * @return the raw classpath for the project, as a list of classpath entries
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        * @see IClasspathEntry
+        */
+//     IClasspathEntry[] getRawClasspath() throws JavaModelException;
+
+       /**
+        * Returns the names of the projects that are directly required by this
+        * project. A project is required if it is in its classpath.
+        * <p>
+        * The project names are returned in the order they appear on the classpath.
+        *
+        * @return the names of the projects that are directly required by this
+        * project in classpath order
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        */
+//     String[] getRequiredProjectNames() throws JavaModelException;
+
+       /**
+        * This is a helper method returning the resolved classpath for the project
+        * as a list of simple (non-variable, non-container) classpath entries.
+        * All classpath variable and classpath container entries in the project's
+        * raw classpath will be replaced by the simple classpath entries they
+        * resolve to.
+        * <p>
+        * The resulting resolved classpath is accurate for the given point in time.
+        * If the project's raw classpath is later modified, or if classpath
+        * variables are changed, the resolved classpath can become out of date.
+        * Because of this, hanging on resolved classpath is not recommended.
+        * </p>
+        * 
+        * @param ignoreUnresolvedEntry indicates how to handle unresolvable
+        * variables and containers; <code>true</code> indicates that missing
+        * variables and unresolvable classpath containers should be silently
+        * ignored, and that the resulting list should consist only of the
+        * entries that could be successfully resolved; <code>false</code> indicates
+        * that a <code>JavaModelException</code> should be thrown for the first
+        * unresolved variable or container
+        * @return the resolved classpath for the project as a list of simple 
+        * classpath entries, where all classpath variable and container entries
+        * have been resolved and substituted with their final target entries
+        * @exception JavaModelException in one of the corresponding situation:
+        * <ul>
+        *    <li>this element does not exist</li>
+        *    <li>an exception occurs while accessing its corresponding resource</li>
+        *    <li>a classpath variable or classpath container was not resolvable
+        *    and <code>ignoreUnresolvedEntry</code> is <code>false</code>.</li>
+        * </ul>
+        * @see IClasspathEntry
+        */
+//     IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry)
+//          throws JavaModelException;
+
+       /**
+        * Returns whether this project has been built at least once and thus whether it has a build state.
+        * @return true if this project has been built at least once, false otherwise
+        */
+//     boolean hasBuildState();
+
+       /**
+        * Returns whether setting this project's classpath to the given classpath entries
+        * would result in a cycle.
+        *
+        * If the set of entries contains some variables, those are resolved in order to determine
+        * cycles.
+        * 
+        * @param entries the given classpath entries
+        * @return true if the given classpath entries would result in a cycle, false otherwise
+        */
+//     boolean hasClasspathCycle(IClasspathEntry[] entries);
+       /**
+        * Returns whether the given element is on the classpath of this project, 
+        * that is, referenced from a classpath entry and not explicitly excluded
+        * using an exclusion pattern. 
+        * 
+        * @param element the given element
+        * @return <code>true</code> if the given element is on the classpath of
+        * this project, <code>false</code> otherwise
+        * @see IClasspathEntry#getExclusionPatterns
+        * @since 2.0
+        */
+//     boolean isOnClasspath(IJavaElement element);
+       /**
+        * Returns whether the given resource is on the classpath of this project,
+        * that is, referenced from a classpath entry and not explicitly excluded
+        * using an exclusion pattern.
+        * 
+        * @param element the given element
+        * @return <code>true</code> if the given resource is on the classpath of
+        * this project, <code>false</code> otherwise
+        * @see IClasspathEntry#getExclusionPatterns
+        * @since 2.1
+        */
+//     boolean isOnClasspath(IResource resource);
+
+       /**
+        * Creates a new evaluation context.
+        * @return a new evaluation context.
+        */
+//     IEvaluationContext newEvaluationContext();
+
+       /**
+        * Creates and returns a type hierarchy for all types in the given
+        * region, considering subtypes within that region.
+        *
+        * @param monitor the given progress monitor
+        * @param region the given region
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        * @exception IllegalArgumentException if region is <code>null</code>
+        * @return a type hierarchy for all types in the given
+        * region, considering subtypes within that region
+        */
+//     ITypeHierarchy newTypeHierarchy(IRegion region, IProgressMonitor monitor)
+//             throws JavaModelException;
+
+       /**
+        * Creates and returns a type hierarchy for the given type considering
+        * subtypes in the specified region.
+        * 
+        * @param monitor the given monitor
+        * @param region the given region
+        * @param type the given type
+        * 
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource
+        *
+        * @exception IllegalArgumentException if type or region is <code>null</code>
+        * @return a type hierarchy for the given type considering
+        * subtypes in the specified region
+        */
+//     ITypeHierarchy newTypeHierarchy(
+//             IType type,
+//             IRegion region,
+//             IProgressMonitor monitor)
+//             throws JavaModelException;
+
+       /**
+        * Sets the project custom options. All and only the options explicitly included in the given table 
+        * are remembered; all previous option settings are forgotten, including ones not explicitly
+        * mentioned.
+        * <p>
+        * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+        * </p>
+        * 
+        * @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
+        *   or <code>null</code> to flush all custom options (clients will automatically get the global JavaCore options).
+        * @see JavaCore#getDefaultOptions
+        * @since 2.1
+        */
+//     void setOptions(Map newOptions);
+
+       /**
+        * Sets the default output location of this project to the location
+        * described by the given workspace-relative absolute path.
+        * <p>
+        * The default output location is where class files are ordinarily generated
+        * (and resource files, copied). Each source classpath entries can also
+        * specify an output location for the generated class files (and copied
+        * resource files) corresponding to compilation units under that source
+        * folder. This makes it possible to arrange that generated class files for
+        * different source folders to end up in different output folders, and not
+        * necessarily the default output folder. This means that the generated
+        * class files for the project may end up scattered across several folders,
+        * rather than all in the default output folder (which is more standard).
+        * </p>
+        * 
+        * @param path the workspace-relative absolute path of the default output
+        * folder
+        * @param monitor the progress monitor
+        * 
+        * @exception JavaModelException if the classpath could not be set. Reasons include:
+        * <ul>
+        *  <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        *  <li> The path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
+        *  <li> The path is not an absolute path (<code>RELATIVE_PATH</code>)
+        *  <li> The path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
+        *  <li> The output location is being modified during resource change event notification (CORE_EXCEPTION)        
+        * </ul>
+        * @see #getOutputLocation
+     * @see IClasspathEntry#getOutputLocation
+        */
+//     void setOutputLocation(IPath path, IProgressMonitor monitor)
+//             throws JavaModelException;
+
+       /**
+        * Sets the classpath of this project using a list of classpath entries. In particular such a classpath may contain
+        * classpath variable entries. Classpath variable entries can be resolved individually (see <code>JavaCore#getClasspathVariable</code>),
+        * or the full classpath can be resolved at once using the helper method <code>getResolvedClasspath</code>.
+        * <p>
+        * A classpath variable provides an indirection level for better sharing a classpath. As an example, it allows
+        * a classpath to no longer refer directly to external JARs located in some user specific location. The classpath
+        * can simply refer to some variables defining the proper locations of these external JARs.
+        * <p>
+        * Setting the classpath to <code>null</code> specifies a default classpath
+        * (the project root). Setting the classpath to an empty array specifies an
+        * empty classpath.
+        * <p>
+        * If a cycle is detected while setting this classpath, an error marker will be added
+        * to the project closing the cycle.
+        * To avoid this problem, use <code>hasClasspathCycle(IClasspathEntry[] entries)</code>
+        * before setting the classpath.
+        *
+        * @param entries a list of classpath entries
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if the classpath could not be set. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+        * <li> The classpath failed the validation check as defined by <code>JavaConventions#validateClasspath</code>
+        * </ul>
+        * @see IClasspathEntry
+        */
+//     void setRawClasspath(IClasspathEntry[] entries, IProgressMonitor monitor)
+//             throws JavaModelException;
+               
+       /**
+        * Sets the both the classpath of this project and its default output
+        * location at once. The classpath is defined using a list of classpath
+        * entries. In particular, such a classpath may contain classpath variable
+        * entries. Classpath variable entries can be resolved individually (see
+        * <code>JavaCore#getClasspathVariable</code>), or the full classpath can be
+        * resolved at once using the helper method
+        * <code>getResolvedClasspath</code>.
+        * <p>
+        * A classpath variable provides an indirection level for better sharing a
+        * classpath. As an example, it allows a classpath to no longer refer
+        * directly to external JARs located in some user specific location. The
+        * classpath can simply refer to some variables defining the proper
+        * locations of these external JARs.
+        * </p>
+        * <p>
+        * Setting the classpath to <code>null</code> specifies a default classpath
+        * (the project root). Setting the classpath to an empty array specifies an
+        * empty classpath.
+        * </p>
+        * <p>
+        * If a cycle is detected while setting this classpath, an error marker will
+        * be added to the project closing the cycle. To avoid this problem, use
+        * <code>hasClasspathCycle(IClasspathEntry[] entries)</code> before setting
+        * the classpath.
+        * </p>
+        * 
+        * @param entries a list of classpath entries
+        * @param monitor the progress monitor
+        * @param outputLocation the default output location
+        * @exception JavaModelException if the classpath could not be set. Reasons
+        * include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> Two or more entries specify source roots with the same or overlapping paths (NAME_COLLISION)
+        * <li> A entry of kind <code>CPE_PROJECT</code> refers to this project (INVALID_PATH)
+        *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        *      <li>The output location path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
+        *      <li>The output location path is not an absolute path (<code>RELATIVE_PATH</code>)
+        *  <li>The output location path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
+        * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+        * </ul>
+        * @see IClasspathEntry
+        * @since 2.0
+        */
+//     void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation, IProgressMonitor monitor)
+//             throws JavaModelException;
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMember.java
new file mode 100644 (file)
index 0000000..8494bd8
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * Common protocol for Java elements that can be members of types.
+ * This set consists of <code>IType</code>, <code>IMethod</code>, 
+ * <code>IField</code>, and <code>IInitializer</code>.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IMember extends IJavaElement , ISourceReference, ISourceManipulation {
+/**
+ * Returns the class file in which this member is declared, or <code>null</code>
+ * if this member is not declared in a class file (for example, a source type).
+ * This is a handle-only method.
+ * 
+ * @return the class file in which this member is declared, or <code>null</code>
+ * if this member is not declared in a class file (for example, a source type)
+ */
+//IClassFile getClassFile();
+/**
+ * Returns the compilation unit in which this member is declared, or <code>null</code>
+ * if this member is not declared in a compilation unit (for example, a binary type).
+ * This is a handle-only method.
+ * 
+ * @return the compilation unit in which this member is declared, or <code>null</code>
+ * if this member is not declared in a compilation unit (for example, a binary type)
+ */
+ICompilationUnit getCompilationUnit();
+/**
+ * Returns the type in which this member is declared, or <code>null</code>
+ * if this member is not declared in a type (for example, a top-level type).
+ * This is a handle-only method.
+ * 
+ * @return the type in which this member is declared, or <code>null</code>
+ * if this member is not declared in a type (for example, a top-level type)
+ */
+//IType getDeclaringType();
+/**
+ * Returns the modifier flags for this member. The flags can be examined using class
+ * <code>Flags</code>.
+ * <p>
+ * Note that only flags as indicated in the source are returned. Thus if an interface
+ * defines a method <code>void myMethod();</code> the flags don't include the
+ * 'public' flag.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the modifier flags for this member
+ * @see Flags
+ */
+int getFlags() throws JavaModelException;
+/**
+ * Returns the source range of this member's simple name,
+ * or <code>null</code> if this member does not have a name
+ * (for example, an initializer), or if this member does not have
+ * associated source code (for example, a binary type).
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the source range of this member's simple name,
+ * or <code>null</code> if this member does not have a name
+ * (for example, an initializer), or if this member does not have
+ * associated source code (for example, a binary type)
+ */
+//ISourceRange getNameRange() throws JavaModelException;
+/**
+ * Returns whether this member is from a class file.
+ * This is a handle-only method.
+ *
+ * @return <code>true</code> if from a class file, and <code>false</code> if
+ *   from a compilation unit
+ */
+boolean isBinary();
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMethod.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IMethod.java
new file mode 100644 (file)
index 0000000..651789a
--- /dev/null
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * Represents a method (or constructor) declared in a type.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IMethod extends IMember {
+/**
+ * Returns the simple name of this method.
+ * For a constructor, this returns the simple name of the declaring type.
+ * Note: This holds whether the constructor appears in a source or binary type
+ * (even though class files internally define constructor names to be <code>"&lt;init&gt;"</code>).
+ * For the class initialization methods in binary types, this returns
+ * the special name <code>"&lt;clinit&gt;"</code>.
+ * This is a handle-only method.
+ */
+String getElementName();
+/**
+ * Returns the type signatures of the exceptions this method throws,
+ * in the order declared in the source. Returns an empty array
+ * if this method throws no exceptions.
+ *
+ * <p>For example, a source method declaring <code>"throws IOException"</code>,
+ * would return the array <code>{"QIOException;"}</code>.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the type signatures of the exceptions this method throws,
+ * in the order declared in the source, an empty array if this method throws no exceptions
+ * @see Signature
+ */
+String[] getExceptionTypes() throws JavaModelException;
+/**
+ * Returns the number of parameters of this method.
+ * This is a handle-only method.
+ * 
+ * @return the number of parameters of this method
+ */
+int getNumberOfParameters();
+/**
+ * Returns the names of parameters in this method.
+ * For binary types, these names are invented as "arg"+i, where i starts at 1 
+ * (even if source is associated with the binary).
+ * Returns an empty array if this method has no parameters.
+ *
+ * <p>For example, a method declared as <code>public void foo(String text, int length)</code>
+ * would return the array <code>{"text","length"}</code>.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the names of parameters in this method, an empty array if this method has no parameters
+ */
+String[] getParameterNames() throws JavaModelException;
+/**
+ * Returns the type signatures for the parameters of this method.
+ * Returns an empty array if this method has no parameters.
+ * This is a handle-only method.
+ *
+ * <p>For example, a source method declared as <code>public void foo(String text, int length)</code>
+ * would return the array <code>{"QString;","I"}</code>.
+ * 
+ * @return the type signatures for the parameters of this method, an empty array if this method has no parameters
+ * @see Signature
+ */
+String[] getParameterTypes();
+/**
+ * Returns the type signature of the return value of this method.
+ * For constructors, this returns the signature for void.
+ *
+ * <p>For example, a source method declared as <code>public String getName()</code>
+ * would return <code>"QString;"</code>.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the type signature of the return value of this method, void  for constructors
+ * @see Signature
+ */
+String getReturnType() throws JavaModelException;
+/**
+ * Returns the signature of the method. This includes the signatures for the parameter
+ * types and return type, but does not include the method name or exception types.
+ *
+ * <p>For example, a source method declared as <code>public void foo(String text, int length)</code>
+ * would return <code>"(QString;I)V"</code>.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ *
+ * @see Signature
+ */
+String getSignature() throws JavaModelException;
+/**
+ * Returns whether this method is a constructor.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * 
+ * @return true if this method is a constructor, false otherwise
+ */
+boolean isConstructor() throws JavaModelException;
+/**
+ * Returns whether this method is a main method.
+ * It is a main method if:
+ * <ul>
+ * <li>its name is equal to <code>"main"</code></li>
+ * <li>its return type is <code>void</code></li>
+ * <li>it is <code>static</code> and <code>public</code></li>
+ * <li>it defines one parameter whose type's simple name is </code>String[]</code></li>
+ * </ul>
+ * 
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @since 2.0
+ * @return true if this method is a main method, false otherwise
+ */
+boolean isMainMethod() throws JavaModelException;
+/**
+ * Returns whether this method is similar to the given method.
+ * Two methods are similar if:
+ * <ul>
+ * <li>their element names are equal</li>
+ * <li>they have the same number of parameters</li>
+ * <li>the simple names of their parameter types are equal</li>
+ * </ul>
+ * This is a handle-only method.
+ * 
+ * @param method the given method
+ * @return true if this method is similar to the given method.
+ * @see Signature#getSimpleName
+ * @since 2.0
+ */
+boolean isSimilar(IMethod method);
+}
index 474e764..9409305 100644 (file)
@@ -10,7 +10,6 @@
  *******************************************************************************/
 package net.sourceforge.phpdt.core;
 
-import org.eclipse.core.runtime.IProgressMonitor;
 
 /**
  * Common protocol for Java elements that must be opened before they can be 
@@ -53,7 +52,7 @@ public interface IOpenable {
  *
  * @exception JavaModelException if an error occurs closing this element
  */
-public void close() throws JavaModelException;
+//public void close() throws JavaModelException;
 /**
  * Returns the buffer opened for this element, or <code>null</code>
  * if this element does not have a buffer.
@@ -83,7 +82,7 @@ public IBuffer getBuffer() throws JavaModelException;
  * element's children and has not yet destroyed
  * </ul>
  */
-boolean hasUnsavedChanges() throws JavaModelException;
+//boolean hasUnsavedChanges() throws JavaModelException;
 /**
  * Returns whether the element is consistent with its underlying resource or buffer.
  * The element is consistent when opened, and is consistent if the underlying resource
@@ -117,7 +116,7 @@ boolean isOpen();
  * </ul>
  * @see IOpenable#isConsistent
  */
-void makeConsistent(IProgressMonitor progress) throws JavaModelException;
+//void makeConsistent(IProgressMonitor progress) throws JavaModelException;
 /**
  * Opens this element and all parent elements that are not already open.
  * For compilation units, a buffer is opened on the contents of the underlying resource.
@@ -133,7 +132,7 @@ void makeConsistent(IProgressMonitor progress) throws JavaModelException;
  *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
  * </ul>
  */
-public void open(IProgressMonitor progress) throws JavaModelException;
+//public void open(IProgressMonitor progress) throws JavaModelException;
 /**
  * Saves any changes in this element's buffer to its underlying resource
  * via a workspace resource operation. This has no effect if the element has no underlying
@@ -164,5 +163,5 @@ public void open(IProgressMonitor progress) throws JavaModelException;
  *  <li>This Java element is read-only (READ_ONLY)</li>
  * </ul>
  */
-public void save(IProgressMonitor progress, boolean force) throws JavaModelException;
+//public void save(IProgressMonitor progress, boolean force) throws JavaModelException;
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragment.java
new file mode 100644 (file)
index 0000000..131d36f
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A package fragment is a portion of the workspace corresponding to an entire package,
+ * or to a portion thereof. The distinction between a package fragment and a package
+ * is that a package with some name is the union of all package fragments in the class path
+ * which have the same name.
+ * <p>
+ * Package fragments elements need to be opened before they can be navigated or manipulated.
+ * The children are of type <code>ICompilationUnit</code> (representing a source file) or 
+ * <code>IClassFile</code> (representing a binary class file).
+ * The children are listed in no particular order.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IPackageFragment extends IParent, IJavaElement, IOpenable { 
+//ISourceManipulation {
+
+       /**     
+        * <p>
+        * The name of package fragment for the default package (value: the empty 
+        * string, <code>""</code>).
+        * </p>
+       */
+       public static final String DEFAULT_PACKAGE_NAME = ""; //$NON-NLS-1$
+       /**
+        * Returns whether this fragment contains at least one Java resource.
+        * @return true if this fragment contains at least one Java resource, false otherwise
+        */
+//     boolean containsJavaResources() throws JavaModelException;
+       /**
+        * Creates and returns a compilation unit in this package fragment 
+        * with the specified name and contents. No verification is performed
+        * on the contents.
+        *
+        * <p>It is possible that a compilation unit with the same name already exists in this 
+        * package fragment.
+        * The value of the <code>force</code> parameter effects the resolution of
+        * such a conflict:<ul>
+        * <li> <code>true</code> - in this case the compilation is created with the new contents</li>
+        * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+        * </ul>
+        *
+        * @param contents the given contents
+        * @param force specify how to handle conflict is the same name already exists
+        * @param monitor the given progress monitor
+        * @param name the given name
+        * @exception JavaModelException if the element could not be created. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while creating an underlying resource
+        * <li> The name is not a valid compilation unit name (INVALID_NAME)
+        * <li> The contents are <code>null</code> (INVALID_CONTENTS)
+        * </ul>
+        * @return a compilation unit in this package fragment 
+        * with the specified name and contents
+        */
+       ICompilationUnit createCompilationUnit(String name, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException;
+       /**
+        * Returns the class file with the specified name
+        * in this package (for example, <code>"Object.class"</code>).
+        * The ".class" suffix is required.
+        * This is a handle-only method.  The class file may or may not be present.
+        * @param name the given name
+        * @return the class file with the specified name in this package
+        */
+//     IClassFile getClassFile(String name);
+       /**
+        * Returns all of the class files in this package fragment.
+        *
+        * <p>Note: it is possible that a package fragment contains only
+        * compilation units (in other words, its kind is <code>K_SOURCE</code>), in
+        * which case this method returns an empty collection.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return all of the class files in this package fragment
+        */
+//     IClassFile[] getClassFiles() throws JavaModelException;
+       /**
+        * Returns the compilation unit with the specified name
+        * in this package (for example, <code>"Object.java"</code>).
+        * The name has to be a valid compilation unit name.
+        * This is a handle-only method.  The compilation unit may or may not be present.
+        * @see JavaConventions#validateCompilationUnitName
+        * @param name the given name
+        * @return the compilation unit with the specified name in this package
+        */
+       ICompilationUnit getCompilationUnit(String name);
+       /**
+        * Returns all of the compilation units in this package fragment.
+        *
+        * <p>Note: it is possible that a package fragment contains only
+        * class files (in other words, its kind is <code>K_BINARY</code>), in which
+        * case this method returns an empty collection.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return all of the compilation units in this package fragment
+        */
+//     ICompilationUnit[] getCompilationUnits() throws JavaModelException;
+       /**
+        * Returns the dot-separated package name of this fragment, for example
+        * <code>"java.lang"</code>, or <code>""</code> (the empty string),
+        * for the default package.
+        * 
+        * @return the dot-separated package name of this fragment
+        */
+       String getElementName();
+       /**
+        * Returns this package fragment's root kind encoded as an integer.
+        * A package fragment can contain <code>.java</code> source files,
+        * or <code>.class</code> files. This is a convenience method.
+        *
+        * @see IPackageFragmentRoot#K_SOURCE
+        * @see IPackageFragmentRoot#K_BINARY
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return this package fragment's root kind encoded as an integer
+        */
+//     int getKind() throws JavaModelException;
+       /**
+        * Returns an array of non-Java resources contained in this package fragment.
+        * <p>
+        * Non-Java resources includes other files and folders located in the same
+        * directory as the compilation units or class files for this package 
+        * fragment. Source files excluded from this package by one or more
+        * exclusion patterns on the corresponding source classpath entry are
+        * considered non-Java resources and will appear in the result
+        * (possibly in a folder).
+        * </p>
+        * 
+        * @return an array of non-Java resources contained in this package fragment
+        * @see IClasspathEntry#getExclusionPatterns
+        */
+//     Object[] getNonJavaResources() throws JavaModelException;
+       /**
+        * Returns whether this package fragment's name is
+        * a prefix of other package fragments in this package fragment's
+        * root.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return true if this package fragment's name is a prefix of other package fragments in this package fragment's root, false otherwise
+        */
+//     boolean hasSubpackages() throws JavaModelException;
+       /**
+        * Returns whether this package fragment is a default package.
+        * This is a handle-only method.
+        * 
+        * @return true if this package fragment is a default package
+        */
+       boolean isDefaultPackage();
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IPackageFragmentRoot.java
new file mode 100644 (file)
index 0000000..ba8d7ea
--- /dev/null
@@ -0,0 +1,418 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - specified that a source archive or a source folder can be attached to a binary
+ *                               package fragment root.
+ *     IBM Corporation - added root manipulation APIs: copy, delete, move
+ *     IBM Corporation - added DESTINATION_PROJECT_CLASSPATH
+ *     IBM Corporation - added OTHER_REFERRING_PROJECTS_CLASSPATH
+ *     IBM Corporation - added NO_RESOURCE_MODIFICATION
+ *     IBM Corporation - added REPLACE
+ *     IBM Corporation - added ORIGINATING_PROJECT_CLASSPATH
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+
+/**
+ * A package fragment root contains a set of package fragments.
+ * It corresponds to an underlying resource which is either a folder,
+ * JAR, or zip.  In the case of a folder, all descendant folders represent
+ * package fragments.  For a given child folder representing a package fragment, 
+ * the corresponding package name is composed of the folder names between the folder 
+ * for this root and the child folder representing the package, separated by '.'.
+ * In the case of a JAR or zip, the contents of the archive dictates 
+ * the set of package fragments in an analogous manner.
+ * Package fragment roots need to be opened before they can be navigated or manipulated.
+ * The children are of type <code>IPackageFragment</code>, and are in no particular order.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IPackageFragmentRoot
+       extends IParent, IJavaElement, IOpenable {
+       /**
+        * Kind constant for a source path root. Indicates this root
+        * only contains source files.
+        */
+       int K_SOURCE = 1;
+       /**
+        * Kind constant for a binary path root. Indicates this
+        * root only contains binary files.
+        */
+       int K_BINARY = 2;
+       /**
+        * Empty root path
+        */
+       String DEFAULT_PACKAGEROOT_PATH = ""; //$NON-NLS-1$
+       /**
+        * Update model flag constant (bit mask value 1) indicating that the operation
+        * is to not copy/move/delete the package fragment root resource.
+        * @since 2.1
+        */
+       int NO_RESOURCE_MODIFICATION = 1;
+       /**
+        * Update model flag constant (bit mask value 2) indicating that the operation
+        * is to update the classpath of the originating project.
+        * @since 2.1
+        */
+       int ORIGINATING_PROJECT_CLASSPATH = 2;
+       /**
+        * Update model flag constant (bit mask value 4) indicating that the operation
+        * is to update the classpath of all referring projects except the originating project.
+        * @since 2.1
+        */
+       int OTHER_REFERRING_PROJECTS_CLASSPATH = 4;
+       /**
+        * Update model flag constant (bit mask value 8) indicating that the operation
+        * is to update the classpath of the destination project.
+        * @since 2.1
+        */
+       int DESTINATION_PROJECT_CLASSPATH = 8;  
+       /**
+        * Update model flag constant (bit mask value 16) indicating that the operation
+        * is to replace the resource and the destination project's classpath entry.
+        * @since 2.1
+        */
+       int REPLACE = 16;       
+       /**
+        * Attaches the source archive identified by the given absolute path to this
+        * binary package fragment root. <code>rootPath</code> specifies the location 
+        * of the root within the archive or folder (empty specifies the default root 
+        * and <code>null</code> specifies the root path should be detected).
+        * Once a source archive or folder is attached to the package fragment root,
+        * the <code>getSource</code> and <code>getSourceRange</code>
+        * methods become operational for binary types/members.
+        * To detach a source archive or folder from a package fragment root, specify 
+        * <code>null</code> as the source path.
+        *
+        * @param sourcePath the given absolute path to the source archive or folder
+        * @param rootPath specifies the location of the root within the archive 
+        *              (empty specifies the default root and <code>null</code> specifies 
+        *               automatic detection of the root path)
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if this operation fails. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while updating a server property
+        * <li> This package fragment root is not of kind binary (INVALID_ELEMENT_TYPES)
+        * <li> The path provided is not absolute (RELATIVE_PATH)
+        * </ul>
+        */
+//     void attachSource(IPath sourcePath, IPath rootPath, IProgressMonitor monitor)
+//             throws JavaModelException;
+
+       /**
+        * Copies the resource of this package fragment root to the destination path
+        * as specified by <code>IResource.copy(IPath, int, IProgressMonitor)</code>
+        * but excluding nested source folders.
+        * <p>
+        * If <code>NO_RESOURCE_MODIFICATION</code> is specified in 
+        * <code>updateModelFlags</code> or if this package fragment root is external, 
+        * this operation doesn't copy the resource. <code>updateResourceFlags</code> 
+        * is then ignored.
+        * </p><p>
+        * If <code>DESTINATION_PROJECT_CLASSPATH</code> is specified in 
+        * <code>updateModelFlags</code>, updates the classpath of the 
+        * destination's project (if it is a Java project). If a non-<code>null</code> 
+        * sibling is specified, a copy of this root's classpath entry is inserted before the 
+        * sibling on the destination project's raw classpath. If <code>null</code> is 
+        * specified, the classpath entry is added at the end of the raw classpath.
+        * </p><p>
+        * If <code>REPLACE</code> is specified in <code>updateModelFlags</code>,
+        * overwrites the resource at the destination path if any.
+        * If the same classpath entry already exists on the destination project's raw
+        * classpath, then the sibling is ignored and the new classpath entry replaces the 
+        * existing one.
+        * </p><p>
+        * If no flags is specified in <code>updateModelFlags</code> (using 
+        * <code>IResource.NONE</code>), the default behavior applies: the
+        * resource is copied (if this package fragment root is not external) and the
+        * classpath is not updated.
+        * </p>
+        * 
+        * @param destination the destination path
+        * @param updateResourceFlags bit-wise or of update resource flag constants
+        *   (<code>IResource.FORCE</code> and <code>IResource.SHALLOW</code>)
+        * @param updateModelFlags bit-wise or of update resource flag constants
+        *   (<code>DESTINATION_PROJECT_CLASSPATH</code> and 
+        *   <code>NO_RESOURCE_MODIFICATION</code>)
+        * @param sibling the classpath entry before which a copy of the classpath
+        * entry should be inserted or <code>null</code> if the classpath entry should
+        * be inserted at the end
+        * @param monitor a progress monitor
+        * 
+        * @exception JavaModelException if this root could not be copied. Reasons
+        * include:
+        * <ul>
+        * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while copying the
+        * resource or updating a classpath</li>
+        * <li>
+        * The destination is not inside an existing project and <code>updateModelFlags</code>
+        * has been specified as <code>DESTINATION_PROJECT_CLASSPATH</code> 
+        * (INVALID_DESTINATION)</li>
+        * <li> The sibling is not a classpath entry on the destination project's
+        * raw classpath (INVALID_SIBLING)</li>
+        * <li> The same classpath entry already exists on the destination project's
+        * classpath (NAME_COLLISION) and <code>updateModelFlags</code>
+        * has not been specified as <code>REPLACE</code></li>
+        * </ul>
+        * @see org.eclipse.core.resources.IResource#copy
+        * @since 2.1
+        */
+//     void copy(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
+       /**
+        * Creates and returns a package fragment in this root with the 
+        * given dot-separated package name.  An empty string specifies the default package. 
+        * This has the side effect of creating all package
+        * fragments that are a prefix of the new package fragment which
+        * do not exist yet. If the package fragment already exists, this
+        * has no effect.
+        *
+        * For a description of the <code>force</code> flag, see <code>IFolder.create</code>.
+        *
+        * @param name the given dot-separated package name
+        * @param force a flag controlling how to deal with resources that
+        *    are not in sync with the local file system
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if the element could not be created. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while creating an underlying resource
+        * <li> This package fragment root is read only (READ_ONLY)
+        * <li> The name is not a valid package name (INVALID_NAME)
+        * </ul>
+        * @return a package fragment in this root with the given dot-separated package name
+        * @see org.eclipse.core.resources.IFolder#create
+        */
+//     IPackageFragment createPackageFragment(
+//             String name,
+//             boolean force,
+//             IProgressMonitor monitor)
+//             throws JavaModelException;
+       /**
+        * Deletes the resource of this package fragment root as specified by
+        * <code>IResource.delete(int, IProgressMonitor)</code> but excluding nested
+        * source folders.
+        * <p>
+        * If <code>NO_RESOURCE_MODIFICATION</code> is specified in 
+        * <code>updateModelFlags</code> or if this package fragment root is external, 
+        * this operation doesn't delete the resource. <code>updateResourceFlags</code> 
+        * is then ignored.
+        * </p><p>
+        * If <code>ORIGINATING_PROJECT_CLASSPATH</code> is specified in 
+        * <code>updateModelFlags</code>, update the raw classpath of this package 
+        * fragment root's project by removing the corresponding classpath entry.
+        * </p><p>
+        * If <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> is specified in 
+        * <code>updateModelFlags</code>, update the raw classpaths of all other Java
+        * projects referring to this root's resource by removing the corresponding classpath 
+        * entries.
+        * </p><p>
+        * If no flags is specified in <code>updateModelFlags</code> (using 
+        * <code>IResource.NONE</code>), the default behavior applies: the
+        * resource is deleted (if this package fragment root is not external) and no
+        * classpaths are updated.
+        * </p>
+        * 
+        * @param updateResourceFlags bit-wise or of update resource flag constants
+        *   (<code>IResource.FORCE</code> and <code>IResource.KEEP_HISTORY</code>)
+        * @param updateModelFlags bit-wise or of update resource flag constants
+        *   (<code>ORIGINATING_PROJECT_CLASSPATH</code>,
+        *   <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> and 
+        *   <code>NO_RESOURCE_MODIFICATION</code>)
+        * @param monitor a progress monitor
+        * 
+        * @exception JavaModelException if this root could not be deleted. Reasons
+        * include:
+        * <ul>
+        * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while deleting the resource 
+        * or updating a classpath
+        * </li>
+        * </ul>
+        * @see org.eclipse.core.resources.IResource#delete
+        * @since 2.1
+        */
+//     void delete(int updateResourceFlags, int updateModelFlags, IProgressMonitor monitor) throws JavaModelException;
+       /**
+        * Returns this package fragment root's kind encoded as an integer.
+        * A package fragment root can contain <code>.java</code> source files,
+        * or <code>.class</code> files, but not both.
+        * If the underlying folder or archive contains other kinds of files, they are ignored.
+        * In particular, <code>.class</code> files are ignored under a source package fragment root,
+        * and <code>.java</code> files are ignored under a binary package fragment root.
+        *
+        * @see IPackageFragmentRoot#K_SOURCE
+        * @see IPackageFragmentRoot#K_BINARY
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return this package fragment root's kind encoded as an integer
+        */
+//     int getKind() throws JavaModelException;
+       
+       /**
+        * Returns an array of non-Java resources contained in this package fragment root.
+        * <p>
+        * Non-Java resources includes other files and folders located in the same
+        * directories as the compilation units or class files under this package
+        * fragment root. Resources excluded from this package fragment root
+        * by one or more exclusion patterns on the corresponding source classpath
+        * entry are considered non-Java resources and will appear in the result
+        * (possibly in a folder). Thus when a nested source folder is excluded, it will appear
+        * in the non-Java resources of the outer folder.
+        * </p>
+        * @return an array of non-Java resources contained in this package fragment root
+        * @see IClasspathEntry#getExclusionPatterns
+        */
+//     Object[] getNonJavaResources() throws JavaModelException;
+       
+       /**
+        * Returns the package fragment with the given package name.
+        * An empty string indicates the default package.
+        * This is a handle-only operation.  The package fragment
+        * may or may not exist.
+        * 
+        * @param packageName the given package name
+        * @return the package fragment with the given package name
+        */
+       IPackageFragment getPackageFragment(String packageName);
+       
+
+       /**
+        * Returns the first raw classpath entry that corresponds to this package
+        * fragment root.
+        * A raw classpath entry corresponds to a package fragment root if once resolved
+        * this entry's path is equal to the root's path. 
+        * 
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return the first raw classpath entry that corresponds to this package fragment root
+        * @since 2.0
+        */
+//     IClasspathEntry getRawClasspathEntry() throws JavaModelException;
+       
+       /**
+        * Returns the absolute path to the source archive attached to
+        * this package fragment root's binary archive.
+        *
+        * @return the absolute path to the corresponding source archive, 
+        *   or <code>null</code> if this package fragment root's binary archive
+        *   has no corresponding source archive, or if this package fragment root
+        *   is not a binary archive
+        * @exception JavaModelException if this operation fails
+        */
+//     IPath getSourceAttachmentPath() throws JavaModelException;
+       
+       /**
+        * Returns the path within this package fragment root's source archive. 
+        * An empty path indicates that packages are located at the root of the
+        * source archive.
+        *
+        * @return the path within the corresponding source archive, 
+        *   or <code>null</code> if this package fragment root's binary archive
+        *   has no corresponding source archive, or if this package fragment root
+        *   is not a binary archive
+        * @exception JavaModelException if this operation fails
+        */
+//     IPath getSourceAttachmentRootPath() throws JavaModelException;
+       
+       /**
+        * Returns whether this package fragment root's underlying
+        * resource is a binary archive (a JAR or zip file).
+        * 
+        * @return true if this package fragment root's underlying resource is a binary archive, false otherwise
+        */
+       public boolean isArchive();
+       
+       /**
+        * Returns whether this package fragment root is external
+        * to the workbench (that is, a local file), and has no
+        * underlying resource.
+        * 
+        * @return true if this package fragment root is external
+        * to the workbench (that is, a local file), and has no
+        * underlying resource, false otherwise
+        */
+       boolean isExternal();
+       
+       /**
+        * Moves the resource of this package fragment root to the destination path
+        * as specified by <code>IResource.move(IPath,int,IProgressMonitor)</code>
+        * but excluding nested source folders.
+        * <p>
+        * If <code>NO_RESOURCE_MODIFICATION</code> is specified in 
+        * <code>updateModelFlags</code> or if this package fragment root is external, 
+        * this operation doesn't move the resource. <code>updateResourceFlags</code> 
+        * is then ignored.
+        * </p><p>
+        * If <code>DESTINATION_PROJECT_CLASSPATH</code> is specified in 
+        * <code>updateModelFlags</code>, updates the classpath of the 
+        * destination's project (if it is a Java project). If a non-<code>null</code> 
+        * sibling is specified, a copy of this root's classpath entry is inserted before the 
+        * sibling on the destination project's raw classpath. If <code>null</code> is 
+        * specified, the classpath entry is added at the end of the raw classpath.
+        * </p><p>
+        * If <code>ORIGINATING_PROJECT_CLASSPATH</code> is specified in 
+        * <code>updateModelFlags</code>, update the raw classpath of this package 
+        * fragment root's project by removing the corresponding classpath entry.
+        * </p><p>
+        * If <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> is specified in 
+        * <code>updateModelFlags</code>, update the raw classpaths of all other Java
+        * projects referring to this root's resource by removing the corresponding classpath 
+        * entries.
+        * </p><p>
+        * If <code>REPLACE</code> is specified in <code>updateModelFlags</code>,
+        * overwrites the resource at the destination path if any.
+        * If the same classpath entry already exists on the destination project's raw
+        * classpath, then the sibling is ignored and the new classpath entry replaces the 
+        * existing one.
+        * </p><p>
+        * If no flags is specified in <code>updateModelFlags</code> (using 
+        * <code>IResource.NONE</code>), the default behavior applies: the
+        * resource is moved (if this package fragment root is not external) and no
+        * classpaths are updated.
+        * </p>
+        * 
+        * @param destination the destination path
+        * @param updateFlags bit-wise or of update flag constants
+        * (<code>IResource.FORCE</code>, <code>IResource.KEEP_HISTORY</code> 
+        * and <code>IResource.SHALLOW</code>)
+        * @param updateModelFlags bit-wise or of update resource flag constants
+        *   (<code>DESTINATION_PROJECT_CLASSPATH</code>,
+        *   <code>ORIGINATING_PROJECT_CLASSPATH</code>,
+        *   <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> and 
+        *   <code>NO_RESOURCE_MODIFICATION</code>)
+        * @param sibling the classpath entry before which a copy of the classpath
+        * entry should be inserted or <code>null</code> if the classpath entry should
+        * be inserted at the end
+        * @param monitor a progress monitor
+        * 
+        * @exception JavaModelException if this root could not be moved. Reasons
+        * include:
+        * <ul>
+        * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while copying the
+        * resource or updating a classpath</li>
+        * <li>
+        * The destination is not inside an existing project and <code>updateModelFlags</code>
+        * has been specified as <code>DESTINATION_PROJECT_CLASSPATH</code> 
+        * (INVALID_DESTINATION)</li>
+        * <li> The sibling is not a classpath entry on the destination project's
+        * raw classpath (INVALID_SIBLING)</li>
+        * <li> The same classpath entry already exists on the destination project's
+        * classpath (NAME_COLLISION) and <code>updateModelFlags</code>
+        * has not been specified as <code>REPLACE</code></li>
+        * </ul>
+        * @see org.eclipse.core.resources.IResource#move
+        * @since 2.1
+        */
+//     void move(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
+}
\ No newline at end of file
index f1571c5..2a31793 100644 (file)
@@ -26,7 +26,7 @@ public interface IParent {
  *      exception occurs while accessing its corresponding resource
  * @return the immediate children of this element
  */
-IJavaElement[] getChildren() throws JavaModelException;
+//IJavaElement[] getChildren() throws JavaModelException;
 /**
  * Returns whether this element has one or more immediate children.
  * This is a convenience method, and may be more efficient than
@@ -36,5 +36,5 @@ IJavaElement[] getChildren() throws JavaModelException;
  *      exception occurs while accessing its corresponding resource
  * @return true if the immediate children of this element, false otherwise
  */
-boolean hasChildren() throws JavaModelException;
+//boolean hasChildren() throws JavaModelException;
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IProblemRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IProblemRequestor.java
new file mode 100644 (file)
index 0000000..5f2e487
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import net.sourceforge.phpdt.core.compiler.IProblem;
+
+
+/**
+ * A callback interface for receiving java problem as they are discovered
+ * by some Java operation.
+ * 
+ * @see IProblem
+ * @since 2.0
+ */
+public interface IProblemRequestor {
+       
+       /**
+        * Notification of a Java problem.
+        * 
+        * @param problem IProblem - The discovered Java problem.
+        */     
+       void acceptProblem(IProblem problem);
+
+       /**
+        * Notification sent before starting the problem detection process.
+        * Typically, this would tell a problem collector to clear previously recorded problems.
+        */
+       void beginReporting();
+
+       /**
+        * Notification sent after having completed problem detection process.
+        * Typically, this would tell a problem collector that no more problems should be expected in this
+        * iteration.
+        */
+       void endReporting();
+
+       /**
+        * Predicate allowing the problem requestor to signal whether or not it is currently
+        * interested by problem reports. When answering <code>false</false>, problem will
+        * not be discovered any more until the next iteration.
+        * 
+        * This  predicate will be invoked once prior to each problem detection iteration.
+        * 
+        * @return boolean - indicates whether the requestor is currently interested by problems.
+        */
+       boolean isActive();
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IRegion.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IRegion.java
new file mode 100644 (file)
index 0000000..6733054
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * A Java model region describes a hierarchical set of elements.
+ * Regions are often used to describe a set of elements to be considered
+ * when performing operations; for example, the set of elements to be
+ * considered during a search. A region may include elements from different
+ * projects.
+ * <p>
+ * When an element is included in a region, all of its children
+ * are considered to be included. Children of an included element 
+ * <b>cannot</b> be selectively excluded.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * Instances can be created via the <code>JavaCore.newRegion</code>.
+ * </p>
+ *
+ * @see JavaCore#newRegion
+ */
+public interface IRegion {
+       /**
+        * Adds the given element and all of its descendents to this region.
+        * If the specified element is already included, or one of its
+        * ancestors is already included, this has no effect. If the element
+        * being added is an ancestor of an element already contained in this
+        * region, the ancestor subsumes the descendent.
+        * 
+        * @param element the given element
+        */
+       void add(IJavaElement element);
+       /**
+        * Returns whether the given element is contained in this region.
+        * 
+        * @param element the given element
+        * @return true if the given element is contained in this region, false otherwise
+        */
+       boolean contains(IJavaElement element);
+       /**
+        * Returns the top level elements in this region.
+        * All descendents of these elements are also included in this region.
+        * 
+        * @return the top level elements in this region
+        */
+       IJavaElement[] getElements();
+       /**
+        * Removes the specified element from the region and returns
+        * <code>true</code> if successful, <code>false</code> if the remove
+        * fails. If an ancestor of the given element is included, the
+        * remove fails (in other words, it is not possible to selectively
+        * exclude descendants of included ancestors).
+        * 
+        * @param element the given element
+        * @return <code>true</code> if successful, <code>false</code> if the remove fails
+        */
+       boolean remove(IJavaElement element);
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceManipulation.java
new file mode 100644 (file)
index 0000000..2747a52
--- /dev/null
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Common protocol for Java elements that support source code manipulations such
+ * as copy, move, rename, and delete.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface ISourceManipulation {
+/**
+ * Copies this element to the given container.
+ *
+ * @param container the container
+ * @param sibling the sibling element before which the copy should be inserted,
+ *   or <code>null</code> if the copy should be inserted as the last child of
+ *   the container
+ * @param rename the new name for the element, or <code>null</code> if the copy
+ *   retains the name of this element
+ * @param replace <code>true</code> if any existing child in the container with
+ *   the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be copied. Reasons include:
+ * <ul>
+ * <li> This Java element, container element, or sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The container is of an incompatible type (INVALID_DESTINATION)
+ * <li> The sibling is not a child of the given container (INVALID_SIBLING)
+ * <li> The new name is invalid (INVALID_NAME)
+ * <li> A child in the container already exists with the same name (NAME_COLLISION)
+ *             and <code>replace</code> has been specified as <code>false</code>
+ * <li> The container or this element is read-only (READ_ONLY) 
+ * </ul>
+ *
+ * @exception IllegalArgumentException if container is <code>null</code>
+ */
+void copy(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Deletes this element, forcing if specified and necessary.
+ *
+ * @param force a flag controlling whether underlying resources that are not
+ *    in sync with the local file system will be tolerated (same as the force flag
+ *       in IResource operations).
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be deleted. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource (CORE_EXCEPTION)</li>
+ * <li> This element is read-only (READ_ONLY)</li>
+ * </ul>
+ */
+void delete(boolean force, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Moves this element to the given container.
+ *
+ * @param container the container
+ * @param sibling the sibling element before which the element should be inserted,
+ *   or <code>null</code> if the element should be inserted as the last child of
+ *   the container
+ * @param rename the new name for the element, or <code>null</code> if the
+ *   element retains its name
+ * @param replace <code>true</code> if any existing child in the container with
+ *   the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be moved. Reasons include:
+ * <ul>
+ * <li> This Java element, container element, or sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The container is of an incompatible type (INVALID_DESTINATION)
+ * <li> The sibling is not a child of the given container (INVALID_SIBLING)
+ * <li> The new name is invalid (INVALID_NAME)
+ * <li> A child in the container already exists with the same name (NAME_COLLISION)
+ *             and <code>replace</code> has been specified as <code>false</code>
+ * <li> The container or this element is read-only (READ_ONLY) 
+ * </ul>
+ *
+ * @exception IllegalArgumentException if container is <code>null</code>
+ */
+void move(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Renames this element to the given name.
+ *
+ * @param name the new name for the element
+ * @param replace <code>true</code> if any existing element with the target name
+ *   should be replaced, and <code>false</code> to throw an exception in the
+ *   event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be renamed. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The new name is invalid (INVALID_NAME)
+ * <li> A child in the container already exists with the same name (NAME_COLLISION)
+ *             and <code>replace</code> has been specified as <code>false</code>
+ * <li> This element is read-only (READ_ONLY) 
+ * </ul>
+ */
+void rename(String name, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceRange.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceRange.java
new file mode 100644 (file)
index 0000000..46ab0f6
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * A source range defines an element's source coordinates relative to
+ * its source buffer.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface ISourceRange {
+
+/**
+ * Returns the number of characters of the source code for this element,
+ * relative to the source buffer in which this element is contained.
+ * 
+ * @return the number of characters of the source code for this element,
+ * relative to the source buffer in which this element is contained
+ */
+int getLength();
+/**
+ * Returns the 0-based index of the first character of the source code for this element,
+ * relative to the source buffer in which this element is contained.
+ * 
+ * @return the 0-based index of the first character of the source code for this element,
+ * relative to the source buffer in which this element is contained
+ */
+int getOffset();
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceReference.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ISourceReference.java
new file mode 100644 (file)
index 0000000..6497066
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+/**
+ * Common protocol for Java elements that have associated source code.
+ * This set consists of <code>IClassFile</code>, <code>ICompilationUnit</code>,
+ * <code>IPackageDeclaration</code>, <code>IImportDeclaration</code>,
+ * <code>IImportContainer</code>, <code>IType</code>, <code>IField</code>,
+ * <code>IMethod</code>, and <code>IInitializer</code>.
+ * </ul>
+ * <p>
+ * Note: For <code>IClassFile</code>, <code>IType</code> and other members
+ * derived from a binary type, the implementation returns source iff the
+ * element has attached source code.
+ * </p>
+ * <p>
+ * Source reference elements may be working copies if they were created from
+ * a compilation unit that is a working copy.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ *
+ * @see IPackageFragmentRoot#attachSource
+ */
+public interface ISourceReference {
+/**
+ * Returns whether this element exists in the model.
+ *
+ * @return <code>true</code> if this element exists in the Java model
+ * @since 2.0
+ */
+boolean exists();
+       
+/**
+ * Returns the source code associated with this element.
+ * This extracts the substring from the source buffer containing this source
+ * element. This corresponds to the source range that would be returned by
+ * <code>getSourceRange</code>.
+ * <p>
+ * For class files, this returns the source of the entire compilation unit 
+ * associated with the class file (if there is one).
+ * </p>
+ *
+ * @return the source code, or <code>null</code> if this element has no 
+ *   associated source code
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+String getSource() throws JavaModelException;
+/**
+ * Returns the source range associated with this element.
+ * <p>
+ * For class files, this returns the range of the entire compilation unit 
+ * associated with the class file (if there is one).
+ * </p>
+ *
+ * @return the source range, or <code>null</code> if this element has no 
+ *   associated source code
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+ISourceRange getSourceRange() throws JavaModelException;
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IType.java
new file mode 100644 (file)
index 0000000..31e4630
--- /dev/null
@@ -0,0 +1,589 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Represents either a source type in a compilation unit (either a top-level
+ * type or a member type) or a binary type in a class file.
+ * <p>
+ * If a binary type cannot be parsed, its structure remains unknown.
+ * Use <code>IJavaElement.isStructureKnown</code> to determine whether this
+ * is the case.
+ * </p>
+ * <p>
+ * The children are of type <code>IMember</code>, which includes <code>IField</code>,
+ * <code>IMethod</code>, <code>IInitializer</code> and <code>IType</code>.
+ * The children are listed in the order in which they appear in the source or class file.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IType extends IMember, IParent {
+       /**
+        * Do code completion inside a code snippet in the context of the current type.
+        * 
+        * If the type can access to his source code and the insertion position is valid,
+        * then completion is performed against source. Otherwise the completion is performed
+        * against type structure and given locals variables.
+        * 
+        * @param snippet the code snippet
+        * @param insertion the position with in source where the snippet
+        * is inserted. This position must not be in comments.
+        * A possible value is -1, if the position is not known.
+        * @param position the position with in snippet where the user 
+        * is performing code assist.
+        * @param localVariableTypesNames an array (possibly empty) of fully qualified 
+        * type names of local variables visible at the current scope
+        * @param localVariableNames an array (possibly empty) of local variable names 
+        * that are visible at the current scope
+        * @param localVariableModifiers an array (possible empty) of modifiers for 
+        * local variables
+        * @param isStatic whether the current scope is in a static context
+        * @param requestor the completion requestor
+        * @since 2.0
+        */
+       void codeComplete(
+               char[] snippet,
+               int insertion,
+               int position,
+               char[][] localVariableTypeNames,
+               char[][] localVariableNames,
+               int[] localVariableModifiers,
+               boolean isStatic,
+               ICompletionRequestor requestor)
+               throws JavaModelException;
+
+       /**
+        * Creates and returns a field in this type with the
+        * given contents.
+        * <p>
+        * Optionally, the new element can be positioned before the specified
+        * sibling. If no sibling is specified, the element will be inserted
+        * as the last field declaration in this type.</p>
+        *
+        * <p>It is possible that a field with the same name already exists in this type.
+        * The value of the <code>force</code> parameter effects the resolution of
+        * such a conflict:<ul>
+        * <li> <code>true</code> - in this case the field is created with the new contents</li>
+        * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+        * </ul></p>
+        *
+        * @param contents the given contents
+        * @param sibling the given sibling
+        * @param force a flag in case the same name already exists in this type
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if the element could not be created. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while updating an underlying resource
+        * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+        * <li> The contents could not be recognized as a field declaration (INVALID_CONTENTS)
+        * <li> This type is read-only (binary) (READ_ONLY)
+        * <li> There was a naming collision with an existing field (NAME_COLLISION)
+        * </ul>
+        * @return a field in this type with the given contents
+        */
+       IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor)
+               throws JavaModelException;
+               
+       /**
+        * Creates and returns a static initializer in this type with the
+        * given contents.
+        * <p>
+        * Optionally, the new element can be positioned before the specified
+        * sibling. If no sibling is specified, the new initializer is positioned
+        * after the last existing initializer declaration, or as the first member
+        * in the type if there are no initializers.</p>
+        *
+        * @param contents the given contents
+        * @param sibling the given sibling
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if the element could not be created. Reasons include:
+        * <ul>
+        * <li> This element does not exist
+        * <li> A <code>CoreException</code> occurred while updating an underlying resource
+        * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+        * <li> The contents could not be recognized as an initializer declaration (INVALID_CONTENTS)
+        * <li> This type is read-only (binary) (READ_ONLY)
+        * </ul>
+        * @return a static initializer in this type with the given contents
+        */
+//     IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor)
+//             throws JavaModelException;
+               
+       /**
+        * Creates and returns a method or constructor in this type with the
+        * given contents.
+        * <p>
+        * Optionally, the new element can be positioned before the specified
+        * sibling. If no sibling is specified, the element will be appended
+        * to this type.
+        *
+        * <p>It is possible that a method with the same signature already exists in this type.
+        * The value of the <code>force</code> parameter effects the resolution of
+        * such a conflict:<ul>
+        * <li> <code>true</code> - in this case the method is created with the new contents</li>
+        * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+        * </ul></p>
+        *
+        * @param contents the given contents
+        * @param sibling the given sibling
+        * @param force a flag in case the same name already exists in this type
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if the element could not be created. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while updating an underlying resource
+        * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+        * <li> The contents could not be recognized as a method or constructor
+        *              declaration (INVALID_CONTENTS)
+        * <li> This type is read-only (binary) (READ_ONLY)
+        * <li> There was a naming collision with an existing method (NAME_COLLISION)
+        * </ul>
+        * @return a method or constructor in this type with the given contents
+        */
+       IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor)
+               throws JavaModelException;
+               
+       /**
+        * Creates and returns a type in this type with the
+        * given contents.
+        * <p>
+        * Optionally, the new type can be positioned before the specified
+        * sibling. If no sibling is specified, the type will be appended
+        * to this type.
+        *
+        * <p>It is possible that a type with the same name already exists in this type.
+        * The value of the <code>force</code> parameter effects the resolution of
+        * such a conflict:<ul>
+        * <li> <code>true</code> - in this case the type is created with the new contents</li>
+        * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+        * </ul></p>
+        *
+        * @param contents the given contents
+        * @param sibling the given sibling
+        * @param force a flag in case the same name already exists in this type
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if the element could not be created. Reasons include:
+        * <ul>
+        * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * <li> A <code>CoreException</code> occurred while updating an underlying resource
+        * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+        * <li> The contents could not be recognized as a type declaration (INVALID_CONTENTS)
+        * <li> This type is read-only (binary) (READ_ONLY)
+        * <li> There was a naming collision with an existing field (NAME_COLLISION)
+        * </ul>
+        * @return a type in this type with the given contents
+        */
+       IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor)
+               throws JavaModelException;
+               
+       /** 
+        * Finds the methods in this type that correspond to
+        * the given method.
+        * A method m1 corresponds to another method m2 if:
+        * <ul>
+        * <li>m1 has the same element name as m2.
+        * <li>m1 has the same number of arguments as m2 and
+        *     the simple names of the argument types must be equals.
+        * <li>m1 exists.
+        * </ul>
+        * @param method the given method
+        * @return the found method or <code>null</code> if no such methods can be found.
+        * 
+        * @since 2.0 
+        */
+       IMethod[] findMethods(IMethod method);
+       
+       /**
+        * Returns the simple name of this type, unqualified by package or enclosing type.
+        * This is a handle-only method.
+        * 
+        * @return the simple name of this type
+        */
+       String getElementName();
+       
+       /**
+        * Returns the field with the specified name
+        * in this type (for example, <code>"bar"</code>).
+        * This is a handle-only method.  The field may or may not exist.
+        * 
+        * @param name the given name
+        * @return the field with the specified name in this type
+        */
+       IField getField(String name);
+       
+       /**
+        * Returns the fields declared by this type.
+        * If this is a source type, the results are listed in the order
+        * in which they appear in the source, otherwise, the results are
+        * in no particular order.  For binary types, this includes synthetic fields.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return the fields declared by this type
+        */
+       IField[] getFields() throws JavaModelException;
+       
+       /**
+        * Returns the fully qualified name of this type, 
+        * including qualification for any containing types and packages.
+        * This is the name of the package, followed by <code>'.'</code>,
+        * followed by the type-qualified name.
+        * This is a handle-only method.
+        *
+        * @see IType#getTypeQualifiedName()
+        * @return the fully qualified name of this type
+        */
+       String getFullyQualifiedName();
+       
+       /**
+        * Returns the fully qualified name of this type, 
+        * including qualification for any containing types and packages.
+        * This is the name of the package, followed by <code>'.'</code>,
+        * followed by the type-qualified name using the <code>enclosingTypeSeparator</code>.
+        * 
+        * For example:
+        * <ul>
+        * <li>the fully qualified name of a class B defined as a member of a class A in a compilation unit A.java 
+        *     in a package x.y using the '.' separator is "x.y.A.B"</li>
+        * <li>the fully qualified name of a class B defined as a member of a class A in a compilation unit A.java 
+        *     in a package x.y using the '$' separator is "x.y.A$B"</li>
+        * <li>the fully qualified name of a binary type whose class file is x/y/A$B.class
+        *     using the '.' separator is "x.y.A.B"</li>
+        * <li>the fully qualified name of a binary type whose class file is x/y/A$B.class
+        *     using the '$' separator is "x.y.A$B"</li>
+        * <li>the fully qualified name of an anonymous binary type whose class file is x/y/A$1.class
+        *     using the '.' separator is "x.y.A$1"</li>
+        * </ul>
+        * 
+        * This is a handle-only method.
+        *
+        * @param enclosingTypeSeparator the given enclosing type separator
+        * @return the fully qualified name of this type, including qualification for any containing types and packages
+        * @see IType#getTypeQualifiedName(char)
+        * @since 2.0
+        */
+       String getFullyQualifiedName(char enclosingTypeSeparator);
+       
+       /**
+        * Returns the initializer with the specified position relative to
+        * the order they are defined in the source.
+        * Numbering starts at 1 (thus the first occurrence is occurrence 1, not occurrence 0).
+        * This is a handle-only method.  The initializer may or may not be present.
+        * 
+        * @param occurrenceCount the specified position
+        * @return the initializer with the specified position relative to the order they are defined in the source
+        */
+//     IInitializer getInitializer(int occurrenceCount);
+       
+       /**
+        * Returns the initializers declared by this type.
+        * For binary types this is an empty collection.
+        * If this is a source type, the results are listed in the order
+        * in which they appear in the source.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return the initializers declared by this type
+        */
+//     IInitializer[] getInitializers() throws JavaModelException;
+       
+       /**
+        * Returns the method with the specified name and parameter types
+        * in this type (for example, <code>"foo", {"I", "QString;"}</code>). To get the
+        * handle for a constructor, the name specified must be the simple
+        * name of the enclosing type.
+        * This is a handle-only method.  The method may or may not be present.
+        * 
+        * @param name the given name
+        * @param parameterTypeSignatures the given parameter types
+        * @return the method with the specified name and parameter types in this type
+        */
+       IMethod getMethod(String name, String[] parameterTypeSignatures);
+       
+       /**
+        * Returns the methods and constructors declared by this type.
+        * For binary types, this may include the special <code>&lt;clinit&gt</code>; method 
+        * and synthetic methods.
+        * If this is a source type, the results are listed in the order
+        * in which they appear in the source, otherwise, the results are
+        * in no particular order.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return the methods and constructors declared by this type
+        */
+       IMethod[] getMethods() throws JavaModelException;
+       
+       /**
+        * Returns the package fragment in which this element is defined.
+        * This is a handle-only method.
+        * 
+        * @return the package fragment in which this element is defined
+        */
+       IPackageFragment getPackageFragment();
+       
+       /**
+        * Returns the name of this type's superclass, or <code>null</code>
+        * for source types that do not specify a superclass.
+        * For interfaces, the superclass name is always <code>"java.lang.Object"</code>.
+        * For source types, the name as declared is returned, for binary types,
+        * the resolved, qualified name is returned.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return the name of this type's superclass, or <code>null</code> for source types that do not specify a superclass
+        */
+       String getSuperclassName() throws JavaModelException;
+       
+       /**
+        * Returns the names of interfaces that this type implements or extends,
+        * in the order in which they are listed in the source.
+        * For classes, this gives the interfaces that this class implements.
+        * For interfaces, this gives the interfaces that this interface extends.
+        * An empty collection is returned if this type does not implement or
+        * extend any interfaces. For source types, simple names are returned,
+        * for binary types, qualified names are returned.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return  the names of interfaces that this type implements or extends, in the order in which they are listed in the source, 
+        * an empty collection if none
+        */
+       String[] getSuperInterfaceNames() throws JavaModelException;
+       
+       /**
+        * Returns the member type declared in this type with the given simple name.
+        * This is a handle-only method. The type may or may not exist.
+        * 
+        * @param the given simple name
+        * @return the member type declared in this type with the given simple name
+        */
+       IType getType(String name);
+       
+       /**
+        * Returns the type-qualified name of this type, 
+        * including qualification for any enclosing types,
+        * but not including package qualification.
+        * For source types, this consists of the simple names of
+        * any enclosing types, separated by <code>"$"</code>, followed by the simple name of this type.
+        * For binary types, this is the name of the class file without the ".class" suffix.
+        * This is a handle-only method.
+        * 
+        * @return the type-qualified name of this type
+        */
+       String getTypeQualifiedName();
+       
+       /**
+        * Returns the type-qualified name of this type, 
+        * including qualification for any enclosing types,
+        * but not including package qualification.
+        * This consists of the simple names of any enclosing types, 
+        * separated by the <code>enclosingTypeSeparator</code>, 
+        * followed by the simple name of this type.
+        * 
+        * For example:
+        * <ul>
+        * <li>the type qualified name of a class B defined as a member of a class A
+        *     using the '.' separator is "A.B"</li>
+        * <li>the type qualified name of a class B defined as a member of a class A
+        *     using the '$' separator is "A$B"</li>
+        * <li>the type qualified name of a binary type whose class file is A$B.class
+        *     using the '.' separator is "A.B"</li>
+        * <li>the type qualified name of a binary type whose class file is A$B.class
+        *     using the '$' separator is "A$B"</li>
+        * <li>the type qualified name of an anonymous binary type whose class file is A$1.class
+        *     using the '.' separator is "A$1"</li>
+        * </ul>
+        *
+        * This is a handle-only method.
+        * 
+        * @param enclosingTypeSeparator the specified enclosing type separator
+        * @return the type-qualified name of this type
+        * @since 2.0
+        */
+       String getTypeQualifiedName(char enclosingTypeSeparator);
+       
+       /**
+        * Returns the immediate member types declared by this type.
+        * The results are listed in the order in which they appear in the source or class file.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return the immediate member types declared by this type
+        */
+       IType[] getTypes() throws JavaModelException;
+       
+       /**
+        * Returns whether this type represents an anonymous type.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return true if this type represents an anonymous type, false otherwise
+        * @since 2.0
+        */
+       boolean isAnonymous() throws JavaModelException;
+
+       /**
+        * Returns whether this type represents a class.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return true if this type represents a class, false otherwise
+        */
+       boolean isClass() throws JavaModelException;
+       
+       /**
+        * Returns whether this type represents an interface.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return true if this type represents an interface, false otherwise
+        */
+       boolean isInterface() throws JavaModelException;
+       
+       /**
+        * Returns whether this type represents a local type.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return true if this type represents a local type, false otherwise
+        * @since 2.0
+        */
+       boolean isLocal() throws JavaModelException;
+
+       /**
+        * Returns whether this type represents a member type.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return true if this type represents a member type, false otherwise
+        * @since 2.0
+        */
+       boolean isMember() throws JavaModelException;
+       /**
+        * Loads a previously saved ITypeHierarchy from an input stream. A type hierarchy can
+        * be stored using ITypeHierachy#store(OutputStream).
+        * 
+        * Only hierarchies originally created by the following methods can be load:
+        * <ul>
+        * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
+        * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
+        * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
+        * </u>
+        * 
+        * @param input stream where hierarchy will be read
+        * @param monitor the given progress monitor
+        * @return the stored hierarchy
+        * @exception JavaModelException if the hierarchy could not be restored, reasons include:
+        *      - type is not the focus of the hierarchy or 
+        *              - unable to read the input stream (wrong format, IOException during reading, ...)
+        * @see ITypeHierarchy#store(OutputStream, IProgressMonitor)
+        * @since 2.1
+        */
+//     ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException;
+       /**
+        * Creates and returns a type hierarchy for this type containing
+        * this type and all of its supertypes.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @param monitor the given progress monitor
+        * @return a type hierarchy for this type containing this type and all of its supertypes
+        */
+//     ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException;
+       
+       /**
+        * Creates and returns a type hierarchy for this type containing
+        * this type and all of its supertypes, considering types in the given 
+        * working copies. In other words, the list of working copies will take 
+        * precedence over their original compilation units in the workspace.
+        * <p>
+        * Note that passing an empty working copy will be as if the original compilation
+        * unit had been deleted.
+        *
+        * @param workingCopies the working copies that take precedence over their original compilation units
+        * @param monitor the given progress monitor
+        * @return a type hierarchy for this type containing this type and all of its supertypes
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @since 2.0
+        */
+//     ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[] workingCopies, IProgressMonitor monitor)
+//             throws JavaModelException;
+               
+       /**
+        * Creates and returns a type hierarchy for this type containing
+        * this type, all of its supertypes, and all its subtypes in the workspace.
+        *
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @param monitor the given progress monitor
+        * @return a type hierarchy for this type containing
+        * this type, all of its supertypes, and all its subtypes in the workspace
+        */
+//     ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException;
+       
+       /**
+        * Creates and returns a type hierarchy for this type containing
+        * this type, all of its supertypes, and all its subtypes in the workspace, 
+        * considering types in the given working copies. In other words, the list of working 
+        * copies that will take precedence over their original compilation units in the workspace.
+        * <p>
+        * Note that passing an empty working copy will be as if the original compilation
+        * unit had been deleted.
+        *
+        * @param workingCopies the working copies that take precedence over their original compilation units
+        * @param monitor the given progress monitor
+        * @return a type hierarchy for this type containing
+        * this type, all of its supertypes, and all its subtypes in the workspace
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @since 2.0
+        */
+//     ITypeHierarchy newTypeHierarchy(IWorkingCopy[] workingCopies, IProgressMonitor monitor) throws JavaModelException;
+       
+       /**
+        * Creates and returns a type hierarchy for this type containing
+        * this type, all of its supertypes, and all its subtypes 
+        * in the context of the given project.
+        *
+        * @param project the given project
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if this element does not exist or if an
+        *              exception occurs while accessing its corresponding resource.
+        * @return a type hierarchy for this type containing
+        * this type, all of its supertypes, and all its subtypes 
+        * in the context of the given project
+        */
+//     ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException;
+       
+       /**
+        * Resolves the given type name within the context of this type (depending on the type hierarchy 
+        * and its imports). Multiple answers might be found in case there are ambiguous matches.
+        *
+        * Each matching type name is decomposed as an array of two strings, the first denoting the package
+        * name (dot-separated) and the second being the type name.
+        * Returns <code>null</code> if unable to find any matching type.
+        *
+        * For example, resolution of <code>"Object"</code> would typically return
+        * <code>{{"java.lang", "Object"}}</code>.
+        * 
+        * @param typeName the given type name
+        * @exception JavaModelException if code resolve could not be performed. 
+        * @return the resolved type names or <code>null</code> if unable to find any matching type
+        */
+       String[][] resolveType(String typeName) throws JavaModelException;
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/IWorkingCopy.java
new file mode 100644 (file)
index 0000000..d364b32
--- /dev/null
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Common protocol for Java elements that support working copies.
+ * <p>
+ * A working copy of a Java element acts just like a regular element (handle),
+ * except it is not attached to an underlying resource. A working copy is not
+ * visible to the rest of the Java model. Changes in a working copy's
+ * buffer are not realized in a resource. To bring the Java model up-to-date with a working
+ * copy's contents, an explicit commit must be performed on the working copy. 
+ * Other operations performed on a working copy update the
+ * contents of the working copy's buffer but do not commit the contents
+ * of the working copy.
+ * </p>
+ * <p>
+ * Note: The contents of a working copy is determined when a working
+ * copy is created, based on the current content of the element the working
+ * copy is created from. If a working copy is an <code>IOpenable</code> and is explicitly
+ * closed, the working copy's buffer will be thrown away. However, clients should not
+ * explicitly open and close working copies.
+ * </p>
+ * <p>
+ * The client that creates a working copy is responsible for
+ * destroying the working copy. The Java model will never automatically
+ * destroy or close a working copy. (Note that destroying a working copy
+ * does not commit it to the model, it only frees up the memory occupied by
+ * the element). After a working copy is destroyed, the working copy cannot
+ * be accessed again. Non-handle methods will throw a 
+ * <code>JavaModelException</code> indicating the Java element does not exist.
+ * </p>
+ * <p>
+ * A working copy cannot be created from another working copy.
+ * Calling <code>getWorkingCopy</code> on a working copy returns the receiver.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ */
+public interface IWorkingCopy {
+       
+       /**
+        * Commits the contents of this working copy to its original element
+        * and underlying resource, bringing the Java model up-to-date with
+        * the current contents of the working copy.
+        *
+        * <p>It is possible that the contents of the original resource have changed
+        * since this working copy was created, in which case there is an update conflict.
+        * The value of the <code>force</code> parameter effects the resolution of
+        * such a conflict:<ul>
+        * <li> <code>true</code> - in this case the contents of this working copy are applied to
+        *      the underlying resource even though this working copy was created before
+        *      a subsequent change in the resource</li>
+        * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+        * </ul>
+        * <p>
+        * Since 2.1, a working copy can be created on a not-yet existing compilation
+        * unit. In particular, such a working copy can then be committed in order to create
+        * the corresponding compilation unit.
+        * </p>
+        * @param force a flag to handle the cases when the contents of the original resource have changed
+        * since this working copy was created
+        * @param monitor the given progress monitor
+        * @exception JavaModelException if this working copy could not commit. Reasons include:
+        * <ul>
+        * <li> A <code>CoreException</code> occurred while updating an underlying resource
+        * <li> This element is not a working copy (INVALID_ELEMENT_TYPES)
+        * <li> A update conflict (described above) (UPDATE_CONFLICT)
+        * </ul>
+        */
+       void commit(boolean force, IProgressMonitor monitor) throws JavaModelException;
+       
+       /**
+        * Destroys this working copy, closing its buffer and discarding
+        * its structure. Subsequent attempts to access non-handle information
+        * for this working copy will result in <code>IJavaModelException</code>s. Has
+        * no effect if this element is not a working copy.
+        * <p>
+        * If this working copy is shared, it is destroyed only when the number of calls to
+        * <code>destroy()</code> is the same as the number of calls to <code>
+        * getSharedWorkingCopy(IProgressMonitor, IBufferFactory)</code>. 
+        * </p><p>
+        * When it is destroyed, a REMOVED IJavaElementDelta is reported on this 
+        * working copy.
+        * </p>
+        */
+       void destroy();
+       
+       /**
+        * Finds the shared working copy for this element, given a <code>IBuffer</code> factory. 
+        * If no working copy has been created for this element associated with this
+        * buffer factory, returns <code>null</code>.
+        * <p>
+        * Users of this method must not destroy the resulting working copy. 
+        * 
+        * @param bufferFactory the given <code>IBuffer</code> factory
+        * @return the found shared working copy for this element, <code>null</code> if none
+        * @see IBufferFactory
+        * @since 2.0
+        */
+       IJavaElement findSharedWorkingCopy(IBufferFactory bufferFactory);
+
+       /**
+        * Returns the original element the specified working copy element was created from,
+        * or <code>null</code> if this is not a working copy element.  This is a handle
+        * only method, the returned element may or may not exist.
+        * 
+        * @return the original element the specified working copy element was created from,
+        * or <code>null</code> if this is not a working copy element
+        */
+       IJavaElement getOriginal(IJavaElement workingCopyElement);
+       
+       /**
+        * Returns the original element this working copy was created from,
+        * or <code>null</code> if this is not a working copy.
+        * 
+        * @return the original element this working copy was created from,
+        * or <code>null</code> if this is not a working copy
+        */
+       IJavaElement getOriginalElement();
+       
+       /** 
+        * Finds the elements in this compilation unit that correspond to
+        * the given element.
+        * An element A corresponds to an element B if:
+        * <ul>
+        * <li>A has the same element name as B.
+        * <li>If A is a method, A must have the same number of arguments as
+        *     B and the simple names of the argument types must be equals.
+        * <li>The parent of A corresponds to the parent of B recursively up to
+        *     their respective compilation units.
+        * <li>A exists.
+        * </ul>
+        * Returns <code>null</code> if no such java elements can be found
+        * or if the given element is not included in a compilation unit.
+        * 
+        * @param element the given element
+        * @return the found elements in this compilation unit that correspond to the given element
+        * @since 2.0 
+        */
+       IJavaElement[] findElements(IJavaElement element);
+       
+       /**
+        * Finds the primary type of this compilation unit (that is, the type with the same name as the
+        * compilation unit), or <code>null</code> if no such a type exists.
+        * 
+        * @return the found primary type of this compilation unit, or <code>null</code> if no such a type exists
+        * @since 2.0
+        */
+//     IType findPrimaryType();
+       
+       /**
+        * Returns a shared working copy on this element using the given factory to create
+        * the buffer, or this element if this element is already a working copy.
+        * This API can only answer an already existing working copy if it is based on the same
+        * original compilation unit AND was using the same buffer factory (that is, as defined by <code>Object.equals</code>).  
+        * <p>
+        * The life time of a shared working copy is as follows:
+        * <ul>
+        * <li>The first call to <code>getSharedWorkingCopy(...)</code> creates a new working copy for this
+        *     element</li>
+        * <li>Subsequent calls increment an internal counter.</li>
+        * <li>A call to <code>destroy()</code> decrements the internal counter.</li>
+        * <li>When this counter is 0, the working copy is destroyed.
+        * </ul>
+        * So users of this method must destroy exactly once the working copy.
+        * <p>
+        * Note that the buffer factory will be used for the life time of this working copy, that is if the 
+        * working copy is closed then reopened, this factory will be used.
+        * The buffer will be automatically initialized with the original's compilation unit content
+        * upon creation.
+        * <p>
+        * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this
+        * working copy.
+        *
+        * @param monitor a progress monitor used to report progress while opening this compilation unit
+        *                 or <code>null</code> if no progress should be reported 
+        * @param factory the factory that creates a buffer that is used to get the content of the working copy
+        *                 or <code>null</code> if the internal factory should be used
+        * @param problemRequestor a requestor which will get notified of problems detected during
+        *      reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+        *      that the client is not interested in problems.
+        * @exception JavaModelException if the contents of this element can
+        *   not be determined. 
+        * @return a shared working copy on this element using the given factory to create
+        * the buffer, or this element if this element is already a working copy
+        * @see IBufferFactory
+        * @see IProblemRequestor
+        * @since 2.0
+        */
+       IJavaElement getSharedWorkingCopy(
+               IProgressMonitor monitor,
+               IBufferFactory factory,
+               IProblemRequestor problemRequestor)
+               throws JavaModelException;
+               
+       /**
+        * Returns a new working copy of this element if this element is not
+        * a working copy, or this element if this element is already a working copy.
+        * <p>
+        * Note: if intending to share a working copy amongst several clients, then 
+        * <code>#getSharedWorkingCopy</code> should be used instead.
+        * </p><p>
+        * When the working copy instance is created, an ADDED IJavaElementDelta is 
+        * reported on this working copy.
+        * </p><p>
+        * Since 2.1, a working copy can be created on a not-yet existing compilation
+        * unit. In particular, such a working copy can then be committed in order to create
+        * the corresponding compilation unit.
+        * </p>
+        * @exception JavaModelException if the contents of this element can
+        *   not be determined. 
+        * @return a new working copy of this element if this element is not
+        * a working copy, or this element if this element is already a working copy
+        */
+       IJavaElement getWorkingCopy() throws JavaModelException;
+       
+       /**
+        * Returns a new working copy of this element using the given factory to create
+        * the buffer, or this element if this element is already a working copy.
+        * Note that this factory will be used for the life time of this working copy, that is if the 
+        * working copy is closed then reopened, this factory will be reused.
+        * The buffer will be automatically initialized with the original's compilation unit content
+        * upon creation.
+        * <p>
+        * Note: if intending to share a working copy amongst several clients, then 
+        * <code>#getSharedWorkingCopy</code> should be used instead.
+        * </p><p>
+        * When the working copy instance is created, an ADDED IJavaElementDelta is 
+        * reported on this working copy.
+        * </p><p>
+        * Since 2.1, a working copy can be created on a not-yet existing compilation
+        * unit. In particular, such a working copy can then be committed in order to create
+        * the corresponding compilation unit.
+        * </p>
+        * @param monitor a progress monitor used to report progress while opening this compilation unit
+        *                 or <code>null</code> if no progress should be reported 
+        * @param factory the factory that creates a buffer that is used to get the content of the working copy
+        *                 or <code>null</code> if the internal factory should be used
+        * @param problemRequestor a requestor which will get notified of problems detected during
+        *      reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+        *      that the client is not interested in problems.
+        * @exception JavaModelException if the contents of this element can
+        *   not be determined. 
+        * @return a new working copy of this element using the given factory to create
+        * the buffer, or this element if this element is already a working copy
+        * @since 2.0
+        */
+       IJavaElement getWorkingCopy(
+               IProgressMonitor monitor,
+               IBufferFactory factory,
+               IProblemRequestor problemRequestor)
+               throws JavaModelException;
+               
+       /**
+        * Returns whether this working copy's original element's content
+        * has not changed since the inception of this working copy.
+        * 
+        * @return true if this working copy's original element's content
+        * has not changed since the inception of this working copy, false otherwise
+        */
+       boolean isBasedOn(IResource resource);
+       
+       /**
+        * Returns whether this element is a working copy.
+        * 
+        * @return true if this element is a working copy, false otherwise
+        */
+       boolean isWorkingCopy();
+       
+       /**
+        * Reconciles the contents of this working copy.
+        * It performs the reconciliation by locally caching the contents of 
+        * the working copy, updating the contents, then creating a delta 
+        * over the cached contents and the new contents, and finally firing
+        * this delta.
+        * <p>
+        * If the working copy hasn't changed, then no problem will be detected,
+        * this is equivalent to <code>IWorkingCopy#reconcile(false, null)</code>.
+        * <p>
+        * Compilation problems found in the new contents are notified through the
+        * <code>IProblemRequestor</code> interface which was passed at
+        * creation, and no longer as transient markers. Therefore this API will
+        * return <code>null</code>.
+        * <p>
+        * Note: It has been assumed that added inner types should
+        * not generate change deltas.  The implementation has been
+        * modified to reflect this assumption.
+        *
+        * @exception JavaModelException if the contents of the original element
+        *              cannot be accessed. Reasons include:
+        * <ul>
+        * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * </ul>
+        * @return <code>null</code>
+        */
+       IMarker[] reconcile() throws JavaModelException;
+       
+       /**
+        * Reconciles the contents of this working copy.
+        * It performs the reconciliation by locally caching the contents of 
+        * the working copy, updating the contents, then creating a delta 
+        * over the cached contents and the new contents, and finally firing
+        * this delta.
+        * <p>
+        * The boolean argument allows to force problem detection even if the
+        * working copy is already consistent.
+        * <p>
+        * Compilation problems found in the new contents are notified through the
+        * <code>IProblemRequestor</code> interface which was passed at
+        * creation, and no longer as transient markers. Therefore this API answers
+        * nothing.
+        * <p>
+        * Note: It has been assumed that added inner types should
+        * not generate change deltas.  The implementation has been
+        * modified to reflect this assumption.
+        *
+        * @param forceProblemDetection boolean indicating whether problem should be recomputed
+        *   even if the source hasn't changed.
+        * @param monitor a progress monitor
+        * @exception JavaModelException if the contents of the original element
+        *              cannot be accessed. Reasons include:
+        * <ul>
+        * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * </ul>
+        * @since 2.0
+        */
+       void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException;
+
+       /**
+        * Restores the contents of this working copy to the current contents of
+        * this working copy's original element. Has no effect if this element
+        * is not a working copy.
+        *
+        * <p>Note: This is the inverse of committing the content of the
+        * working copy to the original element with <code>commit(boolean, IProgressMonitor)</code>.
+        *
+        * @exception JavaModelException if the contents of the original element
+        *              cannot be accessed.  Reasons include:
+        * <ul>
+        * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+        * </ul>
+        */
+       void restore() throws JavaModelException;
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaCore.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/JavaCore.java
new file mode 100644 (file)
index 0000000..6e8531b
--- /dev/null
@@ -0,0 +1,3238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE
+ *                                 COMPILER_PB_STATIC_ACCESS_RECEIVER
+ *                                 COMPILER_TASK_TAGS
+ *                                 CORE_CIRCULAR_CLASSPATH
+ *                                 CORE_INCOMPLETE_CLASSPATH
+ *     IBM Corporation - added run(IWorkspaceRunnable, IProgressMonitor)
+ *     IBM Corporation - added exclusion patterns to source classpath entries
+ *     IBM Corporation - added specific output location to source classpath entries
+ *     IBM Corporation - added the following constants:
+ *                                 CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER
+ *                                 CLEAN
+ *     IBM Corporation - added getClasspathContainerInitializer(String)
+ *     IBM Corporation - added the following constants:
+ *                                 CODEASSIST_ARGUMENT_PREFIXES
+ *                                 CODEASSIST_ARGUMENT_SUFFIXES
+ *                                 CODEASSIST_FIELD_PREFIXES
+ *                                 CODEASSIST_FIELD_SUFFIXES
+ *                                 CODEASSIST_LOCAL_PREFIXES
+ *                                 CODEASSIST_LOCAL_SUFFIXES
+ *                                 CODEASSIST_STATIC_FIELD_PREFIXES
+ *                                 CODEASSIST_STATIC_FIELD_SUFFIXES
+ *                                 COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION
+ *******************************************************************************/
+package net.sourceforge.phpdt.core;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.core.BatchOperation;
+import net.sourceforge.phpdt.internal.core.BufferManager;
+import net.sourceforge.phpdt.internal.core.JavaModel;
+import net.sourceforge.phpdt.internal.core.JavaModelManager;
+import net.sourceforge.phpdt.internal.core.Region;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Preferences;
+
+
+/**
+ * The plug-in runtime class for the Java model plug-in containing the core
+ * (UI-free) support for Java projects.
+ * <p>
+ * Like all plug-in runtime classes (subclasses of <code>Plugin</code>), this
+ * class is automatically instantiated by the platform when the plug-in gets
+ * activated. Clients must not attempt to instantiate plug-in runtime classes
+ * directly.
+ * </p>
+ * <p>
+ * The single instance of this class can be accessed from any plug-in declaring
+ * the Java model plug-in as a prerequisite via 
+ * <code>JavaCore.getJavaCore()</code>. The Java model plug-in will be activated
+ * automatically if not already active.
+ * </p>
+ */
+public final class JavaCore extends Plugin implements IExecutableExtension {
+
+       private static Plugin JAVA_CORE_PLUGIN = null; 
+       /**
+        * The plug-in identifier of the Java core support
+        * (value <code>"org.eclipse.jdt.core"</code>).
+        */
+       public static final String PLUGIN_ID = "org.eclipse.jdt.core" ; //$NON-NLS-1$
+
+       /**
+        * The identifier for the Java builder
+        * (value <code>"org.eclipse.jdt.core.javabuilder"</code>).
+        */
+       public static final String BUILDER_ID = PLUGIN_ID + ".javabuilder" ; //$NON-NLS-1$
+
+       /**
+        * The identifier for the Java model
+        * (value <code>"org.eclipse.jdt.core.javamodel"</code>).
+        */
+       public static final String MODEL_ID = PLUGIN_ID + ".javamodel" ; //$NON-NLS-1$
+
+       /**
+        * The identifier for the Java nature
+        * (value <code>"org.eclipse.jdt.core.javanature"</code>).
+        * The presence of this nature on a project indicates that it is 
+        * Java-capable.
+        *
+        * @see org.eclipse.core.resources.IProject#hasNature(java.lang.String)
+        */
+       public static final String NATURE_ID = PLUGIN_ID + ".javanature" ; //$NON-NLS-1$
+
+       /**
+        * Name of the handle id attribute in a Java marker.
+        */
+       protected static final String ATT_HANDLE_ID =
+               "org.eclipse.jdt.internal.core.JavaModelManager.handleId" ; //$NON-NLS-1$
+
+       // *************** Possible IDs for configurable options. ********************
+
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions()
+        */
+       public static final String COMPILER_LOCAL_VARIABLE_ATTR = PLUGIN_ID + ".compiler.debug.localVariable"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions()
+        */
+       public static final String COMPILER_LINE_NUMBER_ATTR = PLUGIN_ID + ".compiler.debug.lineNumber"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_SOURCE_FILE_ATTR = PLUGIN_ID + ".compiler.debug.sourceFile"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_CODEGEN_UNUSED_LOCAL = PLUGIN_ID + ".compiler.codegen.unusedLocal"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_CODEGEN_TARGET_PLATFORM = PLUGIN_ID + ".compiler.codegen.targetPlatform"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_UNREACHABLE_CODE = PLUGIN_ID + ".compiler.problem.unreachableCode"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_INVALID_IMPORT = PLUGIN_ID + ".compiler.problem.invalidImport"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD = PLUGIN_ID + ".compiler.problem.overridingPackageDefaultMethod"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME = PLUGIN_ID + ".compiler.problem.methodWithConstructorName"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_DEPRECATION = PLUGIN_ID + ".compiler.problem.deprecation"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE = PLUGIN_ID + ".compiler.problem.deprecationInDeprecatedCode"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_HIDDEN_CATCH_BLOCK = PLUGIN_ID + ".compiler.problem.hiddenCatchBlock"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_UNUSED_LOCAL = PLUGIN_ID + ".compiler.problem.unusedLocal"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_UNUSED_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedParameter"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT = PLUGIN_ID + ".compiler.problem.unusedParameterWhenImplementingAbstract"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE = PLUGIN_ID + ".compiler.problem.unusedParameterWhenOverridingConcrete"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPILER_PB_UNUSED_IMPORT = PLUGIN_ID + ".compiler.problem.unusedImport"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPILER_PB_SYNTHETIC_ACCESS_EMULATION = PLUGIN_ID + ".compiler.problem.syntheticAccessEmulation"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPILER_PB_NON_NLS_STRING_LITERAL = PLUGIN_ID + ".compiler.problem.nonExternalizedStringLiteral"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPILER_PB_ASSERT_IDENTIFIER = PLUGIN_ID + ".compiler.problem.assertIdentifier"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_STATIC_ACCESS_RECEIVER = PLUGIN_ID + ".compiler.problem.staticAccessReceiver"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_NO_EFFECT_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.noEffectAssignment"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD = PLUGIN_ID + ".compiler.problem.incompatibleNonInheritedInterfaceMethod"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_UNUSED_PRIVATE_MEMBER = PLUGIN_ID + ".compiler.problem.unusedPrivateMember"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION = PLUGIN_ID + ".compiler.problem.noImplicitStringConversion"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPILER_PB_MAX_PER_UNIT = PLUGIN_ID + ".compiler.maxProblemPerUnit"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPILER_SOURCE = PLUGIN_ID + ".compiler.source"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPILER_COMPLIANCE = PLUGIN_ID + ".compiler.compliance"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_TASK_PRIORITIES = PLUGIN_ID + ".compiler.taskPriorities"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value for COMPILER_TASK_PRIORITIES.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_TASK_PRIORITY_HIGH = "HIGH"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value for COMPILER_TASK_PRIORITIES.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_TASK_PRIORITY_LOW = "LOW"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value for COMPILER_TASK_PRIORITIES.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_TASK_PRIORITY_NORMAL = "NORMAL"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String COMPILER_TASK_TAGS = PLUGIN_ID + ".compiler.taskTags"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        */
+       public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String CORE_JAVA_BUILD_RESOURCE_COPY_FILTER = PLUGIN_ID + ".builder.resourceCopyExclusionFilter"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CORE_JAVA_BUILD_DUPLICATE_RESOURCE = PLUGIN_ID + ".builder.duplicateResourceTask"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER = PLUGIN_ID + ".builder.cleanOutputFolder"; //$NON-NLS-1$                
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CORE_INCOMPLETE_CLASSPATH = PLUGIN_ID + ".incompleteClasspath"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CORE_CIRCULAR_CLASSPATH = PLUGIN_ID + ".circularClasspath"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String CORE_JAVA_BUILD_INVALID_CLASSPATH = PLUGIN_ID + ".builder.invalidClasspath"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1 
+        */
+       public static final String CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS = PLUGIN_ID + ".classpath.exclusionPatterns"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$
+       /**
+        * Default task tag
+        * @since 2.1
+        */
+       public static final String DEFAULT_TASK_TAG = "TODO"; //$NON-NLS-1$
+       /**
+        * Default task priority
+        * @since 2.1
+        */
+       public static final String DEFAULT_TASK_PRIORITY = "NORMAL"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_NEWLINE_OPENING_BRACE = PLUGIN_ID + ".formatter.newline.openingBrace"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_NEWLINE_CONTROL = PLUGIN_ID + ".formatter.newline.controlStatement"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_NEWLINE_ELSE_IF = PLUGIN_ID + ".formatter.newline.elseIf"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_NEWLINE_EMPTY_BLOCK = PLUGIN_ID + ".formatter.newline.emptyBlock"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_CLEAR_BLANK_LINES = PLUGIN_ID + ".formatter.newline.clearAll"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_LINE_SPLIT = PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_COMPACT_ASSIGNMENT = PLUGIN_ID + ".formatter.style.assignment"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_TAB_CHAR = PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String FORMATTER_TAB_SIZE = PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
+       /**
+        * Possible configurable option ID
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String FORMATTER_SPACE_CASTEXPRESSION = PLUGIN_ID + ".formatter.space.castexpression"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String CODEASSIST_VISIBILITY_CHECK = PLUGIN_ID + ".codeComplete.visibilityCheck"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String CODEASSIST_IMPLICIT_QUALIFICATION = PLUGIN_ID + ".codeComplete.forceImplicitQualification"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.fieldPrefixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_STATIC_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.staticFieldPrefixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_LOCAL_PREFIXES = PLUGIN_ID + ".codeComplete.localPrefixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_ARGUMENT_PREFIXES = PLUGIN_ID + ".codeComplete.argumentPrefixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.fieldSuffixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_STATIC_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.staticFieldSuffixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_LOCAL_SUFFIXES = PLUGIN_ID + ".codeComplete.localSuffixes"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option ID.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CODEASSIST_ARGUMENT_SUFFIXES = PLUGIN_ID + ".codeComplete.argumentSuffixes"; //$NON-NLS-1$
+
+       // *************** Possible values for configurable options. ********************
+       
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String GENERATE = "generate"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String DO_NOT_GENERATE = "do not generate"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String PRESERVE = "preserve"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String OPTIMIZE_OUT = "optimize out"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String VERSION_1_1 = "1.1"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String VERSION_1_2 = "1.2"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String VERSION_1_3 = "1.3"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String ABORT = "abort"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String ERROR = "error"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String WARNING = "warning"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String IGNORE = "ignore"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        */
+       public static final String COMPUTE = "compute"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String INSERT = "insert"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String PRESERVE_ONE = "preserve one"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String CLEAR_ALL = "clear all"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String NORMAL = "normal"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String COMPACT = "compact"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String TAB = "tab"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String SPACE = "space"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String ENABLED = "enabled"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.0
+        */
+       public static final String DISABLED = "disabled"; //$NON-NLS-1$
+       /**
+        * Possible  configurable option value.
+        * @see #getDefaultOptions
+        * @since 2.1
+        */
+       public static final String CLEAN = "clean"; //$NON-NLS-1$
+       
+       /**
+        * Creates the Java core plug-in.
+        * @since 2.1
+        */
+       public JavaCore(IPluginDescriptor pluginDescriptor) {
+               super(pluginDescriptor);
+               JAVA_CORE_PLUGIN = this;
+       }
+
+       /**
+        * Adds the given listener for changes to Java elements.
+        * Has no effect if an identical listener is already registered.
+        *
+        * This listener will only be notified during the POST_CHANGE resource change notification
+        * and any reconcile operation (POST_RECONCILE).
+        * For finer control of the notification, use <code>addElementChangedListener(IElementChangedListener,int)</code>,
+        * which allows to specify a different eventMask.
+        * 
+        * @see ElementChangedEvent
+        * @param listener the listener
+        */
+       public static void addElementChangedListener(IElementChangedListener listener) {
+               addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE | ElementChangedEvent.POST_RECONCILE);
+       }
+
+       /**
+        * Adds the given listener for changes to Java elements.
+        * Has no effect if an identical listener is already registered.
+        * After completion of this method, the given listener will be registered for exactly
+        * the specified events.  If they were previously registered for other events, they
+        * will be deregistered.  
+        * <p>
+        * Once registered, a listener starts receiving notification of changes to
+        * java elements in the model. The listener continues to receive 
+        * notifications until it is replaced or removed. 
+        * </p>
+        * <p>
+        * Listeners can listen for several types of event as defined in <code>ElementChangeEvent</code>.
+        * Clients are free to register for any number of event types however if they register
+        * for more than one, it is their responsibility to ensure they correctly handle the
+        * case where the same java element change shows up in multiple notifications.  
+        * Clients are guaranteed to receive only the events for which they are registered.
+        * </p>
+        * 
+        * @param listener the listener
+        * @param eventMask the bit-wise OR of all event types of interest to the listener
+        * @see IElementChangedListener
+        * @see ElementChangedEvent
+        * @see #removeElementChangedListener(IElementChangedListener)
+        * @since 2.0
+        */
+       public static void addElementChangedListener(IElementChangedListener listener, int eventMask) {
+               JavaModelManager.getJavaModelManager().addElementChangedListener(listener, eventMask);
+       }
+
+       /**
+        * Configures the given marker attribute map for the given Java element.
+        * Used for markers, which denote a Java element rather than a resource.
+        *
+        * @param attributes the mutable marker attribute map (key type: <code>String</code>,
+        *   value type: <code>String</code>)
+        * @param element the Java element for which the marker needs to be configured
+        */
+       public static void addJavaElementMarkerAttributes(
+               Map attributes,
+               IJavaElement element) {
+//             if (element instanceof IMember)
+//                     element = ((IMember) element).getClassFile();
+               if (attributes != null && element != null)
+                       attributes.put(ATT_HANDLE_ID, element.getHandleIdentifier());
+       }
+       
+       /**
+        * Configures the given marker for the given Java element.
+        * Used for markers, which denote a Java element rather than a resource.
+        *
+        * @param marker the marker to be configured
+        * @param element the Java element for which the marker needs to be configured
+        * @exception CoreException if the <code>IMarker.setAttribute</code> on the marker fails
+        */
+       public void configureJavaElementMarker(IMarker marker, IJavaElement element)
+               throws CoreException {
+//             if (element instanceof IMember)
+//                     element = ((IMember) element).getClassFile();
+               if (marker != null && element != null)
+                       marker.setAttribute(ATT_HANDLE_ID, element.getHandleIdentifier());
+       }
+       
+       /**
+        * Returns the Java model element corresponding to the given handle identifier
+        * generated by <code>IJavaElement.getHandleIdentifier()</code>, or
+        * <code>null</code> if unable to create the associated element.
+        */
+       public static IJavaElement create(String handleIdentifier) {
+               if (handleIdentifier == null) {
+                       return null;
+               }
+               try {
+                       return JavaModelManager.getJavaModelManager().getHandleFromMemento(handleIdentifier);
+               } catch (JavaModelException e) {
+                       return null;
+               }
+       }
+       /**
+        * Returns the Java element corresponding to the given file, or
+        * <code>null</code> if unable to associate the given file
+        * with a Java element.
+        *
+        * <p>The file must be one of:<ul>
+        *      <li>a <code>.java</code> file - the element returned is the corresponding <code>ICompilationUnit</code></li>
+        *      <li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+        *      <li>a <code>.jar</code> file - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+        *      </ul>
+        * <p>
+        * Creating a Java element has the side effect of creating and opening all of the
+        * element's parents if they are not yet open.
+        * 
+        * @param the given file
+        * @return the Java element corresponding to the given file, or
+        * <code>null</code> if unable to associate the given file
+        * with a Java element
+        */
+       public static IJavaElement create(IFile file) {
+               return JavaModelManager.create(file, null);
+       }
+       /**
+        * Returns the package fragment or package fragment root corresponding to the given folder, or
+        * <code>null</code> if unable to associate the given folder with a Java element.
+        * <p>
+        * Note that a package fragment root is returned rather than a default package.
+        * <p>
+        * Creating a Java element has the side effect of creating and opening all of the
+        * element's parents if they are not yet open.
+        * 
+        * @param the given folder
+        * @return the package fragment or package fragment root corresponding to the given folder, or
+        * <code>null</code> if unable to associate the given folder with a Java element
+        */
+       public static IJavaElement create(IFolder folder) {
+               return JavaModelManager.create(folder, null);
+       }
+       /**
+        * Returns the Java project corresponding to the given project.
+        * <p>
+        * Creating a Java Project has the side effect of creating and opening all of the
+        * project's parents if they are not yet open.
+        * <p>
+        * Note that no check is done at this time on the existence or the java nature of this project.
+        * 
+        * @param project the given project
+        * @return the Java project corresponding to the given project, null if the given project is null
+        */
+       public static IJavaProject create(IProject project) {
+               if (project == null) {
+                       return null;
+               }
+               JavaModel javaModel = JavaModelManager.getJavaModelManager().getJavaModel();
+               return javaModel.getJavaProject(project);
+       }
+       /**
+        * Returns the Java element corresponding to the given resource, or
+        * <code>null</code> if unable to associate the given resource
+        * with a Java element.
+        * <p>
+        * The resource must be one of:<ul>
+        *      <li>a project - the element returned is the corresponding <code>IJavaProject</code></li>
+        *      <li>a <code>.java</code> file - the element returned is the corresponding <code>ICompilationUnit</code></li>
+        *      <li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+        *      <li>a <code>.jar</code> file - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+        *  <li>a folder - the element returned is the corresponding <code>IPackageFragmentRoot</code>
+        *      or <code>IPackageFragment</code></li>
+        *  <li>the workspace root resource - the element returned is the <code>IJavaModel</code></li>
+        *      </ul>
+        * <p>
+        * Creating a Java element has the side effect of creating and opening all of the
+        * element's parents if they are not yet open.
+        * 
+        * @param resource the given resource
+        * @return the Java element corresponding to the given resource, or
+        * <code>null</code> if unable to associate the given resource
+        * with a Java element
+        */
+       public static IJavaElement create(IResource resource) {
+               return JavaModelManager.create(resource, null);
+       }
+       /**
+        * Returns the Java model.
+        * 
+        * @param root the given root
+        * @return the Java model, or <code>null</code> if the root is null
+        */
+       public static IJavaModel create(IWorkspaceRoot root) {
+               if (root == null) {
+                       return null;
+               }
+               return JavaModelManager.getJavaModelManager().getJavaModel();
+       }
+       /**
+        * Creates and returns a class file element for
+        * the given <code>.class</code> file. Returns <code>null</code> if unable
+        * to recognize the class file.
+        * 
+        * @param file the given <code>.class</code> file
+        * @return a class file element for the given <code>.class</code> file, or <code>null</code> if unable
+        * to recognize the class file
+        */
+//     public static IClassFile createClassFileFrom(IFile file) {
+//             return JavaModelManager.createClassFileFrom(file, null);
+//     }
+       /**
+        * Creates and returns a compilation unit element for
+        * the given <code>.java</code> file. Returns <code>null</code> if unable
+        * to recognize the compilation unit.
+        * 
+        * @param file the given <code>.java</code> file
+        * @return a compilation unit element for the given <code>.java</code> file, or <code>null</code> if unable
+        * to recognize the compilation unit
+        */
+       public static ICompilationUnit createCompilationUnitFrom(IFile file) {
+               return JavaModelManager.createCompilationUnitFrom(file, null);
+       }
+       /**
+        * Creates and returns a handle for the given JAR file.
+        * The Java model associated with the JAR's project may be
+        * created as a side effect. 
+        * 
+        * @param file the given JAR file
+        * @return a handle for the given JAR file, or <code>null</code> if unable to create a JAR package fragment root.
+        * (for example, if the JAR file represents a non-Java resource)
+        */
+//     public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile file) {
+//             return JavaModelManager.createJarPackageFragmentRootFrom(file, null);
+//     }
+
+       /** 
+        * Answers the project specific value for a given classpath container.
+        * In case this container path could not be resolved, then will answer <code>null</code>.
+        * Both the container path and the project context are supposed to be non-null.
+        * <p>
+        * The containerPath is a formed by a first ID segment followed with extra segments, which can be 
+        * used as additional hints for resolution. If no container was ever recorded for this container path 
+        * onto this project (using <code>setClasspathContainer</code>, then a 
+        * <code>ClasspathContainerInitializer</code> will be activated if any was registered for this container 
+        * ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+        * <p>
+        * There is no assumption that the returned container must answer the exact same containerPath
+        * when requested <code>IClasspathContainer#getPath</code>. 
+        * Indeed, the containerPath is just an indication for resolving it to an actual container object.
+        * <p>
+        * Classpath container values are persisted locally to the workspace, but 
+        * are not preserved from a session to another. It is thus highly recommended to register a 
+        * <code>ClasspathContainerInitializer</code> for each referenced container 
+        * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer").
+        * <p>
+        * @param containerPath the name of the container, which needs to be resolved
+        * @param project a specific project in which the container is being resolved
+        * @return the corresponding classpath container or <code>null</code> if unable to find one.
+        * 
+        * @exception JavaModelException if an exception occurred while resolving the container, or if the resolved container
+        *   contains illegal entries (contains CPE_CONTAINER entries or null entries).  
+        * 
+        * @see ClasspathContainerInitializer
+        * @see IClasspathContainer
+        * @see #setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
+        * @since 2.0
+        */
+//     public static IClasspathContainer getClasspathContainer(final IPath containerPath, final IJavaProject project) throws JavaModelException {
+//
+//             IClasspathContainer container = JavaModelManager.containerGet(project, containerPath);
+//             if (container == JavaModelManager.ContainerInitializationInProgress) return null; // break cycle
+//
+//             if (container == null){
+//                     final ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(containerPath.segment(0));
+//                     if (initializer != null){
+//                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                     System.out.println("CPContainer INIT - triggering initialization of: ["+project.getElementName()+"] " + containerPath + " using initializer: "+ initializer); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
+//                                     new Exception("FAKE exception for dumping current CPContainer (["+project.getElementName()+"] "+ containerPath+ ")INIT invocation stack trace").printStackTrace(); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+//                             }
+//                             JavaModelManager.containerPut(project, containerPath, JavaModelManager.ContainerInitializationInProgress); // avoid initialization cycles
+//                             boolean ok = false;
+//                             try {
+//                                     // wrap initializer call with Safe runnable in case initializer would be causing some grief
+//                                     Platform.run(new ISafeRunnable() {
+//                                             public void handleException(Throwable exception) {
+//                                                     Util.log(exception, "Exception occurred in classpath container initializer: "+initializer); //$NON-NLS-1$
+//                                             }
+//                                             public void run() throws Exception {
+//                                                     initializer.initialize(containerPath, project);
+//                                             }
+//                                     });
+//                                     
+//                                     // retrieve value (if initialization was successful)
+//                                     container = JavaModelManager.containerGet(project, containerPath);
+//                                     if (container == JavaModelManager.ContainerInitializationInProgress) return null; // break cycle
+//                                     ok = true;
+//                             } finally {
+//                                     if (!ok) JavaModelManager.containerPut(project, containerPath, null); // flush cache
+//                             }
+//                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                     System.out.print("CPContainer INIT - after resolution: ["+project.getElementName()+"] " + containerPath + " --> "); //$NON-NLS-2$//$NON-NLS-1$//$NON-NLS-3$
+//                                     if (container != null){
+//                                             System.out.print("container: "+container.getDescription()+" {"); //$NON-NLS-2$//$NON-NLS-1$
+//                                             IClasspathEntry[] entries = container.getClasspathEntries();
+//                                             if (entries != null){
+//                                                     for (int i = 0; i < entries.length; i++){
+//                                                             if (i > 0) System.out.println(", ");//$NON-NLS-1$
+//                                                             System.out.println(entries[i]);
+//                                                     }
+//                                             }
+//                                             System.out.println("}");//$NON-NLS-1$
+//                                     } else {
+//                                             System.out.println("{unbound}");//$NON-NLS-1$
+//                                     }
+//                             }
+//                     } else {
+//                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                     System.out.println("CPContainer INIT - no initializer found for: "+project.getElementName()+"] " + containerPath); //$NON-NLS-1$ //$NON-NLS-2$
+//                             }
+//                     }
+//             }
+//             return container;                       
+//     }
+
+       /**
+        * Helper method finding the classpath container initializer registered for a given classpath container ID 
+        * or <code>null</code> if none was found while iterating over the contributions to extension point to
+        * the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+        * <p>
+        * A containerID is the first segment of any container path, used to identify the registered container initializer.
+        * <p>
+        * @param String - a containerID identifying a registered initializer
+        * @return ClasspathContainerInitializer - the registered classpath container initializer or <code>null</code> if 
+        * none was found.
+        * @since 2.1
+        */
+//     public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID){
+//             
+//             Plugin jdtCorePlugin = JavaCore.getPlugin();
+//             if (jdtCorePlugin == null) return null;
+//
+//             IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID);
+//             if (extension != null) {
+//                     IExtension[] extensions =  extension.getExtensions();
+//                     for(int i = 0; i < extensions.length; i++){
+//                             IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+//                             for(int j = 0; j < configElements.length; j++){
+//                                     String initializerID = configElements[j].getAttribute("id"); //$NON-NLS-1$
+//                                     if (initializerID != null && initializerID.equals(containerID)){
+//                                             if (JavaModelManager.CP_RESOLVE_VERBOSE) {
+//                                                     System.out.println("CPContainer INIT - found initializer: "+containerID +" --> " + configElements[j].getAttribute("class"));//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+//                                             }                                               
+//                                             try {
+//                                                     Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
+//                                                     if (execExt instanceof ClasspathContainerInitializer){
+//                                                             return (ClasspathContainerInitializer)execExt;
+//                                                     }
+//                                             } catch(CoreException e) {
+//                                             }
+//                                     }
+//                             }
+//                     }       
+//             }
+//             return null;
+//     }
+
+       /**
+        * Returns the path held in the given classpath variable.
+        * Returns <node>null</code> if unable to bind.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        * Note that classpath variables can be contributed registered initializers for,
+        * using the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+        * If an initializer is registered for a variable, its persisted value will be ignored:
+        * its initializer will thus get the opportunity to rebind the variable differently on
+        * each session.
+        *
+        * @param variableName the name of the classpath variable
+        * @return the path, or <code>null</code> if none 
+        * @see #setClasspathVariable
+        */
+//     public static IPath getClasspathVariable(final String variableName) {
+//     
+//             IPath variablePath = JavaModelManager.variableGet(variableName);
+//             if (variablePath == JavaModelManager.VariableInitializationInProgress) return null; // break cycle
+//             
+//             if (variablePath != null) {
+//                     return variablePath;
+//             }
+//
+//             // even if persisted value exists, initializer is given priority, only if no initializer is found the persisted value is reused
+//             final ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(variableName);
+//             if (initializer != null){
+//                     if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                             System.out.println("CPVariable INIT - triggering initialization of: " + variableName+ " using initializer: "+ initializer); //$NON-NLS-1$ //$NON-NLS-2$
+//                             new Exception("FAKE exception for dumping current CPVariable ("+variableName+ ")INIT invocation stack trace").printStackTrace(); //$NON-NLS-1$//$NON-NLS-2$
+//                     }
+//                     JavaModelManager.variablePut(variableName, JavaModelManager.VariableInitializationInProgress); // avoid initialization cycles
+//                     boolean ok = false;
+//                     try {
+//                             // wrap initializer call with Safe runnable in case initializer would be causing some grief
+//                             Platform.run(new ISafeRunnable() {
+//                                     public void handleException(Throwable exception) {
+//                                             Util.log(exception, "Exception occurred in classpath variable initializer: "+initializer+" while initializing variable: "+variableName); //$NON-NLS-1$ //$NON-NLS-2$
+//                                     }
+//                                     public void run() throws Exception {
+//                                             initializer.initialize(variableName);
+//                                     }
+//                             });
+//                             variablePath = (IPath) JavaModelManager.variableGet(variableName); // initializer should have performed side-effect
+//                             if (variablePath == JavaModelManager.VariableInitializationInProgress) return null; // break cycle (initializer did not init or reentering call)
+//                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                     System.out.println("CPVariable INIT - after initialization: " + variableName + " --> " + variablePath); //$NON-NLS-2$//$NON-NLS-1$
+//                             }
+//                             ok = true;
+//                     } finally {
+//                             if (!ok) JavaModelManager.variablePut(variableName, null); // flush cache
+//                     }
+//             } else {
+//                     if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                             System.out.println("CPVariable INIT - no initializer found for: " + variableName); //$NON-NLS-1$
+//                     }
+//             }
+//             return variablePath;
+//     }
+
+       /**
+        * Helper method finding the classpath variable initializer registered for a given classpath variable name 
+        * or <code>null</code> if none was found while iterating over the contributions to extension point to
+        * the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+        * <p>
+        * @param the given variable
+        * @return ClasspathVariableInitializer - the registered classpath variable initializer or <code>null</code> if 
+        * none was found.
+        * @since 2.1
+        */
+//     public static ClasspathVariableInitializer getClasspathVariableInitializer(String variable){
+//             
+//             Plugin jdtCorePlugin = JavaCore.getPlugin();
+//             if (jdtCorePlugin == null) return null;
+//
+//             IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
+//             if (extension != null) {
+//                     IExtension[] extensions =  extension.getExtensions();
+//                     for(int i = 0; i < extensions.length; i++){
+//                             IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+//                             for(int j = 0; j < configElements.length; j++){
+//                                     try {
+//                                             String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$
+//                                             if (variable.equals(varAttribute)) {
+//                                                     if (JavaModelManager.CP_RESOLVE_VERBOSE) {
+//                                                             System.out.println("CPVariable INIT - found initializer: "+variable+" --> " + configElements[j].getAttribute("class"));//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+//                                                     }                                               
+//                                                     Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
+//                                                     if (execExt instanceof ClasspathVariableInitializer){
+//                                                             return (ClasspathVariableInitializer)execExt;
+//                                                     }
+//                                             }
+//                                     } catch(CoreException e){
+//                                     }
+//                                     }
+//                     }       
+//             }
+//             return null;
+//     }       
+       
+       /**
+        * Returns the names of all known classpath variables.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        *
+        * @return the list of classpath variable names
+        * @see #setClasspathVariable
+        */
+//     public static String[] getClasspathVariableNames() {
+//             return JavaModelManager.variableNames();
+//     }
+
+       /**
+        * Returns a table of all known configurable options with their default values.
+        * These options allow to configure the behaviour of the underlying components.
+        * The client may safely use the result as a template that they can modify and
+        * then pass to <code>setOptions</code>.
+        * 
+        * Helper constants have been defined on JavaCore for each of the option ID and 
+        * their possible constant values.
+        * 
+        * Note: more options might be added in further releases.
+        * <pre>
+        * RECOGNIZED OPTIONS:
+        * COMPILER / Generating Local Variable Debug Attribute
+        *    When generated, this attribute will enable local variable names 
+        *    to be displayed in debugger, only in place where variables are 
+        *    definitely assigned (.class file is then bigger)
+        *     - option id:         "org.eclipse.jdt.core.compiler.debug.localVariable"
+        *     - possible values:   { "generate", "do not generate" }
+        *     - default:           "generate"
+        *
+        * COMPILER / Generating Line Number Debug Attribute 
+        *    When generated, this attribute will enable source code highlighting in debugger 
+        *    (.class file is then bigger).
+        *     - option id:         "org.eclipse.jdt.core.compiler.debug.lineNumber"
+        *     - possible values:   { "generate", "do not generate" }
+        *     - default:           "generate"
+        *    
+        * COMPILER / Generating Source Debug Attribute 
+        *    When generated, this attribute will enable the debugger to present the 
+        *    corresponding source code.
+        *     - option id:         "org.eclipse.jdt.core.compiler.debug.sourceFile"
+        *     - possible values:   { "generate", "do not generate" }
+        *     - default:           "generate"
+        *    
+        * COMPILER / Preserving Unused Local Variables
+        *    Unless requested to preserve unused local variables (that is, never read), the 
+        *    compiler will optimize them out, potentially altering debugging
+        *     - option id:         "org.eclipse.jdt.core.compiler.codegen.unusedLocal"
+        *     - possible values:   { "preserve", "optimize out" }
+        *     - default:           "preserve"
+        * 
+        * COMPILER / Defining Target Java Platform
+        *    For binary compatibility reason, .class files can be tagged to with certain VM versions and later.
+        *    Note that "1.4" target require to toggle compliance mode to "1.4" too.
+        *     - option id:         "org.eclipse.jdt.core.compiler.codegen.targetPlatform"
+        *     - possible values:   { "1.1", "1.2", "1.3", "1.4" }
+        *     - default:           "1.1"
+        *
+        * COMPILER / Reporting Unreachable Code
+        *    Unreachable code can optionally be reported as an error, warning or simply 
+        *    ignored. The bytecode generation will always optimized it out.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unreachableCode"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "error"
+        *
+        * COMPILER / Reporting Invalid Import
+        *    An import statement that cannot be resolved might optionally be reported 
+        *    as an error, as a warning or ignored.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidImport"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "error"
+        *
+        * COMPILER / Reporting Attempt to Override Package-Default Method
+        *    A package default method is not visible in a different package, and thus 
+        *    cannot be overridden. When enabling this option, the compiler will signal 
+        *    such scenarii either as an error or a warning.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        *
+        * COMPILER / Reporting Method With Constructor Name
+        *    Naming a method with a constructor name is generally considered poor 
+        *    style programming. When enabling this option, the compiler will signal such 
+        *    scenarii either as an error or a warning.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.methodWithConstructorName"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        *
+        * COMPILER / Reporting Deprecation
+        *    When enabled, the compiler will signal use of deprecated API either as an 
+        *    error or a warning.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.deprecation"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        *
+        * COMPILER / Reporting Deprecation Inside Deprecated Code
+        *    When enabled, the compiler will signal use of deprecated API inside deprecated code.
+        *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.deprecation".
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "disabled"
+        *
+        * COMPILER / Reporting Hidden Catch Block
+        *    Locally to a try statement, some catch blocks may hide others . For example,
+        *      try {  throw new java.io.CharConversionException();
+        *      } catch (java.io.CharConversionException e) {
+        *      } catch (java.io.IOException e) {}. 
+        *    When enabling this option, the compiler will issue an error or a warning for hidden 
+        *    catch blocks corresponding to checked exceptions
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        *
+        * COMPILER / Reporting Unused Local
+        *    When enabled, the compiler will issue an error or a warning for unused local 
+        *    variables (that is, variables never read from)
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedLocal"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "ignore"
+        *
+        * COMPILER / Reporting Unused Parameter
+        *    When enabled, the compiler will issue an error or a warning for unused method 
+        *    parameters (that is, parameters never read from)
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameter"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "ignore"
+        *
+        * COMPILER / Reporting Unused Parameter if Implementing Abstract Method
+        *    When enabled, the compiler will signal unused parameters in abstract method implementations.
+        *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "disabled"
+        *
+        * COMPILER / Reporting Unused Parameter if Overriding Concrete Method
+        *    When enabled, the compiler will signal unused parameters in methods overriding concrete ones.
+        *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "disabled"
+        *
+        * COMPILER / Reporting Unused Import
+        *    When enabled, the compiler will issue an error or a warning for unused import 
+        *    reference 
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedImport"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        *
+        * COMPILER / Reporting Unused Private Members
+        *    When enabled, the compiler will issue an error or a warning whenever a private 
+        *    method or field is declared but never used within the same unit.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedPrivateMember"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "ignore"
+        *
+        * COMPILER / Reporting Synthetic Access Emulation
+        *    When enabled, the compiler will issue an error or a warning whenever it emulates 
+        *    access to a non-accessible member of an enclosing type. Such access can have
+        *    performance implications.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "ignore"
+        *
+        * COMPILER / Reporting Non-Externalized String Literal
+        *    When enabled, the compiler will issue an error or a warning for non externalized 
+        *    String literal (that is, not tagged with //$NON-NLS-<n>$). 
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "ignore"
+        * 
+        * COMPILER / Reporting Usage of 'assert' Identifier
+        *    When enabled, the compiler will issue an error or a warning whenever 'assert' is 
+        *    used as an identifier (reserved keyword in 1.4)
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.assertIdentifier"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "ignore"
+        * 
+        * COMPILER / Reporting Non-Static Reference to a Static Member
+        *    When enabled, the compiler will issue an error or a warning whenever a static field
+        *    or method is accessed with an expression receiver. A reference to a static member should
+        *    be qualified with a type name.
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.staticAccessReceiver"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        * 
+        * COMPILER / Reporting Assignment with no Effect
+        *    When enabled, the compiler will issue an error or a warning whenever an assignment
+        *    has no effect (e.g 'x = x').
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.noEffectAssignment"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        * 
+        * COMPILER / Reporting Interface Method not Compatible with non-Inherited Methods
+        *    When enabled, the compiler will issue an error or a warning whenever an interface
+        *    defines a method incompatible with a non-inherited Object method. Until this conflict
+        *    is resolved, such an interface cannot be implemented, For example, 
+        *      interface I { 
+        *         int clone();
+        *      } 
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        * 
+        * COMPILER / Reporting Usage of char[] Expressions in String Concatenations
+        *    When enabled, the compiler will issue an error or a warning whenever a char[] expression
+        *    is used in String concatenations (for example, "hello" + new char[]{'w','o','r','l','d'}).
+        *     - option id:         "org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion"
+        *     - possible values:   { "error", "warning", "ignore" }
+        *     - default:           "warning"
+        *
+        * COMPILER / Setting Source Compatibility Mode
+        *    Specify whether source is 1.3 or 1.4 compatible. From 1.4 on, 'assert' is a keyword
+        *    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
+        *   level should be set to "1.4" and the compliance mode should be "1.4".
+        *     - option id:         "org.eclipse.jdt.core.compiler.source"
+        *     - possible values:   { "1.3", "1.4" }
+        *     - default:           "1.3"
+        * 
+        * COMPILER / Setting Compliance Level
+        *    Select the compliance level for the compiler. In "1.3" mode, source and target settings
+        *    should not go beyond "1.3" level.
+        *     - option id:         "org.eclipse.jdt.core.compiler.compliance"
+        *     - possible values:   { "1.3", "1.4" }
+        *     - default:           "1.3"
+        * 
+        * COMPILER / Maximum number of problems reported per compilation unit
+        *    Specify the maximum number of problems reported on each compilation unit.
+        *     - option id:         "org.eclipse.jdt.core.compiler.maxProblemPerUnit"
+        *     - possible values:       "<n>" where <n> is zero or a positive integer (if zero then all problems are reported).
+        *     - default:           "100"
+        * 
+        * COMPILER / Define the Automatic Task Tags
+        *    When the tag list is not empty, the compiler will issue a task marker whenever it encounters
+        *    one of the corresponding tag inside any comment in Java source code.
+        *    Generated task messages will include the tag, and range until the next line separator or comment ending.
+        *    Note that tasks messages are trimmed.
+        *     - option id:         "org.eclipse.jdt.core.compiler.taskTags"
+        *     - possible values:   { "<tag>[,<tag>]*" } where <tag> is a String without any wild-card or leading/trailing spaces 
+        *     - default:           ""
+        * 
+        * COMPILER / Define the Automatic Task Priorities
+        *    In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
+        *    of the task markers issued by the compiler.
+        *    If the default is specified, the priority of each task marker is "NORMAL".
+        *     - option id:         "org.eclipse.jdt.core.compiler.taskPriorities"
+        *     - possible values:   { "<priority>[,<priority>]*" } where <priority> is one of "HIGH", "NORMAL" or "LOW"
+        *     - default:           ""
+        *
+        * BUILDER / Specifying Filters for Resource Copying Control
+        *    Allow to specify some filters to control the resource copy process.
+        *     - option id:         "org.eclipse.jdt.core.builder.resourceCopyExclusionFilter"
+        *     - possible values:   { "<name>[,<name>]* } where <name> is a file name pattern (* and ? wild-cards allowed)
+        *       or the name of a folder which ends with '/'
+        *     - default:           ""
+        * 
+        * BUILDER / Abort if Invalid Classpath
+        *    Allow to toggle the builder to abort if the classpath is invalid
+        *     - option id:         "org.eclipse.jdt.core.builder.invalidClasspath"
+        *     - possible values:   { "abort", "ignore" }
+        *     - default:           "abort"
+        * 
+        * BUILDER / Cleaning Output Folder(s)
+        *    Indicate whether the JavaBuilder is allowed to clean the output folders
+        *    when performing full build operations.
+        *     - option id:         "org.eclipse.jdt.core.builder.cleanOutputFolder"
+        *     - possible values:   { "clean", "ignore" }
+        *     - default:           "clean"
+        * 
+        * BUILDER / Reporting Duplicate Resources
+        *    Indicate the severity of the problem reported when more than one occurrence
+        *    of a resource is to be copied into the output location.
+        *     - option id:         "org.eclipse.jdt.core.builder.duplicateResourceTask"
+        *     - possible values:   { "error", "warning" }
+        *     - default:           "warning"
+        * 
+        * JAVACORE / Computing Project Build Order
+        *    Indicate whether JavaCore should enforce the project build order to be based on
+        *    the classpath prerequisite chain. When requesting to compute, this takes over
+        *    the platform default order (based on project references).
+        *     - option id:         "org.eclipse.jdt.core.computeJavaBuildOrder"
+        *     - possible values:   { "compute", "ignore" }
+        *     - default:           "ignore"     
+        * 
+        * JAVACORE / Specify Default Source Encoding Format
+        *    Get the encoding format for compiled sources. This setting is read-only, it is equivalent
+        *    to 'ResourcesPlugin.getEncoding()'.
+        *     - option id:         "org.eclipse.jdt.core.encoding"
+        *     - possible values:   { any of the supported encoding name}.
+        *     - default:           <platform default>
+        * 
+        * JAVACORE / Reporting Incomplete Classpath
+        *    Indicate the severity of the problem reported when an entry on the classpath does not exist, 
+        *    is not legite or is not visible (for example, a referenced project is closed).
+        *     - option id:         "org.eclipse.jdt.core.incompleteClasspath"
+        *     - possible values:   { "error", "warning"}
+        *     - default:           "error"
+        * 
+        * JAVACORE / Reporting Classpath Cycle
+        *    Indicate the severity of the problem reported when a project is involved in a cycle.
+        *     - option id:         "org.eclipse.jdt.core.circularClasspath"
+        *     - possible values:   { "error", "warning" }
+        *     - default:           "error"
+        * 
+        * JAVACORE / Enabling Usage of Classpath Exclusion Patterns
+        *    When disabled, no entry on a project classpath can be associated with
+        *    an exclusion pattern.
+        *     - option id:         "org.eclipse.jdt.core.classpath.exclusionPatterns"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "enabled"
+        * 
+        * JAVACORE / Enabling Usage of Classpath Multiple Output Locations
+        *    When disabled, no entry on a project classpath can be associated with
+        *    a specific output location, preventing thus usage of multiple output locations.
+        *     - option id:         "org.eclipse.jdt.core.classpath.multipleOutputLocations"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "enabled"
+        * 
+        *      FORMATTER / Inserting New Line Before Opening Brace
+        *    When Insert, a new line is inserted before an opening brace, otherwise nothing
+        *    is inserted
+        *     - option id:         "org.eclipse.jdt.core.formatter.newline.openingBrace"
+        *     - possible values:   { "insert", "do not insert" }
+        *     - default:           "do not insert"
+        * 
+        *      FORMATTER / Inserting New Line Inside Control Statement
+        *    When Insert, a new line is inserted between } and following else, catch, finally
+        *     - option id:         "org.eclipse.jdt.core.formatter.newline.controlStatement"
+        *     - possible values:   { "insert", "do not insert" }
+        *     - default:           "do not insert"
+        * 
+        *      FORMATTER / Clearing Blank Lines
+        *    When Clear all, all blank lines are removed. When Preserve one, only one is kept
+        *    and all others removed.
+        *     - option id:         "org.eclipse.jdt.core.formatter.newline.clearAll"
+        *     - possible values:   { "clear all", "preserve one" }
+        *     - default:           "preserve one"
+        * 
+        *      FORMATTER / Inserting New Line Between Else/If 
+        *    When Insert, a blank line is inserted between an else and an if when they are 
+        *    contiguous. When choosing to not insert, else-if will be kept on the same
+        *    line when possible.
+        *     - option id:         "org.eclipse.jdt.core.formatter.newline.elseIf"
+        *     - possible values:   { "insert", "do not insert" }
+        *     - default:           "do not insert"
+        * 
+        *      FORMATTER / Inserting New Line In Empty Block
+        *    When insert, a line break is inserted between contiguous { and }, if } is not followed
+        *    by a keyword.
+        *     - option id:         "org.eclipse.jdt.core.formatter.newline.emptyBlock"
+        *     - possible values:   { "insert", "do not insert" }
+        *     - default:           "insert"
+        * 
+        *      FORMATTER / Splitting Lines Exceeding Length
+        *    Enable splitting of long lines (exceeding the configurable length). Length of 0 will
+        *    disable line splitting
+        *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
+        *     - possible values:       "<n>", where n is zero or a positive integer
+        *     - default:           "80"
+        * 
+        *      FORMATTER / Compacting Assignment
+        *    Assignments can be formatted asymmetrically, for example 'int x= 2;', when Normal, a space
+        *    is inserted before the assignment operator
+        *     - option id:         "org.eclipse.jdt.core.formatter.style.assignment"
+        *     - possible values:   { "compact", "normal" }
+        *     - default:           "normal"
+        * 
+        *      FORMATTER / Defining Indentation Character
+        *    Either choose to indent with tab characters or spaces
+        *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.char"
+        *     - possible values:   { "tab", "space" }
+        *     - default:           "tab"
+        * 
+        *      FORMATTER / Defining Space Indentation Length
+        *    When using spaces, set the amount of space characters to use for each 
+        *    indentation mark.
+        *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.size"
+        *     - possible values:       "<n>", where n is a positive integer
+        *     - default:           "4"
+        * 
+        *      FORMATTER / Inserting space in cast expression
+        *    When Insert, a space is added between the type and the expression in a cast expression.
+        *     - option id:         "org.eclipse.jdt.core.formatter.space.castexpression"
+        *     - possible values:   { "insert", "do not insert" }
+        *     - default:           "insert"
+        * 
+        *      CODEASSIST / Activate Visibility Sensitive Completion
+        *    When active, completion doesn't show that you can not see
+        *    (for example, you can not see private methods of a super class).
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.visibilityCheck"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "disabled"
+        * 
+        *      CODEASSIST / Automatic Qualification of Implicit Members
+        *    When active, completion automatically qualifies completion on implicit
+        *    field references and message expressions.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.forceImplicitQualification"
+        *     - possible values:   { "enabled", "disabled" }
+        *     - default:           "disabled"
+        * 
+        *  CODEASSIST / Define the Prefixes for Field Name
+        *    When the prefixes is non empty, completion for field name will begin with
+        *    one of the proposed prefixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.fieldPrefixes"
+        *     - possible values:   { "<prefix>[,<prefix>]*" } where <prefix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Prefixes for Static Field Name
+        *    When the prefixes is non empty, completion for static field name will begin with
+        *    one of the proposed prefixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.staticFieldPrefixes"
+        *     - possible values:   { "<prefix>[,<prefix>]*" } where <prefix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Prefixes for Local Variable Name
+        *    When the prefixes is non empty, completion for local variable name will begin with
+        *    one of the proposed prefixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.localPrefixes"
+        *     - possible values:   { "<prefix>[,<prefix>]*" } where <prefix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Prefixes for Argument Name
+        *    When the prefixes is non empty, completion for argument name will begin with
+        *    one of the proposed prefixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.argumentPrefixes"
+        *     - possible values:   { "<prefix>[,<prefix>]*" } where <prefix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Suffixes for Field Name
+        *    When the suffixes is non empty, completion for field name will end with
+        *    one of the proposed suffixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.fieldSuffixes"
+        *     - possible values:   { "<suffix>[,<suffix>]*" } where <suffix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Suffixes for Static Field Name
+        *    When the suffixes is non empty, completion for static field name will end with
+        *    one of the proposed suffixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.staticFieldSuffixes"
+        *     - possible values:   { "<suffix>[,<suffix>]*" } where <suffix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Suffixes for Local Variable Name
+        *    When the suffixes is non empty, completion for local variable name will end with
+        *    one of the proposed suffixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.localSuffixes"
+        *     - possible values:   { "<suffix>[,<suffix>]*" } where <suffix> is a String without any wild-card 
+        *     - default:           ""
+        * 
+        *  CODEASSIST / Define the Suffixes for Argument Name
+        *    When the suffixes is non empty, completion for argument name will end with
+        *    one of the proposed suffixes.
+        *     - option id:         "org.eclipse.jdt.core.codeComplete.argumentSuffixes"
+        *     - possible values:   { "<suffix>[,<suffix>]*" } where <prefix> is a String without any wild-card 
+        *     - default:           ""
+        * </pre>
+        * 
+        * @return a mutable table containing the default settings of all known options
+        *   (key type: <code>String</code>; value type: <code>String</code>)
+        * @see #setOptions
+        */
+       public static Hashtable getDefaultOptions(){
+       
+               Hashtable defaultOptions = new Hashtable(10);
+
+               // see #initializeDefaultPluginPreferences() for changing default settings
+               Preferences preferences = getPlugin().getPluginPreferences();
+               HashSet optionNames = JavaModelManager.OptionNames;
+               
+               // get preferences set to their default
+               String[] defaultPropertyNames = preferences.defaultPropertyNames();
+               for (int i = 0; i < defaultPropertyNames.length; i++){
+                       String propertyName = defaultPropertyNames[i];
+                       if (optionNames.contains(propertyName)) {
+                               defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
+                       }
+               }               
+               // get preferences not set to their default
+               String[] propertyNames = preferences.propertyNames();
+               for (int i = 0; i < propertyNames.length; i++){
+                       String propertyName = propertyNames[i];
+                       if (optionNames.contains(propertyName)) {
+                               defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
+                       }
+               }               
+               // get encoding through resource plugin
+               defaultOptions.put(CORE_ENCODING, ResourcesPlugin.getEncoding()); 
+               
+               return defaultOptions;
+       }
+
+       /**
+        * Returns the single instance of the Java core plug-in runtime class.
+        * Equivalent to <code>(JavaCore) getPlugin()</code>.
+        * 
+        * @return the single instance of the Java core plug-in runtime class
+        */
+       public static JavaCore getJavaCore() {
+               return (JavaCore) getPlugin();
+       }
+       
+       /**
+        * Helper method for returning one option value only. Equivalent to <code>(String)JavaCore.getOptions().get(optionName)</code>
+        * Note that it may answer <code>null</code> if this option does not exist.
+        * <p>
+        * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
+        * </p>
+        * 
+        * @param optionName the name of an option
+        * @return the String value of a given option
+        * @see JavaCore#getDefaultOptions
+        * @since 2.0
+        */
+       public static String getOption(String optionName) {
+               
+               if (CORE_ENCODING.equals(optionName)){
+                       return ResourcesPlugin.getEncoding();
+               }
+               if (JavaModelManager.OptionNames.contains(optionName)){
+                       Preferences preferences = getPlugin().getPluginPreferences();
+                       return preferences.getString(optionName).trim();
+               }
+               return null;
+       }
+       
+       /**
+        * Returns the table of the current options. Initially, all options have their default values,
+        * and this method returns a table that includes all known options.
+        * <p>
+        * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
+        * </p>
+        * 
+        * @return table of current settings of all options 
+        *   (key type: <code>String</code>; value type: <code>String</code>)
+        * @see JavaCore#getDefaultOptions
+        */
+       public static Hashtable getOptions() {
+               
+               Hashtable options = new Hashtable(10);
+
+               // see #initializeDefaultPluginPreferences() for changing default settings
+               Plugin plugin = getPlugin();
+               if (plugin != null) {
+                       Preferences preferences = getPlugin().getPluginPreferences();
+                       HashSet optionNames = JavaModelManager.OptionNames;
+                       
+                       // get preferences set to their default
+                       String[] defaultPropertyNames = preferences.defaultPropertyNames();
+                       for (int i = 0; i < defaultPropertyNames.length; i++){
+                               String propertyName = defaultPropertyNames[i];
+                               if (optionNames.contains(propertyName)){
+                                       options.put(propertyName, preferences.getDefaultString(propertyName));
+                               }
+                       }               
+                       // get preferences not set to their default
+                       String[] propertyNames = preferences.propertyNames();
+                       for (int i = 0; i < propertyNames.length; i++){
+                               String propertyName = propertyNames[i];
+                               if (optionNames.contains(propertyName)){
+                                       options.put(propertyName, preferences.getString(propertyName).trim());
+                               }
+                       }               
+                       // get encoding through resource plugin
+                       options.put(CORE_ENCODING, ResourcesPlugin.getEncoding());
+               }
+               return options;
+       }
+               
+       /**
+        * Returns the single instance of the Java core plug-in runtime class.
+        * 
+        * @return the single instance of the Java core plug-in runtime class
+        */
+       public static Plugin getPlugin() {
+               return JAVA_CORE_PLUGIN;
+       }
+
+       /**
+        * This is a helper method, which returns the resolved classpath entry denoted 
+        * by a given entry (if it is a variable entry). It is obtained by resolving the variable 
+        * reference in the first segment. Returns <node>null</code> if unable to resolve using 
+        * the following algorithm:
+        * <ul>
+        * <li> if variable segment cannot be resolved, returns <code>null</code></li>
+        * <li> finds a project, JAR or binary folder in the workspace at the resolved path location</li>
+        * <li> if none finds an external JAR file or folder outside the workspace at the resolved path location </li>
+        * <li> if none returns <code>null</code></li>
+        * </ul>
+        * <p>
+        * Variable source attachment path and root path are also resolved and recorded in the resulting classpath entry.
+        * <p>
+        * NOTE: This helper method does not handle classpath containers, for which should rather be used
+        * <code>JavaCore#getClasspathContainer(IPath, IJavaProject)</code>.
+        * <p>
+        * 
+        * @param entry the given variable entry
+        * @return the resolved library or project classpath entry, or <code>null</code>
+        *   if the given variable entry could not be resolved to a valid classpath entry
+        */
+//     public static IClasspathEntry getResolvedClasspathEntry(IClasspathEntry entry) {
+//     
+//             if (entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE)
+//                     return entry;
+//     
+//             IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+//             IPath resolvedPath = JavaCore.getResolvedVariablePath(entry.getPath());
+//             if (resolvedPath == null)
+//                     return null;
+//     
+//             Object target = JavaModel.getTarget(workspaceRoot, resolvedPath, false);
+//             if (target == null)
+//                     return null;
+//     
+//             // inside the workspace
+//             if (target instanceof IResource) {
+//                     IResource resolvedResource = (IResource) target;
+//                     if (resolvedResource != null) {
+//                             switch (resolvedResource.getType()) {
+//                                     
+//                                     case IResource.PROJECT :  
+//                                             // internal project
+//                                             return JavaCore.newProjectEntry(resolvedPath, entry.isExported());
+//                                             
+//                                     case IResource.FILE : 
+//                                             if (Util.isArchiveFileName(resolvedResource.getName())) {
+//                                                     // internal binary archive
+//                                                     return JavaCore.newLibraryEntry(
+//                                                                     resolvedPath,
+//                                                                     getResolvedVariablePath(entry.getSourceAttachmentPath()),
+//                                                                     getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
+//                                                                     entry.isExported());
+//                                             }
+//                                             break;
+//                                             
+//                                     case IResource.FOLDER : 
+//                                             // internal binary folder
+//                                             return JavaCore.newLibraryEntry(
+//                                                             resolvedPath,
+//                                                             getResolvedVariablePath(entry.getSourceAttachmentPath()),
+//                                                             getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
+//                                                             entry.isExported());
+//                             }
+//                     }
+//             }
+//             // outside the workspace
+//             if (target instanceof File) {
+//                     File externalFile = (File) target;
+//                     if (externalFile.isFile()) {
+//                             String fileName = externalFile.getName().toLowerCase();
+//                             if (fileName.endsWith(".jar"  //$NON-NLS-1$
+//                                     ) || fileName.endsWith(".zip"  //$NON-NLS-1$
+//                                     )) { // external binary archive
+//                                     return JavaCore.newLibraryEntry(
+//                                                     resolvedPath,
+//                                                     getResolvedVariablePath(entry.getSourceAttachmentPath()),
+//                                                     getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
+//                                                     entry.isExported());
+//                             }
+//                     } else { // external binary folder
+//                             if (resolvedPath.isAbsolute()){
+//                                     return JavaCore.newLibraryEntry(
+//                                                     resolvedPath,
+//                                                     getResolvedVariablePath(entry.getSourceAttachmentPath()),
+//                                                     getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
+//                                                     entry.isExported());
+//                             }
+//                     }
+//             }
+//             return null;
+//     }
+
+
+       /**
+        * Resolve a variable path (helper method).
+        * 
+        * @param variablePath the given variable path
+        * @return the resolved variable path or <code>null</code> if none
+        */
+//     public static IPath getResolvedVariablePath(IPath variablePath) {
+//     
+//             if (variablePath == null)
+//                     return null;
+//             int count = variablePath.segmentCount();
+//             if (count == 0)
+//                     return null;
+//     
+//             // lookup variable      
+//             String variableName = variablePath.segment(0);
+//             IPath resolvedPath = JavaCore.getClasspathVariable(variableName);
+//             if (resolvedPath == null)
+//                     return null;
+//     
+//             // append path suffix
+//             if (count > 1) {
+//                     resolvedPath = resolvedPath.append(variablePath.removeFirstSegments(1));
+//             }
+//             return resolvedPath; 
+//     }
+
+       /**
+        * Answers the shared working copies currently registered for this buffer factory. 
+        * Working copies can be shared by several clients using the same buffer factory,see 
+        * <code>IWorkingCopy.getSharedWorkingCopy</code>.
+        * 
+        * @param factory the given buffer factory
+        * @return the list of shared working copies for a given buffer factory
+        * @see IWorkingCopy
+        * @since 2.0
+        */
+       public static IWorkingCopy[] getSharedWorkingCopies(IBufferFactory factory){
+               
+               // if factory is null, default factory must be used
+               if (factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory();
+               Map sharedWorkingCopies = JavaModelManager.getJavaModelManager().sharedWorkingCopies;
+               
+               Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
+               if (perFactoryWorkingCopies == null) return JavaModelManager.NoWorkingCopy;
+               Collection copies = perFactoryWorkingCopies.values();
+               IWorkingCopy[] result = new IWorkingCopy[copies.size()];
+               copies.toArray(result);
+               return result;
+       }
+       
+       /**
+        * Initializes the default preferences settings for this plug-in.
+        */
+       protected void initializeDefaultPluginPreferences() {
+               
+               Preferences preferences = getPluginPreferences();
+               HashSet optionNames = JavaModelManager.OptionNames;
+               
+               // Compiler settings
+               preferences.setDefault(COMPILER_LOCAL_VARIABLE_ATTR, GENERATE);
+               optionNames.add(COMPILER_LOCAL_VARIABLE_ATTR);
+
+               preferences.setDefault(COMPILER_LINE_NUMBER_ATTR, GENERATE); 
+               optionNames.add(COMPILER_LINE_NUMBER_ATTR);
+
+               preferences.setDefault(COMPILER_SOURCE_FILE_ATTR, GENERATE); 
+               optionNames.add(COMPILER_SOURCE_FILE_ATTR);
+
+               preferences.setDefault(COMPILER_CODEGEN_UNUSED_LOCAL, PRESERVE); 
+               optionNames.add(COMPILER_CODEGEN_UNUSED_LOCAL);
+
+               preferences.setDefault(COMPILER_CODEGEN_TARGET_PLATFORM, VERSION_1_1); 
+               optionNames.add(COMPILER_CODEGEN_TARGET_PLATFORM);
+
+               preferences.setDefault(COMPILER_PB_UNREACHABLE_CODE, ERROR); 
+               optionNames.add(COMPILER_PB_UNREACHABLE_CODE);
+
+               preferences.setDefault(COMPILER_PB_INVALID_IMPORT, ERROR); 
+               optionNames.add(COMPILER_PB_INVALID_IMPORT);
+
+               preferences.setDefault(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, WARNING); 
+               optionNames.add(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD);
+
+               preferences.setDefault(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, WARNING); 
+               optionNames.add(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME);
+
+               preferences.setDefault(COMPILER_PB_DEPRECATION, WARNING);
+               optionNames.add(COMPILER_PB_DEPRECATION);
+
+               preferences.setDefault(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, DISABLED);
+               optionNames.add(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE);
+
+               preferences.setDefault(COMPILER_PB_HIDDEN_CATCH_BLOCK, WARNING); 
+               optionNames.add(COMPILER_PB_HIDDEN_CATCH_BLOCK);
+
+               preferences.setDefault(COMPILER_PB_UNUSED_LOCAL, IGNORE); 
+               optionNames.add(COMPILER_PB_UNUSED_LOCAL);
+
+               preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER, IGNORE); 
+               optionNames.add(COMPILER_PB_UNUSED_PARAMETER);
+
+               preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT, DISABLED); 
+               optionNames.add(COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT);
+
+               preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE, DISABLED); 
+               optionNames.add(COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE);
+
+               preferences.setDefault(COMPILER_PB_UNUSED_IMPORT, WARNING); 
+               optionNames.add(COMPILER_PB_UNUSED_IMPORT);
+
+               preferences.setDefault(COMPILER_PB_UNUSED_PRIVATE_MEMBER, IGNORE); 
+               optionNames.add(COMPILER_PB_UNUSED_PRIVATE_MEMBER);
+
+               preferences.setDefault(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, IGNORE); 
+               optionNames.add(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION);
+
+               preferences.setDefault(COMPILER_PB_NON_NLS_STRING_LITERAL, IGNORE); 
+               optionNames.add(COMPILER_PB_NON_NLS_STRING_LITERAL);
+
+               preferences.setDefault(COMPILER_PB_ASSERT_IDENTIFIER, IGNORE); 
+               optionNames.add(COMPILER_PB_ASSERT_IDENTIFIER);
+
+               preferences.setDefault(COMPILER_PB_STATIC_ACCESS_RECEIVER, WARNING); 
+               optionNames.add(COMPILER_PB_STATIC_ACCESS_RECEIVER);
+
+               preferences.setDefault(COMPILER_PB_NO_EFFECT_ASSIGNMENT, WARNING); 
+               optionNames.add(COMPILER_PB_NO_EFFECT_ASSIGNMENT);
+
+               preferences.setDefault(COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD, WARNING); 
+               optionNames.add(COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD);
+
+               preferences.setDefault(COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION, WARNING); 
+               optionNames.add(COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION);
+
+               preferences.setDefault(COMPILER_TASK_TAGS, DEFAULT_TASK_TAG); //$NON-NLS-1$
+               optionNames.add(COMPILER_TASK_TAGS);
+
+               preferences.setDefault(COMPILER_TASK_PRIORITIES, DEFAULT_TASK_PRIORITY); //$NON-NLS-1$
+               optionNames.add(COMPILER_TASK_PRIORITIES);
+
+               preferences.setDefault(COMPILER_SOURCE, VERSION_1_3);
+               optionNames.add(COMPILER_SOURCE);
+
+               preferences.setDefault(COMPILER_COMPLIANCE, VERSION_1_3); 
+               optionNames.add(COMPILER_COMPLIANCE);
+
+               preferences.setDefault(COMPILER_PB_MAX_PER_UNIT, "100"); //$NON-NLS-1$
+               optionNames.add(COMPILER_PB_MAX_PER_UNIT);
+               
+               // Builder settings
+               preferences.setDefault(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
+               optionNames.add(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER);
+
+               preferences.setDefault(CORE_JAVA_BUILD_INVALID_CLASSPATH, ABORT); 
+               optionNames.add(CORE_JAVA_BUILD_INVALID_CLASSPATH);
+       
+               preferences.setDefault(CORE_JAVA_BUILD_DUPLICATE_RESOURCE, WARNING); 
+               optionNames.add(CORE_JAVA_BUILD_DUPLICATE_RESOURCE);
+               
+               preferences.setDefault(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, CLEAN); 
+               optionNames.add(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER);
+
+               // JavaCore settings
+               preferences.setDefault(CORE_JAVA_BUILD_ORDER, IGNORE); 
+               optionNames.add(CORE_JAVA_BUILD_ORDER);
+       
+               preferences.setDefault(CORE_CIRCULAR_CLASSPATH, ERROR); 
+               optionNames.add(CORE_CIRCULAR_CLASSPATH);
+               
+               preferences.setDefault(CORE_INCOMPLETE_CLASSPATH, ERROR); 
+               optionNames.add(CORE_INCOMPLETE_CLASSPATH);
+               
+               preferences.setDefault(CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, ENABLED); 
+               optionNames.add(CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS);
+
+               preferences.setDefault(CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, ENABLED); 
+               optionNames.add(CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS);
+
+               // encoding setting comes from resource plug-in
+               optionNames.add(CORE_ENCODING);
+               
+               // Formatter settings
+               preferences.setDefault(FORMATTER_NEWLINE_OPENING_BRACE, DO_NOT_INSERT); 
+               optionNames.add(FORMATTER_NEWLINE_OPENING_BRACE);
+
+               preferences.setDefault(FORMATTER_NEWLINE_CONTROL, DO_NOT_INSERT);
+               optionNames.add(FORMATTER_NEWLINE_CONTROL);
+
+               preferences.setDefault(FORMATTER_CLEAR_BLANK_LINES, PRESERVE_ONE); 
+               optionNames.add(FORMATTER_CLEAR_BLANK_LINES);
+
+               preferences.setDefault(FORMATTER_NEWLINE_ELSE_IF, DO_NOT_INSERT);
+               optionNames.add(FORMATTER_NEWLINE_ELSE_IF);
+
+               preferences.setDefault(FORMATTER_NEWLINE_EMPTY_BLOCK, INSERT); 
+               optionNames.add(FORMATTER_NEWLINE_EMPTY_BLOCK);
+
+               preferences.setDefault(FORMATTER_LINE_SPLIT, "80"); //$NON-NLS-1$
+               optionNames.add(FORMATTER_LINE_SPLIT);
+
+               preferences.setDefault(FORMATTER_COMPACT_ASSIGNMENT, NORMAL); 
+               optionNames.add(FORMATTER_COMPACT_ASSIGNMENT);
+
+               preferences.setDefault(FORMATTER_TAB_CHAR, TAB); 
+               optionNames.add(FORMATTER_TAB_CHAR);
+
+               preferences.setDefault(FORMATTER_TAB_SIZE, "4"); //$NON-NLS-1$ 
+               optionNames.add(FORMATTER_TAB_SIZE);
+               
+               preferences.setDefault(FORMATTER_SPACE_CASTEXPRESSION, INSERT); //$NON-NLS-1$ 
+               optionNames.add(FORMATTER_SPACE_CASTEXPRESSION);
+
+               // CodeAssist settings
+               preferences.setDefault(CODEASSIST_VISIBILITY_CHECK, DISABLED); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_VISIBILITY_CHECK);
+
+               preferences.setDefault(CODEASSIST_IMPLICIT_QUALIFICATION, DISABLED); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_IMPLICIT_QUALIFICATION);
+               
+               preferences.setDefault(CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_FIELD_PREFIXES);
+               
+               preferences.setDefault(CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_STATIC_FIELD_PREFIXES);
+               
+               preferences.setDefault(CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_LOCAL_PREFIXES);
+               
+               preferences.setDefault(CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_ARGUMENT_PREFIXES);
+               
+               preferences.setDefault(CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_FIELD_SUFFIXES);
+               
+               preferences.setDefault(CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_STATIC_FIELD_SUFFIXES);
+               
+               preferences.setDefault(CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_LOCAL_SUFFIXES);
+               
+               preferences.setDefault(CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
+               optionNames.add(CODEASSIST_ARGUMENT_SUFFIXES);
+       }
+       
+       /**
+        * Returns whether the given marker references the given Java element.
+        * Used for markers, which denote a Java element rather than a resource.
+        *
+        * @param element the element
+        * @param marker the marker
+        * @return <code>true</code> if the marker references the element, false otherwise
+        * @exception CoreException if the <code>IMarker.getAttribute</code> on the marker fails         
+        */
+       public static boolean isReferencedBy(IJavaElement element, IMarker marker) throws CoreException {
+               
+               // only match units or classfiles
+               if (element instanceof IMember){
+                       IMember member = (IMember) element;
+                       if (member.isBinary()){
+                               element = null; //member.getClassFile();
+                       } else {
+                               element = member.getCompilationUnit();
+                       }
+               }
+               if (element == null) return false;                      
+               if (marker == null) return false;
+
+               String markerHandleId = (String)marker.getAttribute(ATT_HANDLE_ID);
+               if (markerHandleId == null) return false;
+               
+               IJavaElement markerElement = JavaCore.create(markerHandleId);
+//             while (true){
+                       if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs.
+                       
+                       // cycle through enclosing types in case marker is associated with a classfile (15568)
+//                     if (markerElement instanceof IClassFile){
+//                             IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType();
+//                             if (enclosingType != null){
+//                                     markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile
+//                                     continue;
+//                             }
+//                     }
+//                     break;
+//             }
+               return false;
+       }
+
+       /**
+        * Returns whether the given marker delta references the given Java element.
+        * Used for markers deltas, which denote a Java element rather than a resource.
+        *
+        * @param element the element
+        * @param markerDelta the marker delta
+        * @return <code>true</code> if the marker delta references the element
+        * @exception CoreException if the  <code>IMarkerDelta.getAttribute</code> on the marker delta fails     
+        */
+       public static boolean isReferencedBy(IJavaElement element, IMarkerDelta markerDelta) throws CoreException {
+               
+               // only match units or classfiles
+               if (element instanceof IMember){
+                       IMember member = (IMember) element;
+                       if (member.isBinary()){
+                               element = null; //member.getClassFile();
+                       } else {
+                               element = member.getCompilationUnit();
+                       }
+               }
+               if (element == null) return false;                      
+               if (markerDelta == null) return false;
+
+               String markerDeltarHandleId = (String)markerDelta.getAttribute(ATT_HANDLE_ID);
+               if (markerDeltarHandleId == null) return false;
+               
+               IJavaElement markerElement = JavaCore.create(markerDeltarHandleId);
+//             while (true){
+                       if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs.
+                       
+                       // cycle through enclosing types in case marker is associated with a classfile (15568)
+//                     if (markerElement instanceof IClassFile){
+//                             IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType();
+//                             if (enclosingType != null){
+//                                     markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile
+//                                     continue;
+//                             }
+//                     }
+//                     break;
+//             }
+               return false;
+       }
+
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
+        * for the given path. The path of the container will be used during resolution so as to map this
+        * container entry to a set of other classpath entries the container is acting for.
+        * <p>
+        * A container entry allows to express indirect references to a set of libraries, projects and variable entries,
+        * which can be interpreted differently for each Java project where it is used.
+        * A classpath container entry can be resolved using <code>JavaCore.getResolvedClasspathContainer</code>,
+        * and updated with <code>JavaCore.classpathContainerChanged</code>
+        * <p>
+        * A container is exclusively resolved by a <code>ClasspathContainerInitializer</code> registered onto the
+        * extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+        * <p>
+        * A container path must be formed of at least one segment, where: <ul>
+        * <li> the first segment is a unique ID identifying the target container, there must be a container initializer registered
+        *      onto this ID through the extension point  "org.eclipse.jdt.core.classpathContainerInitializer". </li>
+        * <li> the remaining segments will be passed onto the initializer, and can be used as additional
+        *      hints during the initialization phase. </li>
+        * </ul>
+        * <p>
+        * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container:
+        * 
+        * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default"));
+        * 
+        * <extension
+        *    point="org.eclipse.jdt.core.classpathContainerInitializer">
+        *    <containerInitializer
+        *       id="MyProvidedJDK"
+        *       class="com.example.MyInitializer"/> 
+        * <p>
+        * Note that this operation does not attempt to validate classpath containers
+        * or access the resources at the given paths.
+        * <p>
+        * The resulting entry is not exported to dependent projects. This method is equivalent to
+        * <code>newContainerEntry(-,false)</code>.
+        * <p>
+        * @param containerPath the path identifying the container, it must be formed of two
+        *      segments
+        * @return a new container classpath entry
+        * 
+        * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
+        * @see JavaCore#newContainerEntry(IPath, boolean)
+        * @since 2.0
+        */
+//     public static IClasspathEntry newContainerEntry(IPath containerPath) {
+//                     
+//             return newContainerEntry(containerPath, false);
+//     }
+
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
+        * for the given path. The path of the container will be used during resolution so as to map this
+        * container entry to a set of other classpath entries the container is acting for.
+        * <p>
+        * A container entry allows to express indirect references to a set of libraries, projects and variable entries,
+        * which can be interpreted differently for each Java project where it is used.
+        * A classpath container entry can be resolved using <code>JavaCore.getResolvedClasspathContainer</code>,
+        * and updated with <code>JavaCore.classpathContainerChanged</code>
+        * <p>
+        * A container is exclusively resolved by a <code>ClasspathContainerInitializer</code> registered onto the
+        * extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+        * <p>
+        * A container path must be formed of at least one segment, where: <ul>
+        * <li> the first segment is a unique ID identifying the target container, there must be a container initializer registered
+        *      onto this ID through the extension point  "org.eclipse.jdt.core.classpathContainerInitializer". </li>
+        * <li> the remaining segments will be passed onto the initializer, and can be used as additional
+        *      hints during the initialization phase. </li>
+        * </ul>
+        * <p>
+        * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container:
+        * 
+        * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default"));
+        * 
+        * <extension
+        *    point="org.eclipse.jdt.core.classpathContainerInitializer">
+        *    <containerInitializer
+        *       id="MyProvidedJDK"
+        *       class="com.example.MyInitializer"/> 
+        * <p>
+        * Note that this operation does not attempt to validate classpath containers
+        * or access the resources at the given paths.
+        * <p>
+        * @param containerPath the path identifying the container, it must be formed of at least
+        *      one segment (ID+hints)
+        * @param isExported a boolean indicating whether this entry is contributed to dependent
+        *    projects in addition to the output location
+        * @return a new container classpath entry
+        * 
+        * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
+        * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
+        * @see JavaCore#newContainerEntry(IPath, boolean)
+        * @since 2.0
+        */
+//     public static IClasspathEntry newContainerEntry(IPath containerPath, boolean isExported) {
+//                     
+//             if (containerPath == null || containerPath.segmentCount() < 1) {
+//                     Assert.isTrue(
+//                             false,
+//                             "Illegal classpath container path: \'" + containerPath.makeRelative().toString() + "\', must have at least one segment (containerID+hints)"); //$NON-NLS-1$//$NON-NLS-2$
+//             }
+//             return new ClasspathEntry(
+//                     IPackageFragmentRoot.K_SOURCE,
+//                     IClasspathEntry.CPE_CONTAINER,
+//                     containerPath,
+//                     ClasspathEntry.NO_EXCLUSION_PATTERNS, 
+//                     null, // source attachment
+//                     null, // source attachment root
+//                     null, // specific output folder
+//                     isExported);
+//     }
+
+       /**
+        * Creates and returns a new non-exported classpath entry of kind <code>CPE_LIBRARY</code> for the 
+        * JAR or folder identified by the given absolute path. This specifies that all package fragments 
+        * within the root will have children of type <code>IClassFile</code>.
+        * <p>
+        * A library entry is used to denote a prerequisite JAR or root folder containing binaries.
+        * The target JAR or folder can either be defined internally to the workspace (absolute path relative
+        * to the workspace root) or externally to the workspace (absolute path in the file system).
+        * <p>
+        * e.g. Here are some examples of binary path usage<ul>
+        *      <li><code> "c:/jdk1.2.2/jre/lib/rt.jar" </code> - reference to an external JAR</li>
+        *      <li><code> "/Project/someLib.jar" </code> - reference to an internal JAR </li>
+        *      <li><code> "c:/classes/" </code> - reference to an external binary folder</li>
+        * </ul>
+        * Note that this operation does not attempt to validate or access the 
+        * resources at the given paths.
+        * <p>
+        * The resulting entry is not exported to dependent projects. This method is equivalent to
+        * <code>newLibraryEntry(-,-,-,false)</code>.
+        * <p>
+        * 
+        * @param path the absolute path of the binary archive
+        * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, 
+        *    or <code>null</code> if none
+        * @param sourceAttachmentRootPath the location of the root within the source archive or folder
+        *    or <code>null</code> if this location should be automatically detected.
+        * @return a new library classpath entry
+        * 
+        * @see #newLibraryEntry(IPath, IPath, IPath, boolean)
+        */
+//     public static IClasspathEntry newLibraryEntry(
+//             IPath path,
+//             IPath sourceAttachmentPath,
+//             IPath sourceAttachmentRootPath) {
+//                     
+//             return newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, false);
+//     }
+
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_LIBRARY</code> for the JAR or folder
+        * identified by the given absolute path. This specifies that all package fragments within the root 
+        * will have children of type <code>IClassFile</code>.
+        * <p>
+        * A library entry is used to denote a prerequisite JAR or root folder containing binaries.
+        * The target JAR or folder can either be defined internally to the workspace (absolute path relative
+        * to the workspace root) or externally to the workspace (absolute path in the file system).
+        *      <p>
+        * e.g. Here are some examples of binary path usage<ul>
+        *      <li><code> "c:/jdk1.2.2/jre/lib/rt.jar" </code> - reference to an external JAR</li>
+        *      <li><code> "/Project/someLib.jar" </code> - reference to an internal JAR </li>
+        *      <li><code> "c:/classes/" </code> - reference to an external binary folder</li>
+        * </ul>
+        * Note that this operation does not attempt to validate or access the 
+        * resources at the given paths.
+        * <p>
+        * 
+        * @param path the absolute path of the binary archive
+        * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, 
+        *    or <code>null</code> if none
+        * @param sourceAttachmentRootPath the location of the root within the source archive or folder
+        *    or <code>null</code> if this location should be automatically detected.
+        * @param isExported indicates whether this entry is contributed to dependent
+        *        projects in addition to the output location
+        * @return a new library classpath entry
+        * @since 2.0
+        */
+//     public static IClasspathEntry newLibraryEntry(
+//             IPath path,
+//             IPath sourceAttachmentPath,
+//             IPath sourceAttachmentRootPath,
+//             boolean isExported) {
+//                     
+//             if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
+//
+//             return new ClasspathEntry(
+//                     IPackageFragmentRoot.K_BINARY,
+//                     IClasspathEntry.CPE_LIBRARY,
+//                     JavaProject.canonicalizedPath(path),
+//                     ClasspathEntry.NO_EXCLUSION_PATTERNS, 
+//                     sourceAttachmentPath,
+//                     sourceAttachmentRootPath,
+//                     null, // specific output folder
+//                     isExported);
+//     }
+
+       /**
+        * Creates and returns a new non-exported classpath entry of kind <code>CPE_PROJECT</code>
+        * for the project identified by the given absolute path.
+        * <p>
+        * A project entry is used to denote a prerequisite project on a classpath.
+        * The referenced project will be contributed as a whole, either as sources (in the Java Model, it
+        * contributes all its package fragment roots) or as binaries (when building, it contributes its 
+        * whole output location).
+        * <p>
+        * A project reference allows to indirect through another project, independently from its internal layout. 
+        * <p>
+        * The prerequisite project is referred to using an absolute path relative to the workspace root.
+        * <p>
+        * The resulting entry is not exported to dependent projects. This method is equivalent to
+        * <code>newProjectEntry(_,false)</code>.
+        * <p>
+        * 
+        * @param path the absolute path of the binary archive
+        * @return a new project classpath entry
+        * 
+        * @see JavaCore#newProjectEntry(IPath, boolean)
+        */
+//     public static IClasspathEntry newProjectEntry(IPath path) {
+//             return newProjectEntry(path, false);
+//     }
+       
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_PROJECT</code>
+        * for the project identified by the given absolute path.
+        * <p>
+        * A project entry is used to denote a prerequisite project on a classpath.
+        * The referenced project will be contributed as a whole, either as sources (in the Java Model, it
+        * contributes all its package fragment roots) or as binaries (when building, it contributes its 
+        * whole output location).
+        * <p>
+        * A project reference allows to indirect through another project, independently from its internal layout. 
+        * <p>
+        * The prerequisite project is referred to using an absolute path relative to the workspace root.
+        * <p>
+        * 
+        * @param path the absolute path of the prerequisite project
+        * @param isExported indicates whether this entry is contributed to dependent
+        *        projects in addition to the output location
+        * @return a new project classpath entry
+        * @since 2.0
+        */
+//     public static IClasspathEntry newProjectEntry(IPath path, boolean isExported) {
+//             
+//             if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
+//             
+//             return new ClasspathEntry(
+//                     IPackageFragmentRoot.K_SOURCE,
+//                     IClasspathEntry.CPE_PROJECT,
+//                     path,
+//                     ClasspathEntry.NO_EXCLUSION_PATTERNS, 
+//                     null, // source attachment
+//                     null, // source attachment root
+//                     null, // specific output folder
+//                     isExported);
+//     }
+
+       /**
+        * Returns a new empty region.
+        * 
+        * @return a new empty region
+        */
+       public static IRegion newRegion() {
+               return new Region();
+       }
+
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+        * for the project's source folder identified by the given absolute 
+        * workspace-relative path. This specifies that all package fragments
+        * within the root will have children of type <code>ICompilationUnit</code>.
+        * <p>
+        * The source folder is referred to using an absolute path relative to the
+        * workspace root, e.g. <code>/Project/src</code>. A project's source 
+        * folders are located with that project. That is, a source classpath
+        * entry specifying the path <code>/P1/src</code> is only usable for
+        * project <code>P1</code>.
+        * </p>
+        * <p>
+        * The source classpath entry created by this method includes all source
+        * files below the given workspace-relative path. To selectively exclude
+        * some of these source files, use the factory method 
+        * <code>JavaCore.newSourceEntry(IPath,IPath[])</code> instead.
+        * </p>
+        * <p>
+        * Note that all sources/binaries inside a project are contributed as a whole through
+        * a project entry (see <code>JavaCore.newProjectEntry</code>). Particular
+        * source entries cannot be selectively exported.
+        * </p>
+        * 
+        * @param path the absolute workspace-relative path of a source folder
+        * @return a new source classpath entry with not exclusion patterns
+        * 
+        * @see #newSourceEntry(org.eclipse.core.runtime.IPath,org.eclipse.core.runtime.IPath[])
+        */
+//     public static IClasspathEntry newSourceEntry(IPath path) {
+//
+//             return newSourceEntry(path, ClasspathEntry.NO_EXCLUSION_PATTERNS, null /*output location*/);
+//     }
+       
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+        * for the project's source folder identified by the given absolute 
+        * workspace-relative path but excluding all source files with paths
+        * matching any of the given patterns. This specifies that all package
+        * fragments within the root will have children of type 
+        * <code>ICompilationUnit</code>.
+        * <p>
+        * The source folder is referred to using an absolute path relative to the
+        * workspace root, e.g. <code>/Project/src</code>. A project's source 
+        * folders are located with that project. That is, a source classpath
+        * entry specifying the path <code>/P1/src</code> is only usable for
+        * project <code>P1</code>.
+        * </p>
+        * <p>
+        * The source classpath entry created by this method includes all source
+        * files below the given workspace-relative path except for those matched
+        * by one (or more) of the given exclusion patterns. Each exclusion pattern
+        * is represented by a relative path, which is interpreted as relative to
+        * the source folder. For example, if the source folder path is 
+        * <code>/Project/src</code> and the exclusion pattern is 
+        * <code>com/xyz/tests/&#42;&#42;</code>, then source files
+        * like <code>/Project/src/com/xyz/Foo.java</code>
+        * and <code>/Project/src/com/xyz/utils/Bar.java</code> would be included,
+        * whereas <code>/Project/src/com/xyz/tests/T1.java</code>
+        * and <code>/Project/src/com/xyz/tests/quick/T2.java</code> would be
+        * excluded. Exclusion patterns can contain can contain '**', '*' or '?'
+        * wildcards; see <code>IClasspathEntry.getExclusionPatterns</code>
+        * for the full description of the syntax and semantics of exclusion
+        * patterns.
+        * </p>
+        * If the empty list of exclusion patterns is specified, the source folder
+        * will automatically include all resources located inside the source
+        * folder. In that case, the result is entirely equivalent to using the
+        * factory method <code>JavaCore.newSourceEntry(IPath)</code>. 
+        * </p>
+        * <p>
+        * Note that all sources/binaries inside a project are contributed as a whole through
+        * a project entry (see <code>JavaCore.newProjectEntry</code>). Particular
+        * source entries cannot be selectively exported.
+        * </p>
+        *
+        * @param path the absolute workspace-relative path of a source folder
+        * @param exclusionPatterns the possibly empty list of exclusion patterns
+        *    represented as relative paths
+        * @return a new source classpath entry with the given exclusion patterns
+        * @see #newSourceEntry(org.eclipse.core.runtime.IPath)
+        * @see IClasspathEntry#getExclusionPatterns
+        * 
+        * @since 2.1
+        */
+//     public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns) {
+//
+//             return newSourceEntry(path, exclusionPatterns, null /*output location*/); 
+//     }
+
+       /**
+        * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+        * for the project's source folder identified by the given absolute 
+        * workspace-relative path but excluding all source files with paths
+        * matching any of the given patterns, and associated with a specific output location
+        * (that is, ".class" files are not going to the project default output location). 
+        * All package fragments within the root will have children of type 
+        * <code>ICompilationUnit</code>.
+        * <p>
+        * The source folder is referred to using an absolute path relative to the
+        * workspace root, e.g. <code>/Project/src</code>. A project's source 
+        * folders are located with that project. That is, a source classpath
+        * entry specifying the path <code>/P1/src</code> is only usable for
+        * project <code>P1</code>.
+        * </p>
+        * <p>
+        * The source classpath entry created by this method includes all source
+        * files below the given workspace-relative path except for those matched
+        * by one (or more) of the given exclusion patterns. Each exclusion pattern
+        * is represented by a relative path, which is interpreted as relative to
+        * the source folder. For example, if the source folder path is 
+        * <code>/Project/src</code> and the exclusion pattern is 
+        * <code>com/xyz/tests/&#42;&#42;</code>, then source files
+        * like <code>/Project/src/com/xyz/Foo.java</code>
+        * and <code>/Project/src/com/xyz/utils/Bar.java</code> would be included,
+        * whereas <code>/Project/src/com/xyz/tests/T1.java</code>
+        * and <code>/Project/src/com/xyz/tests/quick/T2.java</code> would be
+        * excluded. Exclusion patterns can contain can contain '**', '*' or '?'
+        * wildcards; see <code>IClasspathEntry.getExclusionPatterns</code>
+        * for the full description of the syntax and semantics of exclusion
+        * patterns.
+        * </p>
+        * If the empty list of exclusion patterns is specified, the source folder
+        * will automatically include all resources located inside the source
+        * folder. In that case, the result is entirely equivalent to using the
+        * factory method <code>JavaCore.newSourceEntry(IPath)</code>. 
+        * </p>
+        * <p>
+        * Additionally, a source entry can be associated with a specific output location. 
+        * By doing so, the Java builder will ensure that the generated ".class" files will 
+        * be issued inside this output location, as opposed to be generated into the 
+        * project default output location (when output location is <code>null</code>). 
+        * Note that multiple source entries may target the same output location.
+        * The output location is referred to using an absolute path relative to the 
+        * workspace root, e.g. <code>"/Project/bin"</code>, it must be located inside 
+        * the same project as the source folder.
+        * </p>
+        * <p>
+        * Also note that all sources/binaries inside a project are contributed as a whole through
+        * a project entry (see <code>JavaCore.newProjectEntry</code>). Particular
+        * source entries cannot be selectively exported.
+        * </p>
+        *
+        * @param path the absolute workspace-relative path of a source folder
+        * @param exclusionPatterns the possibly empty list of exclusion patterns
+        *    represented as relative paths
+        * @param outputLocation the specific output location for this source entry (<code>null</code> if using project default ouput location)
+        * @return a new source classpath entry with the given exclusion patterns
+        * @see #newSourceEntry(org.eclipse.core.runtime.IPath)
+        * @see IClasspathEntry#getExclusionPatterns
+        * @see IClasspathEntry#getOutputLocation()
+        * 
+        * @since 2.1
+        */
+//     public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns, IPath specificOutputLocation) {
+//
+//             if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
+//             if (exclusionPatterns == null) Assert.isTrue(false, "Exclusion pattern set cannot be null"); //$NON-NLS-1$
+//
+//             return new ClasspathEntry(
+//                     IPackageFragmentRoot.K_SOURCE,
+//                     IClasspathEntry.CPE_SOURCE,
+//                     path,
+//                     exclusionPatterns,
+//                     null, // source attachment
+//                     null, // source attachment root
+//                     specificOutputLocation, // custom output location
+//                     false);
+//     }
+               
+       /**
+        * Creates and returns a new non-exported classpath entry of kind <code>CPE_VARIABLE</code>
+        * for the given path. The first segment of the path is the name of a classpath variable.
+        * The trailing segments of the path will be appended to resolved variable path.
+        * <p>
+        * A variable entry allows to express indirect references on a classpath to other projects or libraries,
+        * depending on what the classpath variable is referring.
+        * <p>
+        *      It is possible to register an automatic initializer (<code>ClasspathVariableInitializer</code>),
+        * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+        * After resolution, a classpath variable entry may either correspond to a project or a library entry. </li>     
+        * <p>
+        * e.g. Here are some examples of variable path usage<ul>
+        * <li> "JDTCORE" where variable <code>JDTCORE</code> is 
+        *              bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"</li>
+        * <li> "JDTCORE" where variable <code>JDTCORE</code> is 
+        *              bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"</li>
+        * <li> "PLUGINS/com.example/example.jar" where variable <code>PLUGINS</code>
+        *      is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"</li>
+        * </ul>
+        * Note that this operation does not attempt to validate classpath variables
+        * or access the resources at the given paths.
+        * <p>
+        * The resulting entry is not exported to dependent projects. This method is equivalent to
+        * <code>newVariableEntry(-,-,-,false)</code>.
+        * <p>
+        * 
+        * @param variablePath the path of the binary archive; first segment is the
+        *   name of a classpath variable
+        * @param variableSourceAttachmentPath the path of the corresponding source archive, 
+        *    or <code>null</code> if none; if present, the first segment is the
+        *    name of a classpath variable (not necessarily the same variable
+        *    as the one that begins <code>variablePath</code>)
+        * @param sourceAttachmentRootPath the location of the root within the source archive
+        *    or <code>null</code> if <code>archivePath</code> is also <code>null</code>
+        * @return a new library classpath entry
+        * 
+        * @see JavaCore#newVariableEntry(IPath, IPath, IPath, boolean)
+        */
+//     public static IClasspathEntry newVariableEntry(
+//             IPath variablePath,
+//             IPath variableSourceAttachmentPath,
+//             IPath sourceAttachmentRootPath) {
+//
+//             return newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, false);
+//     }
+
+       /**
+        * Creates and returns a new non-exported classpath entry of kind <code>CPE_VARIABLE</code>
+        * for the given path. The first segment of the path is the name of a classpath variable.
+        * The trailing segments of the path will be appended to resolved variable path.
+        * <p>
+        * A variable entry allows to express indirect references on a classpath to other projects or libraries,
+        * depending on what the classpath variable is referring.
+        * <p>
+        *      It is possible to register an automatic initializer (<code>ClasspathVariableInitializer</code>),
+        * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+        * After resolution, a classpath variable entry may either correspond to a project or a library entry. </li>     
+        * <p>
+        * e.g. Here are some examples of variable path usage<ul>
+        * <li> "JDTCORE" where variable <code>JDTCORE</code> is 
+        *              bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"</li>
+        * <li> "JDTCORE" where variable <code>JDTCORE</code> is 
+        *              bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"</li>
+        * <li> "PLUGINS/com.example/example.jar" where variable <code>PLUGINS</code>
+        *      is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"</li>
+        * </ul>
+        * Note that this operation does not attempt to validate classpath variables
+        * or access the resources at the given paths.
+        * <p>
+        *
+        * @param variablePath the path of the binary archive; first segment is the
+        *   name of a classpath variable
+        * @param variableSourceAttachmentPath the path of the corresponding source archive, 
+        *    or <code>null</code> if none; if present, the first segment is the
+        *    name of a classpath variable (not necessarily the same variable
+        *    as the one that begins <code>variablePath</code>)
+        * @param sourceAttachmentRootPath the location of the root within the source archive
+        *    or <code>null</code> if <code>archivePath</code> is also <code>null</code>
+        * @param isExported indicates whether this entry is contributed to dependent
+        *        projects in addition to the output location
+        * @return a new variable classpath entry
+        * @since 2.0
+        */
+//     public static IClasspathEntry newVariableEntry(
+//             IPath variablePath,
+//             IPath variableSourceAttachmentPath,
+//             IPath variableSourceAttachmentRootPath,
+//             boolean isExported) {
+//                     
+//             if (variablePath == null || variablePath.segmentCount() < 1) {
+//                     Assert.isTrue(
+//                             false,
+//                             "Illegal classpath variable path: \'" + variablePath.makeRelative().toString() + "\', must have at least one segment"); //$NON-NLS-1$//$NON-NLS-2$
+//             }
+//     
+//             return new ClasspathEntry(
+//                     IPackageFragmentRoot.K_SOURCE,
+//                     IClasspathEntry.CPE_VARIABLE,
+//                     variablePath,
+//                     ClasspathEntry.NO_EXCLUSION_PATTERNS, 
+//                     variableSourceAttachmentPath, // source attachment
+//                     variableSourceAttachmentRootPath, // source attachment root                     
+//                     null, // specific output folder
+//                     isExported);
+//     }
+
+       /**
+        * Removed the given classpath variable. Does nothing if no value was
+        * set for this classpath variable.
+        * <p>
+        * This functionality cannot be used while the resource tree is locked.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        *
+        * @param variableName the name of the classpath variable
+        * @see #setClasspathVariable
+        *
+        * @deprecated - use version with extra IProgressMonitor
+        */
+//     public static void removeClasspathVariable(String variableName) {
+//             removeClasspathVariable(variableName, null);
+//     }
+
+       /**
+        * Removed the given classpath variable. Does nothing if no value was
+        * set for this classpath variable.
+        * <p>
+        * This functionality cannot be used while the resource tree is locked.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        *
+        * @param variableName the name of the classpath variable
+        * @param monitor the progress monitor to report progress
+        * @see #setClasspathVariable
+        */
+//     public static void removeClasspathVariable(
+//             String variableName,
+//             IProgressMonitor monitor) {
+//
+//             try {
+//                     updateVariableValues(new String[]{ variableName}, new IPath[]{ null }, monitor);
+//             } catch (JavaModelException e) {
+//             }
+//     }
+
+       /**
+        * Removes the given element changed listener.
+        * Has no affect if an identical listener is not registered.
+        *
+        * @param listener the listener
+        */
+       public static void removeElementChangedListener(IElementChangedListener listener) {
+               JavaModelManager.getJavaModelManager().removeElementChangedListener(listener);
+       }
+       /**
+        * Runs the given action as an atomic Java model operation.
+        * <p>
+        * After running a method that modifies Java elements,
+        * registered listeners receive after-the-fact notification of
+        * what just transpired, in the form of a element changed event.
+        * This method allows clients to call a number of
+        * methods that modify java elements and only have element
+        * changed event notifications reported at the end of the entire
+        * batch.
+        * </p>
+        * <p>
+        * If this method is called outside the dynamic scope of another such
+        * call, this method runs the action and then reports a single
+        * element changed event describing the net effect of all changes
+        * done to java elements by the action.
+        * </p>
+        * <p>
+        * If this method is called in the dynamic scope of another such
+        * call, this method simply runs the action.
+        * </p>
+        *
+        * @param action the action to perform
+        * @param monitor a progress monitor, or <code>null</code> if progress
+        *    reporting and cancellation are not desired
+        * @exception CoreException if the operation failed.
+        * @since 2.1
+        */
+       public static void run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException {
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               if (workspace.isTreeLocked()) {
+                       new BatchOperation(action).run(monitor);
+               } else {
+                       // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode
+                       workspace.run(new BatchOperation(action), monitor);
+               }
+       }
+       /** 
+        * Bind a container reference path to some actual containers (<code>IClasspathContainer</code>).
+        * This API must be invoked whenever changes in container need to be reflected onto the JavaModel.
+        * Containers can have distinct values in different projects, therefore this API considers a
+        * set of projects with their respective containers.
+        * <p>
+        * <code>containerPath</code> is the path under which these values can be referenced through
+        * container classpath entries (<code>IClasspathEntry#CPE_CONTAINER</code>). A container path 
+        * is formed by a first ID segment followed with extra segments, which can be used as additional hints
+        * for the resolution. The container ID is used to identify a <code>ClasspathContainerInitializer</code> 
+        * registered on the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+        * <p>
+        * There is no assumption that each individual container value passed in argument 
+        * (<code>respectiveContainers</code>) must answer the exact same path when requested 
+        * <code>IClasspathContainer#getPath</code>. 
+        * Indeed, the containerPath is just an indication for resolving it to an actual container object. It can be 
+        * delegated to a <code>ClasspathContainerInitializer</code>, which can be activated through the extension
+        * point "org.eclipse.jdt.core.ClasspathContainerInitializer"). 
+        * <p>
+        * In reaction to changing container values, the JavaModel will be updated to reflect the new
+        * state of the updated container. 
+        * <p>
+        * This functionality cannot be used while the resource tree is locked.
+        * <p>
+        * Classpath container values are persisted locally to the workspace, but 
+        * are not preserved from a session to another. It is thus highly recommended to register a 
+        * <code>ClasspathContainerInitializer</code> for each referenced container 
+        * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer").
+        * <p>
+        * Note: setting a container to <code>null</code> will cause it to be lazily resolved again whenever
+        * its value is required. In particular, this will cause a registered initializer to be invoked
+        * again.
+        * <p>
+        * @param containerPath - the name of the container reference, which is being updated
+        * @param affectedProjects - the set of projects for which this container is being bound
+        * @param respectiveContainers - the set of respective containers for the affected projects
+        * @param monitor a monitor to report progress
+        * 
+        * @see ClasspathContainerInitializer
+        * @see #getClasspathContainer(IPath, IJavaProject)
+        * @see IClasspathContainer
+        * @since 2.0
+        */
+//     public static void setClasspathContainer(final IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer[] respectiveContainers, IProgressMonitor monitor) throws JavaModelException {
+//
+//             if (affectedProjects.length != respectiveContainers.length) Assert.isTrue(false, "Projects and containers collections should have the same size"); //$NON-NLS-1$
+//     
+//             if (monitor != null && monitor.isCanceled()) return;
+//     
+//             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                     System.out.println("CPContainer SET  - setting container: ["+containerPath+"] for projects: {" //$NON-NLS-1$ //$NON-NLS-2$
+//                             + (Util.toString(affectedProjects, 
+//                                             new Util.Displayable(){ 
+//                                                     public String displayString(Object o) { return ((IJavaProject) o).getElementName(); }
+//                                             }))
+//                             + "} with values: " //$NON-NLS-1$
+//                             + (Util.toString(respectiveContainers, 
+//                                             new Util.Displayable(){ 
+//                                                     public String displayString(Object o) { return ((IClasspathContainer) o).getDescription(); }
+//                                             }))
+//                                     );
+//             }
+//
+//             final int projectLength = affectedProjects.length;
+//             final IJavaProject[] modifiedProjects;
+//             System.arraycopy(affectedProjects, 0, modifiedProjects = new IJavaProject[projectLength], 0, projectLength);
+//             final IClasspathEntry[][] oldResolvedPaths = new IClasspathEntry[projectLength][];
+//                     
+//             // filter out unmodified project containers
+//             int remaining = 0;
+//             for (int i = 0; i < projectLength; i++){
+//     
+//                     if (monitor != null && monitor.isCanceled()) return;
+//     
+//                     IJavaProject affectedProject = affectedProjects[i];
+//                     IClasspathContainer newContainer = respectiveContainers[i];
+//                     if (newContainer == null) newContainer = JavaModelManager.ContainerInitializationInProgress; // 30920 - prevent infinite loop
+//                     boolean found = false;
+//                     if (JavaProject.hasJavaNature(affectedProject.getProject())){
+//                             IClasspathEntry[] rawClasspath = affectedProject.getRawClasspath();
+//                             for (int j = 0, cpLength = rawClasspath.length; j <cpLength; j++) {
+//                                     IClasspathEntry entry = rawClasspath[j];
+//                                     if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && entry.getPath().equals(containerPath)){
+//                                             found = true;
+//                                             break;
+//                                     }
+//                             }
+//                     }
+//                     if (!found){
+//                             modifiedProjects[i] = null; // filter out this project - does not reference the container path, or isnt't yet Java project
+//                             JavaModelManager.containerPut(affectedProject, containerPath, newContainer);
+//                             continue;
+//                     }
+//                     IClasspathContainer oldContainer = JavaModelManager.containerGet(affectedProject, containerPath);
+//                     if (oldContainer == JavaModelManager.ContainerInitializationInProgress) {
+//                             Map previousContainerValues = (Map)JavaModelManager.PreviousSessionContainers.get(affectedProject);
+//                             if (previousContainerValues != null){
+//                                     IClasspathContainer previousContainer = (IClasspathContainer)previousContainerValues.get(containerPath);
+//                                     if (previousContainer != null) {
+//                                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                                     System.out.println("CPContainer INIT - reentering access to project container: ["+affectedProject.getElementName()+"] " + containerPath + " during its initialization, will see previous value: "+ previousContainer.getDescription()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+//                                             }
+//                                             JavaModelManager.containerPut(affectedProject, containerPath, previousContainer); 
+//                                     }
+//                                     oldContainer = null; //33695 - cannot filter out restored container, must update affected project to reset cached CP
+//                             } else {
+//                                     oldContainer = null;
+//                             }
+//                     }
+//                     if (oldContainer != null && oldContainer.equals(respectiveContainers[i])){// TODO: could improve to only compare entries
+//                             modifiedProjects[i] = null; // filter out this project - container did not change
+//                             continue;
+//                     }
+//                     remaining++; 
+//                     oldResolvedPaths[i] = affectedProject.getResolvedClasspath(true);
+//                     JavaModelManager.containerPut(affectedProject, containerPath, newContainer);
+//             }
+//             
+//             if (remaining == 0) return;
+//             
+//             // trigger model refresh
+//             try {
+//                     JavaCore.run(new IWorkspaceRunnable() {
+//                             public void run(IProgressMonitor monitor) throws CoreException {
+//                                     for(int i = 0; i < projectLength; i++){
+//             
+//                                             if (monitor != null && monitor.isCanceled()) return;
+//             
+//                                             JavaProject affectedProject = (JavaProject)modifiedProjects[i];
+//                                             if (affectedProject == null) continue; // was filtered out
+//                                             
+//                                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                                     System.out.println("CPContainer SET  - updating affected project: ["+affectedProject.getElementName()+"] due to setting container: " + containerPath); //$NON-NLS-1$ //$NON-NLS-2$
+//                                             }
+//
+//                                             // force a refresh of the affected project (will compute deltas)
+//                                             affectedProject.setRawClasspath(
+//                                                             affectedProject.getRawClasspath(),
+//                                                             SetClasspathOperation.ReuseOutputLocation,
+//                                                             monitor,
+//                                                             !ResourcesPlugin.getWorkspace().isTreeLocked(), // can save resources
+//                                                             oldResolvedPaths[i],
+//                                                             false, // updating - no validation
+//                                                             false); // updating - no need to save
+//                                     }
+//                             }
+//                     },
+//                     monitor);
+//             } catch(CoreException e) {
+//                     if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                             System.out.println("CPContainer SET  - FAILED DUE TO EXCEPTION: "+containerPath); //$NON-NLS-1$
+//                             e.printStackTrace();
+//                     }
+//                     if (e instanceof JavaModelException) {
+//                             throw (JavaModelException)e;
+//                     } else {
+//                             throw new JavaModelException(e);
+//                     }
+//             } finally {
+//                     for (int i = 0; i < projectLength; i++) {
+//                             if (respectiveContainers[i] == null) {
+//                                     JavaModelManager.containerPut(affectedProjects[i], containerPath, null); // reset init in progress marker
+//                             }
+//                     }
+//             }
+//                                     
+//     }
+
+       /**
+        * Sets the value of the given classpath variable.
+        * The path must have at least one segment.
+        * <p>
+        * This functionality cannot be used while the resource tree is locked.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        *
+        * @param variableName the name of the classpath variable
+        * @param path the path
+        * @see #getClasspathVariable
+        *
+        * @deprecated - use API with IProgressMonitor
+        */
+//     public static void setClasspathVariable(String variableName, IPath path)
+//             throws JavaModelException {
+//
+//             setClasspathVariable(variableName, path, null);
+//     }
+
+       /**
+        * Sets the value of the given classpath variable.
+        * The path must not be null.
+        * <p>
+        * This functionality cannot be used while the resource tree is locked.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        * Updating a variable with the same value has no effect.
+        *
+        * @param variableName the name of the classpath variable
+        * @param path the path
+        * @param monitor a monitor to report progress
+        * @see #getClasspathVariable
+        */
+//     public static void setClasspathVariable(
+//             String variableName,
+//             IPath path,
+//             IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             if (path == null) Assert.isTrue(false, "Variable path cannot be null"); //$NON-NLS-1$
+//             setClasspathVariables(new String[]{variableName}, new IPath[]{ path }, monitor);
+//     }
+
+       /**
+        * Sets the values of all the given classpath variables at once.
+        * Null paths can be used to request corresponding variable removal.
+        * <p>
+        * This functionality cannot be used while the resource tree is locked.
+        * <p>
+        * Classpath variable values are persisted locally to the workspace, and 
+        * are preserved from session to session.
+        * <p>
+        * Updating a variable with the same value has no effect.
+        * 
+        * @param variableNames an array of names for the updated classpath variables
+        * @param paths an array of path updates for the modified classpath variables (null
+        *       meaning that the corresponding value will be removed
+        * @param monitor a monitor to report progress
+        * @see #getClasspathVariable
+        * @since 2.0
+        */
+//     public static void setClasspathVariables(
+//             String[] variableNames,
+//             IPath[] paths,
+//             IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             if (variableNames.length != paths.length)       Assert.isTrue(false, "Variable names and paths collections should have the same size"); //$NON-NLS-1$
+//             //TODO: should check that null cannot be used as variable paths
+//             updateVariableValues(variableNames, paths, monitor);
+//     }
+
+       /* (non-Javadoc)
+        * Method declared on IExecutableExtension.
+        * Record any necessary initialization data from the plugin.
+        */
+       public void setInitializationData(
+               IConfigurationElement cfig,
+               String propertyName,
+               Object data)
+               throws CoreException {
+       }
+
+       /**
+        * Sets the current table of options. All and only the options explicitly included in the given table 
+        * are remembered; all previous option settings are forgotten, including ones not explicitly
+        * mentioned.
+        * <p>
+        * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
+        * </p>
+        * 
+        * @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
+        *   or <code>null</code> to reset all options to their default values
+        * @see JavaCore#getDefaultOptions
+        */
+       public static void setOptions(Hashtable newOptions) {
+               
+               // see #initializeDefaultPluginPreferences() for changing default settings
+               Preferences preferences = getPlugin().getPluginPreferences();
+
+               if (newOptions == null){
+                       newOptions = JavaCore.getDefaultOptions();
+               }
+               Enumeration keys = newOptions.keys();
+               while (keys.hasMoreElements()){
+                       String key = (String)keys.nextElement();
+                       if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option
+                       if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs
+                       String value = (String)newOptions.get(key);
+                       preferences.setValue(key, value);
+               }
+               
+               // persist options
+               getPlugin().savePluginPreferences();
+       }
+       
+       /**
+        * Shutdown the JavaCore plug-in.
+        * <p>
+        * De-registers the JavaModelManager as a resource changed listener and save participant.
+        * <p>
+        * @see org.eclipse.core.runtime.Plugin#shutdown()
+        */
+       public void shutdown() {
+
+               savePluginPreferences();
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               workspace.removeResourceChangeListener(JavaModelManager.getJavaModelManager().deltaProcessor);
+               workspace.removeSaveParticipant(this);
+
+               ((JavaModelManager) JavaModelManager.getJavaModelManager()).shutdown();
+       }
+
+       /**
+        * Initiate the background indexing process.
+        * This should be deferred after the plugin activation.
+        */
+//     private void startIndexing() {
+//
+//             JavaModelManager.getJavaModelManager().getIndexManager().reset();
+//     }
+
+       /**
+        * Startup of the JavaCore plug-in.
+        * <p>
+        * Registers the JavaModelManager as a resource changed listener and save participant.
+        * Starts the background indexing, and restore saved classpath variable values.
+        * <p>
+        * @see org.eclipse.core.runtime.Plugin#startup()
+        */
+       public void startup() {
+               
+               JavaModelManager manager = JavaModelManager.getJavaModelManager();
+               try {
+                       manager.configurePluginDebugOptions();
+
+                       // request state folder creation (workaround 19885)
+                       JavaCore.getPlugin().getStateLocation();
+
+                       // retrieve variable values
+                       JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(new JavaModelManager.PluginPreferencesListener());
+//             TODO khartlage temp-del
+//                     manager.loadVariablesAndContainers();
+
+                       IWorkspace workspace = ResourcesPlugin.getWorkspace();
+                       workspace.addResourceChangeListener(
+                               manager.deltaProcessor,
+                               IResourceChangeEvent.PRE_AUTO_BUILD
+                                       | IResourceChangeEvent.POST_AUTO_BUILD
+                                       | IResourceChangeEvent.POST_CHANGE
+                                       | IResourceChangeEvent.PRE_DELETE
+                                       | IResourceChangeEvent.PRE_CLOSE);
+
+//                     startIndexing();
+                       workspace.addSaveParticipant(this, manager);
+                       
+               } catch (CoreException e) {
+               } catch (RuntimeException e) {
+                       manager.shutdown();
+                       throw e;
+               }
+       }
+
+
+       /**
+        * Internal updating of a variable values (null path meaning removal), allowing to change multiple variable values at once.
+        */
+//     private static void updateVariableValues(
+//             String[] variableNames,
+//             IPath[] variablePaths,
+//             IProgressMonitor monitor) throws JavaModelException {
+//     
+//             if (monitor != null && monitor.isCanceled()) return;
+//             
+//             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                     System.out.println("CPVariable SET  - setting variables: {" + Util.toString(variableNames)  //$NON-NLS-1$
+//                             + "} with values: " + Util.toString(variablePaths)); //$NON-NLS-1$
+//             }
+//
+//             int varLength = variableNames.length;
+//             
+//             // gather classpath information for updating
+//             final HashMap affectedProjects = new HashMap(5);
+//             JavaModelManager manager = JavaModelManager.getJavaModelManager();
+//             IJavaModel model = manager.getJavaModel();
+//     
+//             // filter out unmodified variables
+//             int discardCount = 0;
+//             for (int i = 0; i < varLength; i++){
+//                     String variableName = variableNames[i];
+//                     IPath oldPath = (IPath)JavaModelManager.variableGet(variableName); // if reentering will provide previous session value 
+//                     if (oldPath == JavaModelManager.VariableInitializationInProgress){
+//                             IPath previousPath = (IPath)JavaModelManager.PreviousSessionVariables.get(variableName);
+//                             if (previousPath != null){
+//                                     if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                             System.out.println("CPVariable INIT - reentering access to variable: " + variableName+ " during its initialization, will see previous value: "+ previousPath); //$NON-NLS-1$ //$NON-NLS-2$
+//                                     }
+//                                     JavaModelManager.variablePut(variableName, previousPath); // replace value so reentering calls are seeing old value
+//                             }
+//                             oldPath = null;  //33695 - cannot filter out restored variable, must update affected project to reset cached CP
+//                     }
+//                     if (oldPath != null && oldPath.equals(variablePaths[i])){
+//                             variableNames[i] = null;
+//                             discardCount++;
+//                     }
+//             }
+//             if (discardCount > 0){
+//                     if (discardCount == varLength) return;
+//                     int changedLength = varLength - discardCount;
+//                     String[] changedVariableNames = new String[changedLength];
+//                     IPath[] changedVariablePaths = new IPath[changedLength];
+//                     for (int i = 0, index = 0; i < varLength; i++){
+//                             if (variableNames[i] != null){
+//                                     changedVariableNames[index] = variableNames[i];
+//                                     changedVariablePaths[index] = variablePaths[i];
+//                                     index++;
+//                             }
+//                     }
+//                     variableNames = changedVariableNames;
+//                     variablePaths = changedVariablePaths;
+//                     varLength = changedLength;
+//             }
+//             
+//             if (monitor != null && monitor.isCanceled()) return;
+//
+//             if (model != null) {
+//                     IJavaProject[] projects = model.getJavaProjects();
+//                     nextProject : for (int i = 0, projectLength = projects.length; i < projectLength; i++){
+//                             IJavaProject project = projects[i];
+//                                             
+//                             // check to see if any of the modified variables is present on the classpath
+//                             IClasspathEntry[] classpath = project.getRawClasspath();
+//                             for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
+//                                     
+//                                     IClasspathEntry entry = classpath[j];
+//                                     for (int k = 0; k < varLength; k++){
+//     
+//                                             String variableName = variableNames[k];                                         
+//                                             if (entry.getEntryKind() ==  IClasspathEntry.CPE_VARIABLE){
+//     
+//                                                     if (variableName.equals(entry.getPath().segment(0))){
+//                                                             affectedProjects.put(project, project.getResolvedClasspath(true));
+//                                                             continue nextProject;
+//                                                     }
+//                                                     IPath sourcePath, sourceRootPath;
+//                                                     if (((sourcePath = entry.getSourceAttachmentPath()) != null     && variableName.equals(sourcePath.segment(0)))
+//                                                             || ((sourceRootPath = entry.getSourceAttachmentRootPath()) != null      && variableName.equals(sourceRootPath.segment(0)))) {
+//     
+//                                                             affectedProjects.put(project, project.getResolvedClasspath(true));
+//                                                             continue nextProject;
+//                                                     }
+//                                             }                                                                                               
+//                                     }
+//                             }
+//                     }
+//             }
+//             // update variables
+//             for (int i = 0; i < varLength; i++){
+//                     JavaModelManager.variablePut(variableNames[i], variablePaths[i]);
+//             }
+//             final String[] dbgVariableNames = variableNames;
+//                             
+//             // update affected project classpaths
+//             if (!affectedProjects.isEmpty()) {
+//                     try {
+//                             JavaCore.run(
+//                                     new IWorkspaceRunnable() {
+//                                             public void run(IProgressMonitor monitor) throws CoreException {
+//                                                     // propagate classpath change
+//                                                     Iterator projectsToUpdate = affectedProjects.keySet().iterator();
+//                                                     while (projectsToUpdate.hasNext()) {
+//                     
+//                                                             if (monitor != null && monitor.isCanceled()) return;
+//                     
+//                                                             JavaProject project = (JavaProject) projectsToUpdate.next();
+//
+//                                                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                                                     System.out.println("CPVariable SET  - updating affected project: ["+project.getElementName()+"] due to setting variables: "+ Util.toString(dbgVariableNames)); //$NON-NLS-1$ //$NON-NLS-2$
+//                                                             }
+//                                                             
+//                                                             project
+//                                                                     .setRawClasspath(
+//                                                                             project.getRawClasspath(),
+//                                                                             SetClasspathOperation.ReuseOutputLocation,
+//                                                                             null, // don't call beginTask on the monitor (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=3717)
+//                                                                             !ResourcesPlugin.getWorkspace().isTreeLocked(), // can change resources
+//                                                                             (IClasspathEntry[]) affectedProjects.get(project),
+//                                                                             false, // updating - no validation
+//                                                                             false); // updating - no need to save
+//                                                     }
+//                                             }
+//                                     },
+//                                     monitor);
+//                     } catch (CoreException e) {
+//                             if (JavaModelManager.CP_RESOLVE_VERBOSE){
+//                                     System.out.println("CPVariable SET  - FAILED DUE TO EXCEPTION: "+Util.toString(dbgVariableNames)); //$NON-NLS-1$
+//                                     e.printStackTrace();
+//                             }
+//                             if (e instanceof JavaModelException) {
+//                                     throw (JavaModelException)e;
+//                             } else {
+//                                     throw new JavaModelException(e);
+//                             }
+//                     }
+//             }
+//     }
+}
\ No newline at end of file
index cd6ad90..86883a8 100644 (file)
@@ -157,4 +157,5 @@ public interface ITerminalSymbols {
   public final static int TokenNamenull = 1044;
   public final static int TokenNamefalse = 1045;
   public final static int TokenNametrue = 1046;
+       public final static int TokenNamethis = 1047;
 }
index e9965a9..201a295 100644 (file)
@@ -9,6 +9,11 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
+import net.sourceforge.phpdt.externaltools.internal.registry.ExternalToolVariable;
+import net.sourceforge.phpdt.externaltools.model.ToolUtil;
+import net.sourceforge.phpdt.externaltools.variable.IVariableComponent;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StackLayout;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -21,10 +26,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.List;
-import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
-import net.sourceforge.phpdt.externaltools.internal.registry.ExternalToolVariable;
-import net.sourceforge.phpdt.externaltools.model.ToolUtil;
-import net.sourceforge.phpdt.externaltools.variable.IVariableComponent;
 
 /**
  * Visual grouping of controls that allows the user to
index 0baabc1..a2bc1c0 100644 (file)
@@ -27,7 +27,6 @@ import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.resource.ImageRegistry;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IWorkbenchWindow;
 
 /**
index 368d4e7..db8de13 100644 (file)
@@ -7,6 +7,8 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
@@ -22,7 +24,6 @@ import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
-import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
 
 /**
  * Maintains the context used to expand variables. The context is based on
index e913a85..46c3b6d 100644 (file)
@@ -7,10 +7,11 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsRefreshTab;
+
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
-import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsRefreshTab;
 
 public class ProgramBuilderTabGroup extends AbstractLaunchConfigurationTabGroup {
 
index 4ef2b1a..7df974e 100644 (file)
@@ -11,6 +11,9 @@ Contributors:
 
 import java.io.File;
 
+import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsUtil;
+import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -19,8 +22,6 @@ import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
 import org.eclipse.debug.core.model.IProcess;
-import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsUtil;
-import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
 
 /**
  * Launch delegate for a program.
index 08e0978..6217692 100644 (file)
@@ -1,12 +1,13 @@
 package net.sourceforge.phpdt.externaltools.internal.program.launchConfigurations;
 
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.ResourcesPlugin;
 import net.sourceforge.phpdt.externaltools.internal.ui.FileSelectionDialog;
 import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsMainTab;
 import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 import net.sourceforge.phpdt.externaltools.model.ToolUtil;
 
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+
 public class ProgramMainTab extends ExternalToolsMainTab {
 
        /**
index 61acb17..19d81a9 100644 (file)
@@ -7,11 +7,12 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsRefreshTab;
+
 import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
 import org.eclipse.debug.ui.CommonTab;
 import org.eclipse.debug.ui.ILaunchConfigurationDialog;
 import org.eclipse.debug.ui.ILaunchConfigurationTab;
-import net.sourceforge.phpdt.externaltools.launchConfigurations.ExternalToolsRefreshTab;
 
 public class ProgramTabGroup extends AbstractLaunchConfigurationTabGroup {
 
index c4950c6..c46c7d3 100644 (file)
@@ -9,10 +9,11 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
-import org.eclipse.core.runtime.IConfigurationElement;
 import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
 import net.sourceforge.phpdt.externaltools.variable.IVariableTextExpander;
 
+import org.eclipse.core.runtime.IConfigurationElement;
+
 /**
  * Represents the variable for the argument
  */
index 1262e5a..3225808 100644 (file)
@@ -9,9 +9,10 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
-import org.eclipse.core.runtime.IConfigurationElement;
 import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 
+import org.eclipse.core.runtime.IConfigurationElement;
+
 /**
  * Registry of all available argument variables.
  */
index bd65b25..a13d06f 100644 (file)
@@ -11,13 +11,14 @@ Contributors:
 
 import java.util.HashMap;
 
+import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
+import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
+
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
 import org.eclipse.core.runtime.IExtensionPoint;
 import org.eclipse.core.runtime.IPluginRegistry;
 import org.eclipse.core.runtime.Platform;
-import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
-import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 
 /**
  * General registry reader for external tool variables.
index 1bc28c6..2f14656 100644 (file)
@@ -9,10 +9,11 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
+import net.sourceforge.phpdt.externaltools.variable.IVariableLocationExpander;
+
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IPath;
-import net.sourceforge.phpdt.externaltools.variable.IVariableLocationExpander;
-import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
 
 /**
  * Represents the variable for the path location
index 9790a43..24b2ab5 100644 (file)
@@ -9,11 +9,12 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IConfigurationElement;
 import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
 import net.sourceforge.phpdt.externaltools.variable.IVariableResourceExpander;
 
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IConfigurationElement;
+
 /**
  * Represents the variable for a refresh scope.
  */
index fb25f40..111a210 100644 (file)
@@ -9,9 +9,10 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
-import org.eclipse.core.runtime.IConfigurationElement;
 import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 
+import org.eclipse.core.runtime.IConfigurationElement;
+
 /**
  * Registry of all available refresh scope variables.
  */
index d49b0af..01f95f9 100644 (file)
@@ -3,6 +3,8 @@ package net.sourceforge.phpdt.externaltools.internal.ui;
 import java.util.ArrayList;
 import java.util.List;
 
+import net.sourceforge.phpdt.externaltools.model.StringMatcher;
+
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
@@ -20,7 +22,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.TableColumn;
-import net.sourceforge.phpdt.externaltools.model.StringMatcher;
 import org.eclipse.ui.model.WorkbenchContentProvider;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
 
index 7323dcd..b724f3b 100644 (file)
@@ -8,7 +8,6 @@ http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
 import org.eclipse.core.runtime.IStatus;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.graphics.Color;
index 73aa3ec..5b19da3 100644 (file)
@@ -7,6 +7,9 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
@@ -16,11 +19,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
 
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-
-import org.eclipse.core.runtime.IStatus;
-
 /**
  * An abstract base class for dialogs with a status bar and ok/cancel buttons.
  * The status message must be passed over as StatusInfo object and can be
index e50f493..418cef8 100644 (file)
@@ -7,9 +7,10 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
+
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.util.Assert;
-import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 
 /**
  * A settable IStatus.
index 6bc1997..c5c6df7 100644 (file)
@@ -7,6 +7,14 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
+import net.sourceforge.phpdt.externaltools.internal.dialog.ExternalToolVariableForm;
+import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsImages;
+import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
+import net.sourceforge.phpdt.externaltools.internal.registry.ExternalToolVariable;
+import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
+import net.sourceforge.phpdt.externaltools.model.ToolUtil;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
@@ -20,13 +28,6 @@ import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
-import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
-import net.sourceforge.phpdt.externaltools.internal.dialog.ExternalToolVariableForm;
-import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsImages;
-import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
-import net.sourceforge.phpdt.externaltools.internal.registry.ExternalToolVariable;
-import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
-import net.sourceforge.phpdt.externaltools.model.ToolUtil;
 
 public class ExternalToolsRefreshTab extends AbstractLaunchConfigurationTab implements IGroupDialogPage {
 
index 5529436..988f842 100644 (file)
@@ -6,7 +6,7 @@ which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
-import java.util.*;
+import java.util.Vector;
 
 /**
  * Copied from org.eclipse.jdt.internal.ui.util.StringMatcher
index 3d083c9..09dc895 100644 (file)
@@ -11,8 +11,6 @@ Contributors:
 
 import java.util.ArrayList;
 
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.MultiStatus;
 import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
 import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
 import net.sourceforge.phpdt.externaltools.internal.registry.ArgumentVariable;
@@ -21,6 +19,9 @@ import net.sourceforge.phpdt.externaltools.internal.registry.PathLocationVariabl
 import net.sourceforge.phpdt.externaltools.internal.registry.PathLocationVariableRegistry;
 import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
 
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.MultiStatus;
+
 /**
  * General utility class dealing with external tools
  */
index 8fefb33..b5eeb46 100644 (file)
@@ -9,10 +9,11 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IncrementalProjectBuilder;
-import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 
 /**
  * Represents the context the external tool is running in
index 0e5ed62..722ffb2 100644 (file)
@@ -9,9 +9,10 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
+
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
 
 /**
  * Represents the API for a client extending one of the
index 9937f78..d0ddf4a 100644 (file)
@@ -9,6 +9,10 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
+import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
+import net.sourceforge.phpdt.externaltools.model.ToolUtil;
+
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.jface.dialogs.IMessageProvider;
@@ -27,9 +31,6 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Tree;
-import net.sourceforge.phpdt.externaltools.group.IGroupDialogPage;
-import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
-import net.sourceforge.phpdt.externaltools.model.ToolUtil;
 import org.eclipse.ui.model.WorkbenchContentProvider;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
 
index 211027d..2ee69aa 100644 (file)
@@ -9,11 +9,12 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
+
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
-import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
 
 /**
  * Expands a resource type variable into the desired
index 7220f57..010cd13 100644 (file)
@@ -9,13 +9,14 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
+
 import org.eclipse.core.resources.IResource;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Label;
-import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
 
 /**
  * Visual component to edit the resource type variable
index 437ba7b..2fd80c0 100644 (file)
@@ -9,6 +9,8 @@ http://www.eclipse.org/legal/cpl-v10.html
 Contributors:
 **********************************************************************/
 
+import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
+
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.jface.dialogs.IMessageProvider;
@@ -18,7 +20,6 @@ import org.eclipse.jface.viewers.ViewerFilter;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Label;
-import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
 
 /**
  * Visual component to edit the resource type variable
index 08a9d96..624ed03 100644 (file)
@@ -17,7 +17,11 @@ package net.sourceforge.phpdt.internal.compiler;
  * @deprecated backport 1.0 internal functionality
  */
 
-import java.util.*;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.NoSuchElementException;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
 
 public class ConfigurableOption {
        private String componentName;
index 5bdc86e..21f63dd 100644 (file)
@@ -1,9 +1,6 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
-
 import java.util.List;
-import java.util.ArrayList;
 
 /**
  * Here are php comment.
index 247cd34..317b854 100644 (file)
@@ -1,9 +1,6 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
-
 import java.util.List;
-import java.util.ArrayList;
 
 /**
  * an array initializer.
index da77815..e7ed112 100644 (file)
@@ -1,7 +1,6 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
 import java.util.List;
-import java.util.ArrayList;
 
 /**
  * It will be the mother of our own ast tree for php just like the ast tree of Eclipse.
index 56a9d7f..0dbf6dd 100644 (file)
@@ -1,14 +1,15 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
 
-import java.util.ArrayList;
-import java.util.List;
-
 
 /**
  * This class is my ClassDeclaration declaration for php.
index 0457816..9669c82 100644 (file)
@@ -1,13 +1,13 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.resource.ImageDescriptor;
-import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
+import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
 
-import java.util.List;
-import java.util.ArrayList;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.Position;
 
 /**
  * a Define.
index dff3ecd..677faf5 100644 (file)
@@ -1,9 +1,6 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
-
 import java.util.List;
-import java.util.ArrayList;
 
 /**
  * An elseif statement.
index b41df20..2d3be57 100644 (file)
@@ -1,13 +1,13 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
 
-import java.util.List;
-import java.util.ArrayList;
-
 /**
  * A Field declaration.
  * This is a variable declaration for a php class
index 57c483e..8dce333 100644 (file)
@@ -1,15 +1,14 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
-import org.eclipse.core.runtime.CoreException;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
 
 import test.PHPParserSuperclass;
 
index 268f234..1cc212c 100644 (file)
@@ -1,13 +1,13 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
 
-import java.util.List;
-import java.util.ArrayList;
-
 /**
  * @author Matthieu Casanova
  */
index ad18c19..f556cc8 100644 (file)
@@ -1,16 +1,17 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
-import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
+import java.util.ArrayList;
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
+import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
+import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
-import org.eclipse.core.runtime.CoreException;
-
-import java.util.ArrayList;
-import java.util.List;
 
 import test.PHPParserSuperclass;
 
index 92dccf0..74a6c11 100644 (file)
@@ -1,14 +1,15 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
+import java.util.ArrayList;
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
+import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * It's a php document.
  * This class is an outlineable object
index dab65cb..6f8fae9 100644 (file)
@@ -1,9 +1,6 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
-
 import java.util.List;
-import java.util.ArrayList;
 
 /**
  * a php echo block.
index 7ef16a1..d268e64 100644 (file)
  ******************************************************************************/
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import test.Token;
-
 import java.util.List;
 
+import test.Token;
+
 public class StringLiteral extends Literal {
   String source;
 
index 1509737..d3f13bc 100644 (file)
@@ -2,9 +2,6 @@ package net.sourceforge.phpdt.internal.compiler.ast;
 
 import test.Token;
 
-import java.util.List;
-import java.util.ArrayList;
-
 /**
  * the true literal.
  * @author Matthieu Casanova
index 17879e5..6c1c020 100644 (file)
@@ -1,9 +1,6 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-
 import java.util.List;
-import java.util.ArrayList;
 
 /**
  * A Variable assignation.
index cba56c4..2a76db4 100644 (file)
@@ -1,9 +1,8 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
-import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
-
 import java.util.List;
-import java.util.ArrayList;
+
+import net.sourceforge.phpdt.internal.compiler.ast.declarations.VariableUsage;
 
 /**
  * A variable.
index 463128a..4adb02d 100644 (file)
@@ -1,13 +1,13 @@
 package net.sourceforge.phpdt.internal.compiler.ast;
 
+import java.util.List;
+
 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.text.Position;
 
-import java.util.List;
-import java.util.ArrayList;
-
 /**
  * A variable declaration.
  * @author Matthieu Casanova
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/env/IConstants.java
new file mode 100644 (file)
index 0000000..fd4092c
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.compiler.env;
+
+/**
+ * This interface defines constants for use by the builder / compiler interface.
+ */
+public interface IConstants {
+
+       /*
+        * Modifiers
+        */
+       int AccPublic = 0x0001;
+       int AccPrivate = 0x0002;
+       int AccProtected = 0x0004;
+       int AccStatic = 0x0008;
+       int AccFinal = 0x0010;
+//     int AccSynchronized = 0x0020;
+//     int AccVolatile = 0x0040;
+//     int AccTransient = 0x0080;
+//     int AccNative = 0x0100;
+//     int AccInterface = 0x0200;
+//     int AccAbstract = 0x0400;
+//     int AccStrictfp = 0x0800;
+
+       /*
+        * Other VM flags.
+        */
+       int AccSuper = 0x0020;
+
+       /**
+        * Extra flags for types and members.
+        */
+//     int AccSynthetic = 0x20000;
+//     int AccDeprecated = 0x100000;
+}
index 7bb9832..1c86a3f 100644 (file)
@@ -1,16 +1,12 @@
 package net.sourceforge.phpdt.internal.compiler.parser;
 
+import java.util.Enumeration;
+import java.util.Hashtable;
+
 import net.sourceforge.phpdt.internal.ui.PHPUiImages;
 
 import org.eclipse.jface.resource.ImageDescriptor;
 
-import java.util.List;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Enumeration;
-
-import test.PHPVar;
-
 /**
  * A function declaration.
  * @author khartlage
index 7c99c2d..6cb4c91 100644 (file)
@@ -11,17 +11,16 @@ Contributors:
 package net.sourceforge.phpdt.internal.compiler.parser;
 
 import java.util.ArrayList;
-import java.util.Hashtable;
 
-import net.sourceforge.phpdt.core.compiler.*;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.phpeditor.PHPString;
 
 import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.ui.texteditor.MarkerUtilities;
+
 import test.PHPParserSuperclass;
 
 public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
@@ -262,617 +261,8 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     }
     return;
 
-    //         boolean phpFound = false;
-    //         char ch2;
-    //
-    //         phpEnd = false;
-    //         try {
-    //                 if (!phpMode) {
-    //
-    //                         while (str.length() > chIndx) {
-    //                                 token = TokenNameERROR;
-    //                                 ch = str.charAt(chIndx++);
-    //
-    //                                 if (ch == '\n') {
-    //                                         rowCount++;
-    //                                 }
-    //                                 if (ch == '<') {
-    //                                         ch2 = str.charAt(chIndx++);
-    //                                         if (ch2 == '?') {
-    //                                                 ch2 = str.charAt(chIndx++);
-    //                                                 if (Character.isWhitespace(ch2)) {
-    //                                                         // php start
-    //                                                         phpMode = true;
-    //                                                         phpFound = true;
-    //                                                         break;
-    //                                                 } else if (ch2 == 'p' || ch2 == 'P') {
-    //                                                         ch2 = str.charAt(chIndx++);
-    //                                                         if (ch2 == 'h' || ch2 == 'H') {
-    //                                                                 ch2 = str.charAt(chIndx++);
-    //                                                                 if (ch2 == 'p' || ch2 == 'P') {
-    //                                                                         phpMode = true;
-    //                                                                         phpFound = true;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 chIndx--;
-    //                                                         }
-    //                                                         chIndx--;
-    //                                                 }
-    //                                                 chIndx--;
-    //                                         }
-    //                                         chIndx--;
-    //                                 }
-    //                         }
-    //
-    //                 }
-    //
-    //                 if (phpMode) {
-    //                         while (str.length() > chIndx) {
-    //                                 ch = str.charAt(chIndx++);
-    //                                 token = TokenNameERROR;
-    //                                 if (ch == '\n') {
-    //                                         rowCount++;
-    //                                         columnCount = chIndx;
-    //                                         continue; // while loop
-    //                                 }
-    //                                 if (str.length() == chIndx) {
-    //                                         phpEnd = true;
-    //                                 }
-    //                                 if (!Character.isWhitespace(ch)) {
-    //                                         if (ch == '$') {
-    //                                                 if (str.length() > chIndx) {
-    //                                                         if (str.charAt(chIndx) == '{') {
-    //                                                                 chIndx++;
-    //                                                                 token = TokenNameDOLLAROPEN;
-    //                                                                 return;
-    //                                                         }
-    //                                                 }
-    //                                                 getIdentifier();
-    //                                                 return;
-    //                                         }
-    //                                         if ((ch >= 'a' && ch <= 'z')
-    //                                                 || (ch >= 'A' && ch <= 'Z')
-    //                                                 || (ch == '_')
-    //                                                 || (ch == '$')) {
-    //                                                 getIdentifier();
-    //                                                 return;
-    //                                         }
-    //                                         if (ch >= '0' && ch <= '9') {
-    //                                                 getNumber();
-    //                                                 return;
-    //                                         }
-    //                                         if (ch == '/') {
-    //                                                 if (str.length() > chIndx) {
-    //                                                         if (str.charAt(chIndx) == '/') {
-    //                                                                 ch = '/';
-    //                                                                 chIndx++;
-    //                                                                 // read comment until end of line:
-    //                                                                 while ((str.length() > chIndx)
-    //                                                                         && (ch != '\n')) {
-    //                                                                         ch = str.charAt(chIndx++);
-    //                                                                         if (ch == '?') {
-    //                                                                                 ch2 = str.charAt(chIndx);
-    //                                                                                 if (ch2 == '>') {
-    //                                                                                         chIndx++;
-    //                                                                                         token = TokenNameHTML;
-    //                                                                                         // php end
-    //                                                                                         phpMode = false;
-    //                                                                                         phpEnd = true;
-    //                                                                                         return;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                 }
-    //                                                                 rowCount++;
-    //                                                                 continue;
-    //
-    //                                                         } else if (str.charAt(chIndx) == '*') {
-    //                                                                 chIndx++;
-    //                                                                 // multi line comment:
-    //                                                                 while (str.length() > chIndx) {
-    //                                                                         if (str.charAt(chIndx) == '*'
-    //                                                                                 && (str.length() > (chIndx + 1))
-    //                                                                                 && str.charAt(chIndx + 1) == '/') {
-    //                                                                                 chIndx += 2;
-    //                                                                                 break;
-    //                                                                         }
-    //                                                                         ch = str.charAt(chIndx++);
-    //                                                                         if (ch == '\n') {
-    //                                                                                 rowCount++;
-    //                                                                                 columnCount = chIndx;
-    //                                                                         }
-    //                                                                 }
-    //                                                                 continue;
-    //                                                         }
-    //                                                 }
-    //                                         } else if (ch == '#') {
-    //                                                 // read comment until end of line:
-    //                                                 while ((str.length() > chIndx) && (ch != '\n')) {
-    //                                                         ch = str.charAt(chIndx++);
-    //                                                         if (ch == '?') {
-    //                                                                 ch2 = str.charAt(chIndx);
-    //                                                                 if (ch2 == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameHTML;
-    //                                                                         // php end
-    //                                                                         phpMode = false;
-    //                                                                         phpEnd = true;
-    //                                                                         return;
-    //                                                                 }
-    //                                                         }
-    //                                                 }
-    //                                                 rowCount++;
-    //                                                 continue;
-    //
-    //                                         } else if (ch == '"') {
-    //                                                 getString(
-    //                                                         '"',
-    //                                                         TokenNameStringInterpolated,
-    //                                                         "Open string character '\"' at end of file.");
-    //                                                 return;
-    //                                         } else if (ch == '\'') {
-    //                                                 getString(
-    //                                                         '\'',
-    //                                                         TokenNameStringConstant,
-    //                                                         "Open string character \"'\" at end of file.");
-    //                                                 return;
-    //                                         } else if (ch == '`') {
-    //                                                 getString(
-    //                                                         '`',
-    //                                                         TokenNameStringConstant,
-    //                                                         "Open string character \"`\" at end of file.");
-    //                                                 setMarker(
-    //                                                         "Other string delimiters prefered (found \"`\").",
-    //                                                         rowCount,
-    //                                                         PHPParser.INFO);
-    //                                                 return;
-    //                                         }
-    //
-    //                                         switch (ch) {
-    //
-    //                                                 case '(' :
-    //                                                         token = TokenNameLPAREN;
-    //
-    //                                                         break;
-    //                                                 case ')' :
-    //                                                         token = TokenNameRPAREN;
-    //
-    //                                                         break;
-    //                                                 case '{' :
-    //                                                         token = TokenNameLBRACE;
-    //
-    //                                                         break;
-    //                                                 case '}' :
-    //                                                         token = TokenNameRBRACE;
-    //
-    //                                                         break;
-    //                                                 case '[' :
-    //                                                         token = TokenNameLBRACKET;
-    //
-    //                                                         break;
-    //                                                 case ']' :
-    //                                                         token = TokenNameRBRACKET;
-    //
-    //                                                         break;
-    //                                                 case ',' :
-    //                                                         token = TokenNameCOMMA;
-    //
-    //                                                         break;
-    //                                                 case '?' :
-    //                                                         token = TokenNameQUESTION;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameHTML;
-    //                                                                         // php end
-    //                                                                         phpMode = false;
-    //                                                                         phpEnd = true;
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '@' :
-    //                                                         token = TokenNameAT;
-    //                                                         break;
-    //                                                 case '~' :
-    //                                                         token = TokenNameTWIDDLE;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameTWIDDLE_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case '.' :
-    //                                                         token = TokenNameDOT;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameDOT_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '"' :
-    //                                                         token = TokenNameStringLiteral;
-    //
-    //                                                         break;
-    //                                                 case '%' :
-    //                                                         token = TokenNameREMAINDER;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameREMAINDER_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case ';' :
-    //                                                         token = TokenNameSEMICOLON;
-    //
-    //                                                         break;
-    //                                                 case '^' :
-    //                                                         token = TokenNameXOR;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameXOR_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case '/' :
-    //                                                         token = TokenNameDIVIDE;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameDIVIDE_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '*' :
-    //                                                         token = TokenNameMULTIPLY;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '*') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameXOR;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMULTIPLY_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '+' :
-    //                                                         token = TokenNamePLUS;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '+') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNamePLUS_PLUS;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNamePLUS_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case '-' :
-    //                                                         token = TokenNameMINUS;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '-') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMINUS_MINUS;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMINUS_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMINUS_GREATER;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '=' :
-    //                                                         token = TokenNameEQUAL;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 ch = str.charAt(chIndx);
-    //
-    //                                                                 if (ch == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameEQUAL_EQUAL;
-    //                                                                         if (str.length() > chIndx) {
-    //                                                                                 ch = str.charAt(chIndx);
-    //
-    //                                                                                 if (ch == '=') {
-    //                                                                                         chIndx++;
-    //                                                                                         token =
-    //                                                                                                 TokenNameEQUAL_EQUAL_EQUAL;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (ch == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameEQUAL_GREATER;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '!' :
-    //                                                         token = TokenNameNOT;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameNOT_EQUAL;
-    //                                                                         if (str.length() > chIndx) {
-    //                                                                                 ch = str.charAt(chIndx);
-    //
-    //                                                                                 if (ch == '=') {
-    //                                                                                         chIndx++;
-    //                                                                                         token =
-    //                                                                                                 TokenNameNOT_EQUAL_EQUAL;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '>' :
-    //                                                         token = TokenNameGREATER;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameGREATER_EQUAL;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameRIGHT_SHIFT;
-    //                                                                         if (str.length() > chIndx) {
-    //                                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                                         chIndx++;
-    //                                                                                         token =
-    //                                                                                                 TokenNameRIGHT_SHIFT_EQUAL;
-    //                                                                                         break;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '<' :
-    //                                                         token = TokenNameLESS;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameLESS_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '<') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameLEFT_SHIFT;
-    //                                                                         if (str.charAt(chIndx) == '<') {
-    //                                                                                 // heredoc
-    //                                                                                 int startRow = rowCount;
-    //                                                                                 if (str.length() > chIndx) {
-    //
-    //                                                                                         ch = str.charAt(++chIndx);
-    //                                                                                         if ((ch >= 'a' && ch <= 'z')
-    //                                                                                                 || (ch >= 'A' && ch <= 'Z')
-    //                                                                                                 || (ch == '_')) {
-    //                                                                                                 chIndx++;
-    //                                                                                                 getIdentifier();
-    //                                                                                                 token =
-    //                                                                                                         TokenNameStringConstant;
-    //                                                                                                 while (str.length()
-    //                                                                                                         > chIndx) {
-    //                                                                                                         ch =
-    //                                                                                                                 str.charAt(
-    //                                                                                                                         chIndx++);
-    //                                                                                                         if (ch == '\n') {
-    //                                                                                                                 if (str.length()
-    //                                                                                                                         >= chIndx
-    //                                                                                                                                 + identifier
-    //                                                                                                                                         .length()) {
-    //                                                                                                                         if (str
-    //                                                                                                                                 .substring(
-    //                                                                                                                                         chIndx,
-    //                                                                                                                                         chIndx
-    //                                                                                                                                                 + identifier
-    //                                                                                                                                                         .length())
-    //                                                                                                                                 .equals(identifier)) {
-    //                                                                                                                                 chIndx
-    //                                                                                                                                         += identifier
-    //                                                                                                                                                 .length();
-    //                                                                                                                                 return;
-    //                                                                                                                         }
-    //                                                                                                                 }
-    //                                                                                                         }
-    //                                                                                                 }
-    //                                                                                         }
-    //                                                                                 }
-    //                                                                                 throwSyntaxError(
-    //                                                                                         "Open heredoc syntax after operator '<<<'.",
-    //                                                                                         startRow);
-    //                                                                         } else if (str.charAt(chIndx) == '=') {
-    //                                                                                 chIndx++;
-    //                                                                                 token = TokenNameLEFT_SHIFT_EQUAL;
-    //                                                                                 break;
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //
-    //                                                 case '|' :
-    //                                                         token = TokenNameOR;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '|') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameOR_OR;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameOR_EQUAL;
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '&' :
-    //                                                         token = TokenNameAND;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '&') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameAND_AND;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameAND_EQUAL;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 break;
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case ':' :
-    //                                                         token = TokenNameCOLON;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == ':') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameCOLON_COLON;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                         //              case '#' :
-    //                                                         //                token = TokenNameHASH;
-    //                                                         //
-    //                                                         //                break;
-    //                                                         //          case '@' :
-    //                                                         //            token = TokenNameAT;
-    //                                                         //
-    //                                                         //            break;
-    //                                                 default :
-    //                                                         throwSyntaxError(
-    //                                                                 "unexpected character: '" + ch + "'");
-    //                                         }
-    //
-    //                                         if (token == TokenNameERROR) {
-    //                                                 throwSyntaxError("token not found");
-    //                                         }
-    //
-    //                                         return;
-    //                                 }
-    //                         }
-    //                 }
-    //         } catch (StringIndexOutOfBoundsException e) {
-    //                 // catched from charAt
-    //         }
-    //
-    //         chIndx = str.length() + 1;
-    //         ch = ' ';
-    //         token = TokenNameEOF;
-    //         phpEnd = true;
-    //         //PHPString temp;
-    //         //    if (phpList != null) {
-    //         //      if (currentPHPString < phpList.size()) {
-    //         //        token = TokenNameUNDEFINED;
-    //         //        temp = (PHPString) phpList.get(currentPHPString++);
-    //         //        this.str = temp.getPHPString();
-    //         //        this.token = TokenNameEOF;
-    //         //        this.chIndx = 0;
-    //         //        this.rowCount = temp.getLineNumber();
-    //         //        this.columnCount = 0;
-    //         //        getNextToken();
-    //         //        phpEnd = true;
-    //         //      } else {
-    //         //        token = TokenNameUNDEFINED;
-    //         //        return;
-    //         //      }
-    //         //    }
   }
 
-  //   /**
-  //    * Get an identifier.
-  //    */
-  //   private void getIdentifier() {
-  //           //  StringBuffer ident = new StringBuffer();
-  //           int startPosition = chIndx - 1;
-  //           //    ident.append(ch);
-  //           if (ch == '$') {
-  //                   getChar();
-  //                   // attention recursive call:
-  //                   getIdentifier();
-  //                   token = TokenNameVariable;
-  //                   return;
-  //           } else {
-  //                   token = TokenNameIdentifier;
-  //           }
-  //
-  //           getChar();
-  //
-  //           //this will read the buffer until the next character is a forbidden character for identifier
-  //           while ((ch >= 'a' && ch <= 'z')
-  //                   || (ch >= 'A' && ch <= 'Z')
-  //                   || (ch >= '0' && ch <= '9')
-  //                   || (ch == '_')) {
-  //                   //    ident.append(ch);
-  //                   getChar();
-  //           }
-  //           int endPosition = chIndx--;
-  //           int length = (--endPosition) - startPosition;
-  //
-  //           identifier = str.substring(startPosition, endPosition);
-  //           // System.out.println(identifier);
-  //
-  //           // determine if this identitfer is a keyword
-  //           // @todo improve this in future version
-  //           Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
-  //           if (i != null) {
-  //                   token = i.intValue();
-  //           }
-  //   }
-
   /**
    * Get a number.
    * if it's a <code>double</code> the number will be stored in <code>doubleNumber</code> and the token will have the
@@ -1391,6 +781,10 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     return outlineInfo;
   }
 
+  private boolean isVariable() {
+    return token == TokenNameVariable || token == TokenNamethis;
+  }
+
   private void parseDeclarations(PHPOutlineInfo outlineInfo, OutlineableWithChildren current, boolean goBack) {
     char[] ident;
     //   PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
@@ -1423,6 +817,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
               } else {
                 switch (token) {
                   case TokenNameVariable :
+                  case TokenNamethis :
                     current.add(new PHPVarDeclaration(current, variableName,
                     //                      chIndx - ident.length,
                     scanner.getCurrentTokenStartPosition(), new String(ident)));
@@ -1548,6 +943,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
       if ((token == TokenNameRBRACE)
         || (token == TokenNamecase)
         || (token == TokenNamedefault)
+        || (token == TokenNameelse)
         || (token == TokenNameelseif)
         || (token == TokenNameendif)
         || (token == TokenNameendfor)
@@ -1989,6 +1385,9 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
           constant();
         }
       } else {
+        if (token == TokenNamethis) {
+          throwSyntaxError("Reserved word '$this' not allowed after keyword 'var'.");
+        }
         throwSyntaxError("Variable expected after keyword 'var'.");
       }
       if (token != TokenNameCOMMA) {
@@ -2053,7 +1452,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     //variable-reference
     if (token == TokenNameAND) {
       getNextToken();
-      if (token == TokenNameVariable) {
+      if (isVariable()) {
         getNextToken();
       } else {
         throwSyntaxError("Variable expected after reference operator '&'.");
@@ -2068,6 +1467,9 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
       }
       return;
     }
+    if (token == TokenNamethis) {
+      throwSyntaxError("Reserved word '$this' not allowed in parameter declaration.");
+    }
   }
 
   private void labeledStatementList() throws CoreException {
@@ -2077,7 +1479,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     do {
       if (token == TokenNamecase) {
         getNextToken();
-        constant();
+        expression(); //constant();
         if (token == TokenNameCOLON) {
           getNextToken();
           if (token == TokenNamecase || token == TokenNamedefault) { // empty case statement ?
@@ -2173,26 +1575,30 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
     if (token == TokenNameCOLON) {
       getNextToken();
-      statementList();
-      switch (token) {
-        case TokenNameelse :
-          getNextToken();
-          if (token == TokenNameCOLON) {
+      if (token != TokenNameendif) {
+        statementList();
+        switch (token) {
+          case TokenNameelse :
             getNextToken();
-            statementList();
-          } else {
-            if (token == TokenNameif) { //'else if'
+            if (token == TokenNameCOLON) {
               getNextToken();
-              elseifStatementList();
+              if (token != TokenNameendif) {
+                statementList();
+              }
             } else {
-              throwSyntaxError("':' expected after 'else'.");
+              if (token == TokenNameif) { //'else if'
+                getNextToken();
+                elseifStatementList();
+              } else {
+                throwSyntaxError("':' expected after 'else'.");
+              }
             }
-          }
-          break;
-        case TokenNameelseif :
-          getNextToken();
-          elseifStatementList();
-          break;
+            break;
+          case TokenNameelseif :
+            getNextToken();
+            elseifStatementList();
+            break;
+        }
       }
 
       if (token != TokenNameendif) {
@@ -2235,7 +1641,9 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
           getNextToken();
           if (token == TokenNameCOLON) {
             getNextToken();
-            statementList();
+            if (token != TokenNameendif) {
+              statementList();
+            }
             return;
           } else {
             if (token == TokenNameif) { //'else if'
@@ -2258,7 +1666,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     if (token == TokenNameLPAREN) {
       getNextToken();
       expression();
-      if (token != TokenNameLPAREN) {
+      if (token != TokenNameRPAREN) {
         throwSyntaxError("')' expected in else-if-statement.");
       }
       getNextToken();
@@ -2266,7 +1674,9 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
         throwSyntaxError("':' expected in else-if-statement.");
       }
       getNextToken();
-      statementList();
+      if (token != TokenNameendif) {
+        statementList();
+      }
     }
   }
 
@@ -2471,6 +1881,7 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
         getNextToken();
         break;
       case TokenNameVariable :
+      case TokenNamethis :
         ident = scanner.getCurrentIdentifierSource();
         getNextToken();
         if (token == TokenNameLBRACE) {
@@ -2655,16 +2066,14 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
                   throwSyntaxError("] expected after '->'.");
                 }
                 getNextToken();
-              }
-              if (token == TokenNameLPAREN) {
+              } else if (token == TokenNameLPAREN) {
                 getNextToken();
                 expressionList();
                 if (token != TokenNameRPAREN) {
                   throwSyntaxError(") expected after '->'.");
                 }
                 getNextToken();
-              }
-              if (token == TokenNameLBRACE) {
+              } else if (token == TokenNameLBRACE) {
                 getNextToken();
                 expression();
                 if (token != TokenNameRBRACE) {
@@ -2701,7 +2110,14 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
         // '@' '&' '*' '+' '-' '~' '!'
       case TokenNameAT :
         getNextToken();
-        castExpression();
+        if (token == TokenNameinclude
+          || token == TokenNameinclude_once
+          || token == TokenNamerequire
+          || token == TokenNamerequire_once) {
+          statement();
+        } else {
+          postfixExpression(); //  castExpression();
+        }
         break;
       case TokenNameAND :
         getNextToken();
@@ -2744,27 +2160,6 @@ public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
     unaryExpression();
   }
 
-  //  private void typeName() throws CoreException {
-  //    //'string' 'unset' 'array' 'object'
-  //    //'bool' 'boolean'
-  //    //'real' 'double' 'float'
-  //    //'int' 'integer'
-  //    String identifier = "";
-  //    if (token == TokenNameIdentifier) {
-  //      char[] ident = scanner.getCurrentIdentifierSource();
-  //      identifier = new String(ident);
-  //      String str = identifier.toLowerCase();
-  //      getNextToken();
-  //      for (int i = 0; i < PHP_TYPES.length; i++) {
-  //        if (PHP_TYPES[i].equals(str)) {
-  //          return;
-  //        }
-  //      }
-  //    }
-  //    throwSyntaxError(
-  //      "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
-  //  }
-
   private void assignExpression() throws CoreException {
     castExpression();
     if (token == TokenNameEQUAL) { // =
index 3391262..2206c00 100644 (file)
@@ -14,7 +14,9 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import net.sourceforge.phpdt.core.compiler.*;
+import net.sourceforge.phpdt.core.compiler.IScanner;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
 
 public class Scanner implements IScanner, ITerminalSymbols {
@@ -218,8 +220,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public int getCurrentTokenEndPosition() {
     return this.currentPosition - 1;
   }
-  
-  
+
   public final char[] getCurrentTokenSource() {
     // Return the token REAL source (aka unicodes are precomputed)
 
@@ -277,17 +278,17 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public int getCurrentTokenStartPosition() {
     return this.startPosition;
   }
-  
-       public final char[] getCurrentStringLiteralSource() {
-               // Return the token REAL source (aka unicodes are precomputed)
 
-               char[] result;
+  public final char[] getCurrentStringLiteralSource() {
+    // Return the token REAL source (aka unicodes are precomputed)
+
+    char[] result;
 
-               int length;
-               System.arraycopy(source, startPosition+1, result = new char[length = currentPosition - startPosition - 2], 0, length);
-               //    }
-               return result;
-       }
+    int length;
+    System.arraycopy(source, startPosition + 1, result = new char[length = currentPosition - startPosition - 2], 0, length);
+    //    }
+    return result;
+  }
 
   /*
    * Search the source position corresponding to the end of a given line number
@@ -865,8 +866,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 return TokenNameTWIDDLE_EQUAL;
               return TokenNameTWIDDLE;
             case '!' :
-              if (getNextChar('='))
+              if (getNextChar('=')) {
+                if (getNextChar('=')) {
+                  return TokenNameNOT_EQUAL_EQUAL;
+                }
                 return TokenNameNOT_EQUAL;
+              }
               return TokenNameNOT;
             case '*' :
               if (getNextChar('='))
@@ -946,8 +951,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 return TokenNameGREATER;
               }
             case '=' :
-              if (getNextChar('='))
+              if (getNextChar('=')) {
+                if (getNextChar('=')) {
+                  return TokenNameEQUAL_EQUAL_EQUAL;
+                }
                 return TokenNameEQUAL_EQUAL;
+              }
               if (getNextChar('>'))
                 return TokenNameEQUAL_GREATER;
               return TokenNameEQUAL;
@@ -2538,6 +2547,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
     };
 
     if (isVariable) {
+      if (new String(getCurrentTokenSource()).equals("$this")) {
+        return TokenNamethis;
+      }
       return TokenNameVariable;
     }
     int index, length;
@@ -3229,7 +3241,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
 
     switch (act) {
       case TokenNameERROR :
-        return "ScannerError(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
+        return "ScannerError"; // + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
       case TokenNameStopPHP :
         return "StopPHP(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameIdentifier :
@@ -3310,6 +3322,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "var"; //$NON-NLS-1$
       case TokenNamewhile :
         return "while"; //$NON-NLS-1$
+      case TokenNamethis :
+        return "$this"; //$NON-NLS-1$
       case TokenNameIntegerLiteral :
         return "Integer(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameDoubleLiteral :
@@ -3329,6 +3343,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "--"; //$NON-NLS-1$
       case TokenNameEQUAL_EQUAL :
         return "=="; //$NON-NLS-1$
+      case TokenNameEQUAL_EQUAL_EQUAL :
+        return "==="; //$NON-NLS-1$
       case TokenNameEQUAL_GREATER :
         return "=>"; //$NON-NLS-1$
       case TokenNameLESS_EQUAL :
@@ -3337,6 +3353,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return ">="; //$NON-NLS-1$
       case TokenNameNOT_EQUAL :
         return "!="; //$NON-NLS-1$
+      case TokenNameNOT_EQUAL_EQUAL :
+        return "!=="; //$NON-NLS-1$
       case TokenNameLEFT_SHIFT :
         return "<<"; //$NON-NLS-1$
       case TokenNameRIGHT_SHIFT :
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/Util.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/Util.java
new file mode 100644 (file)
index 0000000..9ece7dc
--- /dev/null
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.compiler.util;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+
+public class Util {
+
+       public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+       public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray();
+       public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$
+       public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$
+               
+       private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
+       private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
+       private static final int DEFAULT_READING_SIZE = 8192;
+       
+       /* Bundle containing messages */
+       protected static ResourceBundle bundle;
+       private final static String bundleName =
+               "net.sourceforge.phpdt.internal.compiler.util.messages"; //$NON-NLS-1$
+       static {
+               relocalize();
+       }
+       /**
+        * Lookup the message with the given ID in this catalog and bind its
+        * substitution locations with the given strings.
+        */
+       public static String bind(String id, String binding1, String binding2) {
+               return bind(id, new String[] { binding1, binding2 });
+       }
+       /**
+        * Lookup the message with the given ID in this catalog and bind its
+        * substitution locations with the given string.
+        */
+       public static String bind(String id, String binding) {
+               return bind(id, new String[] { binding });
+       }
+       /**
+        * Lookup the message with the given ID in this catalog and bind its
+        * substitution locations with the given string values.
+        */
+       public static String bind(String id, String[] bindings) {
+               if (id == null)
+                       return "No message available"; //$NON-NLS-1$
+               String message = null;
+               try {
+                       message = bundle.getString(id);
+               } catch (MissingResourceException e) {
+                       // If we got an exception looking for the message, fail gracefully by just returning
+                       // the id we were looking for.  In most cases this is semi-informative so is not too bad.
+                       return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
+               }
+               // for compatibility with MessageFormat which eliminates double quotes in original message
+               char[] messageWithNoDoubleQuotes =
+                       CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
+               message = new String(messageWithNoDoubleQuotes);
+
+               if (bindings == null)
+                       return message;
+
+               int length = message.length();
+               int start = -1;
+               int end = length;
+               StringBuffer output = new StringBuffer(80);
+               while (true) {
+                       if ((end = message.indexOf('{', start)) > -1) {
+                               output.append(message.substring(start + 1, end));
+                               if ((start = message.indexOf('}', end)) > -1) {
+                                       int index = -1;
+                                       try {
+                                               index = Integer.parseInt(message.substring(end + 1, start));
+                                               output.append(bindings[index]);
+                                       } catch (NumberFormatException nfe) {
+                                               output.append(message.substring(end + 1, start + 1));
+                                       } catch (ArrayIndexOutOfBoundsException e) {
+                                               output.append("{missing " + Integer.toString(index) + "}");     //$NON-NLS-2$ //$NON-NLS-1$
+                                       }
+                               } else {
+                                       output.append(message.substring(end, length));
+                                       break;
+                               }
+                       } else {
+                               output.append(message.substring(start + 1, length));
+                               break;
+                       }
+               }
+               return output.toString();
+       }
+       /**
+        * Lookup the message with the given ID in this catalog 
+        */
+       public static String bind(String id) {
+               return bind(id, (String[]) null);
+       }
+       /**
+        * Creates a NLS catalog for the given locale.
+        */
+       public static void relocalize() {
+               try {
+                       bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
+               } catch(MissingResourceException e) {
+                       System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
+                       throw e;
+               }
+       }
+       /**
+        * Returns the given bytes as a char array using a given encoding (null means platform default).
+        */
+       public static char[] bytesToChar(byte[] bytes, String encoding) throws IOException {
+
+               return getInputStreamAsCharArray(new ByteArrayInputStream(bytes), bytes.length, encoding);
+
+       }
+       /**
+        * Returns the contents of the given file as a byte array.
+        * @throws IOException if a problem occured reading the file.
+        */
+       public static byte[] getFileByteContent(File file) throws IOException {
+               InputStream stream = null;
+               try {
+                       stream = new BufferedInputStream(new FileInputStream(file));
+                       return getInputStreamAsByteArray(stream, (int) file.length());
+               } finally {
+                       if (stream != null) {
+                               try {
+                                       stream.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+       }
+       /**
+        * Returns the contents of the given file as a char array.
+        * When encoding is null, then the platform default one is used
+        * @throws IOException if a problem occured reading the file.
+        */
+       public static char[] getFileCharContent(File file, String encoding) throws IOException {
+               InputStream stream = null;
+               try {
+                       stream = new BufferedInputStream(new FileInputStream(file));
+                       return Util.getInputStreamAsCharArray(stream, (int) file.length(), encoding);
+               } finally {
+                       if (stream != null) {
+                               try {
+                                       stream.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+       }
+       /**
+        * Returns the given input stream's contents as a byte array.
+        * If a length is specified (ie. if length != -1), only length bytes
+        * are returned. Otherwise all bytes in the stream are returned.
+        * Note this doesn't close the stream.
+        * @throws IOException if a problem occured reading the stream.
+        */
+       public static byte[] getInputStreamAsByteArray(InputStream stream, int length)
+               throws IOException {
+               byte[] contents;
+               if (length == -1) {
+                       contents = new byte[0];
+                       int contentsLength = 0;
+                       int amountRead = -1;
+                       do {
+                               int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
+                               
+                               // resize contents if needed
+                               if (contentsLength + amountRequested > contents.length) {
+                                       System.arraycopy(
+                                               contents,
+                                               0,
+                                               contents = new byte[contentsLength + amountRequested],
+                                               0,
+                                               contentsLength);
+                               }
+
+                               // read as many bytes as possible
+                               amountRead = stream.read(contents, contentsLength, amountRequested);
+
+                               if (amountRead > 0) {
+                                       // remember length of contents
+                                       contentsLength += amountRead;
+                               }
+                       } while (amountRead != -1); 
+
+                       // resize contents if necessary
+                       if (contentsLength < contents.length) {
+                               System.arraycopy(
+                                       contents,
+                                       0,
+                                       contents = new byte[contentsLength],
+                                       0,
+                                       contentsLength);
+                       }
+               } else {
+                       contents = new byte[length];
+                       int len = 0;
+                       int readSize = 0;
+                       while ((readSize != -1) && (len != length)) {
+                               // See PR 1FMS89U
+                               // We record first the read size. In this case len is the actual read size.
+                               len += readSize;
+                               readSize = stream.read(contents, len, length - len);
+                       }
+               }
+
+               return contents;
+       }
+       /**
+        * Returns the given input stream's contents as a character array.
+        * If a length is specified (ie. if length != -1), only length chars
+        * are returned. Otherwise all chars in the stream are returned.
+        * Note this doesn't close the stream.
+        * @throws IOException if a problem occured reading the stream.
+        */
+       public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding)
+               throws IOException {
+               InputStreamReader reader = null;
+               reader = encoding == null
+                                       ? new InputStreamReader(stream)
+                                       : new InputStreamReader(stream, encoding);
+               char[] contents;
+               if (length == -1) {
+                       contents = CharOperation.NO_CHAR;
+                       int contentsLength = 0;
+                       int amountRead = -1;
+                       do {
+                               int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
+
+                               // resize contents if needed
+                               if (contentsLength + amountRequested > contents.length) {
+                                       System.arraycopy(
+                                               contents,
+                                               0,
+                                               contents = new char[contentsLength + amountRequested],
+                                               0,
+                                               contentsLength);
+                               }
+
+                               // read as many chars as possible
+                               amountRead = reader.read(contents, contentsLength, amountRequested);
+
+                               if (amountRead > 0) {
+                                       // remember length of contents
+                                       contentsLength += amountRead;
+                               }
+                       } while (amountRead != -1);
+
+                       // resize contents if necessary
+                       if (contentsLength < contents.length) {
+                               System.arraycopy(
+                                       contents,
+                                       0,
+                                       contents = new char[contentsLength],
+                                       0,
+                                       contentsLength);
+                       }
+               } else {
+                       contents = new char[length];
+                       int len = 0;
+                       int readSize = 0;
+                       while ((readSize != -1) && (len != length)) {
+                               // See PR 1FMS89U
+                               // We record first the read size. In this case len is the actual read size.
+                               len += readSize;
+                               readSize = reader.read(contents, len, length - len);
+                       }
+                       // See PR 1FMS89U
+                       // Now we need to resize in case the default encoding used more than one byte for each
+                       // character
+                       if (len != length)
+                               System.arraycopy(contents, 0, (contents = new char[len]), 0, len);
+               }
+
+               return contents;
+       }
+       
+       /**
+        * Returns the contents of the given zip entry as a byte array.
+        * @throws IOException if a problem occured reading the zip entry.
+        */
+       public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip)
+               throws IOException {
+
+               InputStream stream = null;
+               try {
+                       stream = new BufferedInputStream(zip.getInputStream(ze));
+                       return getInputStreamAsByteArray(stream, (int) ze.getSize());
+               } finally {
+                       if (stream != null) {
+                               try {
+                                       stream.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+       }
+       /**
+        * Returns true iff str.toLowerCase().endsWith(".jar") || str.toLowerCase().endsWith(".zip")
+        * implementation is not creating extra strings.
+        */
+       public final static boolean isArchiveFileName(String name) {
+               int nameLength = name == null ? 0 : name.length();
+               int suffixLength = SUFFIX_JAR.length;
+               if (nameLength < suffixLength) return false;
+
+               // try to match as JAR file
+               for (int i = 0; i < suffixLength; i++) {
+                       char c = name.charAt(nameLength - i - 1);
+                       int suffixIndex = suffixLength - i - 1;
+                       if (c != SUFFIX_jar[suffixIndex] && c != SUFFIX_JAR[suffixIndex]) {
+
+                               // try to match as ZIP file
+                               suffixLength = SUFFIX_ZIP.length;
+                               if (nameLength < suffixLength) return false;
+                               for (int j = 0; j < suffixLength; j++) {
+                                       c = name.charAt(nameLength - j - 1);
+                                       suffixIndex = suffixLength - j - 1;
+                                       if (c != SUFFIX_zip[suffixIndex] && c != SUFFIX_ZIP[suffixIndex]) return false;
+                               }
+                               return true;
+                       }
+               }
+               return true;            
+       }       
+       /**
+        * Returns true iff str.toLowerCase().endsWith(".class")
+        * implementation is not creating extra strings.
+        */
+       public final static boolean isClassFileName(String name) {
+               int nameLength = name == null ? 0 : name.length();
+               int suffixLength = SUFFIX_CLASS.length;
+               if (nameLength < suffixLength) return false;
+
+               for (int i = 0; i < suffixLength; i++) {
+                       char c = name.charAt(nameLength - i - 1);
+                       int suffixIndex = suffixLength - i - 1;
+                       if (c != SUFFIX_class[suffixIndex] && c != SUFFIX_CLASS[suffixIndex]) return false;
+               }
+               return true;            
+       }       
+       /**
+        * Returns true iff str.toLowerCase().endsWith(".java")
+        * implementation is not creating extra strings.
+        */
+       public final static boolean isJavaFileName(String name) {
+               int nameLength = name == null ? 0 : name.length();
+               int suffixLength = SUFFIX_JAVA.length;
+               if (nameLength < suffixLength) return false;
+
+               for (int i = 0; i < suffixLength; i++) {
+                       char c = name.charAt(nameLength - i - 1);
+                       int suffixIndex = suffixLength - i - 1;
+                       if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false;
+               }
+               return true;            
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/util/messages.properties
new file mode 100644 (file)
index 0000000..99a6994
--- /dev/null
@@ -0,0 +1,68 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+### Eclipse Java Core Compiler messages.
+
+### compilation
+compilation.unresolvedProblem = Unresolved compilation problem: \n
+compilation.unresolvedProblems = Unresolved compilation problems: \n
+compilation.request = request {0}/{1} : {2}
+compilation.process = process {0}/{1} : {2}
+compilation.done = done {0}/{1} : {2}
+compilation.units = {0} units compiled
+compilation.unit = {0} unit compiled
+compilation.internalError = Internal compiler error
+
+### output
+output.isFile =  The outDir is a file : {0}
+output.isFileNotDirectory = The outDir is a file not a directory.
+output.dirName =  The output dir name is : {0}
+output.notValidAll =  The outDir is not a valid directory name. All the directories cannot be created.
+output.fileName =  file name : {0}
+output.notValid = The outDir is not a valid directory name. The directory cannot be created.
+
+### problem
+problem.noSourceInformation = \n!! no source information available !!
+problem.atLine = (at line {0})
+
+### abort
+abort.invalidAttribute = SANITY CHECK: Invalid attribute for local variable {0}
+abort.missingCode = Missing code implementation in the compiler
+abort.againstSourceModel = Cannot compile against source model {0} issued from {1}
+
+### accept
+accept.cannot = Cannot accept the compilation unit: 
+
+### parser
+parser.incorrectPath = The path for the javadcl.java file is incorrect
+parser.moveFiles = MOVE FILES IN THE Runtime DIRECTORY OF Parser.class
+parser.syntaxRecovery = SYNTAX RECOVERY
+parser.regularParse = REGULAR PARSE
+parser.missingFile = missing file {0}
+parser.corruptedFile = corrupted file {0}
+
+### binding
+binding.subclass = anonymous subclass of {0}
+binding.implementation = anonymous implementation of {0}
+
+### ast
+ast.missingStatement = Missing statement code generation implementation
+ast.variableShouldProvide = Assignment variable should provide an implementation for flow analysis
+ast.compoundPreShouldProvide = Compound pre assignments  should provide an implementation for code generation
+ast.compoundVariableShouldProvide = Compound assignment variable  should provide an implementation for code generation
+ast.postIncrShouldProvide = Post increment variable  should provide an implementation for code generation
+ast.missingCode = Missing code gen implementation
+
+### constant
+constant.cannotCastedInto =  {0} constant cannot be casted into {1}
+constant.cannotConvertedTo = {0} constant cannot be converted to {1}
+
+### miscellaneous
+error.undefinedBaseType = Undefined base type: {0}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BatchOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/BatchOperation.java
new file mode 100644 (file)
index 0000000..5f3e020
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import net.sourceforge.phpdt.core.IJavaModelStatus;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+
+
+/**
+ * An operation created as a result of a call to JavaCore.run(IWorkspaceRunnable, IProgressMonitor)
+ * that encapsulates a user defined IWorkspaceRunnable.
+ */
+public class BatchOperation extends JavaModelOperation {
+       protected IWorkspaceRunnable runnable;
+       public BatchOperation(IWorkspaceRunnable runnable) {
+               this.runnable = runnable;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jdt.internal.core.JavaModelOperation#executeOperation()
+        */
+       protected void executeOperation() throws JavaModelException {
+               try {
+                       this.runnable.run(fMonitor);
+               } catch (CoreException ce) {
+                       if (ce instanceof JavaModelException) {
+                               throw (JavaModelException)ce;
+                       } else {
+                               if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
+                                       Throwable e= ce.getStatus().getException();
+                                       if (e instanceof JavaModelException) {
+                                               throw (JavaModelException) e;
+                                       }
+                               }
+                               throw new JavaModelException(ce);
+                       }
+               }
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jdt.internal.core.JavaModelOperation#verify()
+        */
+       protected IJavaModelStatus verify() {
+               // cannot verify user defined operation
+               return JavaModelStatus.VERIFIED_OK;
+       }
+
+       
+}
index 511d041..993c2a7 100644 (file)
@@ -14,12 +14,8 @@ import java.util.Enumeration;
 
 import net.sourceforge.phpdt.core.IBuffer;
 import net.sourceforge.phpdt.core.IBufferFactory;
-import net.sourceforge.phpdt.core.IJavaElement;
 import net.sourceforge.phpdt.core.IOpenable;
 
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-
 
 /**
  * The buffer manager manages the set of open buffers.
@@ -49,15 +45,15 @@ protected void addBuffer(IBuffer buffer) {
 /**
  * @see IBufferFactory#createBuffer(IOpenable)
  */
-public IBuffer createBuffer(IOpenable owner) {
-       IJavaElement element = (IJavaElement)owner;
-       IResource resource = element.getResource();
-       return 
-               new Buffer(
-                       resource instanceof IFile ? (IFile)resource : null, 
-                       owner, 
-                       element.isReadOnly());
-}
+//public IBuffer createBuffer(IOpenable owner) {
+//     IJavaElement element = (IJavaElement)owner;
+//     IResource resource = element.getResource();
+//     return 
+//             new Buffer(
+//                     resource instanceof IFile ? (IFile)resource : null, 
+//                     owner, 
+//                     element.isReadOnly());
+//}
 
 /**
  * Returns the open buffer associated with the given owner,
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/CompilationUnit.java
new file mode 100644 (file)
index 0000000..5a56373
--- /dev/null
@@ -0,0 +1,821 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import net.sourceforge.phpdt.core.IBuffer;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * @see ICompilationUnit
+ */
+
+public class CompilationUnit extends Openable implements ICompilationUnit {
+       
+       public static boolean SHARED_WC_VERBOSE = false;
+       
+       // TODO: Remove when we are certain that every client is ready for this fix
+       public static final boolean FIX_BUG25184 = true;
+
+/**
+ * Constructs a handle to a compilation unit with the given name in the
+ * specified package.
+ *
+ * @exception IllegalArgumentException if the name of the compilation unit
+ * does not end with ".java"
+ */
+protected CompilationUnit(IPackageFragment parent, String name) {
+       super(COMPILATION_UNIT, parent, name);
+//     if (!Util.isJavaFileName(name)) {
+//             throw new IllegalArgumentException(org.eclipse.jdt.internal.core.Util.bind("convention.unit.notJavaName")); //$NON-NLS-1$
+//     }
+}
+/**
+ * Accepts the given visitor onto the parsed tree of this compilation unit, after
+ * having runned the name resolution.
+ * The visitor's corresponding <code>visit</code> method is called with the
+ * corresponding parse tree. If the visitor returns <code>true</code>, this method
+ * visits this parse node's members.
+ *
+ * @param visitor the visitor
+ * @exception JavaModelException if this method fails. Reasons include:
+ * <ul>
+ * <li> This element does not exist.</li>
+ * <li> The visitor failed with this exception.</li>
+ * </ul>
+ */
+//public void accept(IAbstractSyntaxTreeVisitor visitor) throws JavaModelException {
+//     CompilationUnitVisitor.visit(this, visitor);
+//} 
+//
+//protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
+//
+//     if (monitor != null && monitor.isCanceled()) return;
+//
+//     // remove existing (old) infos
+//     removeInfo();
+//
+//     HashMap newElements = new HashMap(11);
+//     info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
+//     JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+//     for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
+//             IJavaElement key = (IJavaElement) iter.next();
+//             Object value = newElements.get(key);
+//             JavaModelManager.getJavaModelManager().putInfo(key, value);
+//     }
+//     // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
+//     // to be flushed. Might lead to performance issues.
+//     // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
+//     JavaModelManager.getJavaModelManager().putInfo(this, info);     
+//}
+//
+///**
+// * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
+// */
+//public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
+//     codeComplete(this, isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this, offset, requestor);
+//}
+///**
+// * @see ICodeAssist#codeSelect(int, int)
+// */
+//public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
+//     return super.codeSelect(this, offset, length);
+//}
+///**
+// * @see IWorkingCopy#commit(boolean, IProgressMonitor)
+// */
+//public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
+//}
+/**
+ * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
+ */
+//public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (container == null) {
+//             throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+//     }
+//     IJavaElement[] elements = new IJavaElement[] {this};
+//     IJavaElement[] containers = new IJavaElement[] {container};
+//     String[] renamings = null;
+//     if (rename != null) {
+//             renamings = new String[] {rename};
+//     }
+//     getJavaModel().copy(elements, containers, null, renamings, force, monitor);
+//}
+/**
+ * Returns a new element info for this element.
+ */
+//protected OpenableElementInfo createElementInfo() {
+//     return new CompilationUnitElementInfo();
+//}
+///**
+// * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
+// */
+//public IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
+//     CreateImportOperation op = new CreateImportOperation(name, this);
+//     if (sibling != null) {
+//             op.createBefore(sibling);
+//     }
+//     runOperation(op, monitor);
+//     return getImport(name);
+//}
+/**
+ * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
+ */
+//public IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException {
+//     
+//     CreatePackageDeclarationOperation op= new CreatePackageDeclarationOperation(name, this);
+//     runOperation(op, monitor);
+//     return getPackageDeclaration(name);
+//}
+///**
+// * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
+// */
+//public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (!exists()) {
+//             //autogenerate this compilation unit
+//             IPackageFragment pkg = (IPackageFragment) getParent();
+//             String source = ""; //$NON-NLS-1$
+//             if (pkg.getElementName().length() > 0) {
+//                     //not the default package...add the package declaration
+//                     source = "package " + pkg.getElementName() + ";"  + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$
+//             }
+//             CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, fName, source, force);
+//             runOperation(op, monitor);
+//     }
+//     CreateTypeOperation op = new CreateTypeOperation(this, content, force);
+//     if (sibling != null) {
+//             op.createBefore(sibling);
+//     }
+//     runOperation(op, monitor);
+//     return (IType) op.getResultElements()[0];
+//}
+/**
+ * @see ISourceManipulation#delete(boolean, IProgressMonitor)
+ */
+//public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     IJavaElement[] elements= new IJavaElement[] {this};
+//     getJavaModel().delete(elements, force, monitor);
+//}
+/**
+ * This is not a working copy, do nothing.
+ *
+ * @see IWorkingCopy#destroy()
+ */
+public void destroy() {
+}
+
+
+/**
+ * Returns true if this handle represents the same Java element
+ * as the given handle.
+ *
+ * <p>Compilation units must also check working copy state;
+ *
+ * @see Object#equals(java.lang.Object)
+ */
+//public boolean equals(Object o) {
+//     return super.equals(o) && !((ICompilationUnit)o).isWorkingCopy();
+//}
+///**
+// * @see JavaElement#equalsDOMNode(IDOMNode)
+// */
+//protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
+//     String name = getElementName();
+//     if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && name != null ) {
+//             String nodeName = node.getName();
+//             if (nodeName == null) return false;             
+//             if (name.equals(nodeName)) {
+//                     return true;
+//             } else {
+//                     // iterate through all the types inside the receiver and see if one of them can fit
+//                     IType[] types = getTypes();
+//                     String typeNodeName = nodeName.substring(0, nodeName.indexOf(".java")); //$NON-NLS-1$
+//                     for (int i = 0, max = types.length; i < max; i++) {
+//                             if (types[i].getElementName().equals(typeNodeName)) {
+//                                     return true;
+//                             }
+//                     }
+//             }
+//     }
+//     return false;
+//}
+/**
+ * @see IWorkingCopy#findElements(IJavaElement)
+ */
+//public IJavaElement[] findElements(IJavaElement element) {
+//     ArrayList children = new ArrayList();
+//     while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
+//             children.add(element);
+//             element = element.getParent();
+//     }
+//     if (element == null) return null;
+//     IJavaElement currentElement = this;
+//     for (int i = children.size()-1; i >= 0; i--) {
+//             IJavaElement child = (IJavaElement)children.get(i);
+//             switch (child.getElementType()) {
+//                     case IJavaElement.PACKAGE_DECLARATION:
+//                             currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
+//                             break;
+//                     case IJavaElement.IMPORT_CONTAINER:
+//                             currentElement = ((ICompilationUnit)currentElement).getImportContainer();
+//                             break;
+//                     case IJavaElement.IMPORT_DECLARATION:
+//                             currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
+//                             break;
+//                     case IJavaElement.TYPE:
+//                             if (currentElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
+//                                     currentElement = ((ICompilationUnit)currentElement).getType(child.getElementName());
+//                             } else {
+//                                     currentElement = ((IType)currentElement).getType(child.getElementName());
+//                             }
+//                             break;
+//                     case IJavaElement.INITIALIZER:
+//                             currentElement = ((IType)currentElement).getInitializer(((JavaElement)child).getOccurrenceCount());
+//                             break;
+//                     case IJavaElement.FIELD:
+//                             currentElement = ((IType)currentElement).getField(child.getElementName());
+//                             break;
+//                     case IJavaElement.METHOD:
+//                             return ((IType)currentElement).findMethods((IMethod)child);
+//             }
+//             
+//     }
+//     if (currentElement != null && currentElement.exists()) {
+//             return new IJavaElement[] {currentElement};
+//     } else {
+//             return null;
+//     }
+//}
+/**
+ * @see IWorkingCopy#findPrimaryType()
+ */
+//public IType findPrimaryType() {
+//     String typeName = Signature.getQualifier(this.getElementName());
+//     IType primaryType= this.getType(typeName);
+//     if (primaryType.exists()) {
+//             return primaryType;
+//     }
+//     return null;
+//}
+
+/**
+ * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
+ */
+//public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
+//
+//     // if factory is null, default factory must be used
+//     if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
+//
+//     // In order to be shared, working copies have to denote the same compilation unit 
+//     // AND use the same buffer factory.
+//     // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
+//     Map sharedWorkingCopies = JavaModelManager.getJavaModelManager().sharedWorkingCopies;
+//     
+//     Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
+//     if (perFactoryWorkingCopies == null) return null;
+//     return (WorkingCopy)perFactoryWorkingCopies.get(this);
+//}
+
+//protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+//
+//     if (getParent() instanceof JarPackageFragment) {
+//             // ignore .java files in jar
+//             throw newNotPresentException();
+//     } else {
+//             // put the info now, because getting the contents requires it
+//             JavaModelManager.getJavaModelManager().putInfo(this, info);
+//             CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
+//
+//             // generate structure
+//             CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
+//             IProblemFactory factory = new DefaultProblemFactory();
+//             SourceElementParser parser = new SourceElementParser(requestor, factory, new CompilerOptions(getJavaProject().getOptions(true)));
+//             requestor.parser = parser;
+//             parser.parseCompilationUnit(this, false);
+//             if (isWorkingCopy()) {
+//                     CompilationUnit original = (CompilationUnit) getOriginalElement();
+//                     // might be IResource.NULL_STAMP if original does not exist
+//                     unitInfo.fTimestamp = ((IFile) original.getResource()).getModificationStamp();
+//             }
+//             return unitInfo.isStructureKnown();
+//     }
+//}
+/**
+ * @see ICompilationUnit#getAllTypes()
+ */
+//public IType[] getAllTypes() throws JavaModelException {
+//     IJavaElement[] types = getTypes();
+//     int i;
+//     ArrayList allTypes = new ArrayList(types.length);
+//     ArrayList typesToTraverse = new ArrayList(types.length);
+//     for (i = 0; i < types.length; i++) {
+//             typesToTraverse.add(types[i]);
+//     }
+//     while (!typesToTraverse.isEmpty()) {
+//             IType type = (IType) typesToTraverse.get(0);
+//             typesToTraverse.remove(type);
+//             allTypes.add(type);
+//             types = type.getTypes();
+//             for (i = 0; i < types.length; i++) {
+//                     typesToTraverse.add(types[i]);
+//             }
+//     } 
+//     IType[] arrayOfAllTypes = new IType[allTypes.size()];
+//     allTypes.toArray(arrayOfAllTypes);
+//     return arrayOfAllTypes;
+//}
+/**
+ * @see IMember#getCompilationUnit()
+ */
+public ICompilationUnit getCompilationUnit() {
+       return this;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents()
+ */
+public char[] getContents() {
+       try {
+               IBuffer buffer = this.getBuffer();
+               return buffer == null ? null : buffer.getCharacters();
+       } catch (JavaModelException e) {
+               return CharOperation.NO_CHAR;
+       }
+}
+/**
+ * A compilation unit has a corresponding resource unless it is contained
+ * in a jar.
+ *
+ * @see IJavaElement#getCorrespondingResource()
+ */
+//public IResource getCorrespondingResource() throws JavaModelException {
+//     IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent();
+//     if (root.isArchive()) {
+//             return null;
+//     } else {
+//             return getUnderlyingResource();
+//     }
+//}
+///**
+// * @see ICompilationUnit#getElementAt(int)
+// */
+//public IJavaElement getElementAt(int position) throws JavaModelException {
+//
+//     IJavaElement e= getSourceElementAt(position);
+//     if (e == this) {
+//             return null;
+//     } else {
+//             return e;
+//     }
+//}
+public char[] getFileName(){
+       return getElementName().toCharArray();
+}
+/**
+ * @see JavaElement#getHandleMementoDelimiter()
+ */
+protected char getHandleMementoDelimiter() {
+       return JavaElement.JEM_COMPILATIONUNIT;
+}
+/**
+ * @see ICompilationUnit#getImport(String)
+ */
+//public IImportDeclaration getImport(String name) {
+//     return new ImportDeclaration(getImportContainer(), name);
+//}
+///**
+// * @see ICompilationUnit#getImportContainer()
+// */
+//public IImportContainer getImportContainer() {
+//     return new ImportContainer(this);
+//}
+
+
+/**
+ * @see ICompilationUnit#getImports()
+ */
+//public IImportDeclaration[] getImports() throws JavaModelException {
+//     IImportContainer container= getImportContainer();
+//     if (container.exists()) {
+//             IJavaElement[] elements= container.getChildren();
+//             IImportDeclaration[] imprts= new IImportDeclaration[elements.length];
+//             System.arraycopy(elements, 0, imprts, 0, elements.length);
+//             return imprts;
+//     } else if (!exists()) {
+//                     throw newNotPresentException();
+//     } else {
+//             return new IImportDeclaration[0];
+//     }
+//
+//}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
+ */
+public char[] getMainTypeName(){
+       String name= getElementName();
+       //remove the .java
+       name= name.substring(0, name.length() - 5);
+       return name.toCharArray();
+}
+/**
+ * Returns <code>null</code>, this is not a working copy.
+ *
+ * @see IWorkingCopy#getOriginal(IJavaElement)
+ */
+public IJavaElement getOriginal(IJavaElement workingCopyElement) {
+       return null;
+}
+/**
+ * Returns <code>null</code>, this is not a working copy.
+ *
+ * @see IWorkingCopy#getOriginalElement()
+ */
+public IJavaElement getOriginalElement() {
+       return null;
+}
+/**
+ * @see ICompilationUnit#getPackageDeclaration(String)
+ */
+//public IPackageDeclaration getPackageDeclaration(String name) {
+//     return new PackageDeclaration(this, name);
+//}
+///**
+// * @see ICompilationUnit#getPackageDeclarations()
+// */
+//public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
+//     ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
+//     IPackageDeclaration[] array= new IPackageDeclaration[list.size()];
+//     list.toArray(array);
+//     return array;
+//}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName()
+ */
+public char[][] getPackageName() {
+       return null;
+}
+/**
+ * @see IJavaElement#getPath()
+ */
+//public IPath getPath() {
+//     PackageFragmentRoot root = this.getPackageFragmentRoot();
+//     if (root.isArchive()) {
+//             return root.getPath();
+//     } else {
+//             return this.getParent().getPath().append(this.getElementName());
+//     }
+//}
+/**
+ * @see IJavaElement#getResource()
+ */
+public IResource getResource() {
+       PackageFragmentRoot root = this.getPackageFragmentRoot();
+       if (root.isArchive()) {
+               return root.getResource();
+       } else {
+               return ((IContainer)this.getParent().getResource()).getFile(new Path(this.getElementName()));
+       }
+}
+
+/**
+ * @see ISourceReference#getSource()
+ */
+public String getSource() throws JavaModelException {
+       IBuffer buffer = getBuffer();
+       if (buffer == null) return ""; //$NON-NLS-1$
+       return buffer.getContents();
+}
+/**
+ * @see ISourceReference#getSourceRange()
+ */
+//public ISourceRange getSourceRange() throws JavaModelException {
+//     return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
+//}
+///**
+// * @see ICompilationUnit#getType(String)
+// */
+//public IType getType(String name) {
+//     return new SourceType(this, name);
+//}
+///**
+// * @see ICompilationUnit#getTypes()
+// */
+//public IType[] getTypes() throws JavaModelException {
+//     ArrayList list = getChildrenOfType(TYPE);
+//     IType[] array= new IType[list.size()];
+//     list.toArray(array);
+//     return array;
+//}
+//public IResource getUnderlyingResource() throws JavaModelException {
+//     if (FIX_BUG25184) {
+//             return super.getUnderlyingResource();
+//     } else {
+//             return getResource();
+//     }
+//}
+///**
+// * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
+// */
+//public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
+//     
+//     // if factory is null, default factory must be used
+//     if (factory == null) factory = this.getBufferManager().getDefaultBufferFactory();
+//
+//     JavaModelManager manager = JavaModelManager.getJavaModelManager();
+//     
+//     // In order to be shared, working copies have to denote the same compilation unit 
+//     // AND use the same buffer factory.
+//     // Assuming there is a little set of buffer factories, then use a 2 level Map cache.
+//     Map sharedWorkingCopies = manager.sharedWorkingCopies;
+//     
+//     Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(factory);
+//     if (perFactoryWorkingCopies == null){
+//             perFactoryWorkingCopies = new HashMap();
+//             sharedWorkingCopies.put(factory, perFactoryWorkingCopies);
+//     }
+//     WorkingCopy workingCopy = (WorkingCopy)perFactoryWorkingCopies.get(this);
+//     if (workingCopy != null) {
+//             workingCopy.useCount++;
+//
+//             if (SHARED_WC_VERBOSE) {
+//                     System.out.println("Incrementing use count of shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
+//             }
+//
+//             return workingCopy;
+//     } else {
+//             CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, problemRequestor);
+//             runOperation(op, pm);
+//             return op.getResultElements()[0];
+//     }
+//}
+/**
+ * @see IWorkingCopy#getWorkingCopy()
+ */
+//public IJavaElement getWorkingCopy() throws JavaModelException {
+//     return this.getWorkingCopy(null, null, null);
+//}
+
+/**
+ * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
+ */
+//public IJavaElement getWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
+//     CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, null, factory, problemRequestor);
+//     runOperation(op, pm);
+//     return op.getResultElements()[0];
+//}
+
+/**
+ * @see Openable#hasBuffer()
+ */
+protected boolean hasBuffer() {
+       return true;
+}
+/**
+ * If I am not open, return true to avoid parsing.
+ *
+ * @see IParent#hasChildren()
+ */
+public boolean hasChildren() throws JavaModelException {
+//     if (isOpen()) {
+//             return getChildren().length > 0;
+//     } else {
+//             return true;
+//     }
+  return false;
+}
+/**
+ * Returns false, this is not a working copy.
+ *
+ * @see IWorkingCopy#isBasedOn(IResource)
+ */
+public boolean isBasedOn(IResource resource) {
+       return false;
+}
+/**
+ * @see IOpenable#isConsistent()
+ */
+//public boolean isConsistent() throws JavaModelException {
+//     return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
+//}
+/**
+ * @see Openable#isSourceElement()
+ */
+protected boolean isSourceElement() {
+       return true;
+}
+/**
+ * @see IWorkingCopy#isWorkingCopy()
+ */
+public boolean isWorkingCopy() {
+       return false;
+}
+/**
+ * @see IOpenable#makeConsistent(IProgressMonitor)
+ */
+//public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
+//     if (!isConsistent()) { // TODO: this code isn't synchronized with regular opening of a working copy
+//             // create a new info and make it the current info
+//             OpenableElementInfo info = createElementInfo();
+//             buildStructure(info, monitor);
+//     }
+//}
+
+/**
+ * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
+ */
+//public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (container == null) {
+//             throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+//     }
+//     IJavaElement[] elements= new IJavaElement[] {this};
+//     IJavaElement[] containers= new IJavaElement[] {container};
+//     
+//     String[] renamings= null;
+//     if (rename != null) {
+//             renamings= new String[] {rename};
+//     }
+//     getJavaModel().move(elements, containers, null, renamings, force, monitor);
+//}
+
+/**
+ * @see Openable#openBuffer(IProgressMonitor)
+ */
+//protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
+//
+//     // create buffer -  compilation units only use default buffer factory
+//     BufferManager bufManager = getBufferManager();
+//     IBuffer buffer = getBufferFactory().createBuffer(this);
+//     if (buffer == null) return null;
+//     
+//     // set the buffer source
+//     if (buffer.getCharacters() == null){
+//             IFile file = (IFile)this.getResource();
+//             if (file == null || !file.exists()) throw newNotPresentException();
+//             buffer.setContents(Util.getResourceContentsAsCharArray(file));
+//     }
+//
+//     // add buffer to buffer cache
+//     bufManager.addBuffer(buffer);
+//                     
+//     // listen to buffer changes
+//     buffer.addBufferChangedListener(this);
+//     
+//     return buffer;
+//}
+//protected void openParent(IProgressMonitor pm) throws JavaModelException {
+//     if (FIX_BUG25184) {
+//             super.openParent(pm);
+//     } else {
+//             try {
+//                     super.openParent(pm);
+//             } catch(JavaModelException e){
+//                     // allow parent to not exist for compilation units defined outside classpath
+//                     if (!e.isDoesNotExist()){ 
+//                             throw e;
+//                     }
+//             }
+//     }
+//}
+//protected boolean parentExists() {
+//     if (FIX_BUG25184) {
+//             return super.parentExists();
+//     } else {
+//             return true; // tolerate units outside classpath
+//     }
+//}
+
+/**
+ * @see IWorkingCopy#reconcile()
+ */
+public IMarker[] reconcile() throws JavaModelException {
+       // Reconciling is not supported on non working copies
+       return null;
+}
+
+/**
+ * @see IWorkingCopy#reconcile(boolean, IProgressMonitor)
+ */
+public void reconcile(
+       boolean forceProblemDetection,
+       IProgressMonitor monitor)
+       throws JavaModelException {
+       // Reconciling is not supported on non working copies
+}
+
+/**
+ * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
+ */
+//public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (name == null) {
+//             throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
+//     }
+//     IJavaElement[] elements= new IJavaElement[] {this};
+//     IJavaElement[] dests= new IJavaElement[] {this.getParent()};
+//     String[] renamings= new String[] {name};
+//     getJavaModel().rename(elements, dests, renamings, force, monitor);
+//}
+/**
+ * Does nothing - this is not a working copy.
+ *
+ * @see IWorkingCopy#restore()
+ */
+public void restore () throws JavaModelException {
+}
+/**
+ * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
+ * @deprecated - use codeComplete(int, ICompletionRequestor)
+ */
+//public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
+//     
+//     if (requestor == null){
+//             codeComplete(offset, (ICompletionRequestor)null);
+//             return;
+//     }
+//     codeComplete(
+//             offset,
+//             new ICompletionRequestor(){
+//                     public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                     }
+//                     public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+//                             requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptError(IProblem error) {
+//                             if (true) return; // was disabled in 1.0
+//
+//                             try {
+//                                     IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
+//                                     marker.setAttribute(IJavaModelMarker.ID, error.getID());
+//                                     marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
+//                                     marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
+//                                     marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
+//                                     marker.setAttribute(IMarker.MESSAGE, error.getMessage());
+//                                     marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+//                                     requestor.acceptError(marker);
+//                             } catch(CoreException e){
+//                             }
+//                     }
+//                     public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+//                             requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+//                             requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptKeyword(keywordName, completionStart, completionEnd);
+//                     }
+//                     public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptLabel(labelName, completionStart, completionEnd);
+//                     }
+//                     public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                             // ignore
+//                     }
+//                     public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                             // skip parameter names
+//                             requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                             // ignore
+//                     }
+//                     public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptModifier(modifierName, completionStart, completionEnd);
+//                     }
+//                     public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
+//                     }
+//                     public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
+//                     }
+//                     public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int completionEnd, int relevance){
+//                             // ignore
+//                     }
+//             });
+//}
+/**
+ * @see JavaElement#rootedAt(IJavaProject)
+ */
+public IJavaElement rootedAt(IJavaProject project) {
+       return
+               new CompilationUnit(
+                       (IPackageFragment)((JavaElement)fParent).rootedAt(project), 
+                       fName);
+}
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/DeltaProcessor.java
new file mode 100644 (file)
index 0000000..ac3dd0f
--- /dev/null
@@ -0,0 +1,2258 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+
+/**
+ * This class is used by <code>JavaModelManager</code> to convert
+ * <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s.
+ * It also does some processing on the <code>JavaElement</code>s involved
+ * (e.g. closing them or updating classpaths).
+ */
+public class DeltaProcessor implements IResourceChangeListener {
+       
+       final static int IGNORE = 0;
+       final static int SOURCE = 1;
+       final static int BINARY = 2;
+       
+       final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
+       final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
+       final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
+       final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
+       final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
+       
+       final static int NON_JAVA_RESOURCE = -1;
+       
+       /**
+        * The <code>JavaElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated.
+        */
+       protected JavaElementDelta currentDelta;
+       
+//     protected IndexManager indexManager = new IndexManager();
+               
+       /* A table from IPath (from a classpath entry) to RootInfo */
+       public Map roots;
+       
+       /* A table from IPath (from a classpath entry) to ArrayList of RootInfo
+        * Used when an IPath corresponds to more than one root */
+       Map otherRoots;
+       
+       /* Whether the roots tables should be recomputed */
+       public boolean rootsAreStale = true;
+       
+       /* A table from IPath (from a classpath entry) to RootInfo
+        * from the last time the delta processor was invoked. */
+       public Map oldRoots;
+
+       /* A table from IPath (from a classpath entry) to ArrayList of RootInfo
+        * from the last time the delta processor was invoked.
+        * Used when an IPath corresponds to more than one root */
+       Map oldOtherRoots;
+       
+       /* A table from IPath (a source attachment path from a classpath entry) to IPath (a root path) */
+       Map sourceAttachments;
+
+       /* The java element that was last created (see createElement(IResource)). 
+        * This is used as a stack of java elements (using getParent() to pop it, and 
+        * using the various get*(...) to push it. */
+       Openable currentElement;
+               
+       public HashMap externalTimeStamps = new HashMap();
+       public HashSet projectsToUpdate = new HashSet();
+       // list of root projects which namelookup caches need to be updated for dependents
+       // TODO: (jerome) is it needed? projectsToUpdate might be sufficient
+       public HashSet projectsForDependentNamelookupRefresh = new HashSet();  
+       
+       JavaModelManager manager;
+       
+       /* A table from IJavaProject to an array of IPackageFragmentRoot.
+        * This table contains the pkg fragment roots of the project that are being deleted.
+        */
+       Map removedRoots;
+       
+       /*
+        * A list of IJavaElement used as a scope for external archives refresh during POST_CHANGE.
+        * This is null if no refresh is needed.
+        */
+       HashSet refreshedElements;
+       public static boolean VERBOSE = false;
+       
+       class OutputsInfo {
+               IPath[] paths;
+               int[] traverseModes;
+               int outputCount;
+               OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
+                       this.paths = paths;
+                       this.traverseModes = traverseModes;
+                       this.outputCount = outputCount;
+               }
+               public String toString() {
+                       if (this.paths == null) return "<none>"; //$NON-NLS-1$
+                       StringBuffer buffer = new StringBuffer();
+                       for (int i = 0; i < this.outputCount; i++) {
+                               buffer.append("path="); //$NON-NLS-1$
+                               buffer.append(this.paths[i].toString());
+                               buffer.append("\n->traverse="); //$NON-NLS-1$
+                               switch (this.traverseModes[i]) {
+                                       case BINARY:
+                                               buffer.append("BINARY"); //$NON-NLS-1$
+                                               break;
+                                       case IGNORE:
+                                               buffer.append("IGNORE"); //$NON-NLS-1$
+                                               break;
+                                       case SOURCE:
+                                               buffer.append("SOURCE"); //$NON-NLS-1$
+                                               break;
+                                       default:
+                                               buffer.append("<unknown>"); //$NON-NLS-1$
+                               }
+                               if (i+1 < this.outputCount) {
+                                       buffer.append('\n');
+                               }
+                       }
+                       return buffer.toString();
+               }
+       }
+       class RootInfo {
+               IJavaProject project;
+               IPath rootPath;
+               char[][] exclusionPatterns;
+               RootInfo(IJavaProject project, IPath rootPath, char[][] exclusionPatterns) {
+                       this.project = project;
+                       this.rootPath = rootPath;
+                       this.exclusionPatterns = exclusionPatterns;
+               }
+               boolean isRootOfProject(IPath path) {
+                       return this.rootPath.equals(path) && this.project.getProject().getFullPath().isPrefixOf(path);
+               }
+               public String toString() {
+                       StringBuffer buffer = new StringBuffer("project="); //$NON-NLS-1$
+                       if (this.project == null) {
+                               buffer.append("null"); //$NON-NLS-1$
+                       } else {
+                               buffer.append(this.project.getElementName());
+                       }
+                       buffer.append("\npath="); //$NON-NLS-1$
+                       if (this.rootPath == null) {
+                               buffer.append("null"); //$NON-NLS-1$
+                       } else {
+                               buffer.append(this.rootPath.toString());
+                       }
+                       buffer.append("\nexcluding="); //$NON-NLS-1$
+                       if (this.exclusionPatterns == null) {
+                               buffer.append("null"); //$NON-NLS-1$
+                       } else {
+                               for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) {
+                                       buffer.append(new String(this.exclusionPatterns[i]));
+                                       if (i < length-1) {
+                                               buffer.append("|"); //$NON-NLS-1$
+                                       }
+                               }
+                       }
+                       return buffer.toString();
+               }
+       }
+
+       DeltaProcessor(JavaModelManager manager) {
+               this.manager = manager;
+       }
+
+       /*
+        * Adds the dependents of the given project to the list of the projects
+        * to update.
+        */
+//     void addDependentProjects(IPath projectPath, HashSet result) {
+//             try {
+//                     IJavaProject[] projects = this.manager.getJavaModel().getJavaProjects();
+//                     for (int i = 0, length = projects.length; i < length; i++) {
+//                             IJavaProject project = projects[i];
+//                             IClasspathEntry[] classpath = ((JavaProject)project).getExpandedClasspath(true);
+//                             for (int j = 0, length2 = classpath.length; j < length2; j++) {
+//                                     IClasspathEntry entry = classpath[j];
+//                                             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
+//                                                             && entry.getPath().equals(projectPath)) {
+//                                                     result.add(project);
+//                                             }
+//                                     }
+//                             }
+//             } catch (JavaModelException e) {
+//             }
+//     }
+       /*
+        * Adds the given element to the list of elements used as a scope for external jars refresh.
+        */
+       public void addForRefresh(IJavaElement element) {
+               if (this.refreshedElements == null) {
+                       this.refreshedElements = new HashSet();
+               }
+               this.refreshedElements.add(element);
+       }
+       /*
+        * Adds the given project and its dependents to the list of the projects
+        * to update.
+        */
+       void addToProjectsToUpdateWithDependents(IProject project) {
+               this.projectsToUpdate.add(JavaCore.create(project));
+//             this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
+       }
+       
+       /**
+        * Adds the given child handle to its parent's cache of children. 
+        */
+       protected void addToParentInfo(Openable child) {
+
+               Openable parent = (Openable) child.getParent();
+               if (parent != null && parent.isOpen()) {
+                       try {
+                               JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
+                               info.addChild(child);
+                       } catch (JavaModelException e) {
+                               // do nothing - we already checked if open
+                       }
+               }
+       }
+
+       /**
+        * Check all external archive (referenced by given roots, projects or model) status and issue a corresponding root delta.
+        * Also triggers index updates
+        */
+//     public void checkExternalArchiveChanges(IJavaElement[] refreshedElements, IProgressMonitor monitor) throws JavaModelException {
+//             try {
+//                     for (int i = 0, length = refreshedElements.length; i < length; i++) {
+//                             this.addForRefresh(refreshedElements[i]);
+//                     }
+//                     boolean hasDelta = this.createExternalArchiveDelta(monitor);
+//                     if (monitor != null && monitor.isCanceled()) return; 
+//                     if (hasDelta){
+//                             // force classpath marker refresh of affected projects
+//                             JavaModel.flushExternalFileCache();
+//                             IJavaElementDelta[] projectDeltas = this.currentDelta.getAffectedChildren();
+//                             for (int i = 0, length = projectDeltas.length; i < length; i++) {
+//                                     IJavaElementDelta delta = projectDeltas[i];
+//                                     ((JavaProject)delta.getElement()).getResolvedClasspath(
+//                                             true, // ignoreUnresolvedEntry
+//                                             true); // generateMarkerOnError
+//                             }               
+//                             if (this.currentDelta != null) { // if delta has not been fired while creating markers
+//                                     this.manager.fire(this.currentDelta, JavaModelManager.DEFAULT_CHANGE_EVENT);
+//                             }
+//                     }
+//             } finally {
+//                     this.currentDelta = null;
+//                     if (monitor != null) monitor.done();
+//             }
+//     }
+       /*
+        * Check if external archives have changed and create the corresponding deltas.
+        * Returns whether at least on delta was created.
+        */
+//     public boolean createExternalArchiveDelta(IProgressMonitor monitor) throws JavaModelException {
+//             
+//             if (this.refreshedElements == null) return false;
+//                     
+//             HashMap externalArchivesStatus = new HashMap();
+//             boolean hasDelta = false;
+//             
+//             // find JARs to refresh
+//             HashSet archivePathsToRefresh = new HashSet();
+//             try {
+//                     Iterator iterator = this.refreshedElements.iterator();
+//                     while (iterator.hasNext()) {
+//                             IJavaElement element = (IJavaElement)iterator.next();
+//                             switch(element.getElementType()){
+//                                     case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+//                                             archivePathsToRefresh.add(element.getPath());
+//                                             break;
+//                                     case IJavaElement.JAVA_PROJECT :
+//                                             IJavaProject project = (IJavaProject) element;
+//                                             if (!JavaProject.hasJavaNature(project.getProject())) {
+//                                                     // project is not accessible or has lost its Java nature
+//                                                     break;
+//                                             }
+//                                             IClasspathEntry[] classpath = project.getResolvedClasspath(true);
+//                                             for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
+//                                                     if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
+//                                                             archivePathsToRefresh.add(classpath[j].getPath());
+//                                                     }
+//                                             }
+//                                             break;
+//                                     case IJavaElement.JAVA_MODEL :
+//                                             IJavaProject[] projects = manager.getJavaModel().getOldJavaProjectsList();
+//                                             for (int j = 0, projectsLength = projects.length; j < projectsLength; j++){
+//                                                     project = projects[j];
+//                                                     if (!JavaProject.hasJavaNature(project.getProject())) {
+//                                                             // project is not accessible or has lost its Java nature
+//                                                             continue;
+//                                                     }
+//                                                     classpath = project.getResolvedClasspath(true);
+//                                                     for (int k = 0, cpLength = classpath.length; k < cpLength; k++){
+//                                                             if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
+//                                                                     archivePathsToRefresh.add(classpath[k].getPath());
+//                                                             }
+//                                                     }
+//                                             }
+//                                             break;
+//                             }
+//                     }
+//             } finally {
+//                     this.refreshedElements = null;
+//             }
+//             
+//             // perform refresh
+//             IJavaProject[] projects = manager.getJavaModel().getOldJavaProjectsList();
+//             IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot();
+//             for (int i = 0, length = projects.length; i < length; i++) {
+//                     
+//                     if (monitor != null && monitor.isCanceled()) break; 
+//                     
+//                     IJavaProject project = projects[i];
+//                     if (!JavaProject.hasJavaNature(project.getProject())) {
+//                             // project is not accessible or has lost its Java nature
+//                             continue;
+//                     }
+//                     IClasspathEntry[] entries = project.getResolvedClasspath(true);
+//                     for (int j = 0; j < entries.length; j++){
+//                             if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+//                                     
+//                                     IPath entryPath = entries[j].getPath();
+//                                     
+//                                     if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed to be refreshed
+//                                     
+//                                     String status = (String)externalArchivesStatus.get(entryPath); 
+//                                     if (status == null){
+//                                             
+//                                             // compute shared status
+//                                             Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
+//             
+//                                             if (targetLibrary == null){ // missing JAR
+//                                                     if (this.externalTimeStamps.containsKey(entryPath)){
+//                                                             this.externalTimeStamps.remove(entryPath);
+//                                                             externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
+//                                                             // the jar was physically removed: remove the index
+//                                                             indexManager.removeIndex(entryPath);
+//                                                     }
+//             
+//                                             } else if (targetLibrary instanceof File){ // external JAR
+//             
+//                                                     File externalFile = (File)targetLibrary;
+//                                                     
+//                                                     // check timestamp to figure if JAR has changed in some way
+//                                                     Long oldTimestamp =(Long) this.externalTimeStamps.get(entryPath);
+//                                                     long newTimeStamp = getTimeStamp(externalFile);
+//                                                     if (oldTimestamp != null){
+//             
+//                                                             if (newTimeStamp == 0){ // file doesn't exist
+//                                                                     externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
+//                                                                     this.externalTimeStamps.remove(entryPath);
+//                                                                     // remove the index
+//                                                                     indexManager.removeIndex(entryPath);
+//             
+//                                                             } else if (oldTimestamp.longValue() != newTimeStamp){
+//                                                                     externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
+//                                                                     this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
+//                                                                     // first remove the index so that it is forced to be re-indexed
+//                                                                     indexManager.removeIndex(entryPath);
+//                                                                     // then index the jar
+//                                                                     indexManager.indexLibrary(entryPath, project.getProject());
+//                                                             } else {
+//                                                                     externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
+//                                                             }
+//                                                     } else {
+//                                                             if (newTimeStamp == 0){ // jar still doesn't exist
+//                                                                     externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
+//                                                             } else {
+//                                                                     externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
+//                                                                     this.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
+//                                                                     // index the new jar
+//                                                                     indexManager.indexLibrary(entryPath, project.getProject());
+//                                                             }
+//                                                     }
+//                                             } else { // internal JAR
+//                                                     externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
+//                                             }
+//                                     }
+//                                     // according to computed status, generate a delta
+//                                     status = (String)externalArchivesStatus.get(entryPath); 
+//                                     if (status != null){
+//                                             if (status == EXTERNAL_JAR_ADDED){
+//                                                     PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
+//                                                     if (VERBOSE){
+//                                                             System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); //$NON-NLS-1$
+//                                                     } 
+//                                                     elementAdded(root, null, null);
+//                                                     hasDelta = true;
+//                                             } else if (status == EXTERNAL_JAR_CHANGED) {
+//                                                     PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
+//                                                     if (VERBOSE){
+//                                                             System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$
+//                                                     }
+//                                                     // reset the corresponding project built state, since the builder would miss this change
+//                                                     this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
+//                                                     contentChanged(root, null);
+//                                                     hasDelta = true;
+//                                             } else if (status == EXTERNAL_JAR_REMOVED) {
+//                                                     PackageFragmentRoot root = (PackageFragmentRoot)project.getPackageFragmentRoot(entryPath.toString());
+//                                                     if (VERBOSE){
+//                                                             System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); //$NON-NLS-1$
+//                                                     }
+//                                                     elementRemoved(root, null, null);
+//                                                     hasDelta = true;
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             }
+//             return hasDelta;
+//     }
+       JavaElementDelta currentDelta() {
+               if (this.currentDelta == null) {
+                       this.currentDelta = new JavaElementDelta(this.manager.getJavaModel());
+               }
+               return this.currentDelta;
+       }
+       
+       /*
+        * Process the given delta and look for projects being added, opened, closed or
+        * with a java nature being added or removed.
+        * Note that projects being deleted are checked in deleting(IProject).
+        * In all cases, add the project's dependents to the list of projects to update
+        * so that the classpath related markers can be updated.
+        */
+//     public void checkProjectsBeingAddedOrRemoved(IResourceDelta delta) {
+//             IResource resource = delta.getResource();
+//             switch (resource.getType()) {
+//                     case IResource.ROOT :
+//                             // workaround for bug 15168 circular errors not reported 
+//                             if (this.manager.javaProjectsCache == null) {
+//                                     try {
+//                                             this.manager.javaProjectsCache = this.manager.getJavaModel().getJavaProjects();
+//                                     } catch (JavaModelException e) {
+//                                     }
+//                             }
+//                             
+//                             IResourceDelta[] children = delta.getAffectedChildren();
+//                             for (int i = 0, length = children.length; i < length; i++) {
+//                                     this.checkProjectsBeingAddedOrRemoved(children[i]);
+//                             }
+//                             break;
+//                     case IResource.PROJECT :
+//                             // NB: No need to check project's nature as if the project is not a java project:
+//                             //     - if the project is added or changed this is a noop for projectsBeingDeleted
+//                             //     - if the project is closed, it has already lost its java nature
+//                             int deltaKind = delta.getKind();
+//                             if (deltaKind == IResourceDelta.ADDED) {
+//                                     // remember project and its dependents
+//                                     IProject project = (IProject)resource;
+//                                     this.addToProjectsToUpdateWithDependents(project);
+//                                     
+//                                     // workaround for bug 15168 circular errors not reported 
+//                                     if (JavaProject.hasJavaNature(project)) {
+//                                             this.addToParentInfo((JavaProject)JavaCore.create(project));
+//                                     }
+//
+//                             } else if (deltaKind == IResourceDelta.CHANGED) {
+//                                     IProject project = (IProject)resource;
+//                                     if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
+//                                             // project opened or closed: remember  project and its dependents
+//                                             this.addToProjectsToUpdateWithDependents(project);
+//                                             
+//                                             // workaround for bug 15168 circular errors not reported 
+//                                             if (project.isOpen()) {
+//                                                     if (JavaProject.hasJavaNature(project)) {
+//                                                             this.addToParentInfo((JavaProject)JavaCore.create(project));
+//                                                     }
+//                                             } else {
+//                                                     JavaProject javaProject = (JavaProject)this.manager.getJavaModel().findJavaProject(project);
+//                                                     if (javaProject != null) {
+//                                                             try {
+//                                                                     javaProject.close();
+//                                                             } catch (JavaModelException e) {
+//                                                             }
+//                                                             this.removeFromParentInfo(javaProject);
+//                                                     }
+//                                             }
+//                                     } else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
+//                                             boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(project) != null;
+//                                             boolean isJavaProject = JavaProject.hasJavaNature(project);
+//                                             if (wasJavaProject != isJavaProject) {
+//                                                     // java nature added or removed: remember  project and its dependents
+//                                                     this.addToProjectsToUpdateWithDependents(project);
+//
+//                                                     // workaround for bug 15168 circular errors not reported 
+//                                                     if (isJavaProject) {
+//                                                             this.addToParentInfo((JavaProject)JavaCore.create(project));
+//                                                     } else {
+//                                                             JavaProject javaProject = (JavaProject)JavaCore.create(project);
+//                                                             
+//                                                             // flush classpath markers
+//                                                             javaProject.
+//                                                                     flushClasspathProblemMarkers(
+//                                                                             true, // flush cycle markers
+//                                                                             true  //flush classpath format markers
+//                                                                     );
+//                                                                     
+//                                                             // remove problems and tasks created  by the builder
+//                                                             JavaBuilder.removeProblemsAndTasksFor(project);
+//
+//                                                             // close project
+//                                                             try {
+//                                                                     javaProject.close();
+//                                                             } catch (JavaModelException e) {
+//                                                             }
+//                                                             this.removeFromParentInfo(javaProject);
+//                                                     }
+//                                             } else {
+//                                                     // in case the project was removed then added then changed (see bug 19799)
+//                                                     if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
+//                                                             this.addToParentInfo((JavaProject)JavaCore.create(project));
+//                                                     }
+//                                             }
+//                                     } else {
+//                                             // workaround for bug 15168 circular errors not reported 
+//                                             // in case the project was removed then added then changed
+//                                             if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
+//                                                     this.addToParentInfo((JavaProject)JavaCore.create(project));
+//                                             }                                               
+//                                     }                                       
+//                             }
+//                             break;
+//             }
+//     }
+
+//     private void checkSourceAttachmentChange(IResourceDelta delta, IResource res) {
+//             IPath rootPath = (IPath)this.sourceAttachments.get(res.getFullPath());
+//             if (rootPath != null) {
+//                     RootInfo rootInfo = this.rootInfo(rootPath, delta.getKind());
+//                     if (rootInfo != null) {
+//                             IJavaProject projectOfRoot = rootInfo.project;
+//                             IPackageFragmentRoot root = null;
+//                             try {
+//                                     // close the root so that source attachement cache is flushed
+//                                     root = projectOfRoot.findPackageFragmentRoot(rootPath);
+//                                     if (root != null) {
+//                                             root.close();
+//                                     }
+//                             } catch (JavaModelException e) {
+//                             }
+//                             if (root == null) return;
+//                             switch (delta.getKind()) {
+//                                     case IResourceDelta.ADDED:
+//                                             currentDelta().sourceAttached(root);
+//                                             break;
+//                                     case IResourceDelta.CHANGED:
+//                                             currentDelta().sourceDetached(root);
+//                                             currentDelta().sourceAttached(root);
+//                                             break;
+//                                     case IResourceDelta.REMOVED:
+//                                             currentDelta().sourceDetached(root);
+//                                             break;
+//                             }
+//                     } 
+//             }
+//     }
+
+       /**
+        * Closes the given element, which removes it from the cache of open elements.
+        */
+//     protected static void close(Openable element) {
+//
+//             try {
+//                     element.close();
+//             } catch (JavaModelException e) {
+//                     // do nothing
+//             }
+//     }
+       /**
+        * Generic processing for elements with changed contents:<ul>
+        * <li>The element is closed such that any subsequent accesses will re-open
+        * the element reflecting its new structure.
+        * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
+        * </ul>
+        * Delta argument could be null if processing an external JAR change
+        */
+//     protected void contentChanged(Openable element, IResourceDelta delta) {
+//
+//             close(element);
+//             int flags = IJavaElementDelta.F_CONTENT;
+//             if (element instanceof JarPackageFragmentRoot){
+//                     flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
+//             }
+//             currentDelta().changed(element, flags);
+//     }
+//     
+       /**
+        * Creates the openables corresponding to this resource.
+        * Returns null if none was found.
+        */
+//     protected Openable createElement(IResource resource, int elementType, RootInfo rootInfo) {
+//             if (resource == null) return null;
+//             
+//             IPath path = resource.getFullPath();
+//             IJavaElement element = null;
+//             switch (elementType) {
+//                     
+//                     case IJavaElement.JAVA_PROJECT:
+//                     
+//                             // note that non-java resources rooted at the project level will also enter this code with
+//                             // an elementType JAVA_PROJECT (see #elementType(...)).
+//                             if (resource instanceof IProject){
+//
+//                                     this.popUntilPrefixOf(path);
+//                                     
+//                                     if (this.currentElement != null 
+//                                             && this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
+//                                             && ((IJavaProject)this.currentElement).getProject().equals(resource)) {
+//                                             return this.currentElement;
+//                                     }
+//                                     if  (rootInfo != null && rootInfo.project.getProject().equals(resource)){
+//                                             element = (Openable)rootInfo.project;
+//                                             break;
+//                                     }
+//                                     IProject proj = (IProject)resource;
+//                                     if (JavaProject.hasJavaNature(proj)) {
+//                                             element = JavaCore.create(proj);
+//                                     } else {
+//                                             // java project may have been been closed or removed (look for
+//                                             // element amongst old java project s list).
+//                                             element =  (Openable) manager.getJavaModel().findJavaProject(proj);
+//                                     }
+//                             }
+//                             break;
+//                     case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+//                             element = rootInfo == null ? JavaCore.create(resource) : rootInfo.project.getPackageFragmentRoot(resource);
+//                             break;
+//                     case IJavaElement.PACKAGE_FRAGMENT:
+//                             // find the element that encloses the resource
+//                             this.popUntilPrefixOf(path);
+//                             
+//                             if (this.currentElement == null) {
+//                                     element = rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
+//                             } else {
+//                                     // find the root
+//                                     IPackageFragmentRoot root = this.currentElement.getPackageFragmentRoot();
+//                                     if (root == null) {
+//                                             element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
+//                                     } else if (((JavaProject)root.getJavaProject()).contains(resource)) {
+//                                             // create package handle
+//                                             IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount());
+//                                             String pkg = Util.packageName(pkgPath);
+//                                             if (pkg == null) return null;
+//                                             element = root.getPackageFragment(pkg);
+//                                     }
+//                             }
+//                             break;
+//                     case IJavaElement.COMPILATION_UNIT:
+//                     case IJavaElement.CLASS_FILE:
+//                             // find the element that encloses the resource
+//                             this.popUntilPrefixOf(path);
+//                             
+//                             if (this.currentElement == null) {
+//                                     element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
+//                             } else {
+//                                     // find the package
+//                                     IPackageFragment pkgFragment = null;
+//                                     switch (this.currentElement.getElementType()) {
+//                                             case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+//                                                     IPackageFragmentRoot root = (IPackageFragmentRoot)this.currentElement;
+//                                                     IPath rootPath = root.getPath();
+//                                                     IPath pkgPath = path.removeLastSegments(1);
+//                                                     String pkgName = Util.packageName(pkgPath.removeFirstSegments(rootPath.segmentCount()));
+//                                                     if (pkgName != null) {
+//                                                             pkgFragment = root.getPackageFragment(pkgName);
+//                                                     }
+//                                                     break;
+//                                             case IJavaElement.PACKAGE_FRAGMENT:
+//                                                     Openable pkg = (Openable)this.currentElement;
+//                                                     if (pkg.getPath().equals(path.removeLastSegments(1))) {
+//                                                             pkgFragment = (IPackageFragment)pkg;
+//                                                     } // else case of package x which is a prefix of x.y
+//                                                     break;
+//                                             case IJavaElement.COMPILATION_UNIT:
+//                                             case IJavaElement.CLASS_FILE:
+//                                                     pkgFragment = (IPackageFragment)this.currentElement.getParent();
+//                                                     break;
+//                                     }
+//                                     if (pkgFragment == null) {
+//                                             element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
+//                                     } else {
+//                                             if (elementType == IJavaElement.COMPILATION_UNIT) {
+//                                                     // create compilation unit handle 
+//                                                     // fileName validation has been done in elementType(IResourceDelta, int, boolean)
+//                                                     String fileName = path.lastSegment();
+//                                                     element = pkgFragment.getCompilationUnit(fileName);
+//                                             } else {
+//                                                     // create class file handle
+//                                                     // fileName validation has been done in elementType(IResourceDelta, int, boolean)
+//                                                     String fileName = path.lastSegment();
+//                                                     element = pkgFragment.getClassFile(fileName);
+//                                             }
+//                                     }
+//                             }
+//                             break;
+//             }
+//             if (element == null) {
+//                     return null;
+//             } else {
+//                     this.currentElement = (Openable)element;
+//                     return this.currentElement;
+//             }
+//     }
+       /**
+        * Note that the project is about to be deleted.
+        */
+//     public void deleting(IProject project) {
+//             
+//             try {
+//                     // discard indexing jobs that belong to this project so that the project can be 
+//                     // deleted without interferences from the index manager
+//                     this.indexManager.discardJobs(project.getName());
+//
+//                     JavaProject javaProject = (JavaProject)JavaCore.create(project);
+//                     
+//                     // remember roots of this project
+//                     if (this.removedRoots == null) {
+//                             this.removedRoots = new HashMap();
+//                     }
+//                     if (javaProject.isOpen()) {
+//                             this.removedRoots.put(javaProject, javaProject.getPackageFragmentRoots());
+//                     } else {
+//                             // compute roots without opening project
+//                             this.removedRoots.put(
+//                                     javaProject, 
+//                                     javaProject.computePackageFragmentRoots(
+//                                             javaProject.getResolvedClasspath(true), 
+//                                             false));
+//                     }
+//                     
+//                     javaProject.close();
+//
+//                     // workaround for bug 15168 circular errors not reported  
+//                     if (this.manager.javaProjectsCache == null) {
+//                             this.manager.javaProjectsCache = this.manager.getJavaModel().getJavaProjects();
+//                     }
+//                     this.removeFromParentInfo(javaProject);
+//
+//             } catch (JavaModelException e) {
+//             }
+//             
+//             this.addDependentProjects(project.getFullPath(), this.projectsToUpdate);
+//     }
+
+
+       /**
+        * Processing for an element that has been added:<ul>
+        * <li>If the element is a project, do nothing, and do not process
+        * children, as when a project is created it does not yet have any
+        * natures - specifically a java nature.
+        * <li>If the elemet is not a project, process it as added (see
+        * <code>basicElementAdded</code>.
+        * </ul>
+        * Delta argument could be null if processing an external JAR change
+        */
+//     protected void elementAdded(Openable element, IResourceDelta delta, RootInfo rootInfo) {
+//             int elementType = element.getElementType();
+//             
+//             if (elementType == IJavaElement.JAVA_PROJECT) {
+//                     // project add is handled by JavaProject.configure() because
+//                     // when a project is created, it does not yet have a java nature
+//                     if (delta != null && JavaProject.hasJavaNature((IProject)delta.getResource())) {
+//                             addToParentInfo(element);
+//                             if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
+//                                     Openable movedFromElement = (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment());
+//                                     currentDelta().movedTo(element, movedFromElement);
+//                             } else {
+//                                     currentDelta().added(element);
+//                             }
+//                             this.projectsToUpdate.add(element);
+//                             this.updateRoots(element.getPath(), delta);
+//                             this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
+//                     }
+//             } else {                        
+//                     addToParentInfo(element);
+//                     
+//                     // Force the element to be closed as it might have been opened 
+//                     // before the resource modification came in and it might have a new child
+//                     // For example, in an IWorkspaceRunnable:
+//                     // 1. create a package fragment p using a java model operation
+//                     // 2. open package p
+//                     // 3. add file X.java in folder p
+//                     // When the resource delta comes in, only the addition of p is notified, 
+//                     // but the package p is already opened, thus its children are not recomputed
+//                     // and it appears empty.
+//                     close(element);
+//                     
+//                     if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
+//                             IPath movedFromPath = delta.getMovedFromPath();
+//                             IResource res = delta.getResource();
+//                             IResource movedFromRes;
+//                             if (res instanceof IFile) {
+//                                     movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath);
+//                             } else {
+//                                     movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
+//                             }
+//                             
+//                             // find the element type of the moved from element
+//                             RootInfo movedFromInfo = this.enclosingRootInfo(movedFromPath, IResourceDelta.REMOVED);
+//                             int movedFromType = 
+//                                     this.elementType(
+//                                             movedFromRes, 
+//                                             IResourceDelta.REMOVED,
+//                                             element.getParent().getElementType(), 
+//                                             movedFromInfo);
+//                             
+//                             // reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
+//                             this.currentElement = null;
+//                     
+//                             // create the moved from element
+//                             Openable movedFromElement = 
+//                                     elementType != IJavaElement.JAVA_PROJECT && movedFromType == IJavaElement.JAVA_PROJECT ? 
+//                                             null : // outside classpath
+//                                             this.createElement(movedFromRes, movedFromType, movedFromInfo);
+//                             if (movedFromElement == null) {
+//                                     // moved from outside classpath
+//                                     currentDelta().added(element);
+//                             } else {
+//                                     currentDelta().movedTo(element, movedFromElement);
+//                             }
+//                     } else {
+//                             currentDelta().added(element);
+//                     }
+//                     
+//                     switch (elementType) {
+//                             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+//                                     // when a root is added, and is on the classpath, the project must be updated
+//                                     JavaProject project = (JavaProject) element.getJavaProject();
+//                                     this.projectsToUpdate.add(project);
+//                                     this.projectsForDependentNamelookupRefresh.add(project);
+//                                     
+//                                     break;
+//                             case IJavaElement.PACKAGE_FRAGMENT :
+//                                     // get rid of namelookup since it holds onto obsolete cached info 
+//                                     project = (JavaProject) element.getJavaProject();
+//                                     try {
+//                                             project.getJavaProjectElementInfo().setNameLookup(null);
+//                                             this.projectsForDependentNamelookupRefresh.add(project);                                                
+//                                     } catch (JavaModelException e) {
+//                                     }
+//                                     // add subpackages
+//                                     if (delta != null){
+//                                             PackageFragmentRoot root = element.getPackageFragmentRoot();
+//                                             String name = element.getElementName();
+//                                             IResourceDelta[] children = delta.getAffectedChildren();
+//                                             for (int i = 0, length = children.length; i < length; i++) {
+//                                                     IResourceDelta child = children[i];
+//                                                     IResource resource = child.getResource();
+//                                                     if (resource instanceof IFolder) {
+//                                                             String folderName = resource.getName();
+//                                                             if (Util.isValidFolderNameForPackage(folderName)) {
+//                                                                     String subpkgName = 
+//                                                                             name.length() == 0 ? 
+//                                                                                     folderName : 
+//                                                                                     name + "." + folderName; //$NON-NLS-1$
+//                                                                     Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
+//                                                                     this.updateIndex(subpkg, child);
+//                                                                     this.elementAdded(subpkg, child, rootInfo);
+//                                                             }
+//                                                     }
+//                                             }
+//                                     }
+//                                     break;
+//                     }
+//             }
+//     }
+
+       /**
+        * Generic processing for a removed element:<ul>
+        * <li>Close the element, removing its structure from the cache
+        * <li>Remove the element from its parent's cache of children
+        * <li>Add a REMOVED entry in the delta
+        * </ul>
+        * Delta argument could be null if processing an external JAR change
+        */
+//     protected void elementRemoved(Openable element, IResourceDelta delta, RootInfo rootInfo) {
+//             
+//             if (element.isOpen()) {
+//                     close(element);
+//             }
+//             removeFromParentInfo(element);
+//             int elementType = element.getElementType();
+//             if (delta != null && (delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+//                     IPath movedToPath = delta.getMovedToPath();
+//                     IResource res = delta.getResource();
+//                     IResource movedToRes;
+//                     switch (res.getType()) {
+//                             case IResource.PROJECT:
+//                                     movedToRes = res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
+//                                     break;
+//                             case IResource.FOLDER:
+//                                     movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
+//                                     break;
+//                             case IResource.FILE:
+//                                     movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
+//                                     break;
+//                             default:
+//                                     return;
+//                     }
+//
+//                     // find the element type of the moved from element
+//                     RootInfo movedToInfo = this.enclosingRootInfo(movedToPath, IResourceDelta.ADDED);
+//                     int movedToType = 
+//                             this.elementType(
+//                                     movedToRes, 
+//                                     IResourceDelta.ADDED,
+//                                     element.getParent().getElementType(), 
+//                                     movedToInfo);
+//
+//                     // reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
+//                     this.currentElement = null;
+//                     
+//                     // create the moved To element
+//                     Openable movedToElement = 
+//                             elementType != IJavaElement.JAVA_PROJECT && movedToType == IJavaElement.JAVA_PROJECT ? 
+//                                     null : // outside classpath
+//                                     this.createElement(movedToRes, movedToType, movedToInfo);
+//                     if (movedToElement == null) {
+//                             // moved outside classpath
+//                             currentDelta().removed(element);
+//                     } else {
+//                             currentDelta().movedFrom(element, movedToElement);
+//                     }
+//             } else {
+//                     currentDelta().removed(element);
+//             }
+//
+//             switch (elementType) {
+//                     case IJavaElement.JAVA_MODEL :
+//                             this.indexManager.reset();
+//                             break;
+//                     case IJavaElement.JAVA_PROJECT :
+//                             this.manager.removePerProjectInfo(
+//                                     (JavaProject) element);
+//                             this.updateRoots(element.getPath(), delta);
+//                             this.projectsForDependentNamelookupRefresh.add((JavaProject) element);
+//                             break;
+//                     case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+//                             JavaProject project = (JavaProject) element.getJavaProject();
+//                             this.projectsToUpdate.add(project);
+//                             this.projectsForDependentNamelookupRefresh.add(project);                                
+//                             break;
+//                     case IJavaElement.PACKAGE_FRAGMENT :
+//                             //1G1TW2T - get rid of namelookup since it holds onto obsolete cached info 
+//                             project = (JavaProject) element.getJavaProject();
+//                             try {
+//                                     project.getJavaProjectElementInfo().setNameLookup(null); 
+//                                     this.projectsForDependentNamelookupRefresh.add(project);
+//                             } catch (JavaModelException e) { 
+//                             }
+//                             // remove subpackages
+//                             if (delta != null){
+//                                     PackageFragmentRoot root = element.getPackageFragmentRoot();
+//                                     String name = element.getElementName();
+//                                     IResourceDelta[] children = delta.getAffectedChildren();
+//                                     for (int i = 0, length = children.length; i < length; i++) {
+//                                             IResourceDelta child = children[i];
+//                                             IResource resource = child.getResource();
+//                                             if (resource instanceof IFolder) {
+//                                                     String folderName = resource.getName();
+//                                                     if (Util.isValidFolderNameForPackage(folderName)) {
+//                                                             String subpkgName = 
+//                                                                     name.length() == 0 ? 
+//                                                                             folderName : 
+//                                                                             name + "." + folderName; //$NON-NLS-1$
+//                                                             Openable subpkg = (Openable)root.getPackageFragment(subpkgName);
+//                                                             this.updateIndex(subpkg, child);
+//                                                             this.elementRemoved(subpkg, child, rootInfo);
+//                                                     }
+//                                             }
+//                                     }
+//                             }
+//                             break;
+//             }
+//     }
+
+       /*
+        * Returns the type of the java element the given delta matches to.
+        * Returns NON_JAVA_RESOURCE if unknown (e.g. a non-java resource or excluded .java file)
+        */
+//     private int elementType(IResource res, int kind, int parentType, RootInfo rootInfo) {
+//             switch (parentType) {
+//                     case IJavaElement.JAVA_MODEL:
+//                             // case of a movedTo or movedFrom project (other cases are handled in processResourceDelta(...)
+//                             return IJavaElement.JAVA_PROJECT;
+//                     case NON_JAVA_RESOURCE:
+//                     case IJavaElement.JAVA_PROJECT:
+//                             if (rootInfo == null) {
+//                                     rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
+//                             }
+//                             if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
+//                                     return IJavaElement.PACKAGE_FRAGMENT_ROOT;
+//                             } else {
+//                                     return NON_JAVA_RESOURCE; // not yet in a package fragment root or root of another project
+//                             }
+//                     case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+//                     case IJavaElement.PACKAGE_FRAGMENT:
+//                             if (rootInfo == null) {
+//                                     rootInfo = this.enclosingRootInfo(res.getFullPath(), kind);
+//                             }
+//                             if (rootInfo == null || Util.isExcluded(res, rootInfo.exclusionPatterns)) {
+//                                     return NON_JAVA_RESOURCE;
+//                             }
+//                             if (res instanceof IFolder) {
+//                                     if (Util.isValidFolderNameForPackage(res.getName())) {
+//                                             return IJavaElement.PACKAGE_FRAGMENT;
+//                                     } else {
+//                                             return NON_JAVA_RESOURCE;
+//                                     }
+//                             } else {
+//                                     String fileName = res.getName();
+//                                     if (Util.isValidCompilationUnitName(fileName)) {
+//                                             return IJavaElement.COMPILATION_UNIT;
+//                                     } else if (Util.isValidClassFileName(fileName)) {
+//                                             return IJavaElement.CLASS_FILE;
+//                                     } else if (this.rootInfo(res.getFullPath(), kind) != null) {
+//                                             // case of proj=src=bin and resource is a jar file on the classpath
+//                                             return IJavaElement.PACKAGE_FRAGMENT_ROOT;
+//                                     } else {
+//                                             return NON_JAVA_RESOURCE;
+//                                     }
+//                             }
+//                     default:
+//                             return NON_JAVA_RESOURCE;
+//             }
+//     }
+
+       /**
+        * Answer a combination of the lastModified stamp and the size.
+        * Used for detecting external JAR changes
+        */
+       public static long getTimeStamp(File file) {
+               return file.lastModified() + file.length();
+       }
+
+//     public void initializeRoots() {
+//             // remember roots infos as old roots infos
+//             this.oldRoots = this.roots == null ? new HashMap() : this.roots;
+//             this.oldOtherRoots = this.otherRoots == null ? new HashMap() : this.otherRoots;
+//             
+//             // recompute root infos only if necessary
+//             if (!rootsAreStale) return;
+//
+//             this.roots = new HashMap();
+//             this.otherRoots = new HashMap();
+//             this.sourceAttachments = new HashMap();
+//             
+//             IJavaModel model = this.manager.getJavaModel();
+//             IJavaProject[] projects;
+//             try {
+//                     projects = model.getJavaProjects();
+//             } catch (JavaModelException e) {
+//                     // nothing can be done
+//                     return;
+//             }
+//             for (int i = 0, length = projects.length; i < length; i++) {
+//                     IJavaProject project = projects[i];
+//                     IClasspathEntry[] classpath;
+//                     try {
+//                             classpath = project.getResolvedClasspath(true);
+//                     } catch (JavaModelException e) {
+//                             // continue with next project
+//                             continue;
+//                     }
+//                     for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) {
+//                             IClasspathEntry entry = classpath[j];
+//                             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
+//                             
+                               // root path
+//                             IPath path = entry.getPath();
+//                             if (this.roots.get(path) == null) {
+//                                     this.roots.put(path, new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars()));
+//                             } else {
+//                                     ArrayList rootList = (ArrayList)this.otherRoots.get(path);
+//                                     if (rootList == null) {
+//                                             rootList = new ArrayList();
+//                                             this.otherRoots.put(path, rootList);
+//                                     }
+//                                     rootList.add(new RootInfo(project, path, ((ClasspathEntry)entry).fullExclusionPatternChars()));
+//                             }
+//                             
+//                             // source attachment path
+//                             if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue;
+//                             QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$;
+//                             String propertyString = null;
+//                             try {
+//                                     propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
+//                             } catch (CoreException e) {
+//                                     continue;
+//                             }
+//                             IPath sourceAttachmentPath;
+//                             if (propertyString != null) {
+//                                     int index= propertyString.lastIndexOf(JarPackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
+//                                     sourceAttachmentPath = (index < 0) ?  new Path(propertyString) : new Path(propertyString.substring(0, index));
+//                             } else {
+//                                     sourceAttachmentPath = entry.getSourceAttachmentPath();
+//                             }
+//                             if (sourceAttachmentPath != null) {
+//                                     this.sourceAttachments.put(sourceAttachmentPath, path);
+//                             }
+//                     }
+//             }
+//             this.rootsAreStale = false;
+//     }
+
+       /*
+        * Returns whether a given delta contains some information relevant to the JavaModel,
+        * in particular it will not consider SYNC or MARKER only deltas.
+        */
+       public boolean isAffectedBy(IResourceDelta rootDelta){
+               //if (rootDelta == null) System.out.println("NULL DELTA");
+               //long start = System.currentTimeMillis();
+               if (rootDelta != null) {
+                       // use local exception to quickly escape from delta traversal
+                       class FoundRelevantDeltaException extends RuntimeException {}
+                       try {
+                               rootDelta.accept(new IResourceDeltaVisitor() {
+                                       public boolean visit(IResourceDelta delta) throws CoreException {
+                                               switch (delta.getKind()){
+                                                       case IResourceDelta.ADDED :
+                                                       case IResourceDelta.REMOVED :
+                                                               throw new FoundRelevantDeltaException();
+                                                       case IResourceDelta.CHANGED :
+                                                               // if any flag is set but SYNC or MARKER, this delta should be considered
+                                                               if (delta.getAffectedChildren().length == 0 // only check leaf delta nodes
+                                                                               && (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
+                                                                       throw new FoundRelevantDeltaException();
+                                                               }
+                                               }
+                                               return true;
+                                       }
+                               });
+                       } catch(FoundRelevantDeltaException e) {
+                               //System.out.println("RELEVANT DELTA detected in: "+ (System.currentTimeMillis() - start));
+                               return true;
+                       } catch(CoreException e) { // ignore delta if not able to traverse
+                       }
+               }
+               //System.out.println("IGNORE SYNC DELTA took: "+ (System.currentTimeMillis() - start));
+               return false;
+       }
+       
+       /*
+        * Returns whether the given resource is in one of the given output folders and if
+        * it is filtered out from this output folder.
+        */
+       private boolean isResFilteredFromOutput(OutputsInfo info, IResource res, int elementType) {
+               if (info != null) {
+                       IPath resPath = res.getFullPath();
+                       for (int i = 0;  i < info.outputCount; i++) {
+                               if (info.paths[i].isPrefixOf(resPath)) {
+                                       if (info.traverseModes[i] != IGNORE) {
+                                               // case of bin=src
+                                               if (info.traverseModes[i] == SOURCE && elementType == IJavaElement.CLASS_FILE) {
+                                                       return true;
+                                               } else {
+                                                       // case of .class file under project and no source folder
+                                                       // proj=bin
+                                                       if (elementType == IJavaElement.JAVA_PROJECT 
+                                                                       && res instanceof IFile 
+                                                                       && PHPFileUtil.isPHPFile((IFile)res)) {
+                                                               return true;
+                                                       }
+                                               }
+                                       } else {
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Generic processing for elements with changed contents:<ul>
+        * <li>The element is closed such that any subsequent accesses will re-open
+        * the element reflecting its new structure.
+        * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
+        * </ul>
+        */
+//     protected void nonJavaResourcesChanged(Openable element, IResourceDelta delta)
+//             throws JavaModelException {
+//
+//             // reset non-java resources if element was open
+//             if (element.isOpen()) {
+//                     JavaElementInfo info = (JavaElementInfo)element.getElementInfo();
+//                     switch (element.getElementType()) {
+//                             case IJavaElement.JAVA_MODEL :
+//                                     ((JavaModelInfo) info).nonJavaResources = null;
+//                                     currentDelta().addResourceDelta(delta);
+//                                     return;
+//                             case IJavaElement.JAVA_PROJECT :
+//                                     ((JavaProjectElementInfo) info).setNonJavaResources(null);
+//     
+//                                     // if a package fragment root is the project, clear it too
+//                                     JavaProject project = (JavaProject) element;
+//                                     PackageFragmentRoot projectRoot =
+//                                             (PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject());
+//                                     if (projectRoot.isOpen()) {
+//                                             ((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources(
+//                                                     null);
+//                                     }
+//                                     break;
+//                             case IJavaElement.PACKAGE_FRAGMENT :
+//                                      ((PackageFragmentInfo) info).setNonJavaResources(null);
+//                                     break;
+//                             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+//                                      ((PackageFragmentRootInfo) info).setNonJavaResources(null);
+//                     }
+//             }
+//
+//             JavaElementDelta elementDelta = currentDelta().find(element);
+//             if (elementDelta == null) {
+//                     currentDelta().changed(element, IJavaElementDelta.F_CONTENT);
+//                     elementDelta = currentDelta().find(element);
+//             }
+//             elementDelta.addResourceDelta(delta);
+//     }
+//     private OutputsInfo outputsInfo(RootInfo rootInfo, IResource res) {
+//             try {
+//                     IJavaProject proj =
+//                             rootInfo == null ?
+//                                     (IJavaProject)this.createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) :
+//                                     rootInfo.project;
+//                     if (proj != null) {
+//                             IPath projectOutput = proj.getOutputLocation();
+//                             int traverseMode = IGNORE;
+//                             if (proj.getProject().getFullPath().equals(projectOutput)){ // case of proj==bin==src
+//                                     return new OutputsInfo(new IPath[] {projectOutput}, new int[] {SOURCE}, 1);
+//                             } else {
+//                                     IClasspathEntry[] classpath = proj.getResolvedClasspath(true);
+//                                     IPath[] outputs = new IPath[classpath.length+1];
+//                                     int[] traverseModes = new int[classpath.length+1];
+//                                     int outputCount = 1;
+//                                     outputs[0] = projectOutput;
+//                                     traverseModes[0] = traverseMode;
+//                                     for (int i = 0, length = classpath.length; i < length; i++) {
+//                                             IClasspathEntry entry = classpath[i];
+//                                             IPath entryPath = entry.getPath();
+//                                             IPath output = entry.getOutputLocation();
+//                                             if (output != null) {
+//                                                     outputs[outputCount] = output;
+//                                                     // check case of src==bin
+//                                                     if (entryPath.equals(output)) {
+//                                                             traverseModes[outputCount++] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
+//                                                     } else {
+//                                                             traverseModes[outputCount++] = IGNORE;
+//                                                     }
+//                                             }
+//                                             
+//                                             // check case of src==bin
+//                                             if (entryPath.equals(projectOutput)) {
+//                                                     traverseModes[0] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
+//                                             }
+//                                     }
+//                                     return new OutputsInfo(outputs, traverseModes, outputCount);
+//                             }
+//                     }
+//             } catch (JavaModelException e) {
+//             }
+//             return null;
+//     }
+       
+       /**
+        * Check whether the updated file is affecting some of the properties of a given project (like
+        * its classpath persisted as a file).
+        * Also force classpath problems to be refresh if not running in autobuild mode.
+        * NOTE: It can induce resource changes, and cannot be called during POST_CHANGE notification.
+        *
+        */
+//     public void performPreBuildCheck(
+//             IResourceDelta delta,
+//             IJavaElement parent) {
+//     
+//             IResource resource = delta.getResource();
+//             IJavaElement element = null;
+//             boolean processChildren = false;
+//     
+//             switch (resource.getType()) {
+//     
+//                     case IResource.ROOT :
+//                             if (delta.getKind() == IResourceDelta.CHANGED) {
+//                                     element = JavaCore.create(resource);
+//                                     processChildren = true;
+//                             }
+//                             break;
+//                     case IResource.PROJECT :
+//                             int kind = delta.getKind();
+//                             switch (kind) {
+//                                     case IResourceDelta.CHANGED:
+//                                             // do not visit non-java projects (see bug 16140 Non-java project gets .classpath)
+//                                             IProject project = (IProject)resource;
+//                                             if (JavaProject.hasJavaNature(project)) {
+//                                                     element = JavaCore.create(resource);
+//                                                     processChildren = true;
+//                                             } else if (JavaModelManager.getJavaModelManager().getJavaModel().findJavaProject(project) != null) {
+//                                                     // project had the java nature
+//                                                     this.rootsAreStale = true;
+//
+//                                                     // remove classpath cache so that initializeRoots() will not consider the project has a classpath
+//                                                     this.manager.removePerProjectInfo((JavaProject)JavaCore.create(project));
+//                                             }
+//                                             break;
+//                                     case IResourceDelta.ADDED:
+//                                             this.rootsAreStale = true;
+//                                             break;
+//                                     case IResourceDelta.REMOVED:
+//                                             // remove classpath cache so that initializeRoots() will not consider the project has a classpath
+//                                             this.manager.removePerProjectInfo((JavaProject)JavaCore.create(resource));
+//                                             
+//                                             this.rootsAreStale = true;
+//                                             break;
+//                             }
+//                             break;
+//                     case IResource.FILE :
+//                             if (parent.getElementType() == IJavaElement.JAVA_PROJECT) {
+//                                     IFile file = (IFile) resource;
+//                                     JavaProject project = (JavaProject) parent;
+//     
+//                                     /* check classpath file change */
+//                                     if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
+//                                             reconcileClasspathFileUpdate(delta, file, project);
+//                                             this.rootsAreStale = true;
+//                                             break;
+//                                     }
+////                                   /* check custom preference file change */
+////                                   if (file.getName().equals(JavaProject.PREF_FILENAME)) {
+////                                           reconcilePreferenceFileUpdate(delta, file, project);
+////                                           break;
+////                                   }
+//                             }
+//                             break;
+//             }
+//             if (processChildren) {
+//                     IResourceDelta[] children = delta.getAffectedChildren();
+//                     for (int i = 0; i < children.length; i++) {
+//                             performPreBuildCheck(children[i], element);
+//                     }
+//             }
+//     }
+       
+//     private void popUntilPrefixOf(IPath path) {
+//             while (this.currentElement != null) {
+//                     IPath currentElementPath = null;
+//                     if (this.currentElement instanceof IPackageFragmentRoot) {
+//                             currentElementPath = ((IPackageFragmentRoot)this.currentElement).getPath();
+//                     } else {
+//                             IResource currentElementResource = this.currentElement.getResource();
+//                             if (currentElementResource != null) {
+//                                     currentElementPath = currentElementResource.getFullPath();
+//                             }
+//                     }
+//                     if (currentElementPath != null) {
+//                             if (this.currentElement instanceof IPackageFragment 
+//                                     && this.currentElement.getElementName().length() == 0
+//                                     && currentElementPath.segmentCount() != path.segmentCount()-1) {
+//                                             // default package and path is not a direct child
+//                                             this.currentElement = (Openable)this.currentElement.getParent();
+//                             }
+//                             if (currentElementPath.isPrefixOf(path)) {
+//                                     return;
+//                             }
+//                     }
+//                     this.currentElement = (Openable)this.currentElement.getParent();
+//             }
+//     }
+
+       /**
+        * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
+        * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
+        * relevant <code>JavaModel</code>s.
+        */
+//     public IJavaElementDelta processResourceDelta(IResourceDelta changes) {
+//
+//             try {
+//                     IJavaModel model = this.manager.getJavaModel();
+//                     if (!model.isOpen()) {
+//                             // force opening of java model so that java element delta are reported
+//                             try {
+//                                     model.open(null);
+//                             } catch (JavaModelException e) {
+//                                     if (VERBOSE) {
+//                                             e.printStackTrace();
+//                                     }
+//                                     return null;
+//                             }
+//                     }
+//                     this.initializeRoots();
+//                     this.currentElement = null;
+//                     
+//                     // get the workspace delta, and start processing there.
+//                     IResourceDelta[] deltas = changes.getAffectedChildren();
+//                     for (int i = 0; i < deltas.length; i++) {
+//                             IResourceDelta delta = deltas[i];
+//                             IResource res = delta.getResource();
+//                             
+//                             // find out the element type
+//                             RootInfo rootInfo = null;
+//                             int elementType;
+//                             IProject proj = (IProject)res;
+//                             boolean wasJavaProject = this.manager.getJavaModel().findJavaProject(proj) != null;
+//                             boolean isJavaProject = JavaProject.hasJavaNature(proj);
+//                             if (!wasJavaProject && !isJavaProject) {
+//                                     elementType = NON_JAVA_RESOURCE;
+//                             } else {
+//                                     rootInfo = this.enclosingRootInfo(res.getFullPath(), delta.getKind());
+//                                     if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
+//                                             elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
+//                                     } else {
+//                                             elementType = IJavaElement.JAVA_PROJECT; 
+//                                     }
+//                             }
+//                             
+//                             // traverse delta
+//                             if (!this.traverseDelta(delta, elementType, rootInfo, null) 
+//                                             || (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project has changed nature (description or open/closed)
+//                                     try {
+//                                             // add child as non java resource
+//                                             nonJavaResourcesChanged((JavaModel)model, delta);
+//                                     } catch (JavaModelException e) {
+//                                     }
+//                             }
+//
+//                     }
+//                     
+//                     // update package fragment roots of projects that were affected
+//                     Iterator iterator = this.projectsToUpdate.iterator();
+//                     while (iterator.hasNext()) {
+//                             JavaProject project = (JavaProject)iterator.next();
+//                             project.updatePackageFragmentRoots();
+//                     }
+//     
+//                     updateDependentNamelookups();
+//
+//                     return this.currentDelta;
+//             } finally {
+//                     this.currentDelta = null;
+//                     this.projectsToUpdate.clear();
+//                     this.projectsForDependentNamelookupRefresh.clear();
+//             }
+//     }
+
+       /**
+        * Update the JavaModel according to a .classpath file change. The file can have changed as a result of a previous
+        * call to JavaProject#setRawClasspath or as a result of some user update (through repository)
+        */
+//     void reconcileClasspathFileUpdate(IResourceDelta delta, IFile file, JavaProject project) {
+//                     
+//             switch (delta.getKind()) {
+//                     case IResourceDelta.REMOVED : // recreate one based on in-memory classpath
+//                             try {
+//                                     JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
+//                                     if (info.classpath != null) { // if there is an in-memory classpath
+//                                             project.saveClasspath(info.classpath, info.outputLocation);
+//                                     }
+//                             } catch (JavaModelException e) {
+//                                     if (project.getProject().isAccessible()) {
+//                                             Util.log(e, "Could not save classpath for "+ project.getPath()); //$NON-NLS-1$
+//                                     }
+//                             }
+//                             break;
+//                     case IResourceDelta.CHANGED :
+//                             if ((delta.getFlags() & IResourceDelta.CONTENT) == 0  // only consider content change
+//                                             && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario (see http://dev.eclipse.org/bugs/show_bug.cgi?id=21420)
+//                                     break;
+//                     case IResourceDelta.ADDED :
+//                             // check if any actual difference
+//                             project.flushClasspathProblemMarkers(false, true);
+//                             boolean wasSuccessful = false; // flag recording if .classpath file change got reflected
+//                             try {
+//                                     // force to (re)read the property file
+//                                     IClasspathEntry[] fileEntries = project.readClasspathFile(true/*create markers*/, false/*don't log problems*/);
+//                                     if (fileEntries == null)
+//                                             break; // could not read, ignore 
+//                                     JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
+//                                     if (info.classpath != null) { // if there is an in-memory classpath
+//                                             if (project.isClasspathEqualsTo(info.classpath, info.outputLocation, fileEntries)) {
+//                                                     wasSuccessful = true;
+//                                                     break;
+//                                             }
+//                                     }
+//             
+//                                     // will force an update of the classpath/output location based on the file information
+//                                     // extract out the output location
+//                                     IPath outputLocation = null;
+//                                     if (fileEntries != null && fileEntries.length > 0) {
+//                                             IClasspathEntry entry = fileEntries[fileEntries.length - 1];
+//                                             if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
+//                                                     outputLocation = entry.getPath();
+//                                                     IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1];
+//                                                     System.arraycopy(fileEntries, 0, copy, 0, copy.length);
+//                                                     fileEntries = copy;
+//                                             }
+//                                     }
+//                                     // restore output location                              
+//                                     if (outputLocation == null) {
+//                                             outputLocation = SetClasspathOperation.ReuseOutputLocation;
+//                                             // clean mode will also default to reusing current one
+//                                     }
+//                                     project.setRawClasspath(
+//                                             fileEntries, 
+//                                             outputLocation, 
+//                                             null, // monitor
+//                                             true, // canChangeResource
+//                                             project.getResolvedClasspath(true), // ignoreUnresolvedVariable
+//                                             true, // needValidation
+//                                             false); // no need to save
+//                                     
+//                                     // if reach that far, the classpath file change got absorbed
+//                                     wasSuccessful = true;
+//                             } catch (RuntimeException e) {
+//                                     // setRawClasspath might fire a delta, and a listener may throw an exception
+//                                     if (project.getProject().isAccessible()) {
+//                                             Util.log(e, "Could not set classpath for "+ project.getPath()); //$NON-NLS-1$
+//                                     }
+//                                     break;
+//                             } catch (JavaModelException e) { // CP failed validation
+//                                     if (project.getProject().isAccessible()) {
+//                                             if (e.getJavaModelStatus().getException() instanceof CoreException) {
+//                                                     // happens if the .classpath could not be written to disk
+//                                                     project.createClasspathProblemMarker(new JavaModelStatus(
+//                                                                     IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+//                                                                     Util.bind("classpath.couldNotWriteClasspathFile", project.getElementName(), e.getMessage()))); //$NON-NLS-1$
+//                                             } else {
+//                                                     project.createClasspathProblemMarker(new JavaModelStatus(
+//                                                                     IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+//                                                                     Util.bind("classpath.invalidClasspathInClasspathFile", project.getElementName(), e.getMessage()))); //$NON-NLS-1$
+//                                             }                       
+//                                     }
+//                                     break;
+//                             } finally {
+//                                     if (!wasSuccessful) { 
+//                                             try {
+//                                                     project.setRawClasspath0(JavaProject.INVALID_CLASSPATH);
+//                                                     project.updatePackageFragmentRoots();
+//                                             } catch (JavaModelException e) {
+//                                             }
+//                                     }
+//                             }
+//             }
+//     }
+
+       /**
+        * Update the JavaModel according to a .jprefs file change. The file can have changed as a result of a previous
+        * call to JavaProject#setOptions or as a result of some user update (through repository)
+        * Unused until preference file get shared (.jpref)
+        */
+//     void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file, JavaProject project) {
+//                     
+//             switch (delta.getKind()) {
+//                     case IResourceDelta.REMOVED : // flush project custom settings
+//                             project.setOptions(null);
+//                             return;
+//                     case IResourceDelta.CHANGED :
+//                             if ((delta.getFlags() & IResourceDelta.CONTENT) == 0  // only consider content change
+//                                             && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario
+//                                     break;
+//                             identityCheck : { // check if any actual difference
+//                                     // force to (re)read the property file
+//                                     Preferences filePreferences = project.loadPreferences();
+//                                     if (filePreferences == null){ 
+//                                             project.setOptions(null); // should have got removed delta.
+//                                             return;
+//                                     }
+//                                     Preferences projectPreferences = project.getPreferences();
+//                                     if (projectPreferences == null) return; // not a Java project
+//                                             
+//                                     // compare preferences set to their default
+//                                     String[] defaultProjectPropertyNames = projectPreferences.defaultPropertyNames();
+//                                     String[] defaultFilePropertyNames = filePreferences.defaultPropertyNames();
+//                                     if (defaultProjectPropertyNames.length == defaultFilePropertyNames.length) {
+//                                             for (int i = 0; i < defaultProjectPropertyNames.length; i++){
+//                                                     String propertyName = defaultProjectPropertyNames[i];
+//                                                     if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
+//                                                             break identityCheck;
+//                                                     }
+//                                             }               
+//                                     } else break identityCheck;
+//
+//                                     // compare custom preferences not set to their default
+//                                     String[] projectPropertyNames = projectPreferences.propertyNames();
+//                                     String[] filePropertyNames = filePreferences.propertyNames();
+//                                     if (projectPropertyNames.length == filePropertyNames.length) {
+//                                             for (int i = 0; i < projectPropertyNames.length; i++){
+//                                             String propertyName = projectPropertyNames[i];
+//                                                     if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){
+//                                                             break identityCheck;
+//                                                     }
+//                                             }               
+//                                     } else break identityCheck;
+//                                     
+//                                     // identical - do nothing
+//                                     return;
+//                             }
+//                     case IResourceDelta.ADDED :
+//                             // not identical, create delta and reset cached preferences
+//                             project.setPreferences(null);
+//                             // create delta
+//                             //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED);                          
+//             }
+//     }
+
+       /**
+        * Removes the given element from its parents cache of children. If the
+        * element does not have a parent, or the parent is not currently open,
+        * this has no effect. 
+        */
+       protected void removeFromParentInfo(Openable child) {
+
+               Openable parent = (Openable) child.getParent();
+               if (parent != null && parent.isOpen()) {
+                       try {
+                               JavaElementInfo info = (JavaElementInfo)parent.getElementInfo();
+                               info.removeChild(child);
+                       } catch (JavaModelException e) {
+                               // do nothing - we already checked if open
+                       }
+               }
+       }
+       /**
+        * Notification that some resource changes have happened
+        * on the platform, and that the Java Model should update any required
+        * internal structures such that its elements remain consistent.
+        * Translates <code>IResourceDeltas</code> into <code>IJavaElementDeltas</code>.
+        *
+        * @see IResourceDelta
+        * @see IResource 
+        */
+       public void resourceChanged(IResourceChangeEvent event) {
+       
+               if (event.getSource() instanceof IWorkspace) {
+                       IResource resource = event.getResource();
+                       IResourceDelta delta = event.getDelta();
+                       
+                       switch(event.getType()){
+                               case IResourceChangeEvent.PRE_DELETE :
+                                       try {
+                                               if(resource.getType() == IResource.PROJECT 
+                                                       && ((IProject) resource).hasNature(JavaCore.NATURE_ID)) {
+                                               // TODO khartlage temp-del
+//                                                     this.deleting((IProject)resource);
+                                               }
+                                       } catch(CoreException e){
+                                       }
+                                       return;
+                                       
+                               case IResourceChangeEvent.PRE_AUTO_BUILD :
+//                     TODO khartlage temp-del
+//                                     if(isAffectedBy(delta)) { // avoid populating for SYNC or MARKER deltas
+//                                             this.checkProjectsBeingAddedOrRemoved(delta);
+//                                             
+//                                             // update the classpath related markers
+//                                             this.updateClasspathMarkers();
+//     
+//                                             // the following will close project if affected by the property file change
+//                                             try {
+//                                                     // don't fire classpath change deltas right away, but batch them
+//                                                     this.manager.stopDeltas();
+//                                                     this.performPreBuildCheck(delta, null); 
+//                                             } finally {
+//                                                     this.manager.startDeltas();
+//                                             }
+//                                     }
+                                       // only fire already computed deltas (resource ones will be processed in post change only)
+                                       this.manager.fire(null, ElementChangedEvent.PRE_AUTO_BUILD);
+                                       break;
+
+                               case IResourceChangeEvent.POST_AUTO_BUILD :
+//                     TODO khartlage temp-del
+//                                     JavaBuilder.finishedBuilding(event);
+                                       break;
+                                       
+                               case IResourceChangeEvent.POST_CHANGE :
+//                     TODO khartlage temp-del
+//                                     if (isAffectedBy(delta)) {
+//                                             try {
+//                                                     if (this.refreshedElements != null) {
+//                                                             try {
+//                                                                     createExternalArchiveDelta(null);
+//                                                             } catch (JavaModelException e) {
+//                                                                     e.printStackTrace();
+//                                                             }
+//                                                     }
+//                                                     IJavaElementDelta translatedDelta = this.processResourceDelta(delta);
+//                                                     if (translatedDelta != null) { 
+//                                                             this.manager.registerJavaModelDelta(translatedDelta);
+//                                                     }
+//                                                     this.manager.fire(null, ElementChangedEvent.POST_CHANGE);
+//                                             } finally {
+//                                                     // workaround for bug 15168 circular errors not reported 
+//                                                     this.manager.javaProjectsCache = null;
+//                                                     this.removedRoots = null;
+//                                             }
+//                                     }
+                       }
+               }
+       }
+       /*
+        * Finds the root info this path is included in.
+        * Returns null if not found.
+        */
+       RootInfo enclosingRootInfo(IPath path, int kind) {
+               while (path != null && path.segmentCount() > 0) {
+                       RootInfo rootInfo =  this.rootInfo(path, kind);
+                       if (rootInfo != null) return rootInfo;
+                       path = path.removeLastSegments(1);
+               }
+               return null;
+       }
+       /*
+        * Returns the root info for the given path. Look in the old roots table if kind is REMOVED.
+        */
+       RootInfo rootInfo(IPath path, int kind) {
+               if (kind == IResourceDelta.REMOVED) {
+                       return (RootInfo)this.oldRoots.get(path);
+               } else {
+                       return (RootInfo)this.roots.get(path);
+               }
+       }
+       /*
+        * Returns the other root infos for the given path. Look in the old other roots table if kind is REMOVED.
+        */
+       ArrayList otherRootsInfo(IPath path, int kind) {
+               if (kind == IResourceDelta.REMOVED) {
+                       return (ArrayList)this.oldOtherRoots.get(path);
+               } else {
+                       return (ArrayList)this.otherRoots.get(path);
+               }
+       }       
+
+       /**
+        * Converts an <code>IResourceDelta</code> and its children into
+        * the corresponding <code>IJavaElementDelta</code>s.
+        * Return whether the delta corresponds to a java element.
+        * If it is not a java element, it will be added as a non-java
+        * resource by the sender of this method.
+        */
+//     protected boolean traverseDelta(
+//             IResourceDelta delta, 
+//             int elementType, 
+//             RootInfo rootInfo,
+//             OutputsInfo outputsInfo) {
+//                     
+//             IResource res = delta.getResource();
+//     
+//             // set stack of elements
+//             if (this.currentElement == null && rootInfo != null) {
+//                     this.currentElement = (Openable)rootInfo.project;
+//             }
+//             
+//             // process current delta
+//             boolean processChildren = true;
+//             if (res instanceof IProject) {
+//                     processChildren = 
+//                             this.updateCurrentDeltaAndIndex(
+//                                     delta, 
+//                                     elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ? 
+//                                             IJavaElement.JAVA_PROJECT : // case of prj=src
+//                                             elementType, 
+//                                     rootInfo);
+//             } else if (rootInfo != null) {
+//                     processChildren = this.updateCurrentDeltaAndIndex(delta, elementType, rootInfo);
+//             } else {
+//                     // not yet inside a package fragment root
+//                     processChildren = true;
+//             }
+//             
+//             // get the project's output locations and traverse mode
+//             if (outputsInfo == null) outputsInfo = this.outputsInfo(rootInfo, res);
+//     
+//             // process children if needed
+//             if (processChildren) {
+//                     IResourceDelta[] children = delta.getAffectedChildren();
+//                     boolean oneChildOnClasspath = false;
+//                     int length = children.length;
+//                     IResourceDelta[] orphanChildren = null;
+//                     Openable parent = null;
+//                     boolean isValidParent = true;
+//                     for (int i = 0; i < length; i++) {
+//                             IResourceDelta child = children[i];
+//                             IResource childRes = child.getResource();
+//     
+//                             // check source attachment change
+//                             this.checkSourceAttachmentChange(child, childRes);
+//                             
+//                             // find out whether the child is a package fragment root of the current project
+//                             IPath childPath = childRes.getFullPath();
+//                             int childKind = child.getKind();
+//                             RootInfo childRootInfo = this.rootInfo(childPath, childKind);
+//                             if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
+//                                     // package fragment root of another project (dealt with later)
+//                                     childRootInfo = null;
+//                             }
+//                             
+//                             // compute child type
+//                             int childType = 
+//                                     this.elementType(
+//                                             childRes, 
+//                                             childKind,
+//                                             elementType, 
+//                                             rootInfo == null ? childRootInfo : rootInfo
+//                                     );
+//                                             
+//                             // is childRes in the output folder and is it filtered out ?
+//                             boolean isResFilteredFromOutput = this.isResFilteredFromOutput(outputsInfo, childRes, childType);
+//
+//                             boolean isNestedRoot = rootInfo != null && childRootInfo != null;
+//                             if (!isResFilteredFromOutput 
+//                                             && !isNestedRoot) { // do not treat as non-java rsc if nested root
+//                                     if (!this.traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo)) { // traverse delta for child in the same project
+//                                             // it is a non-java resource
+//                                             try {
+//                                                     if (rootInfo != null) { // if inside a package fragment root
+//                                                             if (!isValidParent) continue; 
+//                                                             if (parent == null) {
+//                                                                     // find the parent of the non-java resource to attach to
+//                                                                     if (this.currentElement == null 
+//                                                                                     || !this.currentElement.getJavaProject().equals(rootInfo.project)) {
+//                                                                             // force the currentProject to be used
+//                                                                             this.currentElement = (Openable)rootInfo.project;
+//                                                                     }
+//                                                                     if (elementType == IJavaElement.JAVA_PROJECT
+//                                                                             || (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT 
+//                                                                                     && res instanceof IProject)) { 
+//                                                                             // NB: attach non-java resource to project (not to its package fragment root)
+//                                                                             parent = (Openable)rootInfo.project;
+//                                                                     } else {
+//                                                                             parent = this.createElement(res, elementType, rootInfo);
+//                                                                     }
+//                                                                     if (parent == null) {
+//                                                                             isValidParent = false;
+//                                                                             continue;
+//                                                                     }
+//                                                             }
+//                                                             // add child as non java resource
+//                                                             nonJavaResourcesChanged(parent, child);
+//                                                     } else {
+//                                                             // the non-java resource (or its parent folder) will be attached to the java project
+//                                                             if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
+//                                                             orphanChildren[i] = child;
+//                                                     }
+//                                             } catch (JavaModelException e) {
+//                                             }
+//                                     } else {
+//                                             oneChildOnClasspath = true;
+//                                     }
+//                             } else {
+//                                     oneChildOnClasspath = true; // to avoid reporting child delta as non-java resource delta
+//                             }
+//                                                             
+//                             // if child is a nested root 
+//                             // or if it is not a package fragment root of the current project
+//                             // but it is a package fragment root of another project, traverse delta too
+//                             if (isNestedRoot 
+//                                             || (childRootInfo == null && (childRootInfo = this.rootInfo(childPath, childKind)) != null)) {
+//                                     this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
+//                                     // NB: No need to check the return value as the child can only be on the classpath
+//                             }
+//     
+//                             // if the child is a package fragment root of one or several other projects
+//                             ArrayList rootList;
+//                             if ((rootList = this.otherRootsInfo(childPath, childKind)) != null) {
+//                                     Iterator iterator = rootList.iterator();
+//                                     while (iterator.hasNext()) {
+//                                             childRootInfo = (RootInfo) iterator.next();
+//                                             this.traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, childRootInfo, null); // binary output of childRootInfo.project cannot be this root
+//                                     }
+//                             }
+//                     }
+//                     if (orphanChildren != null
+//                                     && (oneChildOnClasspath // orphan children are siblings of a package fragment root
+//                                             || res instanceof IProject)) { // non-java resource directly under a project
+//                                             
+//                             // attach orphan children
+//                             IProject rscProject = res.getProject();
+//                             JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
+//                             if (adoptiveProject != null 
+//                                             && JavaProject.hasJavaNature(rscProject)) { // delta iff Java project (18698)
+//                                     for (int i = 0; i < length; i++) {
+//                                             if (orphanChildren[i] != null) {
+//                                                     try {
+//                                                             nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
+//                                                     } catch (JavaModelException e) {
+//                                                     }
+//                                             }
+//                                     }
+//                             }
+//                     } // else resource delta will be added by parent
+//                     return elementType != NON_JAVA_RESOURCE; // TODO: (jerome) do we still need to return? (check could be done by caller)
+//             } else {
+//                     return elementType != NON_JAVA_RESOURCE;
+//             }
+//     }
+
+       /**
+        * Update the classpath markers and cycle markers for the projects to update.
+        */
+//     void updateClasspathMarkers() {
+//             try {
+//                     if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
+//                             Iterator iterator = this.projectsToUpdate.iterator();
+//                             while (iterator.hasNext()) {
+//                                     try {
+//                                             JavaProject project = (JavaProject)iterator.next();
+//                                             
+//                                              // force classpath marker refresh
+//                                             project.getResolvedClasspath(
+//                                                     true, // ignoreUnresolvedEntry
+//                                                     true); // generateMarkerOnError
+//                                             
+//                                     } catch (JavaModelException e) {
+//                                     }
+//                             }
+//                     }
+//                     if (!this.projectsToUpdate.isEmpty()){
+//                             try {
+//                                     // update all cycle markers
+//                                     JavaProject.updateAllCycleMarkers();
+//                             } catch (JavaModelException e) {
+//                             }
+//                     }                               
+//             } finally {
+//                     this.projectsToUpdate = new HashSet();
+//             }
+//     }
+
+       /*
+        * Update the current delta (ie. add/remove/change the given element) and update the correponding index.
+        * Returns whether the children of the given delta must be processed.
+        * @throws a JavaModelException if the delta doesn't correspond to a java element of the given type.
+        */
+//     private boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int elementType, RootInfo rootInfo) {
+//             Openable element;
+//             switch (delta.getKind()) {
+//                     case IResourceDelta.ADDED :
+//                             IResource deltaRes = delta.getResource();
+//                             element = this.createElement(deltaRes, elementType, rootInfo);
+//                             if (element == null) {
+//                                     // resource might be containing shared roots (see bug 19058)
+//                                     this.updateRoots(deltaRes.getFullPath(), delta);
+//                                     return false;
+//                             }
+//                             this.updateIndex(element, delta);
+//                             this.elementAdded(element, delta, rootInfo);
+//                             return false;
+//                     case IResourceDelta.REMOVED :
+//                             deltaRes = delta.getResource();
+//                             element = this.createElement(deltaRes, elementType, rootInfo);
+//                             if (element == null) {
+//                                     // resource might be containing shared roots (see bug 19058)
+//                                     this.updateRoots(deltaRes.getFullPath(), delta);
+//                                     return false;
+//                             }
+//                             this.updateIndex(element, delta);
+//                             this.elementRemoved(element, delta, rootInfo);
+//     
+//                             if (deltaRes.getType() == IResource.PROJECT){                   
+//                                     // reset the corresponding project built state, since cannot reuse if added back
+//                                     this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
+//                             }
+//                             return false;
+//                     case IResourceDelta.CHANGED :
+//                             int flags = delta.getFlags();
+//                             if ((flags & IResourceDelta.CONTENT) != 0) {
+//                                     // content has changed
+//                                     element = this.createElement(delta.getResource(), elementType, rootInfo);
+//                                     if (element == null) return false;
+//                                     this.updateIndex(element, delta);
+//                                     this.contentChanged(element, delta);
+//                             } else if (elementType == IJavaElement.JAVA_PROJECT) {
+//                                     if ((flags & IResourceDelta.OPEN) != 0) {
+//                                             // project has been opened or closed
+//                                             IProject res = (IProject)delta.getResource();
+//                                             element = this.createElement(res, elementType, rootInfo);
+//                                             if (element == null) {
+//                                                     // resource might be containing shared roots (see bug 19058)
+//                                                     this.updateRoots(res.getFullPath(), delta);
+//                                                     return false;
+//                                             }
+//                                             if (res.isOpen()) {
+//                                                     if (JavaProject.hasJavaNature(res)) {
+//                                                             this.elementAdded(element, delta, rootInfo);
+//                                                             this.indexManager.indexAll(res);
+//                                                     }
+//                                             } else {
+//                                                     JavaModel javaModel = this.manager.getJavaModel();
+//                                                     boolean wasJavaProject = javaModel.findJavaProject(res) != null;
+//                                                     if (wasJavaProject) {
+//                                                             this.elementRemoved(element, delta, rootInfo);
+//                                                             this.indexManager.discardJobs(element.getElementName());
+//                                                             this.indexManager.removeIndexFamily(res.getFullPath());
+//                                                             
+//                                                     }
+//                                             }
+//                                             return false; // when a project is open/closed don't process children
+//                                     }
+//                                     if ((flags & IResourceDelta.DESCRIPTION) != 0) {
+//                                             IProject res = (IProject)delta.getResource();
+//                                             JavaModel javaModel = this.manager.getJavaModel();
+//                                             boolean wasJavaProject = javaModel.findJavaProject(res) != null;
+//                                             boolean isJavaProject = JavaProject.hasJavaNature(res);
+//                                             if (wasJavaProject != isJavaProject) {
+//                                                     // project's nature has been added or removed
+//                                                     element = this.createElement(res, elementType, rootInfo);
+//                                                     if (element == null) return false; // note its resources are still visible as roots to other projects
+//                                                     if (isJavaProject) {
+//                                                             this.elementAdded(element, delta, rootInfo);
+//                                                             this.indexManager.indexAll(res);
+//                                                     } else {
+//                                                             this.elementRemoved(element, delta, rootInfo);
+//                                                             this.indexManager.discardJobs(element.getElementName());
+//                                                             this.indexManager.removeIndexFamily(res.getFullPath());
+//                                                             // reset the corresponding project built state, since cannot reuse if added back
+//                                                             this.manager.setLastBuiltState(res, null /*no state*/);
+//                                                     }
+//                                                     return false; // when a project's nature is added/removed don't process children
+//                                             }
+//                                     }
+//                             }
+//                             return true;
+//             }
+//             return true;
+//     }
+
+       /**
+        * Traverse the set of projects which have changed namespace, and refresh their dependents
+        */
+//     public void updateDependentNamelookups() {
+//             Iterator iterator;
+//             // update namelookup of dependent projects
+//             iterator = this.projectsForDependentNamelookupRefresh.iterator();
+//             HashSet affectedDependents = new HashSet();
+//             while (iterator.hasNext()) {
+//                     JavaProject project = (JavaProject)iterator.next();
+//                     addDependentProjects(project.getPath(), affectedDependents);
+//             }
+//             iterator = affectedDependents.iterator();
+//             while (iterator.hasNext()) {
+//                     JavaProject project = (JavaProject) iterator.next();
+//                     if (project.isOpen()){
+//                             try {
+//                                     ((JavaProjectElementInfo)project.getElementInfo()).setNameLookup(null);
+//                             } catch (JavaModelException e) {
+//                             }
+//                     }
+//             }
+//     }
+
+//protected void updateIndex(Openable element, IResourceDelta delta) {
+//
+//     if (indexManager == null)
+//             return;
+//
+//     switch (element.getElementType()) {
+//             case IJavaElement.JAVA_PROJECT :
+//                     switch (delta.getKind()) {
+//                             case IResourceDelta.ADDED :
+//                                     this.indexManager.indexAll(element.getJavaProject().getProject());
+//                                     break;
+//                             case IResourceDelta.REMOVED :
+//                                     this.indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
+//                                     // NB: Discarding index jobs belonging to this project was done during PRE_DELETE
+//                                     break;
+//                             // NB: Update of index if project is opened, closed, or its java nature is added or removed
+//                             //     is done in updateCurrentDeltaAndIndex
+//                     }
+//                     break;
+//             case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+//                     if (element instanceof JarPackageFragmentRoot) {
+//                             JarPackageFragmentRoot root = (JarPackageFragmentRoot)element;
+//                             // index jar file only once (if the root is in its declaring project)
+//                             IPath jarPath = root.getPath();
+//                             switch (delta.getKind()) {
+//                                     case IResourceDelta.ADDED:
+//                                             // index the new jar
+//                                             indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
+//                                             break;
+//                                     case IResourceDelta.CHANGED:
+//                                             // first remove the index so that it is forced to be re-indexed
+//                                             indexManager.removeIndex(jarPath);
+//                                             // then index the jar
+//                                             indexManager.indexLibrary(jarPath, root.getJavaProject().getProject());
+//                                             break;
+//                                     case IResourceDelta.REMOVED:
+//                                             // the jar was physically removed: remove the index
+//                                             this.indexManager.discardJobs(jarPath.toString());
+//                                             this.indexManager.removeIndex(jarPath);
+//                                             break;
+//                             }
+//                             break;
+//                     } else {
+//                             int kind = delta.getKind();
+//                             if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED) {
+//                                     IPackageFragmentRoot root = (IPackageFragmentRoot)element;
+//                                     this.updateRootIndex(root, root.getPackageFragment(""), delta); //$NON-NLS-1$
+//                                     break;
+//                             }
+//                     }
+//                     // don't break as packages of the package fragment root can be indexed below
+//             case IJavaElement.PACKAGE_FRAGMENT :
+//                     switch (delta.getKind()) {
+//                             case IResourceDelta.ADDED:
+//                             case IResourceDelta.REMOVED:
+//                                     IPackageFragment pkg = null;
+//                                     if (element instanceof IPackageFragmentRoot) {
+//                                             IPackageFragmentRoot root = (IPackageFragmentRoot)element;
+//                                             pkg = root.getPackageFragment(""); //$NON-NLS-1$
+//                                     } else {
+//                                             pkg = (IPackageFragment)element;
+//                                     }
+//                                     IResourceDelta[] children = delta.getAffectedChildren();
+//                                     for (int i = 0, length = children.length; i < length; i++) {
+//                                             IResourceDelta child = children[i];
+//                                             IResource resource = child.getResource();
+//                                             if (resource instanceof IFile) {
+//                                                     String name = resource.getName();
+//                                                     if (Util.isJavaFileName(name)) {
+//                                                             Openable cu = (Openable)pkg.getCompilationUnit(name);
+//                                                             this.updateIndex(cu, child);
+//                                                     } else if (Util.isClassFileName(name)) {
+//                                                             Openable classFile = (Openable)pkg.getClassFile(name);
+//                                                             this.updateIndex(classFile, child);
+//                                                     }
+//                                             }
+//                                     }
+//                                     break;
+//                     }
+//                     break;
+//             case IJavaElement.CLASS_FILE :
+//                     IFile file = (IFile) delta.getResource();
+//                     IJavaProject project = element.getJavaProject();
+//                     IPath binaryFolderPath = element.getPackageFragmentRoot().getPath();
+//                     // if the class file is part of the binary output, it has been created by
+//                     // the java builder -> ignore
+//                     try {
+//                             if (binaryFolderPath.equals(project.getOutputLocation())) {
+//                                     break;
+//                             }
+//                     } catch (JavaModelException e) {
+//                     }
+//                     switch (delta.getKind()) {
+//                             case IResourceDelta.CHANGED :
+//                                     // no need to index if the content has not changed
+//                                     if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
+//                                             break;
+//                             case IResourceDelta.ADDED :
+//                                     indexManager.addBinary(file, binaryFolderPath);
+//                                     break;
+//                             case IResourceDelta.REMOVED :
+//                                     indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
+//                                     break;
+//                     }
+//                     break;
+//             case IJavaElement.COMPILATION_UNIT :
+//                     file = (IFile) delta.getResource();
+//                     switch (delta.getKind()) {
+//                             case IResourceDelta.CHANGED :
+//                                     // no need to index if the content has not changed
+//                                     if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)
+//                                             break;
+//                             case IResourceDelta.ADDED :
+//                                     indexManager.addSource(file, file.getProject().getProject().getFullPath());
+//                                     break;
+//                             case IResourceDelta.REMOVED :
+//                                     indexManager.remove(file.getFullPath().toString(), file.getProject().getProject().getFullPath());
+//                                     break;
+//                     }
+//     }
+//}
+/**
+ * Upadtes the index of the given root (assuming it's an addition or a removal).
+ * This is done recusively, pkg being the current package.
+ */
+//private void updateRootIndex(IPackageFragmentRoot root, IPackageFragment pkg, IResourceDelta delta) {
+//     this.updateIndex((Openable)pkg, delta);
+//     IResourceDelta[] children = delta.getAffectedChildren();
+//     String name = pkg.getElementName();
+//     for (int i = 0, length = children.length; i < length; i++) {
+//             IResourceDelta child = children[i];
+//             IResource resource = child.getResource();
+//             if (resource instanceof IFolder) {
+//                     String subpkgName = 
+//                             name.length() == 0 ? 
+//                                     resource.getName() : 
+//                                     name + "." + resource.getName(); //$NON-NLS-1$
+//                     IPackageFragment subpkg = root.getPackageFragment(subpkgName);
+//                     this.updateRootIndex(root, subpkg, child);
+//             }
+//     }
+//}
+/*
+ * Update the roots that are affected by the addition or the removal of the given container resource.
+ */
+//private void updateRoots(IPath containerPath, IResourceDelta containerDelta) {
+//     Map roots;
+//     Map otherRoots;
+//     if (containerDelta.getKind() == IResourceDelta.REMOVED) {
+//             roots = this.oldRoots;
+//             otherRoots = this.oldOtherRoots;
+//     } else {
+//             roots = this.roots;
+//             otherRoots = this.otherRoots;
+//     }
+//     Iterator iterator = roots.keySet().iterator();
+//     while (iterator.hasNext()) {
+//             IPath path = (IPath)iterator.next();
+//             if (containerPath.isPrefixOf(path) && !containerPath.equals(path)) {
+//                     IResourceDelta rootDelta = containerDelta.findMember(path.removeFirstSegments(1));
+//                     if (rootDelta == null) continue;
+//                     RootInfo rootInfo = (RootInfo)roots.get(path);
+//
+//                     if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider roots that are not included in the container
+//                             this.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
+//                     }
+//                     
+//                     ArrayList rootList = (ArrayList)otherRoots.get(path);
+//                     if (rootList != null) {
+//                             Iterator otherProjects = rootList.iterator();
+//                             while (otherProjects.hasNext()) {
+//                                     rootInfo = (RootInfo)otherProjects.next();
+//                                     if (!rootInfo.project.getPath().isPrefixOf(path)) { // only consider roots that are not included in the container
+//                                             this.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
+//                                     }
+//                             }
+//                     }
+//             }
+//     }
+//}
+
+}
index bababc6..c45befb 100644 (file)
  *******************************************************************************/
 package net.sourceforge.phpdt.internal.core;
 
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
 import net.sourceforge.phpdt.core.IJavaElement;
 import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
+import net.sourceforge.phpdt.core.IJavaProject;
 import net.sourceforge.phpdt.core.IOpenable;
 import net.sourceforge.phpdt.core.JavaModelException;
 
@@ -160,15 +165,15 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
        /**
         * @see IJavaElement
         */
-//     public boolean exists() {
-//             
-//             try {
-//                     getElementInfo();
-//                     return true;
-//             } catch (JavaModelException e) {
-//             }
-//             return false;
-//     }
+       public boolean exists() {
+               
+               try {
+                       getElementInfo();
+                       return true;
+               } catch (JavaModelException e) {
+               }
+               return false;
+       }
        
        /**
         * Returns the <code>IDOMNode</code> that corresponds to this <code>JavaElement</code>
@@ -249,39 +254,39 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
        /**
         * @see IParent 
         */
-//     public IJavaElement[] getChildren() throws JavaModelException {
-//             return ((JavaElementInfo)getElementInfo()).getChildren();
-//     }
+       public IJavaElement[] getChildren() throws JavaModelException {
+               return ((JavaElementInfo)getElementInfo()).getChildren();
+       }
        /**
         * Returns a collection of (immediate) children of this node of the
         * specified type.
         *
         * @param type - one of constants defined by IJavaLanguageElementTypes
         */
-//     public ArrayList getChildrenOfType(int type) throws JavaModelException {
-//             IJavaElement[] children = getChildren();
-//             int size = children.length;
-//             ArrayList list = new ArrayList(size);
-//             for (int i = 0; i < size; ++i) {
-//                     JavaElement elt = (JavaElement)children[i];
-//                     if (elt.getElementType() == type) {
-//                             list.add(elt);
-//                     }
-//             }
-//             return list;
-//     }
+       public ArrayList getChildrenOfType(int type) throws JavaModelException {
+               IJavaElement[] children = getChildren();
+               int size = children.length;
+               ArrayList list = new ArrayList(size);
+               for (int i = 0; i < size; ++i) {
+                       JavaElement elt = (JavaElement)children[i];
+                       if (elt.getElementType() == type) {
+                               list.add(elt);
+                       }
+               }
+               return list;
+       }
        /**
         * @see IMember
         */
 //     public IClassFile getClassFile() {
 //             return null;
 //     }
-//     /**
-//      * @see IMember
-//      */
-//     public ICompilationUnit getCompilationUnit() {
-//             return null;
-//     }
+       /**
+        * @see IMember
+        */
+       public ICompilationUnit getCompilationUnit() {
+               return null;
+       }
        /**
         * Returns the info for this handle.  
         * If this element is not already open, it and all of its parents are opened.
@@ -289,10 +294,10 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
         * NOTE: BinaryType infos are NJOT rooted under JavaElementInfo.
         * @exception JavaModelException if the element is not present or not accessible
         */
-//     public Object getElementInfo() throws JavaModelException {
-//
-//             // workaround to ensure parent project resolved classpath is available to avoid triggering initializers
-//             // while the JavaModelManager lock is acquired (can cause deadlocks in clients)
+       public Object getElementInfo() throws JavaModelException {
+return null;
+               // workaround to ensure parent project resolved classpath is available to avoid triggering initializers
+               // while the JavaModelManager lock is acquired (can cause deadlocks in clients)
 //             IJavaProject project = getJavaProject();
 //             if (project != null && !project.isOpen()) {
 //                     // TODO: need to revisit, since deadlock could still occur if perProjectInfo is removed concurrent before entering the lock
@@ -316,7 +321,7 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
 //                     }
 //                     return info;
 //             }
-//     }
+       }
        /**
         * @see IAdaptable
         */
@@ -359,17 +364,17 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
                } while ((current = current.getParent()) != null);
                return null;
        }
-//
-//     /**
-//      * @see IJavaElement
-//      */
-//     public IJavaProject getJavaProject() {
-//             IJavaElement current = this;
-//             do {
-//                     if (current instanceof IJavaProject) return (IJavaProject) current;
-//             } while ((current = current.getParent()) != null);
-//             return null;
-//     }
+
+       /**
+        * @see IJavaElement
+        */
+       public IJavaProject getJavaProject() {
+               IJavaElement current = this;
+               do {
+                       if (current instanceof IJavaProject) return (IJavaProject) current;
+               } while ((current = current.getParent()) != null);
+               return null;
+       }
        /**
         * Returns the occurrence count of the handle.
         */
@@ -473,12 +478,12 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
 //     public boolean isStructureKnown() throws JavaModelException {
 //             return ((JavaElementInfo)getElementInfo()).isStructureKnown();
 //     }
-//     /**
-//      * Creates and returns and not present exception for this element.
-//      */
-//     protected JavaModelException newNotPresentException() {
-//             return new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
-//     }
+       /**
+        * Creates and returns and not present exception for this element.
+        */
+       protected JavaModelException newNotPresentException() {
+               return new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
+       }
 //     /**
 //      * Opens this element and all parents that are not already open.
 //      *
@@ -529,7 +534,7 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement
 //     /**
 //      * Returns a copy of this element rooted at the given project.
 //      */
-//     public abstract IJavaElement rootedAt(IJavaProject project);
+       public abstract IJavaElement rootedAt(IJavaProject project);
 //     /**
 //      * Runs a Java Model Operation
 //      */
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementDelta.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaElementDelta.java
new file mode 100644 (file)
index 0000000..ea6d97d
--- /dev/null
@@ -0,0 +1,743 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaProject;
+
+import org.eclipse.core.resources.IResourceDelta;
+
+
+/**
+ * @see IJavaElementDelta
+ */
+public class JavaElementDelta implements IJavaElementDelta {
+       /**
+        * The element that this delta describes the change to.
+        * @see #getElement()
+        */
+       protected IJavaElement fChangedElement;
+       /**
+        * @see #getKind()
+        */
+       private int fKind = 0;
+       /**
+        * @see #getFlags()
+        */
+       private int fChangeFlags = 0;
+       /**
+        * @see #getAffectedChildren()
+        */
+       protected IJavaElementDelta[] fAffectedChildren = fgEmptyDelta;
+
+       /**
+        * Collection of resource deltas that correspond to non java resources deltas.
+        */
+       protected IResourceDelta[] resourceDeltas = null;
+
+       /**
+        * Counter of resource deltas
+        */
+       protected int resourceDeltasCounter;
+       /**
+        * @see #getMovedFromHandle()
+        */
+       protected IJavaElement fMovedFromHandle = null;
+       /**
+        * @see #getMovedToHandle()
+        */
+       protected IJavaElement fMovedToHandle = null;
+       /**
+        * Empty array of IJavaElementDelta
+        */
+       protected static  IJavaElementDelta[] fgEmptyDelta= new IJavaElementDelta[] {};
+/**
+ * Creates the root delta. To create the nested delta
+ * hierarchies use the following convenience methods. The root
+ * delta can be created at any level (for example: project, package root,
+ * package fragment...).
+ * <ul>
+ * <li><code>added(IJavaElement)</code>
+ * <li><code>changed(IJavaElement)</code>
+ * <li><code>moved(IJavaElement, IJavaElement)</code>
+ * <li><code>removed(IJavaElement)</code>
+ * <li><code>renamed(IJavaElement, IJavaElement)</code>
+ * </ul>
+ */
+public JavaElementDelta(IJavaElement element) {
+       super();
+       fChangedElement = element;
+}
+/**
+ * Adds the child delta to the collection of affected children.  If the
+ * child is already in the collection, walk down the hierarchy.
+ */
+protected void addAffectedChild(JavaElementDelta child) {
+       switch (fKind) {
+               case ADDED:
+               case REMOVED:
+                       // no need to add a child if this parent is added or removed
+                       return;
+               case CHANGED:
+                       fChangeFlags |= F_CHILDREN;
+                       break;
+               default:
+                       fKind = CHANGED;
+                       fChangeFlags |= F_CHILDREN;
+       }
+
+       // if a child delta is added to a compilation unit delta or below, 
+       // it's a fine grained delta
+       if (fChangedElement.getElementType() >= IJavaElement.COMPILATION_UNIT) {
+               this.fineGrained();
+       }
+       
+       if (fAffectedChildren.length == 0) {
+               fAffectedChildren = new IJavaElementDelta[] {child};
+               return;
+       }
+       IJavaElementDelta existingChild = null;
+       int existingChildIndex = -1;
+       if (fAffectedChildren != null) {
+               for (int i = 0; i < fAffectedChildren.length; i++) {
+                       if (this.equalsAndSameParent(fAffectedChildren[i].getElement(), child.getElement())) { // handle case of two jars that can be equals but not in the same project
+                               existingChild = fAffectedChildren[i];
+                               existingChildIndex = i;
+                               break;
+                       }
+               }
+       }
+       if (existingChild == null) { //new affected child
+               fAffectedChildren= growAndAddToArray(fAffectedChildren, child);
+       } else {
+               switch (existingChild.getKind()) {
+                       case ADDED:
+                               switch (child.getKind()) {
+                                       case ADDED: // child was added then added -> it is added
+                                       case CHANGED: // child was added then changed -> it is added
+                                               return;
+                                       case REMOVED: // child was added then removed -> noop
+                                               fAffectedChildren = this.removeAndShrinkArray(fAffectedChildren, existingChildIndex);
+                                               return;
+                               }
+                               break;
+                       case REMOVED:
+                               switch (child.getKind()) {
+                                       case ADDED: // child was removed then added -> it is changed
+                                               child.fKind = CHANGED;
+                                               fAffectedChildren[existingChildIndex] = child;
+                                               return;
+                                       case CHANGED: // child was removed then changed -> it is removed
+                                       case REMOVED: // child was removed then removed -> it is removed
+                                               return;
+                               }
+                               break;
+                       case CHANGED:
+                               switch (child.getKind()) {
+                                       case ADDED: // child was changed then added -> it is added
+                                       case REMOVED: // child was changed then removed -> it is removed
+                                               fAffectedChildren[existingChildIndex] = child;
+                                               return;
+                                       case CHANGED: // child was changed then changed -> it is changed
+                                               IJavaElementDelta[] children = child.getAffectedChildren();
+                                               for (int i = 0; i < children.length; i++) {
+                                                       JavaElementDelta childsChild = (JavaElementDelta) children[i];
+                                                       ((JavaElementDelta) existingChild).addAffectedChild(childsChild);
+                                               }
+                                               
+                                               // update flags if needed
+                                               switch (((JavaElementDelta) existingChild).fChangeFlags) {
+                                                       case F_ADDED_TO_CLASSPATH:
+                                                       case F_REMOVED_FROM_CLASSPATH:
+                                                       case F_SOURCEATTACHED:
+                                                       case F_SOURCEDETACHED:
+                                                               ((JavaElementDelta) existingChild).fChangeFlags |= ((JavaElementDelta) child).fChangeFlags;
+                                                               break;
+                                               }
+                                               
+                                               // add the non-java resource deltas if needed
+                                               // note that the child delta always takes precedence over this existing child delta
+                                               // as non-java resource deltas are always created last (by the DeltaProcessor)
+                                               IResourceDelta[] resDeltas = child.getResourceDeltas();
+                                               if (resDeltas != null) {
+                                                       ((JavaElementDelta)existingChild).resourceDeltas = resDeltas;
+                                                       ((JavaElementDelta)existingChild).resourceDeltasCounter = child.resourceDeltasCounter;
+                                               }
+                                               return;
+                               }
+                               break;
+                       default: 
+                               // unknown -> existing child becomes the child with the existing child's flags
+                               int flags = existingChild.getFlags();
+                               fAffectedChildren[existingChildIndex] = child;
+                               child.fChangeFlags |= flags;
+               }
+       }
+}
+/**
+ * Creates the nested deltas resulting from an add operation.
+ * Convenience method for creating add deltas.
+ * The constructor should be used to create the root delta 
+ * and then an add operation should call this method.
+ */
+public void added(IJavaElement element) {
+       JavaElementDelta addedDelta = new JavaElementDelta(element);
+       addedDelta.fKind = ADDED;
+       insertDeltaTree(element, addedDelta);
+}
+/**
+ * Adds the child delta to the collection of affected children.  If the
+ * child is already in the collection, walk down the hierarchy.
+ */
+protected void addResourceDelta(IResourceDelta child) {
+       switch (fKind) {
+               case ADDED:
+               case REMOVED:
+                       // no need to add a child if this parent is added or removed
+                       return;
+               case CHANGED:
+                       fChangeFlags |= F_CONTENT;
+                       break;
+               default:
+                       fKind = CHANGED;
+                       fChangeFlags |= F_CONTENT;
+       }
+       if (resourceDeltas == null) {
+               resourceDeltas = new IResourceDelta[5];
+               resourceDeltas[resourceDeltasCounter++] = child;
+               return;
+       }
+       if (resourceDeltas.length == resourceDeltasCounter) {
+               // need a resize
+               System.arraycopy(resourceDeltas, 0, (resourceDeltas = new IResourceDelta[resourceDeltasCounter * 2]), 0, resourceDeltasCounter);
+       }
+       resourceDeltas[resourceDeltasCounter++] = child;
+}
+/**
+ * Creates the nested deltas resulting from a change operation.
+ * Convenience method for creating change deltas.
+ * The constructor should be used to create the root delta 
+ * and then a change operation should call this method.
+ */
+public void changed(IJavaElement element, int changeFlag) {
+       JavaElementDelta changedDelta = new JavaElementDelta(element);
+       changedDelta.fKind = CHANGED;
+       changedDelta.fChangeFlags |= changeFlag;
+       insertDeltaTree(element, changedDelta);
+}
+/**
+ * Mark this delta as a content changed delta.
+ */
+public void contentChanged() {
+       fChangeFlags |= F_CONTENT;
+}
+/**
+ * Clone this delta so that its elements are rooted at the given project.
+ */
+public IJavaElementDelta clone(IJavaProject project) {
+       JavaElementDelta clone = 
+               new JavaElementDelta(((JavaElement)fChangedElement).rootedAt(project));
+       if (fAffectedChildren != fgEmptyDelta) {
+               int length = fAffectedChildren.length;
+               IJavaElementDelta[] cloneChildren = new IJavaElementDelta[length];
+               for (int i= 0; i < length; i++) {
+                       cloneChildren[i] = ((JavaElementDelta)fAffectedChildren[i]).clone(project);
+               }
+               clone.fAffectedChildren = cloneChildren;
+       }       
+       clone.fChangeFlags = fChangeFlags;
+       clone.fKind = fKind;
+       if (fMovedFromHandle != null) {
+               clone.fMovedFromHandle = ((JavaElement)fMovedFromHandle).rootedAt(project);
+       }
+       if (fMovedToHandle != null) {
+               clone.fMovedToHandle = ((JavaElement)fMovedToHandle).rootedAt(project);
+       }
+       clone.resourceDeltas = this.resourceDeltas;
+       clone.resourceDeltasCounter = this.resourceDeltasCounter;
+       return clone;
+}
+
+/**
+ * Creates the nested deltas for a closed element.
+ */
+public void closed(IJavaElement element) {
+       JavaElementDelta delta = new JavaElementDelta(element);
+       delta.fKind = CHANGED;
+       delta.fChangeFlags |= F_CLOSED;
+       insertDeltaTree(element, delta);
+}
+/**
+ * Creates the nested delta deltas based on the affected element
+ * its delta, and the root of this delta tree. Returns the root
+ * of the created delta tree.
+ */
+protected JavaElementDelta createDeltaTree(IJavaElement element, JavaElementDelta delta) {
+       JavaElementDelta childDelta = delta;
+       ArrayList ancestors= getAncestors(element);
+       if (ancestors == null) {
+               if (this.equalsAndSameParent(delta.getElement(), getElement())) { // handle case of two jars that can be equals but not in the same project
+                       // the element being changed is the root element
+                       fKind= delta.fKind;
+                       fChangeFlags = delta.fChangeFlags;
+                       fMovedToHandle = delta.fMovedToHandle;
+                       fMovedFromHandle = delta.fMovedFromHandle;
+               }
+       } else {
+               for (int i = 0, size = ancestors.size(); i < size; i++) {
+                       IJavaElement ancestor = (IJavaElement) ancestors.get(i);
+                       JavaElementDelta ancestorDelta = new JavaElementDelta(ancestor);
+                       ancestorDelta.addAffectedChild(childDelta);
+                       childDelta = ancestorDelta;
+               }
+       }
+       return childDelta;
+}
+/**
+ * Returns whether the two java elements are equals and have the same parent.
+ */
+protected boolean equalsAndSameParent(IJavaElement e1, IJavaElement e2) {
+       IJavaElement parent1;
+       return e1.equals(e2) && ((parent1 = e1.getParent()) != null) && parent1.equals(e2.getParent());
+}
+/**
+ * Returns the <code>JavaElementDelta</code> for the given element
+ * in the delta tree, or null, if no delta for the given element is found.
+ */
+protected JavaElementDelta find(IJavaElement e) {
+       if (this.equalsAndSameParent(fChangedElement, e)) { // handle case of two jars that can be equals but not in the same project
+               return this;
+       } else {
+               for (int i = 0; i < fAffectedChildren.length; i++) {
+                       JavaElementDelta delta = ((JavaElementDelta)fAffectedChildren[i]).find(e);
+                       if (delta != null) {
+                               return delta;
+                       }
+               }
+       }
+       return null;
+}
+/**
+ * Mark this delta as a fine-grained delta.
+ */
+public void fineGrained() {
+       if (fKind == 0) { // if not set yet
+               fKind = CHANGED;
+       }
+       fChangeFlags |= F_FINE_GRAINED;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getAddedChildren() {
+       return getChildrenOfType(ADDED);
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getAffectedChildren() {
+       return fAffectedChildren;
+}
+/**
+ * Returns a collection of all the parents of this element up to (but
+ * not including) the root of this tree in bottom-up order. If the given
+ * element is not a descendant of the root of this tree, <code>null</code>
+ * is returned.
+ */
+private ArrayList getAncestors(IJavaElement element) {
+       IJavaElement parent = element.getParent();
+       if (parent == null) {
+               return null;
+       }
+       ArrayList parents = new ArrayList();
+       while (!parent.equals(fChangedElement)) {
+               parents.add(parent);
+               parent = parent.getParent();
+               if (parent == null) {
+                       return null;
+               }
+       }
+       parents.trimToSize();
+       return parents;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getChangedChildren() {
+       return getChildrenOfType(CHANGED);
+}
+/**
+ * @see IJavaElementDelta
+ */
+protected IJavaElementDelta[] getChildrenOfType(int type) {
+       int length = fAffectedChildren.length;
+       if (length == 0) {
+               return new IJavaElementDelta[] {};
+       }
+       ArrayList children= new ArrayList(length);
+       for (int i = 0; i < length; i++) {
+               if (fAffectedChildren[i].getKind() == type) {
+                       children.add(fAffectedChildren[i]);
+               }
+       }
+
+       IJavaElementDelta[] childrenOfType = new IJavaElementDelta[children.size()];
+       children.toArray(childrenOfType);
+       
+       return childrenOfType;
+}
+/**
+ * Returns the delta for a given element.  Only looks below this
+ * delta.
+ */
+protected JavaElementDelta getDeltaFor(IJavaElement element) {
+       if (this.equalsAndSameParent(getElement(), element)) // handle case of two jars that can be equals but not in the same project
+               return this;
+       if (fAffectedChildren.length == 0)
+               return null;
+       int childrenCount = fAffectedChildren.length;
+       for (int i = 0; i < childrenCount; i++) {
+               JavaElementDelta delta = (JavaElementDelta)fAffectedChildren[i];
+               if (this.equalsAndSameParent(delta.getElement(), element)) { // handle case of two jars that can be equals but not in the same project
+                       return delta;
+               } else {
+                       delta = ((JavaElementDelta)delta).getDeltaFor(element);
+                       if (delta != null)
+                               return delta;
+               }
+       }
+       return null;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElement getElement() {
+       return fChangedElement;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public int getFlags() {
+       return fChangeFlags;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public int getKind() {
+       return fKind;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElement getMovedFromElement() {
+       return fMovedFromHandle;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElement getMovedToElement() {
+       return fMovedToHandle;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getRemovedChildren() {
+       return getChildrenOfType(REMOVED);
+}
+/**
+ * Return the collection of resource deltas. Return null if none.
+ */
+public IResourceDelta[] getResourceDeltas() {
+       if (resourceDeltas == null) return null;
+       if (resourceDeltas.length != resourceDeltasCounter) {
+               System.arraycopy(resourceDeltas, 0, resourceDeltas = new IResourceDelta[resourceDeltasCounter], 0, resourceDeltasCounter);
+       }
+       return resourceDeltas;
+}
+/**
+ * Adds the new element to a new array that contains all of the elements of the old array.
+ * Returns the new array.
+ */
+protected IJavaElementDelta[] growAndAddToArray(IJavaElementDelta[] array, IJavaElementDelta addition) {
+       IJavaElementDelta[] old = array;
+       array = new IJavaElementDelta[old.length + 1];
+       System.arraycopy(old, 0, array, 0, old.length);
+       array[old.length] = addition;
+       return array;
+}
+/**
+ * Creates the delta tree for the given element and delta, and then
+ * inserts the tree as an affected child of this node.
+ */
+protected void insertDeltaTree(IJavaElement element, JavaElementDelta delta) {
+       JavaElementDelta childDelta= createDeltaTree(element, delta);
+       if (!this.equalsAndSameParent(element, getElement())) { // handle case of two jars that can be equals but not in the same project
+               addAffectedChild(childDelta);
+       }
+}
+/**
+ * Creates the nested deltas resulting from an move operation.
+ * Convenience method for creating the "move from" delta.
+ * The constructor should be used to create the root delta 
+ * and then the move operation should call this method.
+ */
+public void movedFrom(IJavaElement movedFromElement, IJavaElement movedToElement) {
+       JavaElementDelta removedDelta = new JavaElementDelta(movedFromElement);
+       removedDelta.fKind = REMOVED;
+       removedDelta.fChangeFlags |= F_MOVED_TO;
+       removedDelta.fMovedToHandle = movedToElement;
+       insertDeltaTree(movedFromElement, removedDelta);
+}
+/**
+ * Creates the nested deltas resulting from an move operation.
+ * Convenience method for creating the "move to" delta.
+ * The constructor should be used to create the root delta 
+ * and then the move operation should call this method.
+ */
+public void movedTo(IJavaElement movedToElement, IJavaElement movedFromElement) {
+       JavaElementDelta addedDelta = new JavaElementDelta(movedToElement);
+       addedDelta.fKind = ADDED;
+       addedDelta.fChangeFlags |= F_MOVED_FROM;
+       addedDelta.fMovedFromHandle = movedFromElement;
+       insertDeltaTree(movedToElement, addedDelta);
+}
+/**
+ * Creates the nested deltas for an opened element.
+ */
+public void opened(IJavaElement element) {
+       JavaElementDelta delta = new JavaElementDelta(element);
+       delta.fKind = CHANGED;
+       delta.fChangeFlags |= F_OPENED;
+       insertDeltaTree(element, delta);
+}
+/**
+ * Removes the child delta from the collection of affected children.
+ */
+protected void removeAffectedChild(JavaElementDelta child) {
+       int index = -1;
+       if (fAffectedChildren != null) {
+               for (int i = 0; i < fAffectedChildren.length; i++) {
+                       if (this.equalsAndSameParent(fAffectedChildren[i].getElement(), child.getElement())) { // handle case of two jars that can be equals but not in the same project
+                               index = i;
+                               break;
+                       }
+               }
+       }
+       if (index >= 0) {
+               fAffectedChildren= removeAndShrinkArray(fAffectedChildren, index);
+       }
+}
+/**
+ * Removes the element from the array.
+ * Returns the a new array which has shrunk.
+ */
+protected IJavaElementDelta[] removeAndShrinkArray(IJavaElementDelta[] old, int index) {
+       IJavaElementDelta[] array = new IJavaElementDelta[old.length - 1];
+       if (index > 0)
+               System.arraycopy(old, 0, array, 0, index);
+       int rest = old.length - index - 1;
+       if (rest > 0)
+               System.arraycopy(old, index + 1, array, index, rest);
+       return array;
+}
+/**
+ * Creates the nested deltas resulting from an delete operation.
+ * Convenience method for creating removed deltas.
+ * The constructor should be used to create the root delta 
+ * and then the delete operation should call this method.
+ */
+public void removed(IJavaElement element) {
+       JavaElementDelta removedDelta= new JavaElementDelta(element);
+       insertDeltaTree(element, removedDelta);
+       JavaElementDelta actualDelta = getDeltaFor(element);
+       if (actualDelta != null) {
+               actualDelta.fKind = REMOVED;
+               actualDelta.fChangeFlags = 0;
+               actualDelta.fAffectedChildren = fgEmptyDelta;
+       }
+}
+/**
+ * Creates the nested deltas resulting from a change operation.
+ * Convenience method for creating change deltas.
+ * The constructor should be used to create the root delta 
+ * and then a change operation should call this method.
+ */
+public void sourceAttached(IJavaElement element) {
+       JavaElementDelta attachedDelta = new JavaElementDelta(element);
+       attachedDelta.fKind = CHANGED;
+       attachedDelta.fChangeFlags |= F_SOURCEATTACHED;
+       insertDeltaTree(element, attachedDelta);
+}
+/**
+ * Creates the nested deltas resulting from a change operation.
+ * Convenience method for creating change deltas.
+ * The constructor should be used to create the root delta 
+ * and then a change operation should call this method.
+ */
+public void sourceDetached(IJavaElement element) {
+       JavaElementDelta detachedDelta = new JavaElementDelta(element);
+       detachedDelta.fKind = CHANGED;
+       detachedDelta.fChangeFlags |= F_SOURCEDETACHED;
+       insertDeltaTree(element, detachedDelta);
+}
+/** 
+ * Returns a string representation of this delta's
+ * structure suitable for debug purposes.
+ *
+ * @see #toString()
+ */
+public String toDebugString(int depth) {
+       StringBuffer buffer = new StringBuffer();
+       for (int i= 0; i < depth; i++) {
+               buffer.append('\t');
+       }
+       buffer.append(((JavaElement)getElement()).toDebugString());
+       buffer.append("["); //$NON-NLS-1$
+       switch (getKind()) {
+               case IJavaElementDelta.ADDED :
+                       buffer.append('+');
+                       break;
+               case IJavaElementDelta.REMOVED :
+                       buffer.append('-');
+                       break;
+               case IJavaElementDelta.CHANGED :
+                       buffer.append('*');
+                       break;
+               default :
+                       buffer.append('?');
+                       break;
+       }
+       buffer.append("]: {"); //$NON-NLS-1$
+       int changeFlags = getFlags();
+       boolean prev = false;
+       if ((changeFlags & IJavaElementDelta.F_CHILDREN) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("CHILDREN"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_CONTENT) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("CONTENT"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_MOVED_FROM) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("MOVED_FROM(" + ((JavaElement)getMovedFromElement()).toStringWithAncestors() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_MOVED_TO) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("MOVED_TO(" + ((JavaElement)getMovedToElement()).toStringWithAncestors() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("ADDED TO CLASSPATH"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("REMOVED FROM CLASSPATH"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_REORDER) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("REORDERED"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("ARCHIVE CONTENT CHANGED"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_SOURCEATTACHED) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("SOURCE ATTACHED"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_SOURCEDETACHED) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("SOURCE DETACHED"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_MODIFIERS) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("MODIFIERS CHANGED"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_SUPER_TYPES) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("SUPER TYPES CHANGED"); //$NON-NLS-1$
+               prev = true;
+       }
+       if ((changeFlags & IJavaElementDelta.F_FINE_GRAINED) != 0) {
+               if (prev)
+                       buffer.append(" | "); //$NON-NLS-1$
+               buffer.append("FINE GRAINED"); //$NON-NLS-1$
+               prev = true;
+       }
+       buffer.append("}"); //$NON-NLS-1$
+       IJavaElementDelta[] children = getAffectedChildren();
+       if (children != null) {
+               for (int i = 0; i < children.length; ++i) {
+                       buffer.append("\n"); //$NON-NLS-1$
+                       buffer.append(((JavaElementDelta) children[i]).toDebugString(depth + 1));
+               }
+       }
+       for (int i = 0; i < resourceDeltasCounter; i++) {
+               buffer.append("\n");//$NON-NLS-1$
+               for (int j = 0; j < depth+1; j++) {
+                       buffer.append('\t');
+               }
+               IResourceDelta resourceDelta = resourceDeltas[i];
+               buffer.append(resourceDelta.toString());
+               buffer.append("["); //$NON-NLS-1$
+               switch (resourceDelta.getKind()) {
+                       case IResourceDelta.ADDED :
+                               buffer.append('+');
+                               break;
+                       case IResourceDelta.REMOVED :
+                               buffer.append('-');
+                               break;
+                       case IResourceDelta.CHANGED :
+                               buffer.append('*');
+                               break;
+                       default :
+                               buffer.append('?');
+                               break;
+               }
+               buffer.append("]"); //$NON-NLS-1$
+       }
+       return buffer.toString();
+}
+/** 
+ * Returns a string representation of this delta's
+ * structure suitable for debug purposes.
+ */
+public String toString() {
+       return toDebugString(0);
+}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModel.java
new file mode 100644 (file)
index 0000000..41c449f
--- /dev/null
@@ -0,0 +1,531 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.util.Assert;
+
+
+/**
+ * Implementation of <code>IJavaModel<code>. The Java Model maintains a cache of
+ * active <code>IJavaProject</code>s in a workspace. A Java Model is specific to a
+ * workspace. To retrieve a workspace's model, use the
+ * <code>#getJavaModel(IWorkspace)</code> method.
+ *
+ * @see IJavaModel
+ */
+public class JavaModel extends Openable implements IJavaModel {
+
+       /**
+        * A set of java.io.Files used as a cache of external jars that 
+        * are known to be existing.
+        * Note this cache is kept for the whole session.
+        */ 
+       public static HashSet existingExternalFiles = new HashSet();
+               
+/**
+ * Constructs a new Java Model on the given workspace.
+ * Note that only one instance of JavaModel handle should ever be created.
+ * One should only indirect through JavaModelManager#getJavaModel() to get
+ * access to it.
+ * 
+ * @exception Error if called more than once
+ */
+protected JavaModel() throws Error {
+       super(JAVA_MODEL, null, "" /*workspace has empty name*/); //$NON-NLS-1$
+}
+/*
+ * @see IJavaModel
+ */
+//public boolean contains(IResource resource) {
+//     switch (resource.getType()) {
+//             case IResource.ROOT:
+//             case IResource.PROJECT:
+//                     return true;
+//     }
+//     // file or folder
+//     IJavaProject[] projects;
+//     try {
+//             projects = this.getJavaProjects();
+//     } catch (JavaModelException e) {
+//             return false;
+//     }
+//     for (int i = 0, length = projects.length; i < length; i++) {
+//             JavaProject project = (JavaProject)projects[i];
+//     
+//             if (!project.contains(resource)) {
+//                     return false;
+//             }
+//     }
+//     return true;
+//}
+/**
+ * @see IJavaModel
+ */
+//public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+//             runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+//     } else {
+//             runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+//     }
+//}
+/**
+ * Returns a new element info for this element.
+ */
+//protected OpenableElementInfo createElementInfo() {
+//     return new JavaModelInfo();
+//}
+
+/**
+ * @see IJavaModel
+ */
+//public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+//             runOperation(new DeleteResourceElementsOperation(elements, force), monitor);
+//     } else {
+//             runOperation(new DeleteElementsOperation(elements, force), monitor);
+//     }
+//}
+/**
+ * Finds the given project in the list of the java model's children.
+ * Returns null if not found.
+ */
+public IJavaProject findJavaProject(IProject project) {
+       try {
+               IJavaProject[] projects = this.getOldJavaProjectsList();
+               for (int i = 0, length = projects.length; i < length; i++) {
+                       IJavaProject javaProject = projects[i];
+                       if (project.equals(javaProject.getProject())) {
+                               return javaProject;
+                       }
+               }
+       } catch (JavaModelException e) {
+       }
+       return null;
+}
+
+/**
+ * Flushes the cache of external files known to be existing.
+ */
+public static void flushExternalFileCache() {
+       existingExternalFiles = new HashSet();
+}
+
+/**
+ */
+//protected boolean generateInfos(
+//     OpenableElementInfo info,
+//     IProgressMonitor pm,
+//     Map newElements,
+//     IResource underlyingResource)   throws JavaModelException {
+//
+//     JavaModelManager.getJavaModelManager().putInfo(this, info);
+//     // determine my children
+//     IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+//     for (int i = 0, max = projects.length; i < max; i++) {
+//             IProject project = projects[i];
+//             if (JavaProject.hasJavaNature(project)) {
+//                     info.addChild(getJavaProject(project));
+//             }
+//     }
+//     return true;
+//}
+/**
+ * Returns the <code>IJavaElement</code> represented by the <code>String</code>
+ * memento.
+ * @see getHandleMemento()
+ */
+//protected IJavaElement getHandleFromMementoForBinaryMembers(String memento, IPackageFragmentRoot root, int rootEnd, int end) throws JavaModelException {
+//
+//     //deal with class file and binary members
+//     IPackageFragment frag = null;
+//     if (rootEnd == end - 1) {
+//             //default package
+//             frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+//     } else {
+//             frag= root.getPackageFragment(memento.substring(rootEnd + 1, end));
+//     }
+//     int oldEnd = end;
+//     end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
+//     if (end == -1) {
+//             //we ended with a class file 
+//             return frag.getClassFile(memento.substring(oldEnd + 1));
+//     }
+//     IClassFile cf = frag.getClassFile(memento.substring(oldEnd + 1, end));
+//     oldEnd = end;
+//     end = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
+//     oldEnd = end;
+//     end = memento.indexOf(JavaElement.JEM_FIELD, end);
+//     if (end != -1) {
+//             //binary field
+//             IType type = cf.getType();
+//             return type.getField(memento.substring(end + 1));
+//     }
+//     end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd);
+//     if (end != -1) {
+//             //binary method
+//             oldEnd = end;
+//             IType type = cf.getType();
+//             String methodName;
+//             end = memento.lastIndexOf(JavaElement.JEM_METHOD);
+//             String[] parameterTypes = null;
+//             if (end == oldEnd) {
+//                     methodName = memento.substring(end + 1);
+//                     //no parameter types
+//                     parameterTypes = new String[] {};
+//             } else {
+//                     String parameters = memento.substring(oldEnd + 1);
+//                     StringTokenizer tokenizer = new StringTokenizer(parameters, new String(new char[] {JavaElement.JEM_METHOD}));
+//                     parameterTypes = new String[tokenizer.countTokens() - 1];
+//                     methodName= tokenizer.nextToken();
+//                     int i = 0;
+//                     while (tokenizer.hasMoreTokens()) {
+//                             parameterTypes[i] = tokenizer.nextToken();
+//                             i++;
+//                     }
+//             }
+//             return type.getMethod(methodName, parameterTypes);
+//     }
+//
+//     //binary type
+//     return cf.getType();
+//}
+/**
+ * Returns the <code>IPackageFragmentRoot</code> represented by the <code>String</code>
+ * memento.
+ * @see getHandleMemento()
+ */
+//protected IPackageFragmentRoot getHandleFromMementoForRoot(String memento, JavaProject project, int projectEnd, int rootEnd) {
+//     String rootName = null;
+//     if (rootEnd == projectEnd - 1) {
+//             //default root
+//             rootName = IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
+//     } else {
+//             rootName = memento.substring(projectEnd + 1, rootEnd);
+//     }
+//     return project.getPackageFragmentRoot(new Path(rootName));
+//}
+/**
+ * Returns the <code>IJavaElement</code> represented by the <code>String</code>
+ * memento.
+ * @see getHandleMemento()
+ */
+//protected IJavaElement getHandleFromMementoForSourceMembers(String memento, IPackageFragmentRoot root, int rootEnd, int end) throws JavaModelException {
+//
+//     //deal with compilation units and source members
+//     IPackageFragment frag = null;
+//     if (rootEnd == end - 1) {
+//             //default package
+//             frag= root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+//     } else {
+//             frag= root.getPackageFragment(memento.substring(rootEnd + 1, end));
+//     }
+//     int oldEnd = end;
+//     end = memento.indexOf(JavaElement.JEM_PACKAGEDECLARATION, end);
+//     if (end != -1) {
+//             //package declaration
+//             ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, end));
+//             return cu.getPackageDeclaration(memento.substring(end + 1));
+//     }
+//     end = memento.indexOf(JavaElement.JEM_IMPORTDECLARATION, oldEnd);
+//     if (end != -1) {
+//             //import declaration
+//             ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, end));
+//             return cu.getImport(memento.substring(end + 1));
+//     }
+//     int typeStart = memento.indexOf(JavaElement.JEM_TYPE, oldEnd);
+//     if (typeStart == -1) {
+//             //we ended with a compilation unit
+//             return frag.getCompilationUnit(memento.substring(oldEnd + 1));
+//     }
+//
+//     //source members
+//     ICompilationUnit cu = frag.getCompilationUnit(memento.substring(oldEnd + 1, typeStart));
+//     end = memento.indexOf(JavaElement.JEM_FIELD, oldEnd);
+//     if (end != -1) {
+//             //source field
+//             IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
+//             return type.getField(memento.substring(end + 1));
+//     }
+//     end = memento.indexOf(JavaElement.JEM_METHOD, oldEnd);
+//     if (end != -1) {
+//             //source method
+//             IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
+//             oldEnd = end;
+//             String methodName;
+//             end = memento.lastIndexOf(JavaElement.JEM_METHOD);
+//             String[] parameterTypes = null;
+//             if (end == oldEnd) {
+//                     methodName = memento.substring(end + 1);
+//                     //no parameter types
+//                     parameterTypes = new String[] {};
+//             } else {
+//                     String parameters = memento.substring(oldEnd + 1);
+//                     StringTokenizer mTokenizer = new StringTokenizer(parameters, new String(new char[] {JavaElement.JEM_METHOD}));
+//                     parameterTypes = new String[mTokenizer.countTokens() - 1];
+//                     methodName = mTokenizer.nextToken();
+//                     int i = 0;
+//                     while (mTokenizer.hasMoreTokens()) {
+//                             parameterTypes[i] = mTokenizer.nextToken();
+//                             i++;
+//                     }
+//             }
+//             return type.getMethod(methodName, parameterTypes);
+//     }
+//     
+//     end = memento.indexOf(JavaElement.JEM_INITIALIZER, oldEnd);
+//     if (end != -1 ) {
+//             //initializer
+//             IType type = getHandleFromMementoForSourceType(memento, cu, typeStart, end);
+//             return type.getInitializer(Integer.parseInt(memento.substring(end + 1)));
+//     }
+//     //source type
+//     return getHandleFromMementoForSourceType(memento, cu, typeStart, memento.length());
+//}
+/**
+ * Returns the <code>IJavaElement</code> represented by the <code>String</code>
+ * memento.
+ * @see getHandleMemento()
+ */
+//protected IType getHandleFromMementoForSourceType(String memento, ICompilationUnit cu, int typeStart, int typeEnd) throws JavaModelException {
+//     int end = memento.lastIndexOf(JavaElement.JEM_TYPE);
+//     IType type = null;
+//     if (end == typeStart) {
+//             String typeName = memento.substring(typeStart + 1, typeEnd);
+//             type = cu.getType(typeName);
+//             
+//     } else {
+//             String typeNames = memento.substring(typeStart + 1, typeEnd);
+//             StringTokenizer tokenizer = new StringTokenizer(typeNames, new String(new char[] {JavaElement.JEM_TYPE}));
+//             type = cu.getType(tokenizer.nextToken());
+//             while (tokenizer.hasMoreTokens()) {
+//                     //deal with inner types
+//                     type= type.getType(tokenizer.nextToken());
+//             }
+//     }
+//     return type;
+//}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+public String getHandleMemento(){
+       return getElementName();
+}
+/**
+ * Returns the <code>char</code> that marks the start of this handles
+ * contribution to a memento.
+ */
+protected char getHandleMementoDelimiter(){
+       Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$
+       return 0;
+}
+/**
+ * @see IJavaModel
+ */
+public IJavaProject getJavaProject(String name) {
+       return new JavaProject(ResourcesPlugin.getWorkspace().getRoot().getProject(name), this);
+}
+/**
+ * Returns the active Java project associated with the specified
+ * resource, or <code>null</code> if no Java project yet exists
+ * for the resource.
+ *
+ * @exception IllegalArgumentException if the given resource
+ * is not one of an IProject, IFolder, or IFile.
+ */
+public IJavaProject getJavaProject(IResource resource) {
+       switch(resource.getType()){
+               case IResource.FOLDER:
+                       return new JavaProject(((IFolder)resource).getProject(), this);
+               case IResource.FILE:
+                       return new JavaProject(((IFile)resource).getProject(), this);
+               case IResource.PROJECT:
+                       return new JavaProject((IProject)resource, this);
+               default:
+                       throw new IllegalArgumentException(Util.bind("element.invalidResourceForProject")); //$NON-NLS-1$
+       }
+}
+/**
+ * @see IJavaModel
+ */
+public IJavaProject[] getJavaProjects() throws JavaModelException {
+       ArrayList list = getChildrenOfType(JAVA_PROJECT);
+       IJavaProject[] array= new IJavaProject[list.size()];
+       list.toArray(array);
+       return array;
+
+}
+///**
+// * @see IJavaModel
+// */
+//public Object[] getNonJavaResources() throws JavaModelException {
+//             return ((JavaModelInfo) getElementInfo()).getNonJavaResources();
+//}
+
+/**
+ * Workaround for bug 15168 circular errors not reported 
+ * Returns the list of java projects before resource delta processing
+ * has started.
+ */
+public IJavaProject[] getOldJavaProjectsList() throws JavaModelException {
+       JavaModelManager manager = JavaModelManager.getJavaModelManager();
+       return 
+               manager.javaProjectsCache == null ? 
+                       this.getJavaProjects() : 
+                       manager.javaProjectsCache; 
+}
+/*
+ * @see IJavaElement
+ */
+public IPath getPath() {
+       return Path.ROOT;
+}
+/*
+ * @see IJavaElement
+ */
+public IResource getResource() {
+       return ResourcesPlugin.getWorkspace().getRoot();
+}
+/**
+ * @see IOpenable
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+       return null;
+}
+/**
+ * Returns the workbench associated with this object.
+ */
+public IWorkspace getWorkspace() {
+       return ResourcesPlugin.getWorkspace();
+}
+
+/**
+ * @see IJavaModel
+ */
+//public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+//             runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+//     } else {
+//             runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+//     }
+//}
+
+/**
+ * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor)
+ */
+//public void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException {
+//     if (elementsScope == null){
+//             elementsScope = new IJavaElement[] { this };
+//     }
+//     JavaModelManager.getJavaModelManager().deltaProcessor.checkExternalArchiveChanges(elementsScope, monitor);
+//}
+
+/**
+ * @see IJavaModel
+ */
+//public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     MultiOperation op;
+//     if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+//             op = new RenameResourceElementsOperation(elements, destinations, renamings, force);
+//     } else {
+//             op = new RenameElementsOperation(elements, destinations, renamings, force);
+//     }
+//     
+//     runOperation(op, monitor);
+//}
+/*
+ * @see JavaElement#rootedAt(IJavaProject)
+ */
+public IJavaElement rootedAt(IJavaProject project) {
+       return this;
+
+}
+/**
+ * Configures and runs the <code>MultiOperation</code>.
+ */
+//protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException {
+//     op.setRenamings(renamings);
+//     if (siblings != null) {
+//             for (int i = 0; i < elements.length; i++) {
+//                     op.setInsertBefore(elements[i], siblings[i]);
+//             }
+//     }
+//     runOperation(op, monitor);
+//}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+       buffer.append(this.tabString(tab));
+       buffer.append("Java Model"); //$NON-NLS-1$
+       if (info == null) {
+               buffer.append(" (not open)"); //$NON-NLS-1$
+       }
+}
+
+/**
+ * Helper method - returns the targeted item (IResource if internal or java.io.File if external), 
+ * or null if unbound
+ * Internal items must be referred to using container relative paths.
+ */
+//public static Object getTarget(IContainer container, IPath path, boolean checkResourceExistence) {
+//
+//     if (path == null) return null;
+//     
+//     // lookup - inside the container
+//     if (path.getDevice() == null) { // container relative paths should not contain a device 
+//                                                                                             // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=18684)
+//                                                                                             // (case of a workspace rooted at d:\ )
+//             IResource resource = container.findMember(path);
+//             if (resource != null){
+//                     if (!checkResourceExistence ||resource.exists()) return resource;
+//                     return null;
+//             }
+//     }
+//     
+//     // if path is relative, it cannot be an external path
+//     // (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517)
+//     if (!path.isAbsolute()) return null; 
+//
+//     // lookup - outside the container
+//     File externalFile = new File(path.toOSString());
+//     if (!checkResourceExistence) {
+//             return externalFile;
+//     } else if (existingExternalFiles.contains(externalFile)) {
+//             return externalFile;
+//     } else { 
+//             if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+//                     System.out.println("(" + Thread.currentThread() + ") [JavaModel.getTarget(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+//             }
+//             if (externalFile.exists()) {
+//                     // cache external file
+//                     existingExternalFiles.add(externalFile);
+//                     return externalFile;
+//             }
+//     }
+//     return null;    
+//}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelManager.java
new file mode 100644 (file)
index 0000000..6652089
--- /dev/null
@@ -0,0 +1,1669 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.zip.ZipFile;
+
+import net.sourceforge.phpdt.core.ElementChangedEvent;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IElementChangedListener;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IWorkingCopy;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * The <code>JavaModelManager</code> manages instances of <code>IJavaModel</code>.
+ * <code>IElementChangedListener</code>s register with the <code>JavaModelManager</code>,
+ * and receive <code>ElementChangedEvent</code>s for all <code>IJavaModel</code>s.
+ * <p>
+ * The single instance of <code>JavaModelManager</code> is available from
+ * the static method <code>JavaModelManager.getJavaModelManager()</code>.
+ */
+public class JavaModelManager implements ISaveParticipant {    
+       /**
+        * Unique handle onto the JavaModel
+        */
+       final JavaModel javaModel = new JavaModel();
+       
+       /**
+        * Classpath variables pool
+        */
+       public static HashMap Variables = new HashMap(5);
+       public static HashMap PreviousSessionVariables = new HashMap(5);
+       public static HashSet OptionNames = new HashSet(20);
+       public final static String CP_VARIABLE_PREFERENCES_PREFIX = PHPeclipsePlugin.PLUGIN_ID+".classpathVariable."; //$NON-NLS-1$
+//     public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
+       public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
+               
+       /**
+        * Classpath containers pool
+        */
+       public static HashMap Containers = new HashMap(5);
+       public static HashMap PreviousSessionContainers = new HashMap(5);
+
+       /**
+        * Name of the extension point for contributing classpath variable initializers
+        */
+//     public static final String CPVARIABLE_INITIALIZER_EXTPOINT_ID = "classpathVariableInitializer" ; //$NON-NLS-1$
+
+       /**
+        * Name of the extension point for contributing classpath container initializers
+        */
+//     public static final String CPCONTAINER_INITIALIZER_EXTPOINT_ID = "classpathContainerInitializer" ; //$NON-NLS-1$
+
+       /**
+        * Name of the extension point for contributing a source code formatter
+        */
+       public static final String FORMATTER_EXTPOINT_ID = "codeFormatter" ; //$NON-NLS-1$
+       
+       /**
+        * Special value used for recognizing ongoing initialization and breaking initialization cycles
+        */
+       public final static IPath VariableInitializationInProgress = new Path("Variable Initialization In Progress"); //$NON-NLS-1$
+//     public final static IClasspathContainer ContainerInitializationInProgress = new IClasspathContainer() {
+//             public IClasspathEntry[] getClasspathEntries() { return null; }
+//             public String getDescription() { return "Container Initialization In Progress"; } //$NON-NLS-1$
+//             public int getKind() { return 0; }
+//             public IPath getPath() { return null; }
+//             public String toString() { return getDescription(); }
+//     };
+       
+       private static final String INDEX_MANAGER_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/indexmanager" ; //$NON-NLS-1$
+       private static final String COMPILER_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/compiler" ; //$NON-NLS-1$
+       private static final String JAVAMODEL_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/javamodel" ; //$NON-NLS-1$
+       private static final String CP_RESOLVE_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/cpresolution" ; //$NON-NLS-1$
+       private static final String ZIP_ACCESS_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/zipaccess" ; //$NON-NLS-1$
+       private static final String DELTA_DEBUG =PHPeclipsePlugin.PLUGIN_ID + "/debug/javadelta" ; //$NON-NLS-1$
+       private static final String HIERARCHY_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/hierarchy" ; //$NON-NLS-1$
+       private static final String POST_ACTION_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/postaction" ; //$NON-NLS-1$
+       private static final String BUILDER_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/builder" ; //$NON-NLS-1$
+       private static final String COMPLETION_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/completion" ; //$NON-NLS-1$
+       private static final String SELECTION_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/selection" ; //$NON-NLS-1$
+       private static final String SHARED_WC_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/sharedworkingcopy" ; //$NON-NLS-1$
+       private static final String SEARCH_DEBUG = PHPeclipsePlugin.PLUGIN_ID + "/debug/search" ; //$NON-NLS-1$
+
+       public final static IWorkingCopy[] NoWorkingCopy = new IWorkingCopy[0];
+       
+       /**
+        * Returns whether the given full path (for a package) conflicts with the output location
+        * of the given project.
+        */
+//     public static boolean conflictsWithOutputLocation(IPath folderPath, JavaProject project) {
+//             try {
+//                     IPath outputLocation = project.getOutputLocation();
+//                     if (outputLocation == null) {
+//                             // in doubt, there is a conflict
+//                             return true;
+//                     }
+//                     if (outputLocation.isPrefixOf(folderPath)) {
+//                             // only allow nesting in project's output if there is a corresponding source folder
+//                             // or if the project's output is not used (in other words, if all source folders have their custom output)
+//                             IClasspathEntry[] classpath = project.getResolvedClasspath(true);
+//                             boolean isOutputUsed = false;
+//                             for (int i = 0, length = classpath.length; i < length; i++) {
+//                                     IClasspathEntry entry = classpath[i];
+//                                     if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+//                                             if (entry.getPath().equals(outputLocation)) {
+//                                                     return false;
+//                                             }
+//                                             if (entry.getOutputLocation() == null) {
+//                                                     isOutputUsed = true;
+//                                             }
+//                                     }
+//                             }
+//                             return isOutputUsed;
+//                     }
+//                     return false;
+//             } catch (JavaModelException e) {
+//                     // in doubt, there is a conflict
+//                     return true;
+//             }
+//     }
+//
+//     public static IClasspathContainer containerGet(IJavaProject project, IPath containerPath) {     
+//             Map projectContainers = (Map)Containers.get(project);
+//             if (projectContainers == null){
+//                     return null;
+//             }
+//             IClasspathContainer container = (IClasspathContainer)projectContainers.get(containerPath);
+//             return container;
+//     }
+
+//     public static void containerPut(IJavaProject project, IPath containerPath, IClasspathContainer container){
+//
+//             Map projectContainers = (Map)Containers.get(project);
+//             if (projectContainers == null){
+//                     projectContainers = new HashMap(1);
+//                     Containers.put(project, projectContainers);
+//             }
+//
+//             if (container == null) {
+//                     projectContainers.remove(containerPath);
+//                     Map previousContainers = (Map)PreviousSessionContainers.get(project);
+//                     if (previousContainers != null){
+//                             previousContainers.remove(containerPath);
+//                     }
+//             } else {
+//                     projectContainers.put(containerPath, container);
+//             }
+//
+//             // do not write out intermediate initialization value
+//             if (container == JavaModelManager.ContainerInitializationInProgress) {
+//                     return;
+//             }
+//             Preferences preferences = PHPeclipsePlugin.getPlugin().getPluginPreferences();
+//             String containerKey = CP_CONTAINER_PREFERENCES_PREFIX+project.getElementName() +"|"+containerPath;//$NON-NLS-1$
+//             String containerString = CP_ENTRY_IGNORE;
+//             try {
+//                     if (container != null) {
+//                             containerString = ((JavaProject)project).encodeClasspath(container.getClasspathEntries(), null, false);
+//                     }
+//             } catch(JavaModelException e){
+//             }
+//             preferences.setDefault(containerKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones
+//             preferences.setValue(containerKey, containerString);
+//             PHPeclipsePlugin.getPlugin().savePluginPreferences();
+//     }
+
+       /**
+        * Returns the Java element corresponding to the given resource, or
+        * <code>null</code> if unable to associate the given resource
+        * with a Java element.
+        * <p>
+        * The resource must be one of:<ul>
+        *      <li>a project - the element returned is the corresponding <code>IJavaProject</code></li>
+        *      <li>a <code>.java</code> file - the element returned is the corresponding <code>ICompilationUnit</code></li>
+        *      <li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+        *      <li>a <code>.jar</code> file - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+        *  <li>a folder - the element returned is the corresponding <code>IPackageFragmentRoot</code>
+        *                      or <code>IPackageFragment</code></li>
+        *  <li>the workspace root resource - the element returned is the <code>IJavaModel</code></li>
+        *      </ul>
+        * <p>
+        * Creating a Java element has the side effect of creating and opening all of the
+        * element's parents if they are not yet open.
+        */
+       public static IJavaElement create(IResource resource, IJavaProject project) {
+               if (resource == null) {
+                       return null;
+               }
+               int type = resource.getType();
+               switch (type) {
+                       case IResource.PROJECT :
+                               return JavaCore.create((IProject) resource);
+                       case IResource.FILE :
+                               return create((IFile) resource, project);
+                       case IResource.FOLDER :
+                               return create((IFolder) resource, project);
+                       case IResource.ROOT :
+                               return JavaCore.create((IWorkspaceRoot) resource);
+                       default :
+                               return null;
+               }
+       }
+
+       /**
+        * Returns the Java element corresponding to the given file, its project being the given
+        * project.
+        * Returns <code>null</code> if unable to associate the given file
+        * with a Java element.
+        *
+        * <p>The file must be one of:<ul>
+        *      <li>a <code>.java</code> file - the element returned is the corresponding <code>ICompilationUnit</code></li>
+        *      <li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+        *      <li>a <code>.jar</code> file - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+        *      </ul>
+        * <p>
+        * Creating a Java element has the side effect of creating and opening all of the
+        * element's parents if they are not yet open.
+        */
+       public static IJavaElement create(IFile file, IJavaProject project) {
+               if (file == null) {
+                       return null;
+               }
+               if (project == null) {
+                       project = JavaCore.create(file.getProject());
+               }
+       
+               if (file.getFileExtension() != null) {
+                       String name = file.getName();
+//                     if (Util.isValidCompilationUnitName(name))
+                       if (PHPFileUtil.isPHPFile(file))
+                               return createCompilationUnitFrom(file, project);
+//                     if (Util.isValidClassFileName(name))
+//                             return createClassFileFrom(file, project);
+//                     if (Util.isArchiveFileName(name))
+//                             return createJarPackageFragmentRootFrom(file, project);
+               }
+               return null;
+       }
+
+       /**
+        * Returns the package fragment or package fragment root corresponding to the given folder,
+        * its parent or great parent being the given project. 
+        * or <code>null</code> if unable to associate the given folder with a Java element.
+        * <p>
+        * Note that a package fragment root is returned rather than a default package.
+        * <p>
+        * Creating a Java element has the side effect of creating and opening all of the
+        * element's parents if they are not yet open.
+        */
+       public static IJavaElement create(IFolder folder, IJavaProject project) {
+               if (folder == null) {
+                       return null;
+               }
+               if (project == null) {
+                       project = JavaCore.create(folder.getProject());
+               }
+//     TODO khartlage temp-del
+//             IJavaElement element = determineIfOnClasspath(folder, project);
+//             if (conflictsWithOutputLocation(folder.getFullPath(), (JavaProject)project)
+//                     || (folder.getName().indexOf('.') >= 0 
+//                             && !(element instanceof IPackageFragmentRoot))) {
+//                     return null; // only package fragment roots are allowed with dot names
+//             } else {
+//                     return element;
+//             }
+return null;
+       }
+
+       /**
+        * Creates and returns a class file element for the given <code>.class</code> file,
+        * its project being the given project. Returns <code>null</code> if unable
+        * to recognize the class file.
+        */
+//     public static IClassFile createClassFileFrom(IFile file, IJavaProject project ) {
+//             if (file == null) {
+//                     return null;
+//             }
+//             if (project == null) {
+//                     project = JavaCore.create(file.getProject());
+//             }
+//             IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
+//             if (pkg == null) {
+//                     // fix for 1FVS7WE
+//                     // not on classpath - make the root its folder, and a default package
+//                     IPackageFragmentRoot root = project.getPackageFragmentRoot(file.getParent());
+//                     pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+//             }
+//             return pkg.getClassFile(file.getName());
+//     }
+       
+       /**
+        * Creates and returns a compilation unit element for the given <code>.java</code> 
+        * file, its project being the given project. Returns <code>null</code> if unable
+        * to recognize the compilation unit.
+        */
+       public static ICompilationUnit createCompilationUnitFrom(IFile file, IJavaProject project) {
+
+               if (file == null) return null;
+
+               if (project == null) {
+                       project = JavaCore.create(file.getProject());
+               }
+//     TODO khartlage temp-del
+//             IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
+//             if (pkg == null) {
+
+                       // not on classpath - make the root its folder, and a default package
+//                     IPackageFragmentRoot root = project.getPackageFragmentRoot(file.getParent());
+//                     pkg = root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+//                     
+//                     if (VERBOSE){
+//                             System.out.println("WARNING : creating unit element outside classpath ("+ Thread.currentThread()+"): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+//                     }
+//             }
+//             return pkg.getCompilationUnit(file.getName());
+return null;
+       }
+       
+       /**
+        * Creates and returns a handle for the given JAR file, its project being the given project.
+        * The Java model associated with the JAR's project may be
+        * created as a side effect. 
+        * Returns <code>null</code> if unable to create a JAR package fragment root.
+        * (for example, if the JAR file represents a non-Java resource)
+        */
+//     public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile file, IJavaProject project) {
+//             if (file == null) {
+//                     return null;
+//             }
+//             if (project == null) {
+//                     project = JavaCore.create(file.getProject());
+//             }
+//     
+//             // Create a jar package fragment root only if on the classpath
+//             IPath resourcePath = file.getFullPath();
+//             try {
+//                     IClasspathEntry[] entries = ((JavaProject)project).getResolvedClasspath(true);
+//                     for (int i = 0, length = entries.length; i < length; i++) {
+//                             IClasspathEntry entry = entries[i];
+//                             IPath rootPath = entry.getPath();
+//                             if (rootPath.equals(resourcePath)) {
+//                                     return project.getPackageFragmentRoot(file);
+//                             }
+//                     }
+//             } catch (JavaModelException e) {
+//             }
+//             return null;
+//     }
+       
+       /**
+        * Returns the package fragment root represented by the resource, or
+        * the package fragment the given resource is located in, or <code>null</code>
+        * if the given resource is not on the classpath of the given project.
+        */
+//     public static IJavaElement determineIfOnClasspath(
+//             IResource resource,
+//             IJavaProject project) {
+//                     
+//             IPath resourcePath = resource.getFullPath();
+//             try {
+//                     IClasspathEntry[] entries = 
+//                             Util.isJavaFileName(resourcePath.lastSegment())
+//                                     ? project.getRawClasspath() // JAVA file can only live inside SRC folder (on the raw path)
+//                                     : ((JavaProject)project).getResolvedClasspath(true);
+//                             
+//                     for (int i = 0; i < entries.length; i++) {
+//                             IClasspathEntry entry = entries[i];
+//                             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
+//                             IPath rootPath = entry.getPath();
+//                             if (rootPath.equals(resourcePath)) {
+//                                     return project.getPackageFragmentRoot(resource);
+//                             } else if (rootPath.isPrefixOf(resourcePath) && !Util.isExcluded(resource, ((ClasspathEntry)entry).fullExclusionPatternChars())) {
+//                                     // given we have a resource child of the root, it cannot be a JAR pkg root
+//                                     IPackageFragmentRoot root = ((JavaProject) project).getFolderPackageFragmentRoot(rootPath);
+//                                     if (root == null) return null;
+//                                     IPath pkgPath = resourcePath.removeFirstSegments(rootPath.segmentCount());
+//                                     if (resource.getType() == IResource.FILE) {
+//                                             // if the resource is a file, then remove the last segment which
+//                                             // is the file name in the package
+//                                             pkgPath = pkgPath.removeLastSegments(1);
+//                                             
+//                                             // don't check validity of package name (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706)
+//                                             String pkgName = pkgPath.toString().replace('/', '.');
+//                                             return root.getPackageFragment(pkgName);
+//                                     } else {
+//                                             String pkgName = Util.packageName(pkgPath);
+//                                             if (pkgName == null || JavaConventions.validatePackageName(pkgName).getSeverity() == IStatus.ERROR) {
+//                                                     return null;
+//                                             }
+//                                             return root.getPackageFragment(pkgName);
+//                                     }
+//                             }
+//                     }
+//             } catch (JavaModelException npe) {
+//                     return null;
+//             }
+//             return null;
+//     }
+       
+       /**
+        * The singleton manager
+        */
+       private final static JavaModelManager Manager= new JavaModelManager();
+
+       /**
+        * Infos cache.
+        */
+//     protected JavaModelCache cache = new JavaModelCache();
+
+       /**
+        * Set of elements which are out of sync with their buffers.
+        */
+       protected Map elementsOutOfSynchWithBuffers = new HashMap(11);
+       
+       /**
+        * Turns delta firing on/off. By default it is on.
+        */
+       private boolean isFiring= true;
+
+       /**
+        * Queue of deltas created explicily by the Java Model that
+        * have yet to be fired.
+        */
+       ArrayList javaModelDeltas= new ArrayList();
+       /**
+        * Queue of reconcile deltas on working copies that have yet to be fired.
+        * This is a table form IWorkingCopy to IJavaElementDelta
+        */
+       HashMap reconcileDeltas = new HashMap();
+
+
+       /**
+        * Collection of listeners for Java element deltas
+        */
+       private IElementChangedListener[] elementChangedListeners = new IElementChangedListener[5];
+       private int[] elementChangedListenerMasks = new int[5];
+       private int elementChangedListenerCount = 0;
+       public int currentChangeEventType = ElementChangedEvent.PRE_AUTO_BUILD;
+       public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with ElementChangedEvent event masks
+
+
+
+       /**
+        * Used to convert <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s.
+        */
+       public final DeltaProcessor deltaProcessor = new DeltaProcessor(this);
+       /**
+        * Used to update the JavaModel for <code>IJavaElementDelta</code>s.
+        */
+//     private final ModelUpdater modelUpdater =new ModelUpdater();
+       /**
+        * Workaround for bug 15168 circular errors not reported  
+        * This is a cache of the projects before any project addition/deletion has started.
+        */
+       public IJavaProject[] javaProjectsCache;
+
+       /**
+        * Table from IProject to PerProjectInfo.
+        * NOTE: this object itself is used as a lock to synchronize creation/removal of per project infos
+        */
+       protected Map perProjectInfo = new HashMap(5);
+       
+       /**
+        * A map from ICompilationUnit to IWorkingCopy
+        * of the shared working copies.
+        */
+       public Map sharedWorkingCopies = new HashMap();
+       
+       /**
+        * A weak set of the known scopes.
+        */
+       protected WeakHashMap scopes = new WeakHashMap();
+
+       public static class PerProjectInfo {
+               public IProject project;
+               public Object savedState;
+               public boolean triedRead;
+//             public IClasspathEntry[] classpath;
+//             public IClasspathEntry[] lastResolvedClasspath;
+               public Map resolvedPathToRawEntries; // reverse map from resolved path to raw entries
+               public IPath outputLocation;
+               public Preferences preferences;
+               public PerProjectInfo(IProject project) {
+
+                       this.triedRead = false;
+                       this.savedState = null;
+                       this.project = project;
+               }
+       }
+       public static boolean VERBOSE = false;
+       public static boolean CP_RESOLVE_VERBOSE = false;
+       public static boolean ZIP_ACCESS_VERBOSE = false;
+       
+       /**
+        * A cache of opened zip files per thread.
+        * (map from Thread to map of IPath to java.io.ZipFile)
+        * NOTE: this object itself is used as a lock to synchronize creation/removal of entries
+        */
+       private HashMap zipFiles = new HashMap();
+       
+       
+       /**
+        * Update the classpath variable cache
+        */
+       public static class PluginPreferencesListener implements Preferences.IPropertyChangeListener {
+               /**
+                * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+                */
+               public void propertyChange(Preferences.PropertyChangeEvent event) {
+
+                       String propertyName = event.getProperty();
+                       if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
+                               String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
+                               String newValue = (String)event.getNewValue();
+                               if (newValue != null && !(newValue = newValue.trim()).equals(CP_ENTRY_IGNORE)) {
+                                       Variables.put(varName, new Path(newValue));
+                               } else {
+                                       Variables.remove(varName);
+                               }
+                       }
+//             TODO khartlage temp-del
+//                     if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)) {
+//                             recreatePersistedContainer(propertyName, (String)event.getNewValue(), false);
+//                     }
+               }
+       }
+
+       /**
+        * Line separator to use throughout the JavaModel for any source edit operation
+        */
+       //      public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+       /**
+        * Constructs a new JavaModelManager
+        */
+       private JavaModelManager() {
+       }
+
+       /**
+        * @deprecated - discard once debug has converted to not using it
+        */
+       public void addElementChangedListener(IElementChangedListener listener) {
+               this.addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE | ElementChangedEvent.POST_RECONCILE);
+       }
+       /**
+        * addElementChangedListener method comment.
+        * Need to clone defensively the listener information, in case some listener is reacting to some notification iteration by adding/changing/removing
+        * any of the other (for example, if it deregisters itself).
+        */
+       public void addElementChangedListener(IElementChangedListener listener, int eventMask) {
+               for (int i = 0; i < this.elementChangedListenerCount; i++){
+                       if (this.elementChangedListeners[i].equals(listener)){
+                               
+                               // only clone the masks, since we could be in the middle of notifications and one listener decide to change
+                               // any event mask of another listeners (yet not notified).
+                               int cloneLength = this.elementChangedListenerMasks.length;
+                               System.arraycopy(this.elementChangedListenerMasks, 0, this.elementChangedListenerMasks = new int[cloneLength], 0, cloneLength);
+                               this.elementChangedListenerMasks[i] = eventMask; // could be different
+                               return;
+                       }
+               }
+               // may need to grow, no need to clone, since iterators will have cached original arrays and max boundary and we only add to the end.
+               int length;
+               if ((length = this.elementChangedListeners.length) == this.elementChangedListenerCount){
+                       System.arraycopy(this.elementChangedListeners, 0, this.elementChangedListeners = new IElementChangedListener[length*2], 0, length);
+                       System.arraycopy(this.elementChangedListenerMasks, 0, this.elementChangedListenerMasks = new int[length*2], 0, length);
+               }
+               this.elementChangedListeners[this.elementChangedListenerCount] = listener;
+               this.elementChangedListenerMasks[this.elementChangedListenerCount] = eventMask;
+               this.elementChangedListenerCount++;
+       }
+
+       /**
+        * Starts caching ZipFiles.
+        * Ignores if there are already clients.
+        */
+       public void cacheZipFiles() {
+               synchronized(this.zipFiles) {
+                       Thread currentThread = Thread.currentThread();
+                       if (this.zipFiles.get(currentThread) != null) return;
+                       this.zipFiles.put(currentThread, new HashMap());
+               }
+       }
+       public void closeZipFile(ZipFile zipFile) {
+               if (zipFile == null) return;
+               synchronized(this.zipFiles) {
+                       if (this.zipFiles.get(Thread.currentThread()) != null) {
+                               return; // zip file will be closed by call to flushZipFiles
+                       }
+                       try {
+                               if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+                                       System.out.println("(" + Thread.currentThread() + ") [JavaModelManager.closeZipFile(ZipFile)] Closing ZipFile on " +zipFile.getName()); //$NON-NLS-1$   //$NON-NLS-2$
+                               }
+                               zipFile.close();
+                       } catch (IOException e) {
+                       }
+               }
+       }
+       
+
+
+       /**
+        * Configure the plugin with respect to option settings defined in ".options" file
+        */
+       public void configurePluginDebugOptions(){
+               if(JavaCore.getPlugin().isDebugging()){
+//             TODO khartlage temp-del
+                       String option = Platform.getDebugOption(BUILDER_DEBUG);
+//                     if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+//                     
+//                     option = Platform.getDebugOption(COMPILER_DEBUG);
+//                     if(option != null) Compiler.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+//
+//                     option = Platform.getDebugOption(COMPLETION_DEBUG);
+//                     if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+//                     
+                       option = Platform.getDebugOption(CP_RESOLVE_DEBUG);
+                       if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+                       option = Platform.getDebugOption(DELTA_DEBUG);
+                       if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+//                     option = Platform.getDebugOption(HIERARCHY_DEBUG);
+//                     if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+//
+//                     option = Platform.getDebugOption(INDEX_MANAGER_DEBUG);
+//                     if(option != null) IndexManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+                       
+                       option = Platform.getDebugOption(JAVAMODEL_DEBUG);
+                       if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+                       option = Platform.getDebugOption(POST_ACTION_DEBUG);
+                       if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+//                     option = Platform.getDebugOption(SEARCH_DEBUG);
+//                     if(option != null) SearchEngine.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+//
+//                     option = Platform.getDebugOption(SELECTION_DEBUG);
+//                     if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+                       option = Platform.getDebugOption(SHARED_WC_DEBUG);
+                       if(option != null) CompilationUnit.SHARED_WC_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+                       option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
+                       if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+               }
+       }
+       
+
+       
+       /**
+        * @see ISaveParticipant
+        */
+       public void doneSaving(ISaveContext context){
+       }
+       
+       /**
+        * Fire Java Model delta, flushing them after the fact after post_change notification.
+        * If the firing mode has been turned off, this has no effect. 
+        */
+       public void fire(IJavaElementDelta customDelta, int eventType) {
+
+               if (!this.isFiring) return;
+               
+               if (DeltaProcessor.VERBOSE && (eventType == DEFAULT_CHANGE_EVENT || eventType == ElementChangedEvent.PRE_AUTO_BUILD)) {
+                       System.out.println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
+               }
+
+               IJavaElementDelta deltaToNotify;
+               if (customDelta == null){
+                       deltaToNotify = this.mergeDeltas(this.javaModelDeltas);
+               } else {
+                       deltaToNotify = customDelta;
+               }
+                       
+               // Refresh internal scopes
+               if (deltaToNotify != null) {
+//             TODO khartlage temp-del
+//                     Iterator scopes = this.scopes.keySet().iterator();
+//                     while (scopes.hasNext()) {
+//                             AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
+//                             scope.processDelta(deltaToNotify);
+//                     }
+               }
+                       
+               // Notification
+       
+               // Important: if any listener reacts to notification by updating the listeners list or mask, these lists will
+               // be duplicated, so it is necessary to remember original lists in a variable (since field values may change under us)
+               IElementChangedListener[] listeners = this.elementChangedListeners;
+               int[] listenerMask = this.elementChangedListenerMasks;
+               int listenerCount = this.elementChangedListenerCount;
+
+               switch (eventType) {
+                       case DEFAULT_CHANGE_EVENT:
+                               firePreAutoBuildDelta(deltaToNotify, listeners, listenerMask, listenerCount);
+                               firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
+                               fireReconcileDelta(listeners, listenerMask, listenerCount);
+                               break;
+                       case ElementChangedEvent.PRE_AUTO_BUILD:
+                               firePreAutoBuildDelta(deltaToNotify, listeners, listenerMask, listenerCount);
+                               break;
+                       case ElementChangedEvent.POST_CHANGE:
+                               firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
+                               fireReconcileDelta(listeners, listenerMask, listenerCount);
+                               break;
+               }
+
+       }
+
+       private void firePreAutoBuildDelta(
+               IJavaElementDelta deltaToNotify,
+               IElementChangedListener[] listeners,
+               int[] listenerMask,
+               int listenerCount) {
+                       
+               if (DeltaProcessor.VERBOSE){
+                       System.out.println("FIRING PRE_AUTO_BUILD Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
+                       System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+               }
+               if (deltaToNotify != null) {
+                       notifyListeners(deltaToNotify, ElementChangedEvent.PRE_AUTO_BUILD, listeners, listenerMask, listenerCount);
+               }
+       }
+
+       private void firePostChangeDelta(
+               IJavaElementDelta deltaToNotify,
+               IElementChangedListener[] listeners,
+               int[] listenerMask,
+               int listenerCount) {
+                       
+               // post change deltas
+               if (DeltaProcessor.VERBOSE){
+                       System.out.println("FIRING POST_CHANGE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
+                       System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+               }
+               if (deltaToNotify != null) {
+                       // flush now so as to keep listener reactions to post their own deltas for subsequent iteration
+                       this.flush();
+                       
+                       notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount);
+               } 
+       }               
+       private void fireReconcileDelta(
+               IElementChangedListener[] listeners,
+               int[] listenerMask,
+               int listenerCount) {
+
+
+               IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas.values());
+               if (DeltaProcessor.VERBOSE){
+                       System.out.println("FIRING POST_RECONCILE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
+                       System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+               }
+               if (deltaToNotify != null) {
+                       // flush now so as to keep listener reactions to post their own deltas for subsequent iteration
+                       this.reconcileDeltas = new HashMap();
+               
+                       notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount);
+               } 
+       }
+
+       public void notifyListeners(IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
+               final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType);
+               for (int i= 0; i < listenerCount; i++) {
+                       if ((listenerMask[i] & eventType) != 0){
+                               final IElementChangedListener listener = listeners[i];
+                               long start = -1;
+                               if (DeltaProcessor.VERBOSE) {
+                                       System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
+                                       start = System.currentTimeMillis();
+                               }
+                               // wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+                               Platform.run(new ISafeRunnable() {
+                                       public void handleException(Throwable exception) {
+                                               Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
+                                       }
+                                       public void run() throws Exception {
+                                               listener.elementChanged(extraEvent);
+                                       }
+                               });
+                               if (DeltaProcessor.VERBOSE) {
+                                       System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Flushes all deltas without firing them.
+        */
+       protected void flush() {
+               this.javaModelDeltas = new ArrayList();
+       }
+
+       /**
+        * Flushes ZipFiles cache if there are no more clients.
+        */
+       public void flushZipFiles() {
+               synchronized(this.zipFiles) {
+                       Thread currentThread = Thread.currentThread();
+                       HashMap map = (HashMap)this.zipFiles.remove(currentThread);
+                       if (map == null) return;
+                       Iterator iterator = map.values().iterator();
+                       while (iterator.hasNext()) {
+                               try {
+                                       ZipFile zipFile = (ZipFile)iterator.next();
+                                       if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+                                               System.out.println("(" + currentThread + ") [JavaModelManager.flushZipFiles()] Closing ZipFile on " +zipFile.getName()); //$NON-NLS-1$//$NON-NLS-2$
+                                       }
+                                       zipFile.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }       
+       }
+       
+
+       
+       /** 
+        * Returns the set of elements which are out of synch with their buffers.
+        */
+       protected Map getElementsOutOfSynchWithBuffers() {
+               return this.elementsOutOfSynchWithBuffers;
+       }
+
+       /**
+        * Returns the <code>IJavaElement</code> represented by the 
+        * <code>String</code> memento.
+        */
+       public IJavaElement getHandleFromMemento(String memento) throws JavaModelException {
+               if (memento == null) {
+                       return null;
+               }
+               JavaModel model= (JavaModel) getJavaModel();
+               if (memento.equals("")){ // workspace memento //$NON-NLS-1$
+                       return model;
+               }
+               int modelEnd= memento.indexOf(JavaElement.JEM_JAVAPROJECT);
+               if (modelEnd == -1) {
+                       return null;
+               }
+               boolean returnProject= false;
+               int projectEnd= memento.indexOf(JavaElement.JEM_PACKAGEFRAGMENTROOT, modelEnd);
+               if (projectEnd == -1) {
+                       projectEnd= memento.length();
+                       returnProject= true;
+               }
+               String projectName= memento.substring(modelEnd + 1, projectEnd);
+               JavaProject proj= (JavaProject) model.getJavaProject(projectName);
+               if (returnProject) {
+                       return proj;
+               }
+               int rootEnd= memento.indexOf(JavaElement.JEM_PACKAGEFRAGMENT, projectEnd + 1);
+//     TODO khartlage temp-del
+//             if (rootEnd == -1) {
+//                     return model.getHandleFromMementoForRoot(memento, proj, projectEnd, memento.length());
+//             }
+//             IPackageFragmentRoot root = model.getHandleFromMementoForRoot(memento, proj, projectEnd, rootEnd);
+//             if (root == null)
+//                     return null;
+//
+//             int end= memento.indexOf(JavaElement.JEM_COMPILATIONUNIT, rootEnd);
+//             if (end == -1) {
+//                     end= memento.indexOf(JavaElement.JEM_CLASSFILE, rootEnd);
+//                     if (end == -1) {
+//                             if (rootEnd + 1 == memento.length()) {
+//                                     return root.getPackageFragment(IPackageFragment.DEFAULT_PACKAGE_NAME);
+//                             } else {
+//                                     return root.getPackageFragment(memento.substring(rootEnd + 1));
+//                             }
+//                     }
+//                     //deal with class file and binary members
+//                     return model.getHandleFromMementoForBinaryMembers(memento, root, rootEnd, end);
+//             }
+//
+//             //deal with compilation units and source members
+//             return model.getHandleFromMementoForSourceMembers(memento, root, rootEnd, end);
+         return null;
+       }
+//     public IndexManager getIndexManager() {
+//             return this.deltaProcessor.indexManager;
+//     }
+
+       /**
+        *  Returns the info for the element.
+        */
+//     public Object getInfo(IJavaElement element) {
+//             return this.cache.getInfo(element);
+//     }
+
+       /**
+        * Returns the handle to the active Java Model.
+        */
+       public final JavaModel getJavaModel() {
+               return javaModel;
+       }
+
+       /**
+        * Returns the singleton JavaModelManager
+        */
+       public final static JavaModelManager getJavaModelManager() {
+               return Manager;
+       }
+
+       /**
+        * Returns the last built state for the given project, or null if there is none.
+        * Deserializes the state if necessary.
+        *
+        * For use by image builder and evaluation support only
+        */
+       public Object getLastBuiltState(IProject project, IProgressMonitor monitor) {
+               if (!JavaProject.hasJavaNature(project)) return null; // should never be requested on non-Java projects
+               PerProjectInfo info = getPerProjectInfo(project, true/*create if missing*/);
+               if (!info.triedRead) {
+                       info.triedRead = true;
+                       try {
+                               if (monitor != null)
+                                       monitor.subTask(Util.bind("build.readStateProgress", project.getName())); //$NON-NLS-1$
+                               info.savedState = readState(project);
+                       } catch (CoreException e) {
+                               e.printStackTrace();
+                       }
+               }
+               return info.savedState;
+       }
+
+       /*
+        * Returns the per-project info for the given project. If specified, create the info if the info doesn't exist.
+        */
+       public PerProjectInfo getPerProjectInfo(IProject project, boolean create) {
+               synchronized(perProjectInfo) { // use the perProjectInfo collection as its own lock
+                       PerProjectInfo info= (PerProjectInfo) perProjectInfo.get(project);
+                       if (info == null && create) {
+                               info= new PerProjectInfo(project);
+                               perProjectInfo.put(project, info);
+                       }
+                       return info;
+               }
+       }       
+       
+       /*
+        * Returns  the per-project info for the given project.
+        * If the info doesn't exist, check for the project existence and create the info.
+        * @throws JavaModelException if the project doesn't exist.
+        */
+       public PerProjectInfo getPerProjectInfoCheckExistence(IProject project) throws JavaModelException {
+               JavaModelManager.PerProjectInfo info = getPerProjectInfo(project, false /* don't create info */);
+               if (info == null) {
+                       if (!JavaProject.hasJavaNature(project)) {
+                               throw ((JavaProject)JavaCore.create(project)).newNotPresentException();
+                       }
+                       info = getPerProjectInfo(project, true /* create info */);
+               }
+               return info;
+       }
+
+       /**
+        * Returns the name of the variables for which an CP variable initializer is registered through an extension point
+        */
+//     public static String[] getRegisteredVariableNames(){
+//             
+//             Plugin jdtCorePlugin = JavaCore.getPlugin();
+//             if (jdtCorePlugin == null) return null;
+//
+//             ArrayList variableList = new ArrayList(5);
+//             IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
+//             if (extension != null) {
+//                     IExtension[] extensions =  extension.getExtensions();
+//                     for(int i = 0; i < extensions.length; i++){
+//                             IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+//                             for(int j = 0; j < configElements.length; j++){
+//                                     String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$
+//                                     if (varAttribute != null) variableList.add(varAttribute);
+//                             }
+//                     }       
+//             }
+//             String[] variableNames = new String[variableList.size()];
+//             variableList.toArray(variableNames);
+//             return variableNames;
+//     }       
+
+       /**
+        * Returns the name of the container IDs for which an CP container initializer is registered through an extension point
+        */
+//     public static String[] getRegisteredContainerIDs(){
+//             
+//             Plugin jdtCorePlugin = JavaCore.getPlugin();
+//             if (jdtCorePlugin == null) return null;
+//
+//             ArrayList containerIDList = new ArrayList(5);
+//             IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID);
+//             if (extension != null) {
+//                     IExtension[] extensions =  extension.getExtensions();
+//                     for(int i = 0; i < extensions.length; i++){
+//                             IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+//                             for(int j = 0; j < configElements.length; j++){
+//                                     String idAttribute = configElements[j].getAttribute("id"); //$NON-NLS-1$
+//                                     if (idAttribute != null) containerIDList.add(idAttribute);
+//                             }
+//                     }       
+//             }
+//             String[] containerIDs = new String[containerIDList.size()];
+//             containerIDList.toArray(containerIDs);
+//             return containerIDs;
+//     }       
+
+       /**
+        * Returns the File to use for saving and restoring the last built state for the given project.
+        */
+       private File getSerializationFile(IProject project) {
+               if (!project.exists()) return null;
+               IPluginDescriptor descr= JavaCore.getJavaCore().getDescriptor();
+               IPath workingLocation= project.getPluginWorkingLocation(descr);
+               return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the open ZipFile at the given location. If the ZipFile
+        * does not yet exist, it is created, opened, and added to the cache
+        * of open ZipFiles. The location must be a absolute path.
+        *
+        * @exception CoreException If unable to create/open the ZipFile
+        */
+       public ZipFile getZipFile(IPath path) throws CoreException {
+                       
+               synchronized(this.zipFiles) { // TODO:  use PeThreadObject which does synchronization
+                       Thread currentThread = Thread.currentThread();
+                       HashMap map = null;
+                       ZipFile zipFile;
+                       if ((map = (HashMap)this.zipFiles.get(currentThread)) != null 
+                                       && (zipFile = (ZipFile)map.get(path)) != null) {
+                                       
+                               return zipFile;
+                       }
+                       String fileSystemPath= null;
+                       IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+                       IResource file = root.findMember(path);
+                       if (path.isAbsolute() && file != null) {
+                               if (file == null) { // external file
+                                       fileSystemPath= path.toOSString();
+                               } else { // internal resource (not an IFile or not existing)
+                                       IPath location;
+                                       if (file.getType() != IResource.FILE || (location = file.getLocation()) == null) {
+                                               throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$
+                                       }
+                                       fileSystemPath= location.toOSString();
+                               }
+                       } else if (!path.isAbsolute()) {
+                               file= root.getFile(path);
+                               if (file == null || file.getType() != IResource.FILE) {
+                                       throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$
+                               }
+                               IPath location = file.getLocation();
+                               if (location == null) {
+                                       throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$
+                               }
+                               fileSystemPath= location.toOSString();
+                       } else {
+                               fileSystemPath= path.toOSString();
+                       }
+       
+                       try {
+                               if (ZIP_ACCESS_VERBOSE) {
+                                       System.out.println("(" + currentThread + ") [JavaModelManager.getZipFile(IPath)] Creating ZipFile on " + fileSystemPath ); //$NON-NLS-1$ //$NON-NLS-2$
+                               }
+                               zipFile = new ZipFile(fileSystemPath);
+                               if (map != null) {
+                                       map.put(path, zipFile);
+                               }
+                               return zipFile;
+                       } catch (IOException e) {
+                               throw new CoreException(new Status(Status.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("status.IOException"), e)); //$NON-NLS-1$
+                       }
+               }
+       }
+
+//     public void loadVariablesAndContainers() throws CoreException {
+//
+//             // backward compatibility, consider persistent property 
+//             QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "variables"); //$NON-NLS-1$
+//             String xmlString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
+//             
+//             try {
+//                     if (xmlString != null){
+//                             StringReader reader = new StringReader(xmlString);
+//                             Element cpElement;
+//                             try {
+//                                     DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+//                                     cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
+//                             } catch(SAXException e) {
+//                                     return;
+//                             } catch(ParserConfigurationException e){
+//                                     return;
+//                             } finally {
+//                                     reader.close();
+//                             }
+//                             if (cpElement == null) return;
+//                             if (!cpElement.getNodeName().equalsIgnoreCase("variables")) { //$NON-NLS-1$
+//                                     return;
+//                             }
+//                             
+//                             NodeList list= cpElement.getChildNodes();
+//                             int length= list.getLength();
+//                             for (int i= 0; i < length; ++i) {
+//                                     Node node= list.item(i);
+//                                     short type= node.getNodeType();
+//                                     if (type == Node.ELEMENT_NODE) {
+//                                             Element element= (Element) node;
+//                                             if (element.getNodeName().equalsIgnoreCase("variable")) { //$NON-NLS-1$
+//                                                     variablePut( 
+//                                                             element.getAttribute("name"), //$NON-NLS-1$
+//                                                             new Path(element.getAttribute("path"))); //$NON-NLS-1$
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             } catch(IOException e){
+//             } finally {
+//                     if (xmlString != null){
+//                             ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(qName, null); // flush old one
+//                     }
+//                     
+//             }
+//             
+//             // load variables and containers from preferences into cache
+//             Preferences preferences = JavaCore.getPlugin().getPluginPreferences();
+//
+//             // only get variable from preferences not set to their default
+//             String[] propertyNames = preferences.propertyNames();
+//             int variablePrefixLength = CP_VARIABLE_PREFERENCES_PREFIX.length();
+//             for (int i = 0; i < propertyNames.length; i++){
+//                     String propertyName = propertyNames[i];
+//                     if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)){
+//                             String varName = propertyName.substring(variablePrefixLength);
+//                             IPath varPath = new Path(preferences.getString(propertyName).trim());
+//                             
+//                             Variables.put(varName, varPath); 
+//                             PreviousSessionVariables.put(varName, varPath);
+//                     }
+//                     if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){
+//                             recreatePersistedContainer(propertyName, preferences.getString(propertyName), true/*add to container values*/);
+//                     }
+//             }
+//             // override persisted values for variables which have a registered initializer
+//             String[] registeredVariables = getRegisteredVariableNames();
+//             for (int i = 0; i < registeredVariables.length; i++) {
+//                     String varName = registeredVariables[i];
+//                     Variables.put(varName, null); // reset variable, but leave its entry in the Map, so it will be part of variable names.
+//             }
+//             // override persisted values for containers which have a registered initializer
+//             String[] registeredContainerIDs = getRegisteredContainerIDs();
+//             for (int i = 0; i < registeredContainerIDs.length; i++) {
+//                     String containerID = registeredContainerIDs[i];
+//                     Iterator projectIterator = Containers.keySet().iterator();
+//                     while (projectIterator.hasNext()){
+//                             IJavaProject project = (IJavaProject)projectIterator.next();
+//                             Map projectContainers = (Map)Containers.get(project);
+//                             if (projectContainers != null){
+//                                     Iterator containerIterator = projectContainers.keySet().iterator();
+//                                     while (containerIterator.hasNext()){
+//                                             IPath containerPath = (IPath)containerIterator.next();
+//                                             if (containerPath.segment(0).equals(containerID)) { // registered container
+//                                                     projectContainers.put(containerPath, null); // reset container value, but leave entry in Map
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             }
+//     }
+
+       /**
+        * Merged all awaiting deltas.
+        */
+       public IJavaElementDelta mergeDeltas(Collection deltas) {
+               if (deltas.size() == 0) return null;
+               if (deltas.size() == 1) return (IJavaElementDelta)deltas.iterator().next();
+               
+               if (DeltaProcessor.VERBOSE) {
+                       System.out.println("MERGING " + deltas.size() + " DELTAS ["+Thread.currentThread()+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+               }
+               
+               Iterator iterator = deltas.iterator();
+               IJavaElement javaModel = this.getJavaModel();
+               JavaElementDelta rootDelta = new JavaElementDelta(javaModel);
+               boolean insertedTree = false;
+               while (iterator.hasNext()) {
+                       JavaElementDelta delta = (JavaElementDelta)iterator.next();
+                       if (DeltaProcessor.VERBOSE) {
+                               System.out.println(delta.toString());
+                       }
+                       IJavaElement element = delta.getElement();
+                       if (javaModel.equals(element)) {
+                               IJavaElementDelta[] children = delta.getAffectedChildren();
+                               for (int j = 0; j < children.length; j++) {
+                                       JavaElementDelta projectDelta = (JavaElementDelta) children[j];
+                                       rootDelta.insertDeltaTree(projectDelta.getElement(), projectDelta);
+                                       insertedTree = true;
+                               }
+                               IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
+                               if (resourceDeltas != null) {
+                                       for (int i = 0, length = resourceDeltas.length; i < length; i++) {
+                                               rootDelta.addResourceDelta(resourceDeltas[i]);
+                                               insertedTree = true;
+                                       }
+                               }
+                       } else {
+                               rootDelta.insertDeltaTree(element, delta);
+                               insertedTree = true;
+                       }
+               }
+               if (insertedTree) {
+                       return rootDelta;
+               }
+               else {
+                       return null;
+               }
+       }       
+
+       /**
+        *  Returns the info for this element without
+        *  disturbing the cache ordering.
+        */ // TODO: should be synchronized, could answer unitialized info or if cache is in middle of rehash, could even answer distinct element info
+//     protected Object peekAtInfo(IJavaElement element) {
+//             return this.cache.peekAtInfo(element);
+//     }
+
+       /**
+        * @see ISaveParticipant
+        */
+       public void prepareToSave(ISaveContext context) throws CoreException {
+       }
+//     protected void putInfo(IJavaElement element, Object info) {
+//             this.cache.putInfo(element, info);
+//     }
+
+       /**
+        * Reads the build state for the relevant project.
+        */
+       protected Object readState(IProject project) throws CoreException {
+               File file = getSerializationFile(project);
+               if (file != null && file.exists()) {
+                       try {
+                               DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+                               try {
+                                       String pluginID= in.readUTF();
+                                       if (!pluginID.equals(JavaCore.PLUGIN_ID))
+                                               throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$
+                                       String kind= in.readUTF();
+                                       if (!kind.equals("STATE")) //$NON-NLS-1$
+                                               throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$
+//                             TODO khartlage temp-del
+//                                     if (in.readBoolean())
+//                                             return JavaBuilder.readState(project, in);
+//                                     if (JavaBuilder.DEBUG)
+//                                             System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
+                               } finally {
+                                       in.close();
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                               throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$
+                       }
+               }
+               return null;
+       }
+
+//     public static void recreatePersistedContainer(String propertyName, String containerString, boolean addToContainerValues) {
+//             int containerPrefixLength = CP_CONTAINER_PREFERENCES_PREFIX.length();
+//             int index = propertyName.indexOf('|', containerPrefixLength);
+//             if (containerString != null) containerString = containerString.trim();
+//             if (index > 0) {
+//                     final String projectName = propertyName.substring(containerPrefixLength, index).trim();
+//                     JavaProject project = (JavaProject)getJavaModelManager().getJavaModel().getJavaProject(projectName);
+//                     final IPath containerPath = new Path(propertyName.substring(index+1).trim());
+//                     
+//                     if (containerString == null || containerString.equals(CP_ENTRY_IGNORE)) {
+//                             containerPut(project, containerPath, null);
+//                     } else {
+//                             final IClasspathEntry[] containerEntries = project.decodeClasspath(containerString, false, false);
+//                             if (containerEntries != null && containerEntries != JavaProject.INVALID_CLASSPATH) {
+//                                     IClasspathContainer container = new IClasspathContainer() {
+//                                             public IClasspathEntry[] getClasspathEntries() {
+//                                                     return containerEntries;
+//                                             }
+//                                             public String getDescription() {
+//                                                     return "Persisted container ["+containerPath+" for project ["+ projectName+"]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+//                                             }
+//                                             public int getKind() {
+//                                                     return 0; 
+//                                             }
+//                                             public IPath getPath() {
+//                                                     return containerPath;
+//                                             }
+//                                             public String toString() {
+//                                                     return getDescription();
+//                                             }
+//
+//                                     };
+//                                     if (addToContainerValues) {
+//                                             containerPut(project, containerPath, container);
+//                                     }
+//                                     Map projectContainers = (Map)PreviousSessionContainers.get(project);
+//                                     if (projectContainers == null){
+//                                             projectContainers = new HashMap(1);
+//                                             PreviousSessionContainers.put(project, projectContainers);
+//                                     }
+//                                     projectContainers.put(containerPath, container);
+//                             }
+//                     }
+//             }
+//     }
+
+       /**
+        * Registers the given delta with this manager.
+        */
+       protected void registerJavaModelDelta(IJavaElementDelta delta) {
+               this.javaModelDeltas.add(delta);
+       }
+       
+       /**
+        * Remembers the given scope in a weak set
+        * (so no need to remove it: it will be removed by the garbage collector)
+        */
+//     public void rememberScope(AbstractSearchScope scope) {
+//             // NB: The value has to be null so as to not create a strong reference on the scope
+//             this.scopes.put(scope, null); 
+//     }
+
+       /**
+        * removeElementChangedListener method comment.
+        */
+       public void removeElementChangedListener(IElementChangedListener listener) {
+               
+               for (int i = 0; i < this.elementChangedListenerCount; i++){
+                       
+                       if (this.elementChangedListeners[i].equals(listener)){
+                               
+                               // need to clone defensively since we might be in the middle of listener notifications (#fire)
+                               int length = this.elementChangedListeners.length;
+                               IElementChangedListener[] newListeners = new IElementChangedListener[length];
+                               System.arraycopy(this.elementChangedListeners, 0, newListeners, 0, i);
+                               int[] newMasks = new int[length];
+                               System.arraycopy(this.elementChangedListenerMasks, 0, newMasks, 0, i);
+                               
+                               // copy trailing listeners
+                               int trailingLength = this.elementChangedListenerCount - i - 1;
+                               if (trailingLength > 0){
+                                       System.arraycopy(this.elementChangedListeners, i+1, newListeners, i, trailingLength);
+                                       System.arraycopy(this.elementChangedListenerMasks, i+1, newMasks, i, trailingLength);
+                               }
+                               
+                               // update manager listener state (#fire need to iterate over original listeners through a local variable to hold onto
+                               // the original ones)
+                               this.elementChangedListeners = newListeners;
+                               this.elementChangedListenerMasks = newMasks;
+                               this.elementChangedListenerCount--;
+                               return;
+                       }
+               }
+       }
+       
+//     protected void removeInfo(IJavaElement element) {
+//             this.cache.removeInfo(element);
+//     }
+
+       public void removePerProjectInfo(JavaProject javaProject) {
+               synchronized(perProjectInfo) { // use the perProjectInfo collection as its own lock
+                       IProject project = javaProject.getProject();
+                       PerProjectInfo info= (PerProjectInfo) perProjectInfo.get(project);
+                       if (info != null) {
+                               perProjectInfo.remove(project);
+                       }
+               }
+       }
+
+       /**
+        * @see ISaveParticipant
+        */
+       public void rollback(ISaveContext context){
+       }
+
+       private void saveState(PerProjectInfo info, ISaveContext context) throws CoreException {
+
+               // passed this point, save actions are non trivial
+               if (context.getKind() == ISaveContext.SNAPSHOT) return;
+               
+               // save built state
+               // TODO khartlage temp-del
+//             if (info.triedRead) saveBuiltState(info);
+       }
+       
+       /**
+        * Saves the built state for the project.
+        */
+//     private void saveBuiltState(PerProjectInfo info) throws CoreException {
+//             if (JavaBuilder.DEBUG)
+//                     System.out.println(Util.bind("build.saveStateProgress", info.project.getName())); //$NON-NLS-1$
+//             File file = getSerializationFile(info.project);
+//             if (file == null) return;
+//             long t = System.currentTimeMillis();
+//             try {
+//                     DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+//                     try {
+//                             out.writeUTF(JavaCore.PLUGIN_ID);
+//                             out.writeUTF("STATE"); //$NON-NLS-1$
+//                             if (info.savedState == null) {
+//                                     out.writeBoolean(false);
+//                             } else {
+//                                     out.writeBoolean(true);
+//                                     JavaBuilder.writeState(info.savedState, out);
+//                             }
+//                     } finally {
+//                             out.close();
+//                     }
+//             } catch (RuntimeException e) {
+//                     try {file.delete();} catch(SecurityException se) {}
+//                     throw new CoreException(
+//                             new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
+//                                     Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+//             } catch (IOException e) {
+//                     try {file.delete();} catch(SecurityException se) {}
+//                     throw new CoreException(
+//                             new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
+//                                     Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+//             }
+//             if (JavaBuilder.DEBUG) {
+//                     t = System.currentTimeMillis() - t;
+//                     System.out.println(Util.bind("build.saveStateComplete", String.valueOf(t))); //$NON-NLS-1$
+//             }
+//     }
+
+       /**
+        * @see ISaveParticipant
+        */
+       public void saving(ISaveContext context) throws CoreException {
+       
+               IProject savedProject = context.getProject();
+               if (savedProject != null) {
+                       if (!JavaProject.hasJavaNature(savedProject)) return; // ignore
+                       PerProjectInfo info = getPerProjectInfo(savedProject, true /* create info */);
+                       saveState(info, context);
+                       return;
+               }
+
+               ArrayList vStats= null; // lazy initialized
+               for (Iterator iter =  perProjectInfo.values().iterator(); iter.hasNext();) {
+                       try {
+                               PerProjectInfo info = (PerProjectInfo) iter.next();
+                               saveState(info, context);
+                       } catch (CoreException e) {
+                               if (vStats == null)
+                                       vStats= new ArrayList();
+                               vStats.add(e.getStatus());
+                       }
+               }
+               if (vStats != null) {
+                       IStatus[] stats= new IStatus[vStats.size()];
+                       vStats.toArray(stats);
+                       throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR, stats, Util.bind("build.cannotSaveStates"), null)); //$NON-NLS-1$
+               }
+       }
+
+       /**
+        * Record the order in which to build the java projects (batch build). This order is based
+        * on the projects classpath settings.
+        */
+       protected void setBuildOrder(String[] javaBuildOrder) throws JavaModelException {
+
+               // optional behaviour
+               // possible value of index 0 is Compute
+               if (!JavaCore.COMPUTE.equals(JavaCore.getOption(JavaCore.CORE_JAVA_BUILD_ORDER))) return; // cannot be customized at project level
+               
+               if (javaBuildOrder == null || javaBuildOrder.length <= 1) return;
+               
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               IWorkspaceDescription description = workspace.getDescription();
+               String[] wksBuildOrder = description.getBuildOrder();
+
+               String[] newOrder;
+               if (wksBuildOrder == null){
+                       newOrder = javaBuildOrder;
+               } else {
+                       // remove projects which are already mentionned in java builder order
+                       int javaCount = javaBuildOrder.length;
+                       HashMap newSet = new HashMap(javaCount); // create a set for fast check
+                       for (int i = 0; i < javaCount; i++){
+                               newSet.put(javaBuildOrder[i], javaBuildOrder[i]);
+                       }
+                       int removed = 0;
+                       int oldCount = wksBuildOrder.length;
+                       for (int i = 0; i < oldCount; i++){
+                               if (newSet.containsKey(wksBuildOrder[i])){
+                                       wksBuildOrder[i] = null;
+                                       removed++;
+                               }
+                       }
+                       // add Java ones first
+                       newOrder = new String[oldCount - removed + javaCount];
+                       System.arraycopy(javaBuildOrder, 0, newOrder, 0, javaCount); // java projects are built first
+
+                       // copy previous items in their respective order
+                       int index = javaCount;
+                       for (int i = 0; i < oldCount; i++){
+                               if (wksBuildOrder[i] != null){
+                                       newOrder[index++] = wksBuildOrder[i];
+                               }
+                       }
+               }
+               // commit the new build order out
+               description.setBuildOrder(newOrder);
+               try {
+                       workspace.setDescription(description);
+               } catch(CoreException e){
+                       throw new JavaModelException(e);
+               }
+       }
+
+       /**
+        * Sets the last built state for the given project, or null to reset it.
+        */
+       public void setLastBuiltState(IProject project, Object state) {
+               if (!JavaProject.hasJavaNature(project)) return; // should never be requested on non-Java projects
+               PerProjectInfo info = getPerProjectInfo(project, true /*create if missing*/);
+               info.triedRead = true; // no point trying to re-read once using setter
+               info.savedState = state;
+               if (state == null) { // delete state file to ensure a full build happens if the workspace crashes
+                       try {
+                               File file = getSerializationFile(project);
+                               if (file != null && file.exists())
+                                       file.delete();
+                       } catch(SecurityException se) {}
+               }
+       }
+
+       public void shutdown () {
+//     TODO khartlage temp-del
+//             if (this.deltaProcessor.indexManager != null){ // no more indexing
+//                     this.deltaProcessor.indexManager.shutdown();
+//             }
+//             try {
+//                     IJavaModel model = this.getJavaModel();
+//                     if (model != null) {
+
+//                             model.close();
+//                     }
+//             } catch (JavaModelException e) {
+//             }
+       }
+
+       /**
+        * Turns the firing mode to on. That is, deltas that are/have been
+        * registered will be fired.
+        */
+       public void startDeltas() {
+               this.isFiring= true;
+       }
+
+       /**
+        * Turns the firing mode to off. That is, deltas that are/have been
+        * registered will not be fired until deltas are started again.
+        */
+       public void stopDeltas() {
+               this.isFiring= false;
+       }
+       
+       /**
+        * Update Java Model given some delta
+        */
+//     public void updateJavaModel(IJavaElementDelta customDelta) {
+//
+//             if (customDelta == null){
+//                     for (int i = 0, length = this.javaModelDeltas.size(); i < length; i++){
+//                             IJavaElementDelta delta = (IJavaElementDelta)this.javaModelDeltas.get(i);
+//                             this.modelUpdater.processJavaDelta(delta);
+//                     }
+//             } else {
+//                     this.modelUpdater.processJavaDelta(customDelta);
+//             }
+//     }
+
+
+       
+       public static IPath variableGet(String variableName){
+               return (IPath)Variables.get(variableName);
+       }
+
+       public static String[] variableNames(){
+               int length = Variables.size();
+               String[] result = new String[length];
+               Iterator vars = Variables.keySet().iterator();
+               int index = 0;
+               while (vars.hasNext()) {
+                       result[index++] = (String) vars.next();
+               }
+               return result;
+       }
+       
+       public static void variablePut(String variableName, IPath variablePath){                
+
+               // update cache - do not only rely on listener refresh          
+               if (variablePath == null) {
+                       Variables.remove(variableName);
+                       PreviousSessionVariables.remove(variableName);
+               } else {
+                       Variables.put(variableName, variablePath);
+               }
+
+               // do not write out intermediate initialization value
+               if (variablePath == JavaModelManager.VariableInitializationInProgress){
+                       return;
+               } 
+               Preferences preferences = JavaCore.getPlugin().getPluginPreferences();
+               String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
+               String variableString = variablePath == null ? CP_ENTRY_IGNORE : variablePath.toString();
+               preferences.setDefault(variableKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones
+               preferences.setValue(variableKey, variableString);
+               JavaCore.getPlugin().savePluginPreferences();
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaModelOperation.java
new file mode 100644 (file)
index 0000000..0347ce1
--- /dev/null
@@ -0,0 +1,808 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaElementDelta;
+import net.sourceforge.phpdt.core.IJavaModel;
+import net.sourceforge.phpdt.core.IJavaModelStatus;
+import net.sourceforge.phpdt.core.IJavaModelStatusConstants;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IWorkingCopy;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.core.util.PerThreadObject;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+
+/**
+ * Defines behavior common to all Java Model operations
+ */
+public abstract class JavaModelOperation implements IWorkspaceRunnable, IProgressMonitor {
+       protected interface IPostAction {
+               /*
+                * Returns the id of this action.
+                * @see JavaModelOperation#postAction
+                */
+               String getID();
+               /*
+                * Run this action.
+                */
+               void run() throws JavaModelException;
+       }
+       /*
+        * Constants controlling the insertion mode of an action.
+        * @see JavaModelOperation#postAction
+        */
+       protected static final int APPEND = 1; // insert at the end
+       protected static final int REMOVEALL_APPEND = 2; // remove all existing ones with same ID, and add new one at the end
+       protected static final int KEEP_EXISTING = 3; // do not insert if already existing with same ID
+       
+       /*
+        * Whether tracing post actions is enabled.
+        */
+       protected static boolean POST_ACTION_VERBOSE;
+
+       /*
+        * A list of IPostActions.
+        */
+       protected IPostAction[] actions;
+       protected int actionsStart = 0;
+       protected int actionsEnd = -1;
+       /*
+        * A HashMap of attributes that can be used by operations
+        */
+       protected HashMap attributes;
+
+       public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$
+       public static final String TRUE = "true"; //$NON-NLS-1$
+       //public static final String FALSE = "false"; //$NON-NLS-1$
+               
+       /**
+        * The elements this operation operates on,
+        * or <code>null</code> if this operation
+        * does not operate on specific elements.
+        */
+       protected IJavaElement[] fElementsToProcess;
+       /**
+        * The parent elements this operation operates with
+        * or <code>null</code> if this operation
+        * does not operate with specific parent elements.
+        */
+       protected IJavaElement[] fParentElements;
+       /**
+        * An empty collection of <code>IJavaElement</code>s - the common
+        * empty result if no elements are created, or if this
+        * operation is not actually executed.
+        */
+       protected static IJavaElement[] fgEmptyResult= new IJavaElement[] {};
+
+
+       /**
+        * The elements created by this operation - empty
+        * until the operation actually creates elements.
+        */
+       protected IJavaElement[] fResultElements= fgEmptyResult;
+
+       /**
+        * The progress monitor passed into this operation
+        */
+       protected IProgressMonitor fMonitor= null;
+       /**
+        * A flag indicating whether this operation is nested.
+        */
+       protected boolean fNested = false;
+       /**
+        * Conflict resolution policy - by default do not force (fail on a conflict).
+        */
+       protected boolean fForce= false;
+
+       /*
+        * A per thread stack of java model operations (PerThreadObject of ArrayList).
+        */
+       protected static PerThreadObject operationStacks = new PerThreadObject();
+       protected JavaModelOperation() {
+       }
+       /**
+        * A common constructor for all Java Model operations.
+        */
+       protected JavaModelOperation(IJavaElement[] elements) {
+               fElementsToProcess = elements;
+       }
+       /**
+        * Common constructor for all Java Model operations.
+        */
+       protected JavaModelOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements) {
+               fElementsToProcess = elementsToProcess;
+               fParentElements= parentElements;
+       }
+       /**
+        * A common constructor for all Java Model operations.
+        */
+       protected JavaModelOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements, boolean force) {
+               fElementsToProcess = elementsToProcess;
+               fParentElements= parentElements;
+               fForce= force;
+       }
+       /**
+        * A common constructor for all Java Model operations.
+        */
+       protected JavaModelOperation(IJavaElement[] elements, boolean force) {
+               fElementsToProcess = elements;
+               fForce= force;
+       }
+       
+       /**
+        * Common constructor for all Java Model operations.
+        */
+       protected JavaModelOperation(IJavaElement element) {
+               fElementsToProcess = new IJavaElement[]{element};
+       }
+       /**
+        * A common constructor for all Java Model operations.
+        */
+       protected JavaModelOperation(IJavaElement element, boolean force) {
+               fElementsToProcess = new IJavaElement[]{element};
+               fForce= force;
+       }
+       
+       /*
+        * Registers the given action at the end of the list of actions to run.
+        */
+       protected void addAction(IPostAction action) {
+               int length = this.actions.length;
+               if (length == ++this.actionsEnd) {
+                       System.arraycopy(this.actions, 0, this.actions = new IPostAction[length*2], 0, length);
+               }
+               this.actions[this.actionsEnd] = action;
+       }
+       /*
+        * Registers the given delta with the Java Model Manager.
+        */
+       protected void addDelta(IJavaElementDelta delta) {
+               JavaModelManager.getJavaModelManager().registerJavaModelDelta(delta);
+       }
+       /*
+        * Registers the given reconcile delta with the Java Model Manager.
+        */
+       protected void addReconcileDelta(IWorkingCopy workingCopy, IJavaElementDelta delta) {
+               HashMap reconcileDeltas = JavaModelManager.getJavaModelManager().reconcileDeltas;
+               JavaElementDelta previousDelta = (JavaElementDelta)reconcileDeltas.get(workingCopy);
+               if (previousDelta != null) {
+                       IJavaElementDelta[] children = delta.getAffectedChildren();
+                       for (int i = 0, length = children.length; i < length; i++) {
+                               JavaElementDelta child = (JavaElementDelta)children[i];
+                               previousDelta.insertDeltaTree(child.getElement(), child);
+                       }
+               } else {
+                       reconcileDeltas.put(workingCopy, delta);
+               }
+       }
+       /*
+        * Deregister the reconcile delta for the given working copy
+        */
+       protected void removeReconcileDelta(IWorkingCopy workingCopy) {
+               JavaModelManager.getJavaModelManager().reconcileDeltas.remove(workingCopy);             
+       }
+       /**
+        * @see IProgressMonitor
+        */
+       public void beginTask(String name, int totalWork) {
+               if (fMonitor != null) {
+                       fMonitor.beginTask(name, totalWork);
+               }
+       }
+       /**
+        * Checks with the progress monitor to see whether this operation
+        * should be canceled. An operation should regularly call this method
+        * during its operation so that the user can cancel it.
+        *
+        * @exception OperationCanceledException if cancelling the operation has been requested
+        * @see IProgressMonitor#isCanceled
+        */
+       protected void checkCanceled() {
+               if (isCanceled()) {
+                       throw new OperationCanceledException(Util.bind("operation.cancelled")); //$NON-NLS-1$
+               }
+       }
+       /**
+        * Common code used to verify the elements this operation is processing.
+        * @see JavaModelOperation#verify()
+        */
+       protected IJavaModelStatus commonVerify() {
+               if (fElementsToProcess == null || fElementsToProcess.length == 0) {
+                       return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+               }
+               for (int i = 0; i < fElementsToProcess.length; i++) {
+                       if (fElementsToProcess[i] == null) {
+                               return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+                       }
+               }
+               return JavaModelStatus.VERIFIED_OK;
+       }
+       /**
+        * Convenience method to copy resources
+        */
+       protected void copyResources(IResource[] resources, IPath destinationPath) throws JavaModelException {
+               IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
+               IWorkspace workspace = resources[0].getWorkspace();
+               try {
+                       workspace.copy(resources, destinationPath, false, subProgressMonitor);
+                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * Convenience method to create a file
+        */
+       protected void createFile(IContainer folder, String name, InputStream contents, boolean force) throws JavaModelException {
+               IFile file= folder.getFile(new Path(name));
+               try {
+                       file.create(
+                               contents, 
+                               force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, 
+                               getSubProgressMonitor(1));
+                               this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * Convenience method to create a folder
+        */
+       protected void createFolder(IContainer parentFolder, String name, boolean force) throws JavaModelException {
+               IFolder folder= parentFolder.getFolder(new Path(name));
+               try {
+                       // we should use true to create the file locally. Only VCM should use tru/false
+                       folder.create(
+                               force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+                               true, // local
+                               getSubProgressMonitor(1));
+                               this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * Convenience method to delete an empty package fragment
+        */
+       protected void deleteEmptyPackageFragment(
+               IPackageFragment fragment,
+               boolean force,
+               IResource rootResource)
+               throws JavaModelException {
+       
+               IContainer resource = (IContainer) fragment.getResource();
+       
+               try {
+                       resource.delete(
+                               force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, 
+                               getSubProgressMonitor(1));
+                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+                       while (resource instanceof IFolder) {
+                               // deleting a package: delete the parent if it is empty (eg. deleting x.y where folder x doesn't have resources but y)
+                               // without deleting the package fragment root
+                               resource = resource.getParent();
+                               if (!resource.equals(rootResource) && resource.members().length == 0) {
+                                       resource.delete(
+                                               force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, 
+                                               getSubProgressMonitor(1));
+                                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+                               }
+                       }
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * Convenience method to delete a resource
+        */
+       protected void deleteResource(IResource resource,int flags) throws JavaModelException {
+               try {
+                       resource.delete(flags, getSubProgressMonitor(1));
+                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * Convenience method to delete resources
+        */
+       protected void deleteResources(IResource[] resources, boolean force) throws JavaModelException {
+               if (resources == null || resources.length == 0) return;
+               IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
+               IWorkspace workspace = resources[0].getWorkspace();
+               try {
+                       workspace.delete(
+                               resources,
+                               force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, 
+                               subProgressMonitor);
+                               this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * @see IProgressMonitor
+        */
+       public void done() {
+               if (fMonitor != null) {
+                       fMonitor.done();
+               }
+       }
+       /*
+        * Returns whether the given path is equals to one of the given other paths.
+        */
+       protected boolean equalsOneOf(IPath path, IPath[] otherPaths) {
+               for (int i = 0, length = otherPaths.length; i < length; i++) {
+                       if (path.equals(otherPaths[i])) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       /**
+        * Verifies the operation can proceed and executes the operation.
+        * Subclasses should override <code>#verify</code> and
+        * <code>executeOperation</code> to implement the specific operation behavior.
+        *
+        * @exception JavaModelException The operation has failed.
+        */
+       protected void execute() throws JavaModelException {
+               IJavaModelStatus status= verify();
+               if (status.isOK()) {
+                       // if first time here, computes the root infos before executing the operation
+                       DeltaProcessor deltaProcessor = JavaModelManager.getJavaModelManager().deltaProcessor;
+                       if (deltaProcessor.roots == null) {
+//                     TODO khartlage temp-del
+//                             deltaProcessor.initializeRoots();
+                       }
+
+                       executeOperation();
+               } else {
+                       throw new JavaModelException(status);
+               }
+       }
+       /**
+        * Convenience method to run an operation within this operation
+        */
+       public void executeNestedOperation(JavaModelOperation operation, int subWorkAmount) throws JavaModelException {
+               IProgressMonitor subProgressMonitor = getSubProgressMonitor(subWorkAmount);
+               // fix for 1FW7IKC, part (1)
+               try {
+                       operation.setNested(true);
+                       operation.run(subProgressMonitor);
+               } catch (CoreException ce) {
+                       if (ce instanceof JavaModelException) {
+                               throw (JavaModelException)ce;
+                       } else {
+                               // translate the core exception to a java model exception
+                               if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
+                                       Throwable e = ce.getStatus().getException();
+                                       if (e instanceof JavaModelException) {
+                                               throw (JavaModelException) e;
+                                       }
+                               }
+                               throw new JavaModelException(ce);
+                       }
+               }
+       }
+       /**
+        * Performs the operation specific behavior. Subclasses must override.
+        */
+       protected abstract void executeOperation() throws JavaModelException;
+       /*
+        * Returns the attribute registered at the given key with the top level operation.
+        * Returns null if no such attribute is found.
+        */
+       protected Object getAttribute(Object key) {
+               ArrayList stack = this.getCurrentOperationStack();
+               if (stack.size() == 0) return null;
+               JavaModelOperation topLevelOp = (JavaModelOperation)stack.get(0);
+               if (topLevelOp.attributes == null) {
+                       return null;
+               } else {
+                       return topLevelOp.attributes.get(key);
+               }
+       }
+       /**
+        * Returns the compilation unit the given element is contained in,
+        * or the element itself (if it is a compilation unit),
+        * otherwise <code>null</code>.
+        */
+       protected ICompilationUnit getCompilationUnitFor(IJavaElement element) {
+       
+               return ((JavaElement)element).getCompilationUnit();
+       }
+       /*
+        * Returns the stack of operations running in the current thread.
+        * Returns an empty stack if no operations are currently running in this thread. 
+        */
+       protected ArrayList getCurrentOperationStack() {
+               ArrayList stack = (ArrayList)operationStacks.getCurrent();
+               if (stack == null) {
+                       stack = new ArrayList();
+                       operationStacks.setCurrent(stack);
+               }
+               return stack;
+       }
+       /**
+        * Returns the elements to which this operation applies,
+        * or <code>null</code> if not applicable.
+        */
+       protected IJavaElement[] getElementsToProcess() {
+               return fElementsToProcess;
+       }
+       /**
+        * Returns the element to which this operation applies,
+        * or <code>null</code> if not applicable.
+        */
+       protected IJavaElement getElementToProcess() {
+               if (fElementsToProcess == null || fElementsToProcess.length == 0) {
+                       return null;
+               }
+               return fElementsToProcess[0];
+       }
+       /**
+        * Returns the Java Model this operation is operating in.
+        */
+       public IJavaModel getJavaModel() {
+               if (fElementsToProcess == null || fElementsToProcess.length == 0) {
+                       return getParentElement().getJavaModel();
+               } else {
+                       return fElementsToProcess[0].getJavaModel();
+               }
+       }
+//     protected IPath[] getNestedFolders(IPackageFragmentRoot root) throws JavaModelException {
+//             IPath rootPath = root.getPath();
+//             IClasspathEntry[] classpath = root.getJavaProject().getRawClasspath();
+//             int length = classpath.length;
+//             IPath[] result = new IPath[length];
+//             int index = 0;
+//             for (int i = 0; i < length; i++) {
+//                     IPath path = classpath[i].getPath();
+//                     if (rootPath.isPrefixOf(path) && !rootPath.equals(path)) {
+//                             result[index++] = path;
+//                     }
+//             }
+//             if (index < length) {
+//                     System.arraycopy(result, 0, result = new IPath[index], 0, index);
+//             }
+//             return result;
+//     }
+       /**
+        * Returns the parent element to which this operation applies,
+        * or <code>null</code> if not applicable.
+        */
+       protected IJavaElement getParentElement() {
+               if (fParentElements == null || fParentElements.length == 0) {
+                       return null;
+               }
+               return fParentElements[0];
+       }
+       /**
+        * Returns the parent elements to which this operation applies,
+        * or <code>null</code> if not applicable.
+        */
+       protected IJavaElement[] getParentElements() {
+               return fParentElements;
+       }
+       /**
+        * Returns the elements created by this operation.
+        */
+       public IJavaElement[] getResultElements() {
+               return fResultElements;
+       }
+       /**
+        * Creates and returns a subprogress monitor if appropriate.
+        */
+       protected IProgressMonitor getSubProgressMonitor(int workAmount) {
+               IProgressMonitor sub = null;
+               if (fMonitor != null) {
+                       sub = new SubProgressMonitor(fMonitor, workAmount, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+               }
+               return sub;
+       }
+
+       /**
+        * Returns whether this operation has performed any resource modifications.
+        * Returns false if this operation has not been executed yet.
+        */
+       public boolean hasModifiedResource() {
+               return !this.isReadOnly() && this.getAttribute(HAS_MODIFIED_RESOURCE_ATTR) == TRUE; 
+       }
+       public void internalWorked(double work) {
+               if (fMonitor != null) {
+                       fMonitor.internalWorked(work);
+               }
+       }
+       /**
+        * @see IProgressMonitor
+        */
+       public boolean isCanceled() {
+               if (fMonitor != null) {
+                       return fMonitor.isCanceled();
+               }
+               return false;
+       }
+       /**
+        * Returns <code>true</code> if this operation performs no resource modifications,
+        * otherwise <code>false</code>. Subclasses must override.
+        */
+       public boolean isReadOnly() {
+               return false;
+       }
+       /*
+        * Returns whether this operation is the first operation to run in the current thread.
+        */
+       protected boolean isTopLevelOperation() {
+               ArrayList stack;
+               return 
+                       (stack = this.getCurrentOperationStack()).size() > 0
+                       && stack.get(0) == this;
+       }
+       /*
+        * Returns the index of the first registered action with the given id, starting from a given position.
+        * Returns -1 if not found.
+        */
+       protected int firstActionWithID(String id, int start) {
+               for (int i = start; i <= this.actionsEnd; i++) {
+                       if (this.actions[i].getID().equals(id)) {
+                               return i;
+                       }
+               }
+               return -1;
+       }
+       
+       /**
+        * Convenience method to move resources
+        */
+       protected void moveResources(IResource[] resources, IPath destinationPath) throws JavaModelException {
+               IProgressMonitor subProgressMonitor = null;
+               if (fMonitor != null) {
+                       subProgressMonitor = new SubProgressMonitor(fMonitor, resources.length, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+               }
+               IWorkspace workspace = resources[0].getWorkspace();
+               try {
+                       workspace.move(resources, destinationPath, false, subProgressMonitor);
+                       this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+               } catch (CoreException e) {
+                       throw new JavaModelException(e);
+               }
+       }
+       /**
+        * Creates and returns a new <code>IJavaElementDelta</code>
+        * on the Java Model.
+        */
+       public JavaElementDelta newJavaElementDelta() {
+               return new JavaElementDelta(getJavaModel());
+       }
+       /*
+        * Removes the last pushed operation from the stack of running operations.
+        * Returns the poped operation or null if the stack was empty.
+        */
+       protected JavaModelOperation popOperation() {
+               ArrayList stack = getCurrentOperationStack();
+               int size = stack.size();
+               if (size > 0) {
+                       if (size == 1) { // top level operation 
+                               operationStacks.setCurrent(null); // release reference (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=33927)
+                       }
+                       return (JavaModelOperation)stack.remove(size-1);
+               } else {
+                       return null;
+               }
+       }
+       /*
+        * Registers the given action to be run when the outer most java model operation has finished.
+        * The insertion mode controls whether:
+        * - the action should discard all existing actions with the same id, and be queued at the end (REMOVEALL_APPEND),
+        * - the action should be ignored if there is already an action with the same id (KEEP_EXISTING),
+        * - the action should be queued at the end without looking at existing actions (APPEND)
+        */
+       protected void postAction(IPostAction action, int insertionMode) {
+               if (POST_ACTION_VERBOSE) {
+                       System.out.print("(" + Thread.currentThread() + ") [JavaModelOperation.postAction(IPostAction, int)] Posting action " + action.getID()); //$NON-NLS-1$ //$NON-NLS-2$
+                       switch(insertionMode) {
+                               case REMOVEALL_APPEND:
+                                       System.out.println(" (REMOVEALL_APPEND)"); //$NON-NLS-1$
+                                       break;
+                               case KEEP_EXISTING:
+                                       System.out.println(" (KEEP_EXISTING)"); //$NON-NLS-1$
+                                       break;
+                               case APPEND:
+                                       System.out.println(" (APPEND)"); //$NON-NLS-1$
+                                       break;
+                       }
+               }
+               
+               JavaModelOperation topLevelOp = (JavaModelOperation)getCurrentOperationStack().get(0);
+               IPostAction[] postActions = topLevelOp.actions;
+               if (postActions == null) {
+                       topLevelOp.actions = postActions = new IPostAction[1];
+                       postActions[0] = action;
+                       topLevelOp.actionsEnd = 0;
+               } else {
+                       String id = action.getID();
+                       switch (insertionMode) {
+                               case REMOVEALL_APPEND :
+                                       int index = this.actionsStart-1;
+                                       while ((index = topLevelOp.firstActionWithID(id, index+1)) >= 0) {
+                                               // remove action[index]
+                                               System.arraycopy(postActions, index+1, postActions, index, topLevelOp.actionsEnd - index);
+                                               postActions[topLevelOp.actionsEnd--] = null;
+                                       }
+                                       topLevelOp.addAction(action);
+                                       break;
+                               case KEEP_EXISTING:
+                                       if (topLevelOp.firstActionWithID(id, 0) < 0) {
+                                               topLevelOp.addAction(action);
+                                       }
+                                       break;
+                               case APPEND:
+                                       topLevelOp.addAction(action);
+                                       break;
+                       }
+               }
+       }
+       /*
+        * Returns whether the given path is the prefix of one of the given other paths.
+        */
+       protected boolean prefixesOneOf(IPath path, IPath[] otherPaths) {
+               for (int i = 0, length = otherPaths.length; i < length; i++) {
+                       if (path.isPrefixOf(otherPaths[i])) {
+                               return true;
+                       }
+               }
+               return false;
+       }       
+       /*
+        * Pushes the given operation on the stack of operations currently running in this thread.
+        */
+       protected void pushOperation(JavaModelOperation operation) {
+               getCurrentOperationStack().add(operation);
+       }
+       
+       /**
+        * Main entry point for Java Model operations.  Executes this operation
+        * and registers any deltas created.
+        *
+        * @see IWorkspaceRunnable
+        * @exception CoreException if the operation fails
+        */
+       public void run(IProgressMonitor monitor) throws CoreException {
+               JavaModelManager manager = JavaModelManager.getJavaModelManager();
+               int previousDeltaCount = manager.javaModelDeltas.size();
+               try {
+                       fMonitor = monitor;
+                       pushOperation(this);
+                       try {
+                               this.execute();
+                       } finally {
+                               if (this.isTopLevelOperation()) {
+                                       this.runPostActions();
+                               }
+                       }
+               } finally {
+//             TODO khartlage temp-del
+//                     try {
+//                             // update JavaModel using deltas that were recorded during this operation
+//                             for (int i = previousDeltaCount, size = manager.javaModelDeltas.size(); i < size; i++) {
+//                                     manager.updateJavaModel((IJavaElementDelta)manager.javaModelDeltas.get(i));
+//                             }
+//                             
+//                             // fire only iff:
+//                             // - the operation is a top level operation
+//                             // - the operation did produce some delta(s)
+//                             // - but the operation has not modified any resource
+//                             if (this.isTopLevelOperation()) {
+//                                     if ((manager.javaModelDeltas.size() > previousDeltaCount || !manager.reconcileDeltas.isEmpty()) 
+//                                                     && !this.hasModifiedResource()) {
+//                                             manager.fire(null, JavaModelManager.DEFAULT_CHANGE_EVENT);
+//                                     } // else deltas are fired while processing the resource delta
+//                             }
+//                     } finally {
+//                             popOperation();
+//                     }
+               }
+       }
+       protected void runPostActions() throws JavaModelException {
+               while (this.actionsStart <= this.actionsEnd) {
+                       IPostAction postAction = this.actions[this.actionsStart++];
+                       if (POST_ACTION_VERBOSE) {
+                               System.out.println("(" + Thread.currentThread() + ") [JavaModelOperation.runPostActions()] Running action " + postAction.getID()); //$NON-NLS-1$ //$NON-NLS-2$
+                       }
+                       postAction.run();
+               }
+       }
+       /*
+        * Registers the given attribute at the given key with the top level operation.
+        */
+       protected void setAttribute(Object key, Object attribute) {
+               JavaModelOperation topLevelOp = (JavaModelOperation)this.getCurrentOperationStack().get(0);
+               if (topLevelOp.attributes == null) {
+                       topLevelOp.attributes = new HashMap();
+               }
+               topLevelOp.attributes.put(key, attribute);
+       }
+       /**
+        * @see IProgressMonitor
+        */
+       public void setCanceled(boolean b) {
+               if (fMonitor != null) {
+                       fMonitor.setCanceled(b);
+               }
+       }
+       /**
+        * Sets whether this operation is nested or not.
+        * @see CreateElementInCUOperation#checkCanceled
+        */
+       protected void setNested(boolean nested) {
+               fNested = nested;
+       }
+       /**
+        * @see IProgressMonitor
+        */
+       public void setTaskName(String name) {
+               if (fMonitor != null) {
+                       fMonitor.setTaskName(name);
+               }
+       }
+       /**
+        * @see IProgressMonitor
+        */
+       public void subTask(String name) {
+               if (fMonitor != null) {
+                       fMonitor.subTask(name);
+               }
+       }
+       /**
+        * Returns a status indicating if there is any known reason
+        * this operation will fail.  Operations are verified before they
+        * are run.
+        *
+        * Subclasses must override if they have any conditions to verify
+        * before this operation executes.
+        *
+        * @see IJavaModelStatus
+        */
+       protected IJavaModelStatus verify() {
+               return commonVerify();
+       }
+       
+       /**
+        * @see IProgressMonitor
+        */
+       public void worked(int work) {
+               if (fMonitor != null) {
+                       fMonitor.worked(work);
+                       checkCanceled();
+               }
+       }
+}
index e895a82..37a591d 100644 (file)
@@ -124,26 +124,26 @@ public class JavaModelStatus
    * Constructs an Java model status with the given corresponding
    * element.
    */
-  //   public JavaModelStatus(int code, IJavaElement element) {
-  //           this(code, new IJavaElement[]{element});
-  //   }
+       public JavaModelStatus(int code, IJavaElement element) {
+               this(code, new IJavaElement[]{element});
+       }
   /**
    * Constructs an Java model status with the given corresponding
    * element and string
    */
-  //   public JavaModelStatus(int code, IJavaElement element, String string) {
-  //           this(code, new IJavaElement[]{element});
-  //           fString = string;
-  //   }
-  //   
-  //   /**
-  //    * Constructs an Java model status with the given corresponding
-  //    * element and path
-  //    */
-  //   public JavaModelStatus(int code, IJavaElement element, IPath path) {
-  //           this(code, new IJavaElement[]{element});
-  //           fPath = path;
-  //   }       
+       public JavaModelStatus(int code, IJavaElement element, String string) {
+               this(code, new IJavaElement[]{element});
+               fString = string;
+       }
+       
+       /**
+        * Constructs an Java model status with the given corresponding
+        * element and path
+        */
+       public JavaModelStatus(int code, IJavaElement element, IPath path) {
+               this(code, new IJavaElement[]{element});
+               fPath = path;
+       }       
   /**
    * Constructs an Java model status with no corresponding elements.
    */
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/JavaProject.java
new file mode 100644 (file)
index 0000000..c8541ba
--- /dev/null
@@ -0,0 +1,2371 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+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 net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpeclipse.PHPCore;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.QualifiedName;
+
+/**
+ * Handle for a Java Project.
+ *
+ * <p>A Java Project internally maintains a devpath that corresponds
+ * to the project's classpath. The classpath may include source folders
+ * from the current project; jars in the current project, other projects,
+ * and the local file system; and binary folders (output location) of other
+ * projects. The Java Model presents source elements corresponding to output
+ * .class files in other projects, and thus uses the devpath rather than
+ * the classpath (which is really a compilation path). The devpath mimics
+ * the classpath, except has source folder entries in place of output
+ * locations in external projects.
+ *
+ * <p>Each JavaProject has a NameLookup facility that locates elements
+ * on by name, based on the devpath.
+ *
+ * @see IJavaProject
+ */
+public class JavaProject
+       extends Openable 
+       implements IJavaProject , IProjectNature {
+
+       /**
+        * Whether the underlying file system is case sensitive.
+        */
+       protected static final boolean IS_CASE_SENSITIVE = !new File("Temp").equals(new File("temp")); //$NON-NLS-1$ //$NON-NLS-2$
+
+       /**
+        * An empty array of strings indicating that a project doesn't have any prerequesite projects.
+        */
+       protected static final String[] NO_PREREQUISITES = new String[0];
+
+       /**
+        * The platform project this <code>IJavaProject</code> is based on
+        */
+       protected IProject fProject;
+       
+       /**
+        * Name of file containing project classpath
+        */
+       public static final String CLASSPATH_FILENAME = ".classpath";  //$NON-NLS-1$
+
+       /**
+        * Name of file containing custom project preferences
+        */
+       public static final String PREF_FILENAME = ".jprefs";  //$NON-NLS-1$
+       
+       /**
+        * Value of the project's raw classpath if the .classpath file contains invalid entries.
+        */
+//     public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0];
+
+       private static final String CUSTOM_DEFAULT_OPTION_VALUE = "#\r\n\r#custom-non-empty-default-value#\r\n\r#"; //$NON-NLS-1$
+       
+       /**
+        * Returns a canonicalized path from the given external path.
+        * Note that the return path contains the same number of segments
+        * and it contains a device only if the given path contained one.
+        * @see java.io.File for the definition of a canonicalized path
+        */
+       public static IPath canonicalizedPath(IPath externalPath) {
+               
+               if (externalPath == null)
+                       return null;
+
+//             if (JavaModelManager.VERBOSE) {
+//                     System.out.println("JAVA MODEL - Canonicalizing " + externalPath.toString()); //$NON-NLS-1$
+//             }
+
+               if (IS_CASE_SENSITIVE) {
+//                     if (JavaModelManager.VERBOSE) {
+//                             System.out.println("JAVA MODEL - Canonical path is original path (file system is case sensitive)"); //$NON-NLS-1$
+//                     }
+                       return externalPath;
+               }
+
+               // if not external path, return original path
+               IWorkspace workspace = ResourcesPlugin.getWorkspace();
+               if (workspace == null) return externalPath; // protection during shutdown (30487)
+               if (workspace.getRoot().findMember(externalPath) != null) {
+//                     if (JavaModelManager.VERBOSE) {
+//                             System.out.println("JAVA MODEL - Canonical path is original path (member of workspace)"); //$NON-NLS-1$
+//                     }
+                       return externalPath;
+               }
+
+               IPath canonicalPath = null;
+               try {
+                       canonicalPath =
+                               new Path(new File(externalPath.toOSString()).getCanonicalPath());
+               } catch (IOException e) {
+                       // default to original path
+//                     if (JavaModelManager.VERBOSE) {
+//                             System.out.println("JAVA MODEL - Canonical path is original path (IOException)"); //$NON-NLS-1$
+//                     }
+                       return externalPath;
+               }
+               
+               IPath result;
+               int canonicalLength = canonicalPath.segmentCount();
+               if (canonicalLength == 0) {
+                       // the java.io.File canonicalization failed
+//                     if (JavaModelManager.VERBOSE) {
+//                             System.out.println("JAVA MODEL - Canonical path is original path (canonical path is empty)"); //$NON-NLS-1$
+//                     }
+                       return externalPath;
+               } else if (externalPath.isAbsolute()) {
+                       result = canonicalPath;
+               } else {
+                       // if path is relative, remove the first segments that were added by the java.io.File canonicalization
+                       // e.g. 'lib/classes.zip' was converted to 'd:/myfolder/lib/classes.zip'
+                       int externalLength = externalPath.segmentCount();
+                       if (canonicalLength >= externalLength) {
+                               result = canonicalPath.removeFirstSegments(canonicalLength - externalLength);
+                       } else {
+//                             if (JavaModelManager.VERBOSE) {
+//                                     System.out.println("JAVA MODEL - Canonical path is original path (canonical path is " + canonicalPath.toString() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+//                             }
+                               return externalPath;
+                       }
+               }
+               
+               // keep device only if it was specified (this is because File.getCanonicalPath() converts '/lib/classed.zip' to 'd:/lib/classes/zip')
+               if (externalPath.getDevice() == null) {
+                       result = result.setDevice(null);
+               } 
+//             if (JavaModelManager.VERBOSE) {
+//                     System.out.println("JAVA MODEL - Canonical path is " + result.toString()); //$NON-NLS-1$
+//             }
+               return result;
+       }
+
+       /**
+        * Constructor needed for <code>IProject.getNature()</code> and <code>IProject.addNature()</code>.
+        *
+        * @see #setProject
+        */
+       public JavaProject() {
+               super(JAVA_PROJECT, null, null);
+       }
+
+       public JavaProject(IProject project, IJavaElement parent) {
+               super(JAVA_PROJECT, parent, project.getName());
+               fProject = project;
+       }
+
+       /**
+        * Adds a builder to the build spec for the given project.
+        */
+       protected void addToBuildSpec(String builderID) throws CoreException {
+
+               IProjectDescription description = getProject().getDescription();
+               ICommand javaCommand = getJavaCommand(description);
+
+               if (javaCommand == null) {
+
+                       // Add a Java command to the build spec
+                       ICommand command = description.newCommand();
+                       command.setBuilderName(builderID);
+                       setJavaCommand(description, command);
+               }
+       }
+
+//     protected void closing(Object info) throws JavaModelException {
+//             
+//             // forget source attachment recommendations
+//             IPackageFragmentRoot[] roots = this.getPackageFragmentRoots();
+//             for (int i = 0; i < roots.length; i++) {
+//                     if (roots[i] instanceof JarPackageFragmentRoot){
+//                             ((JarPackageFragmentRoot) roots[i]).setSourceAttachmentProperty(null); 
+//                     }
+//             }
+//             
+//             super.closing(info);
+//     }
+       
+
+
+       /**
+        * Internal computation of an expanded classpath. It will eliminate duplicates, and produce copies
+        * of exported classpath entries to avoid possible side-effects ever after.
+        */                     
+//     private void computeExpandedClasspath(
+//             JavaProject initialProject, 
+//             boolean ignoreUnresolvedVariable,
+//             boolean generateMarkerOnError,
+//             HashSet visitedProjects, 
+//             ObjectVector accumulatedEntries) throws JavaModelException {
+//             
+//             if (visitedProjects.contains(this)){
+//                     return; // break cycles if any
+//             }
+//             visitedProjects.add(this);
+//
+//             if (generateMarkerOnError && !this.equals(initialProject)){
+//                     generateMarkerOnError = false;
+//             }
+//             IClasspathEntry[] immediateClasspath = 
+//                     getResolvedClasspath(ignoreUnresolvedVariable, generateMarkerOnError);
+//                     
+//             IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+//             for (int i = 0, length = immediateClasspath.length; i < length; i++){
+//                     IClasspathEntry entry = immediateClasspath[i];
+//
+//                     boolean isInitialProject = this.equals(initialProject);
+//                     if (isInitialProject || entry.isExported()){
+//                             
+//                             accumulatedEntries.add(entry);
+//                             
+//                             // recurse in project to get all its indirect exports (only consider exported entries from there on)                            
+//                             if (entry.getEntryKind() == ClasspathEntry.CPE_PROJECT) {
+//                                     IResource member = workspaceRoot.findMember(entry.getPath()); 
+//                                     if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977)
+//                                             IProject projRsc = (IProject) member;
+//                                             if (JavaProject.hasJavaNature(projRsc)) {                               
+//                                                     JavaProject project = (JavaProject) JavaCore.create(projRsc);
+//                                                     project.computeExpandedClasspath(
+//                                                             initialProject, 
+//                                                             ignoreUnresolvedVariable, 
+//                                                             generateMarkerOnError,
+//                                                             visitedProjects, 
+//                                                             accumulatedEntries);
+//                                             }
+//                                     }
+//                             }
+//                     }                       
+//             }
+//     }
+       
+       /**
+        * Returns (local/all) the package fragment roots identified by the given project's classpath.
+        * Note: this follows project classpath references to find required project contributions,
+        * eliminating duplicates silently.
+        * Only works with resolved entries
+        */
+//     public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry[] resolvedClasspath, boolean retrieveExportedRoots) throws JavaModelException {
+//
+//             ObjectVector accumulatedRoots = new ObjectVector();
+//             computePackageFragmentRoots(
+//                     resolvedClasspath, 
+//                     accumulatedRoots, 
+//                     new HashSet(5), // rootIDs
+//                     true, // inside original project
+//                     true, // check existency
+//                     retrieveExportedRoots);
+//             IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()];
+//             accumulatedRoots.copyInto(rootArray);
+//             return rootArray;
+//     }
+//
+//     /**
+//      * Computes the package fragment roots identified by the given entry.
+//      * Only works with resolved entry
+//      */
+//     public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) {
+//             try {
+//                     return 
+//                             computePackageFragmentRoots(
+//                                     new IClasspathEntry[]{ resolvedEntry }, 
+//                                     false // don't retrieve exported roots
+//                             );
+//             } catch (JavaModelException e) {
+//                     return new IPackageFragmentRoot[] {};
+//             }
+//     }
+       
+       /**
+        * Returns the package fragment roots identified by the given entry. In case it refers to
+        * a project, it will follow its classpath so as to find exported roots as well.
+        * Only works with resolved entry
+        */
+//     public void computePackageFragmentRoots(
+//             IClasspathEntry resolvedEntry,
+//             ObjectVector accumulatedRoots, 
+//             HashSet rootIDs, 
+//             boolean insideOriginalProject,
+//             boolean checkExistency,
+//             boolean retrieveExportedRoots) throws JavaModelException {
+//                     
+//             String rootID = ((ClasspathEntry)resolvedEntry).rootID();
+//             if (rootIDs.contains(rootID)) return;
+//
+//             IPath projectPath = getProject().getFullPath();
+//             IPath entryPath = resolvedEntry.getPath();
+//             IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+//             
+//             switch(resolvedEntry.getEntryKind()){
+//                     
+//                     // source folder
+//                     case IClasspathEntry.CPE_SOURCE :
+//
+//                             if (projectPath.isPrefixOf(entryPath)){
+//                                     if (checkExistency) {
+//                                             Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency);
+//                                             if (target == null) return;
+//     
+//                                             if (target instanceof IFolder || target instanceof IProject){
+//                                                     accumulatedRoots.add(
+//                                                             getPackageFragmentRoot((IResource)target));
+//                                                     rootIDs.add(rootID);
+//                                             }
+//                                     } else {
+//                                             IPackageFragmentRoot root = getFolderPackageFragmentRoot(entryPath);
+//                                             if (root != null) {
+//                                                     accumulatedRoots.add(root);
+//                                                     rootIDs.add(rootID);
+//                                             }
+//                                     }
+//                             }
+//                             break;
+//
+//                     // internal/external JAR or folder
+//                     case IClasspathEntry.CPE_LIBRARY :
+//                     
+//                             if (!insideOriginalProject && !resolvedEntry.isExported()) return;
+//                             
+//                             if (checkExistency) {
+//                                     Object target = JavaModel.getTarget(workspaceRoot, entryPath, checkExistency);
+//                                     if (target == null) return;
+//     
+//                                     if (target instanceof IResource){
+//                                             // internal target
+//                                             IResource resource = (IResource) target;
+//                                             IPackageFragmentRoot root = getPackageFragmentRoot(resource);
+//                                             if (root != null) {
+//                                                     accumulatedRoots.add(root);
+//                                                     rootIDs.add(rootID);
+//                                             }
+//                                     } else {
+//                                             // external target - only JARs allowed
+//                                             if (((java.io.File)target).isFile() && (Util.isArchiveFileName(entryPath.lastSegment()))) {
+//                                                     accumulatedRoots.add(
+//                                                             new JarPackageFragmentRoot(entryPath, this));
+//                                                     rootIDs.add(rootID);
+//                                             }
+//                                     }
+//                             } else {
+//                                     IPackageFragmentRoot root = getPackageFragmentRoot(entryPath);
+//                                     if (root != null) {
+//                                             accumulatedRoots.add(root);
+//                                             rootIDs.add(rootID);
+//                                     }
+//                             }
+//                             break;
+//
+//                     // recurse into required project
+//                     case IClasspathEntry.CPE_PROJECT :
+//
+//                             if (!retrieveExportedRoots) return;
+//                             if (!insideOriginalProject && !resolvedEntry.isExported()) return;
+//
+//                             IResource member = workspaceRoot.findMember(entryPath);
+//                             if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977)
+//                                     IProject requiredProjectRsc = (IProject) member;
+//                                     if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output
+//                                             rootIDs.add(rootID);
+//                                             JavaProject requiredProject = (JavaProject)JavaCore.create(requiredProjectRsc);
+//                                             requiredProject.computePackageFragmentRoots(
+//                                                     requiredProject.getResolvedClasspath(true), 
+//                                                     accumulatedRoots, 
+//                                                     rootIDs, 
+//                                                     false, 
+//                                                     checkExistency, 
+//                                                     retrieveExportedRoots);
+//                                     }
+//                             break;
+//                     }
+//             }
+//     }
+
+       /**
+        * Returns (local/all) the package fragment roots identified by the given project's classpath.
+        * Note: this follows project classpath references to find required project contributions,
+        * eliminating duplicates silently.
+        * Only works with resolved entries
+        */
+//     public void computePackageFragmentRoots(
+//             IClasspathEntry[] resolvedClasspath,
+//             ObjectVector accumulatedRoots, 
+//             HashSet rootIDs, 
+//             boolean insideOriginalProject,
+//             boolean checkExistency,
+//             boolean retrieveExportedRoots) throws JavaModelException {
+//
+//             if (insideOriginalProject){
+//                     rootIDs.add(rootID());
+//             }       
+//             for (int i = 0, length = resolvedClasspath.length; i < length; i++){
+//                     computePackageFragmentRoots(
+//                             resolvedClasspath[i],
+//                             accumulatedRoots,
+//                             rootIDs,
+//                             insideOriginalProject,
+//                             checkExistency,
+//                             retrieveExportedRoots);
+//             }
+//     }
+
+       /**
+        * Compute the file name to use for a given shared property
+        */
+       public String computeSharedPropertyFileName(QualifiedName qName) {
+
+               return '.' + qName.getLocalName();
+       }
+       
+       /**
+        * Configure the project with Java nature.
+        */
+       public void configure() throws CoreException {
+
+               // register Java builder
+               addToBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID);
+       }
+       /*
+        * Returns whether the given resource is accessible through the children or the non-Java resources of this project.
+        * Returns true if the resource is not in the project.
+        * Assumes that the resource is a folder or a file.
+        */
+//     public boolean contains(IResource resource) {
+//                     
+//             IClasspathEntry[] classpath;
+//             IPath output;
+//             try {
+//                     classpath = getResolvedClasspath(true);
+//                     output = getOutputLocation();
+//             } catch (JavaModelException e) {
+//                     return false;
+//             }
+//             
+//             IPath fullPath = resource.getFullPath();
+//             IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null;
+//             IClasspathEntry innerMostEntry = null;
+//             for (int j = 0, cpLength = classpath.length; j < cpLength; j++) {
+//                     IClasspathEntry entry = classpath[j];
+//             
+//                     IPath entryPath = entry.getPath();
+//                     if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath))
+//                                     && entryPath.isPrefixOf(fullPath)) {
+//                             innerMostEntry = entry;
+//                     }
+//                     IPath entryOutput = classpath[j].getOutputLocation();
+//                     if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) {
+//                             innerMostOutput = entryOutput;
+//                     }
+//             }
+//             if (innerMostEntry != null) {
+//                     // special case prj==src and nested output location
+//                     if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project
+//                                     && innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name
+//                             return false;
+//                     }
+//                     if  (resource instanceof IFolder) {
+//                              // folders are always included in src/lib entries
+//                              return true;
+//                     }
+//                     switch (innerMostEntry.getEntryKind()) {
+//                             case IClasspathEntry.CPE_SOURCE:
+//                                     // .class files are not visible in source folders 
+//                                     return !Util.isClassFileName(fullPath.lastSegment());
+//                             case IClasspathEntry.CPE_LIBRARY:
+//                                     // .java files are not visible in library folders
+//                                     return !Util.isJavaFileName(fullPath.lastSegment());
+//                     }
+//             }
+//             if (innerMostOutput != null) {
+//                     return false;
+//             }
+//             return true;
+//     }
+
+       /**
+        * Record a new marker denoting a classpath problem
+        */
+//     IMarker createClasspathProblemMarker(IJavaModelStatus status) {
+//                     
+//             IMarker marker = null;
+//             int severity;
+//             String[] arguments = new String[0];
+//             boolean isCycleProblem = false, isClasspathFileFormatProblem = false;
+//             switch (status.getCode()) {
+//
+//                     case  IJavaModelStatusConstants.CLASSPATH_CYCLE :
+//                             isCycleProblem = true;
+//                             if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) {
+//                                     severity = IMarker.SEVERITY_ERROR;
+//                             } else {
+//                                     severity = IMarker.SEVERITY_WARNING;
+//                             }
+//                             break;
+//
+//                     case  IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT :
+//                             isClasspathFileFormatProblem = true;
+//                             severity = IMarker.SEVERITY_ERROR;
+//                             break;
+//
+//                     default:
+//                             IPath path = status.getPath();
+//                             if (path != null) arguments = new String[] { path.toString() };
+//                             if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true))) {
+//                                     severity = IMarker.SEVERITY_ERROR;
+//                             } else {
+//                                     severity = IMarker.SEVERITY_WARNING;
+//                             }
+//                             break;
+//             }
+//             
+//             try {
+//                     marker = getProject().createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER);
+//                     marker.setAttributes(
+//                             new String[] { 
+//                                     IMarker.MESSAGE, 
+//                                     IMarker.SEVERITY, 
+//                                     IMarker.LOCATION, 
+//                                     IJavaModelMarker.CYCLE_DETECTED,
+//                                     IJavaModelMarker.CLASSPATH_FILE_FORMAT,
+//                                     IJavaModelMarker.ID,
+//                                     IJavaModelMarker.ARGUMENTS ,
+//                             },
+//                             new Object[] {
+//                                     status.getMessage(),
+//                                     new Integer(severity), 
+//                                     Util.bind("classpath.buildPath"),//$NON-NLS-1$
+//                                     isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
+//                                     isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
+//                                     new Integer(status.getCode()),
+//                                     Util.getProblemArgumentsForMarker(arguments) ,
+//                             }
+//                     );
+//             } catch (CoreException e) {
+//             }
+//             return marker;
+//     }
+       
+       /**
+        * Returns a new element info for this element.
+        */
+//     protected OpenableElementInfo createElementInfo() {
+//
+//             return new JavaProjectElementInfo();
+//     }
+
+       /**
+        * Reads and decode an XML classpath string
+        */
+//     protected IClasspathEntry[] decodeClasspath(String xmlClasspath, boolean createMarker, boolean logProblems) {
+//
+//             ArrayList paths = new ArrayList();
+//             IClasspathEntry defaultOutput = null;
+//             try {
+//                     if (xmlClasspath == null) return null;
+//                     StringReader reader = new StringReader(xmlClasspath);
+//                     Element cpElement;
+//     
+//                     try {
+//                             DocumentBuilder parser =
+//                                     DocumentBuilderFactory.newInstance().newDocumentBuilder();
+//                             cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
+//                     } catch (SAXException e) {
+//                             throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+//                     } catch (ParserConfigurationException e) {
+//                             throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+//                     } finally {
+//                             reader.close();
+//                     }
+//     
+//                     if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$
+//                             throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+//                     }
+//                     NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$
+//                     int length = list.getLength();
+//     
+//                     for (int i = 0; i < length; ++i) {
+//                             Node node = list.item(i);
+//                             if (node.getNodeType() == Node.ELEMENT_NODE) {
+//                                     IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this);
+//                                     if (entry != null){
+//                                             if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { 
+//                                                     defaultOutput = entry; // separate output
+//                                             } else {
+//                                                     paths.add(entry);
+//                             }
+//                     }
+//                             }
+//                     }
+//             } catch (IOException e) {
+//                     // bad format
+//                     if (createMarker && this.getProject().isAccessible()) {
+//                                     this.createClasspathProblemMarker(new JavaModelStatus(
+//                                                     IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+//                                                     Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$
+//                     }
+//                     if (logProblems) {
+//                             Util.log(e, 
+//                                     "Exception while retrieving "+ this.getPath() //$NON-NLS-1$
+//                                     +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$
+//                     }
+//                     return INVALID_CLASSPATH;
+//             } catch (Assert.AssertionFailedException e) { 
+//                     // failed creating CP entries from file
+//                     if (createMarker && this.getProject().isAccessible()) {
+//                             this.createClasspathProblemMarker(new JavaModelStatus(
+//                                             IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+//                                             Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$
+//                     }
+//                     if (logProblems) {
+//                             Util.log(e, 
+//                                     "Exception while retrieving "+ this.getPath() //$NON-NLS-1$
+//                                     +"/.classpath, will mark classpath as invalid"); //$NON-NLS-1$
+//                     }
+//                     return INVALID_CLASSPATH;
+//             }
+//             int pathSize = paths.size();
+//             if (pathSize > 0 || defaultOutput != null) {
+//                     IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)];
+//                     paths.toArray(entries);
+//                     if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item
+//                     return entries;
+//             } else {
+//                     return null;
+//             }
+//     }
+
+       /**
+       /**
+        * Removes the Java nature from the project.
+        */
+       public void deconfigure() throws CoreException {
+
+               // deregister Java builder
+               removeFromBuildSpec(PHPeclipsePlugin.BUILDER_PARSER_ID);
+       }
+//
+//     /**
+//      * Returns a default class path.
+//      * This is the root of the project
+//      */
+//     protected IClasspathEntry[] defaultClasspath() throws JavaModelException {
+//
+//             return new IClasspathEntry[] {
+//                      JavaCore.newSourceEntry(getProject().getFullPath())};
+//     }
+
+       /**
+        * Returns a default output location.
+        * This is the project bin folder
+        */
+       protected IPath defaultOutputLocation() throws JavaModelException {
+               return getProject().getFullPath().append("bin"); //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the XML String encoding of the class path.
+        */
+//     protected String encodeClasspath(IClasspathEntry[] classpath, IPath outputLocation, boolean useLineSeparator) throws JavaModelException {
+//
+//             Document document = new DocumentImpl();
+//             Element cpElement = document.createElement("classpath"); //$NON-NLS-1$
+//             document.appendChild(cpElement);
+//
+//             for (int i = 0; i < classpath.length; ++i) {
+//                     cpElement.appendChild(((ClasspathEntry)classpath[i]).elementEncode(document, getProject().getFullPath()));
+//             }
+//
+//             if (outputLocation != null) {
+//                     outputLocation = outputLocation.removeFirstSegments(1);
+//                     outputLocation = outputLocation.makeRelative();
+//                     Element oElement = document.createElement("classpathentry"); //$NON-NLS-1$
+//                     oElement.setAttribute("kind", ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT));    //$NON-NLS-1$
+//                     oElement.setAttribute("path", outputLocation.toString()); //$NON-NLS-1$
+//                     cpElement.appendChild(oElement);
+//             }
+//
+//             // produce a String output
+//             try {
+//                     ByteArrayOutputStream s = new ByteArrayOutputStream();
+//                     OutputFormat format = new OutputFormat();
+//                     if (useLineSeparator) {
+//                             format.setIndenting(true);
+//                             format.setLineSeparator(System.getProperty("line.separator"));  //$NON-NLS-1$
+//                     } else {
+//                             format.setPreserveSpace(true);
+//                     }                       
+//                     Serializer serializer =
+//                             SerializerFactory.getSerializerFactory(Method.XML).makeSerializer(
+//                                     new OutputStreamWriter(s, "UTF8"), //$NON-NLS-1$
+//                                     format);
+//                     serializer.asDOMSerializer().serialize(document);
+//                     return s.toString("UTF8"); //$NON-NLS-1$
+//             } catch (IOException e) {
+//                     throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+//             }
+//     }
+//     
+       /**
+        * Returns true if this handle represents the same Java project
+        * as the given handle. Two handles represent the same
+        * project if they are identical or if they represent a project with 
+        * the same underlying resource and occurrence counts.
+        *
+        * @see JavaElement#equals
+        */
+       public boolean equals(Object o) {
+
+               if (this == o)
+                       return true;
+
+               if (!(o instanceof JavaProject))
+                       return false;
+
+               JavaProject other = (JavaProject) o;
+               return getProject().equals(other.getProject())
+                       && fOccurrenceCount == other.fOccurrenceCount;
+       }
+
+       public boolean exists() {
+               if (!hasJavaNature(fProject)) return false;
+               return super.exists();
+       }       
+
+       /**
+        * @see IJavaProject
+        */
+//     public IJavaElement findElement(IPath path) throws JavaModelException {
+//
+//             if (path == null || path.isAbsolute()) {
+//                     throw new JavaModelException(
+//                             new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path));
+//             }
+//             try {
+//
+//                     String extension = path.getFileExtension();
+//                     if (extension == null) {
+//                             String packageName = path.toString().replace(IPath.SEPARATOR, '.');
+//
+//                             IPackageFragment[] pkgFragments =
+//                                     getNameLookup().findPackageFragments(packageName, false);
+//                             if (pkgFragments == null) {
+//                                     return null;
+//
+//                             } else {
+//                                     // try to return one that is a child of this project
+//                                     for (int i = 0, length = pkgFragments.length; i < length; i++) {
+//
+//                                             IPackageFragment pkgFragment = pkgFragments[i];
+//                                             if (this.equals(pkgFragment.getParent().getParent())) {
+//                                                     return pkgFragment;
+//                                             }
+//                                     }
+//                                     // default to the first one
+//                                     return pkgFragments[0];
+//                             }
+//                     } else if (
+//                             extension.equalsIgnoreCase("java") //$NON-NLS-1$
+//                                     || extension.equalsIgnoreCase("class")) {  //$NON-NLS-1$
+//                             IPath packagePath = path.removeLastSegments(1);
+//                             String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.');
+//                             String typeName = path.lastSegment();
+//                             typeName = typeName.substring(0, typeName.length() - extension.length() - 1);
+//                             String qualifiedName = null;
+//                             if (packageName.length() > 0) {
+//                                     qualifiedName = packageName + "." + typeName; //$NON-NLS-1$
+//                             } else {
+//                                     qualifiedName = typeName;
+//                             }
+//                             IType type =
+//                                     getNameLookup().findType(
+//                                             qualifiedName,
+//                                             false,
+//                                             NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
+//                             if (type != null) {
+//                                     return type.getParent();
+//                             } else {
+//                                     return null;
+//                             }
+//                     } else {
+//                             // unsupported extension
+//                             return null;
+//                     }
+//             } catch (JavaModelException e) {
+//                     if (e.getStatus().getCode()
+//                             == IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST) {
+//                             return null;
+//                     } else {
+//                             throw e;
+//                     }
+//             }
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public IPackageFragment findPackageFragment(IPath path)
+//             throws JavaModelException {
+//
+//             return findPackageFragment0(JavaProject.canonicalizedPath(path));
+//     }
+
+       /**
+        * non path canonicalizing version
+        */
+//     public IPackageFragment findPackageFragment0(IPath path) 
+//             throws JavaModelException {
+//
+//             return getNameLookup().findPackageFragment(path);
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public IPackageFragmentRoot findPackageFragmentRoot(IPath path)
+//             throws JavaModelException {
+//
+//             return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path));
+//     }
+
+       /**
+        * no path canonicalization 
+        */
+//     public IPackageFragmentRoot findPackageFragmentRoot0(IPath path)
+//             throws JavaModelException {
+//
+//             IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots();
+//             if (!path.isAbsolute()) {
+//                     throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$
+//             }
+//             for (int i= 0; i < allRoots.length; i++) {
+//                     IPackageFragmentRoot classpathRoot= allRoots[i];
+//                     if (classpathRoot.getPath().equals(path)) {
+//                             return classpathRoot;
+//                     }
+//             }
+//             return null;
+//     }
+       /**
+        * @see IJavaProject
+        */
+//     public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) {
+//             try {
+//                     IClasspathEntry[] classpath = this.getRawClasspath();
+//                     for (int i = 0, length = classpath.length; i < length; i++) {
+//                             if (classpath[i].equals(entry)) { // entry may need to be resolved
+//                                     return 
+//                                             computePackageFragmentRoots(
+//                                                     getResolvedClasspath(new IClasspathEntry[] {entry}, null, true, false, null/*no reverse map*/), 
+//                                                     false); // don't retrieve exported roots
+//                             }
+//                     }
+//             } catch (JavaModelException e) {
+//             }
+//             return new IPackageFragmentRoot[] {};
+//     }
+//     
+       /**
+        * @see IJavaProject#findType(String)
+        */
+//     public IType findType(String fullyQualifiedName) throws JavaModelException {
+//             IType type = 
+//                     this.getNameLookup().findType(
+//                             fullyQualifiedName, 
+//                             false,
+//                             NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
+//             if (type == null) {
+//                     // try to find enclosing type
+//                     int lastDot = fullyQualifiedName.lastIndexOf('.');
+//                     if (lastDot == -1) return null;
+//                     type = this.findType(fullyQualifiedName.substring(0, lastDot));
+//                     if (type != null) {
+//                             type = type.getType(fullyQualifiedName.substring(lastDot+1));
+//                             if (!type.exists()) {
+//                                     return null;
+//                             }
+//                     }
+//             }
+//             return type;
+//     }
+       
+       /**
+        * @see IJavaProject#findType(String, String)
+        */
+//     public IType findType(String packageName, String typeQualifiedName) throws JavaModelException {
+//             return 
+//                     this.getNameLookup().findType(
+//                             typeQualifiedName, 
+//                             packageName,
+//                             false,
+//                             NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
+//     }       
+//     
+//     /**
+//      * Remove all markers denoting classpath problems
+//      */
+//     protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers) {
+//             try {
+//                     IProject project = getProject();
+//                     if (project.exists()) {
+//                             IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+//                             for (int i = 0, length = markers.length; i < length; i++) {
+//                                     IMarker marker = markers[i];
+//                                     if (flushCycleMarkers && flushClasspathFormatMarkers) {
+//                                             marker.delete();
+//                                     } else {
+//                                             String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
+//                                             String classpathFileFormatAttr =  (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT);
+//                                             if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$
+//                                                     && (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$
+//                                                     marker.delete();
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             } catch (CoreException e) {
+//             }
+//     }
+//
+//     /**
+//      * @see Openable
+//      */
+//     protected boolean generateInfos(
+//             OpenableElementInfo info,
+//             IProgressMonitor pm,
+//             Map newElements,
+//             IResource underlyingResource) throws JavaModelException {
+//
+//             boolean validInfo = false;
+//             try {
+//                     if (getProject().isOpen()) {
+//                             // put the info now, because computing the roots requires it
+//                             JavaModelManager.getJavaModelManager().putInfo(this, info);
+//
+//                             // compute the pkg fragment roots
+//                             updatePackageFragmentRoots();                           
+//     
+//                             // remember the timestamps of external libraries the first time they are looked up
+//                             IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignore unresolved variable*/);
+//                             for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
+//                                     IClasspathEntry entry = resolvedClasspath[i];
+//                                     if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+//                                             IPath path = entry.getPath();
+//                                             Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true);
+//                                             if (target instanceof java.io.File) {
+//                                                     Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaProcessor.externalTimeStamps;
+//                                                     if (externalTimeStamps.get(path) == null) {
+//                                                             long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target);
+//                                                             externalTimeStamps.put(path, new Long(timestamp));                                                      
+//                                                     }
+//                                             }
+//                                     }
+//                             }                       
+//
+//                             // only valid if reaches here                           
+//                             validInfo = true;
+//                     }
+//             } finally {
+//                     if (!validInfo)
+//                             JavaModelManager.getJavaModelManager().removeInfo(this);
+//             }
+//             return validInfo;
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public IPackageFragmentRoot[] getAllPackageFragmentRoots()
+//             throws JavaModelException {
+//
+//             return computePackageFragmentRoots(getResolvedClasspath(true), true);
+//     }
+//
+//     /**
+//      * Returns the classpath entry that refers to the given path
+//      * or <code>null</code> if there is no reference to the path.
+//      */
+//     public IClasspathEntry getClasspathEntryFor(IPath path)
+//             throws JavaModelException {
+//
+//             IClasspathEntry[] entries = getExpandedClasspath(true);
+//             for (int i = 0; i < entries.length; i++) {
+//                     if (entries[i].getPath().equals(path)) {
+//                             return entries[i];
+//                     }
+//             }
+//             return null;
+//     }
+
+       /*
+        * Returns the cycle marker associated with this project or null if none.
+        */
+//     public IMarker getCycleMarker(){
+//             try {
+//                     IProject project = getProject();
+//                     if (project.exists()) {
+//                             IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+//                             for (int i = 0, length = markers.length; i < length; i++) {
+//                                     IMarker marker = markers[i];
+//                                     String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
+//                                     if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$
+//                                             return marker;
+//                                     }
+//                             }
+//                     }
+//             } catch (CoreException e) {
+//             }
+//             return null;
+//     }
+//
+//     /**
+//      * This is a helper method returning the expanded classpath for the project, as a list of classpath entries, 
+//      * where all classpath variable entries have been resolved and substituted with their final target entries.
+//      * All project exports have been appended to project entries.
+//      */
+//     public IClasspathEntry[] getExpandedClasspath(boolean ignoreUnresolvedVariable) throws JavaModelException {
+//                     
+//                     return getExpandedClasspath(ignoreUnresolvedVariable, false);
+//     }
+               
+       /**
+        * Internal variant which can create marker on project for invalid entries,
+        * it will also perform classpath expansion in presence of project prerequisites
+        * exporting their entries.
+        */
+//     public IClasspathEntry[] getExpandedClasspath(
+//             boolean ignoreUnresolvedVariable,
+//             boolean generateMarkerOnError) throws JavaModelException {
+//     
+//             ObjectVector accumulatedEntries = new ObjectVector();           
+//             computeExpandedClasspath(this, ignoreUnresolvedVariable, generateMarkerOnError, new HashSet(5), accumulatedEntries);
+//             
+//             IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()];
+//             accumulatedEntries.copyInto(expandedPath);
+//
+//             return expandedPath;
+//     }
+
+       /**
+        * Returns the <code>char</code> that marks the start of this handles
+        * contribution to a memento.
+        */
+       protected char getHandleMementoDelimiter() {
+
+               return JEM_JAVAPROJECT;
+       }
+
+       /**
+        * Find the specific Java command amongst the build spec of a given description
+        */
+       private ICommand getJavaCommand(IProjectDescription description)
+               throws CoreException {
+
+               ICommand[] commands = description.getBuildSpec();
+               for (int i = 0; i < commands.length; ++i) {
+                       if (commands[i].getBuilderName().equals(PHPeclipsePlugin.BUILDER_PARSER_ID)) {
+                               return commands[i];
+                       }
+               }
+               return null;
+       }
+//
+//     /**
+//      * Convenience method that returns the specific type of info for a Java project.
+//      */
+//     protected JavaProjectElementInfo getJavaProjectElementInfo()
+//             throws JavaModelException {
+//
+//             return (JavaProjectElementInfo) getElementInfo();
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public NameLookup getNameLookup() throws JavaModelException {
+//
+//             JavaProjectElementInfo info = getJavaProjectElementInfo();
+//             // lock on the project info to avoid race condition
+//             synchronized(info){
+//                     NameLookup nameLookup;
+//                     if ((nameLookup = info.getNameLookup()) == null){
+//                             info.setNameLookup(nameLookup = new NameLookup(this));
+//                     }
+//                     return nameLookup;
+//             }
+//     }
+//
+//     /**
+//      * Returns an array of non-java resources contained in the receiver.
+//      */
+//     public Object[] getNonJavaResources() throws JavaModelException {
+//
+//             return ((JavaProjectElementInfo) getElementInfo()).getNonJavaResources(this);
+//     }
+
+       /**
+        * @see org.eclipse.jdt.core.IJavaProject#getOption(String, boolean)
+        */     
+//     public String getOption(String optionName, boolean inheritJavaCoreOptions) {
+//             
+//             if (JavaModelManager.OptionNames.contains(optionName)){
+//                     
+//                     Preferences preferences = getPreferences();
+//                     if (preferences == null || preferences.isDefault(optionName)) {
+//                             return inheritJavaCoreOptions ? PHPCore.getOption(optionName) : null;
+//                     }
+//                     return preferences.getString(optionName).trim();
+//             }
+//             return null;
+//     }
+       
+       /**
+        * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
+        */
+//     public Map getOptions(boolean inheritJavaCoreOptions) {
+//             
+//             // initialize to the defaults from JavaCore options pool
+//             Map options = inheritJavaCoreOptions ? PHPCore.getOptions() : new Hashtable(5);
+//
+//             Preferences preferences = getPreferences();
+//             if (preferences == null) return options; // cannot do better (non-Java project)
+//             HashSet optionNames = JavaModelManager.OptionNames;
+//             
+//             // get preferences set to their default
+//             if (inheritJavaCoreOptions){
+//                     String[] defaultPropertyNames = preferences.defaultPropertyNames();
+//                     for (int i = 0; i < defaultPropertyNames.length; i++){
+//                             String propertyName = defaultPropertyNames[i];
+//                             if (optionNames.contains(propertyName)){
+//                                     options.put(propertyName, preferences.getDefaultString(propertyName).trim());
+//                             }
+//                     }               
+//             }
+//             // get custom preferences not set to their default
+//             String[] propertyNames = preferences.propertyNames();
+//             for (int i = 0; i < propertyNames.length; i++){
+//                     String propertyName = propertyNames[i];
+//                     if (optionNames.contains(propertyName)){
+//                             options.put(propertyName, preferences.getString(propertyName).trim());
+//                     }
+//             }               
+//             return options;
+//     }
+       
+       /**
+        * @see IJavaProject
+        */
+//     public IPath getOutputLocation() throws JavaModelException {
+//
+//             JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject);
+//             IPath outputLocation = perProjectInfo.outputLocation;
+//             if (outputLocation != null) return outputLocation;
+//
+//             // force to read classpath - will position output location as well
+//             this.getRawClasspath();
+//             outputLocation = perProjectInfo.outputLocation;
+//             if (outputLocation == null) {
+//                     return defaultOutputLocation();
+//             }
+//             return outputLocation;
+//     }
+//
+//     /**
+//      * @return A handle to the package fragment root identified by the given path.
+//      * This method is handle-only and the element may or may not exist. Returns
+//      * <code>null</code> if unable to generate a handle from the path (for example,
+//      * an absolute path that has less than 1 segment. The path may be relative or
+//      * absolute.
+//      */
+//     public IPackageFragmentRoot getPackageFragmentRoot(IPath path) {
+//             if (!path.isAbsolute()) {
+//                     path = getPath().append(path);
+//             }
+//             int segmentCount = path.segmentCount();
+//             switch (segmentCount) {
+//                     case 0:
+//                             return null;
+//                     case 1:
+//                             // default root
+//                             return getPackageFragmentRoot(getProject());
+//                     default:
+//                             // a path ending with .jar/.zip is still ambiguous and could still resolve to a source/lib folder 
+//                             // thus will try to guess based on existing resource
+//                             if (Util.isArchiveFileName(path.lastSegment())) {
+//                                     IResource resource = getProject().getWorkspace().getRoot().findMember(path); 
+//                                     if (resource != null && resource.getType() == IResource.FOLDER){
+//                                             return getPackageFragmentRoot(resource);
+//                                     }
+//                                     return getPackageFragmentRoot0(path);
+//                             } else {
+//                                     return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path));
+//                             }
+//             }
+//     }
+//
+//     /**
+//      * The path is known to match a source/library folder entry.
+//      */
+//     public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) {
+//             if (path.segmentCount() == 1) { // default project root
+//                     return getPackageFragmentRoot(getProject());
+//             }
+//             return getPackageFragmentRoot(getProject().getWorkspace().getRoot().getFolder(path));
+//     }
+//     
+//     /**
+//      * @see IJavaProject
+//      */
+//     public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) {
+//
+//             switch (resource.getType()) {
+//                     case IResource.FILE:
+//                             if (Util.isArchiveFileName(resource.getName())) {
+//                                     return new JarPackageFragmentRoot(resource, this);
+//                             } else {
+//                                     return null;
+//                             }
+//                     case IResource.FOLDER:
+//                             return new PackageFragmentRoot(resource, this, resource.getName());
+//                     case IResource.PROJECT:
+//                             return new PackageFragmentRoot(resource, this, ""); //$NON-NLS-1$
+//                     default:
+//                             return null;
+//             }
+//     }
+//
+//     /**
+//      * @see IJavaProject
+//      */
+//     public IPackageFragmentRoot getPackageFragmentRoot(String jarPath) {
+//
+//             return getPackageFragmentRoot0(JavaProject.canonicalizedPath(new Path(jarPath)));
+//     }
+//     
+//     /**
+//      * no path canonicalization
+//      */
+//     public IPackageFragmentRoot getPackageFragmentRoot0(IPath jarPath) {
+//
+//             return new JarPackageFragmentRoot(jarPath, this);
+//     }
+//
+//     /**
+//      * @see IJavaProject
+//      */
+//     public IPackageFragmentRoot[] getPackageFragmentRoots()
+//             throws JavaModelException {
+//
+//             Object[] children;
+//             int length;
+//             IPackageFragmentRoot[] roots;
+//
+//             System.arraycopy(
+//                     children = getChildren(), 
+//                     0, 
+//                     roots = new IPackageFragmentRoot[length = children.length], 
+//                     0, 
+//                     length);
+//                     
+//             return roots;
+//     }
+
+       /**
+        * @see IJavaProject
+        * @deprecated
+        */
+//     public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) {
+//             return findPackageFragmentRoots(entry);
+//     }
+
+       /**
+        * Returns the package fragment root prefixed by the given path, or
+        * an empty collection if there are no such elements in the model.
+        */
+//     protected IPackageFragmentRoot[] getPackageFragmentRoots(IPath path)
+//
+//             throws JavaModelException {
+//             IPackageFragmentRoot[] roots = getAllPackageFragmentRoots();
+//             ArrayList matches = new ArrayList();
+//
+//             for (int i = 0; i < roots.length; ++i) {
+//                     if (path.isPrefixOf(roots[i].getPath())) {
+//                             matches.add(roots[i]);
+//                     }
+//             }
+//             IPackageFragmentRoot[] copy = new IPackageFragmentRoot[matches.size()];
+//             matches.toArray(copy);
+//             return copy;
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public IPackageFragment[] getPackageFragments() throws JavaModelException {
+//
+//             IPackageFragmentRoot[] roots = getPackageFragmentRoots();
+//             return getPackageFragmentsInRoots(roots);
+//     }
+
+       /**
+        * Returns all the package fragments found in the specified
+        * package fragment roots.
+        */
+//     public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) {
+//
+//             ArrayList frags = new ArrayList();
+//             for (int i = 0; i < roots.length; i++) {
+//                     IPackageFragmentRoot root = roots[i];
+//                     try {
+//                             IJavaElement[] rootFragments = root.getChildren();
+//                             for (int j = 0; j < rootFragments.length; j++) {
+//                                     frags.add(rootFragments[j]);
+//                             }
+//                     } catch (JavaModelException e) {
+//                             // do nothing
+//                     }
+//             }
+//             IPackageFragment[] fragments = new IPackageFragment[frags.size()];
+//             frags.toArray(fragments);
+//             return fragments;
+//     }
+       
+       /*
+        * @see IJavaElement
+        */
+       public IPath getPath() {
+               return this.getProject().getFullPath();
+       }
+       
+       /**
+        * @see IJavaProject
+        */
+       public IProject getProject() {
+
+               return fProject;
+       }
+
+       /**
+        * Returns the project custom preference pool.
+        * Project preferences may include custom encoding.
+        */     
+//     public Preferences getPreferences(){
+//             IProject project = getProject();
+//             if (!JavaProject.hasJavaNature(project)) return null;
+//             JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true);
+//             Preferences preferences =  perProjectInfo.preferences;
+//             if (preferences != null) return preferences;
+//             preferences = loadPreferences();
+//             if (preferences == null) preferences = new Preferences();
+//             perProjectInfo.preferences = preferences;
+//             return preferences;
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public IClasspathEntry[] getRawClasspath() throws JavaModelException {
+//
+//             JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject);
+//             IClasspathEntry[] classpath = perProjectInfo.classpath;
+//             if (classpath != null) return classpath;
+//             classpath = this.readClasspathFile(false/*don't create markers*/, true/*log problems*/);
+//             
+//             // extract out the output location
+//             IPath outputLocation = null;
+//             if (classpath != null && classpath.length > 0) {
+//                     IClasspathEntry entry = classpath[classpath.length - 1];
+//                     if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
+//                             outputLocation = entry.getPath();
+//                             IClasspathEntry[] copy = new IClasspathEntry[classpath.length - 1];
+//                             System.arraycopy(classpath, 0, copy, 0, copy.length);
+//                             classpath = copy;
+//                     }
+//             }
+//             if (classpath == null) {
+//                     return defaultClasspath();
+//             }
+//             /* Disable validate: classpath can contain CP variables and container that need to be resolved 
+//             if (classpath != INVALID_CLASSPATH
+//                             && !JavaConventions.validateClasspath(this, classpath, outputLocation).isOK()) {
+//                     classpath = INVALID_CLASSPATH;
+//             }
+//             */
+//             perProjectInfo.classpath = classpath;
+//             perProjectInfo.outputLocation = outputLocation;
+//             return classpath;
+//     }
+
+       /**
+        * @see IJavaProject#getRequiredProjectNames
+        */
+//     public String[] getRequiredProjectNames() throws JavaModelException {
+//
+//             return this.projectPrerequisites(getResolvedClasspath(true));
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry)
+//             throws JavaModelException {
+//
+//             return 
+//                     this.getResolvedClasspath(
+//                             ignoreUnresolvedEntry, 
+//                             false); // generateMarkerOnError
+//     }
+
+       /**
+        * Internal variant which can create marker on project for invalid entries
+        * and caches the resolved classpath on perProjectInfo
+        */
+//     public IClasspathEntry[] getResolvedClasspath(
+//             boolean ignoreUnresolvedEntry,
+//             boolean generateMarkerOnError)
+//             throws JavaModelException {
+//
+//             JavaModelManager manager = JavaModelManager.getJavaModelManager();
+//             JavaModelManager.PerProjectInfo perProjectInfo = manager.getPerProjectInfoCheckExistence(fProject);
+//             
+//             // reuse cache if not needing to refresh markers or checking bound variables
+//             if (ignoreUnresolvedEntry && !generateMarkerOnError && perProjectInfo != null){
+//                     // resolved path is cached on its info
+//                     IClasspathEntry[] infoPath = perProjectInfo.lastResolvedClasspath;
+//                     if (infoPath != null) return infoPath;
+//             }
+//             Map reverseMap = perProjectInfo == null ? null : new HashMap(5);
+//             IClasspathEntry[] resolvedPath = getResolvedClasspath(
+//                     getRawClasspath(), 
+//                     generateMarkerOnError ? getOutputLocation() : null, 
+//                     ignoreUnresolvedEntry, 
+//                     generateMarkerOnError,
+//                     reverseMap);
+//
+//             if (perProjectInfo != null){
+//                     if (perProjectInfo.classpath == null // .classpath file could not be read
+//                             && generateMarkerOnError 
+//                             && JavaProject.hasJavaNature(fProject)) {
+//                                     this.createClasspathProblemMarker(new JavaModelStatus(
+//                                             IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+//                                             Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
+//                             }
+//
+//                     perProjectInfo.lastResolvedClasspath = resolvedPath;
+//                     perProjectInfo.resolvedPathToRawEntries = reverseMap;
+//             }
+//             return resolvedPath;
+//     }
+       
+       /**
+        * Internal variant which can process any arbitrary classpath
+        */
+//     public IClasspathEntry[] getResolvedClasspath(
+//             IClasspathEntry[] classpathEntries,
+//             IPath projectOutputLocation, // only set if needing full classpath validation (and markers)
+//             boolean ignoreUnresolvedEntry, // if unresolved entries are met, should it trigger initializations
+//             boolean generateMarkerOnError,
+//             Map reverseMap) // can be null if not interested in reverse mapping
+//             throws JavaModelException {
+//
+//             IJavaModelStatus status;
+//             if (generateMarkerOnError){
+//                     flushClasspathProblemMarkers(false, false);
+//             }
+//
+//             int length = classpathEntries.length;
+//             ArrayList resolvedEntries = new ArrayList();
+//             
+//             for (int i = 0; i < length; i++) {
+//
+//                     IClasspathEntry rawEntry = classpathEntries[i];
+//                     IPath resolvedPath;
+//                     status = null;
+//                     
+//                     /* validation if needed */
+//                     if (generateMarkerOnError || !ignoreUnresolvedEntry) {
+//                             status = JavaConventions.validateClasspathEntry(this, rawEntry, false);
+//                             if (generateMarkerOnError && !status.isOK()) createClasspathProblemMarker(status);
+//                     }
+//
+//                     switch (rawEntry.getEntryKind()){
+//                             
+//                             case IClasspathEntry.CPE_VARIABLE :
+//                             
+//                                     IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(rawEntry);
+//                                     if (resolvedEntry == null) {
+//                                             if (!ignoreUnresolvedEntry) throw new JavaModelException(status);
+//                                     } else {
+//                                             if (reverseMap != null && reverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) reverseMap.put(resolvedPath , rawEntry);
+//                                             resolvedEntries.add(resolvedEntry);
+//                                     }
+//                                     break; 
+//
+//                             case IClasspathEntry.CPE_CONTAINER :
+//                             
+//                                     IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), this);
+//                                     if (container == null){
+//                                             if (!ignoreUnresolvedEntry) throw new JavaModelException(status);
+//                                             break;
+//                                     }
+//
+//                                     IClasspathEntry[] containerEntries = container.getClasspathEntries();
+//                                     if (containerEntries == null) break;
+//
+//                                     // container was bound
+//                                     for (int j = 0, containerLength = containerEntries.length; j < containerLength; j++){
+//                                             IClasspathEntry cEntry = containerEntries[j];
+//                                             
+//                                             if (generateMarkerOnError) {
+//                                                     IJavaModelStatus containerStatus = JavaConventions.validateClasspathEntry(this, cEntry, false);
+//                                                     if (!containerStatus.isOK()) createClasspathProblemMarker(containerStatus);
+//                                             }
+//                                             // if container is exported, then its nested entries must in turn be exported  (21749)
+//                                             if (rawEntry.isExported()){
+//                                                     cEntry = new ClasspathEntry(cEntry.getContentKind(),
+//                                                             cEntry.getEntryKind(), cEntry.getPath(),
+//                                                             cEntry.getExclusionPatterns(), cEntry.getSourceAttachmentPath(),
+//                                                             cEntry.getSourceAttachmentRootPath(), cEntry.getOutputLocation(), 
+//                                                             true); // duplicate container entry for tagging it as exported
+//                                             }
+//                                             if (reverseMap != null && reverseMap.get(resolvedPath = cEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry);
+//                                             resolvedEntries.add(cEntry);
+//                                     }
+//                                     break;
+//                                                                             
+//                             default :
+//
+//                                     if (reverseMap != null && reverseMap.get(resolvedPath = rawEntry.getPath()) == null) reverseMap.put(resolvedPath, rawEntry);
+//                                     resolvedEntries.add(rawEntry);
+//                             
+//                     }                                       
+//             }
+//
+//             IClasspathEntry[] resolvedPath = new IClasspathEntry[resolvedEntries.size()];
+//             resolvedEntries.toArray(resolvedPath);
+//
+//             if (generateMarkerOnError && projectOutputLocation != null) {
+//                     status = JavaConventions.validateClasspath(this, resolvedPath, projectOutputLocation);
+//                     if (!status.isOK()) createClasspathProblemMarker(status);
+//             }
+//             return resolvedPath;
+//     }
+
+       /*
+        * @see IJavaElement
+        */
+       public IResource getResource() {
+               return this.getProject();
+       }
+
+       /**
+        * @see IJavaProject
+        */
+//     public ISearchableNameEnvironment getSearchableNameEnvironment()
+//             throws JavaModelException {
+//
+//             JavaProjectElementInfo info = getJavaProjectElementInfo();
+//             if (info.getSearchableEnvironment() == null) {
+//                     info.setSearchableEnvironment(new SearchableEnvironment(this));
+//             }
+//             return info.getSearchableEnvironment();
+//     }
+
+       /**
+        * Retrieve a shared property on a project. If the property is not defined, answers null.
+        * Note that it is orthogonal to IResource persistent properties, and client code has to decide
+        * which form of storage to use appropriately. Shared properties produce real resource files which
+        * can be shared through a VCM onto a server. Persistent properties are not shareable.
+        *
+        * @see JavaProject#setSharedProperty(String, String)
+        */
+//     public String getSharedProperty(String key) throws CoreException {
+//
+//             String property = null;
+//             IFile rscFile = getProject().getFile(key);
+//             if (rscFile.exists()) {
+//                     property = new String(Util.getResourceContentsAsByteArray(rscFile));
+//             }
+//             return property;
+//     }
+
+       /**
+        * @see JavaElement
+        */
+//     public SourceMapper getSourceMapper() {
+//
+//             return null;
+//     }
+
+       /**
+        * @see IJavaElement
+        */
+       public IResource getUnderlyingResource() throws JavaModelException {
+               if (!exists()) throw newNotPresentException();
+               return getProject();
+       }
+
+       /**
+        * @see IJavaProject
+        */
+//     public boolean hasBuildState() {
+//
+//             return JavaModelManager.getJavaModelManager().getLastBuiltState(this.getProject(), null) != null;
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) {
+//             HashSet cycleParticipants = new HashSet();
+//             updateCycleParticipants(preferredClasspath, new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2));
+//             return !cycleParticipants.isEmpty();
+//     }
+       
+//     public boolean hasCycleMarker(){
+//             return this.getCycleMarker() != null;
+//     }
+
+       public int hashCode() {
+               return fProject.hashCode();
+       }
+
+       /**
+        * Returns true if the given project is accessible and it has
+        * a java nature, otherwise false.
+        */
+       public static boolean hasJavaNature(IProject project) { 
+               try {
+                       return project.hasNature(PHPeclipsePlugin.PHP_NATURE_ID);
+               } catch (CoreException e) {
+                       // project does not exist or is not open
+               }
+               return false;
+       }
+       
+       /**
+        * Answers true if the project potentially contains any source. A project which has no source is immutable.
+        */
+//     public boolean hasSource() {
+//
+//             // look if any source folder on the classpath
+//             // no need for resolved path given source folder cannot be abstracted
+//             IClasspathEntry[] entries;
+//             try {
+//                     entries = this.getRawClasspath();
+//             } catch (JavaModelException e) {
+//                     return true; // unsure
+//             }
+//             for (int i = 0, max = entries.length; i < max; i++) {
+//                     if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+//                             return true;
+//                     }
+//             }
+//             return false;
+//     }
+
+       /**
+        * Compare current classpath with given one to see if any different.
+        * Note that the argument classpath contains its binary output.
+        */
+//     public boolean isClasspathEqualsTo(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput)
+//             throws JavaModelException {
+//
+//             if (otherClasspathWithOutput != null && otherClasspathWithOutput.length > 0) {
+//
+//                     int length = otherClasspathWithOutput.length;
+//                     if (length == newClasspath.length + 1) {
+//                             // output is amongst file entries (last one)
+//
+//                             // compare classpath entries
+//                             for (int i = 0; i < length - 1; i++) {
+//                                     if (!otherClasspathWithOutput[i].equals(newClasspath[i]))
+//                                             return false;
+//                             }
+//                             // compare binary outputs
+//                             IClasspathEntry output = otherClasspathWithOutput[length - 1];
+//                             if (output.getContentKind() == ClasspathEntry.K_OUTPUT
+//                                             && output.getPath().equals(newOutputLocation))
+//                                     return true;
+//                     }
+//             }
+//             return false;
+//     }
+       
+
+       
+       /*
+        * @see IJavaProject
+        */
+//     public boolean isOnClasspath(IJavaElement element) {
+//             IPath path = element.getPath();
+//             switch (element.getElementType()) {
+//                     case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+//                             if (!((IPackageFragmentRoot)element).isArchive()) {
+//                                     // ensure that folders are only excluded if all of their children are excluded
+//                                     path = path.append("*"); //$NON-NLS-1$
+//                             }
+//                             break;
+//                     case IJavaElement.PACKAGE_FRAGMENT:
+//                             if (!((IPackageFragmentRoot)element.getParent()).isArchive()) {
+//                                     // ensure that folders are only excluded if all of their children are excluded
+//                                     path = path.append("*"); //$NON-NLS-1$
+//                             }
+//                             break;
+//             }
+//             return this.isOnClasspath(path);
+//     }
+//     private boolean isOnClasspath(IPath path) {
+//             IClasspathEntry[] classpath;
+//             try {
+//                     classpath = this.getResolvedClasspath(true/*ignore unresolved variable*/);
+//             } catch(JavaModelException e){
+//                     return false; // not a Java project
+//             }
+//             for (int i = 0; i < classpath.length; i++) {
+//                     IClasspathEntry entry = classpath[i];
+//                     if (entry.getPath().isPrefixOf(path) 
+//                                     && !Util.isExcluded(path, ((ClasspathEntry)entry).fullExclusionPatternChars())) {
+//                             return true;
+//                     }
+//             }
+//             return false;
+//     }
+       /*
+        * @see IJavaProject
+        */
+//     public boolean isOnClasspath(IResource resource) {
+//             IPath path = resource.getFullPath();
+//             
+//             // ensure that folders are only excluded if all of their children are excluded
+//             if (resource.getType() == IResource.FOLDER) {
+//                     path = path.append("*"); //$NON-NLS-1$
+//             }
+//             
+//             return this.isOnClasspath(path);
+//     }
+
+
+       /*
+        * load preferences from a shareable format (VCM-wise)
+        */
+        public Preferences loadPreferences() {
+               
+               Preferences preferences = new Preferences();
+               
+//             File prefFile = getProject().getLocation().append(PREF_FILENAME).toFile();
+               IPath projectMetaLocation = getProject().getPluginWorkingLocation(PHPCore.getPlugin().getDescriptor());
+               if (projectMetaLocation != null) {
+                       File prefFile = projectMetaLocation.append(PREF_FILENAME).toFile();
+                       if (prefFile.exists()) { // load preferences from file
+                               InputStream in = null;
+                               try {
+                                       in = new BufferedInputStream(new FileInputStream(prefFile));
+                                       preferences.load(in);
+                                       return preferences;
+                               } catch (IOException e) { // problems loading preference store - quietly ignore
+                               } finally {
+                                       if (in != null) {
+                                               try {
+                                                       in.close();
+                                               } catch (IOException e) { // ignore problems with close
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return null;
+        }
+        
+       /**
+        * @see IJavaProject#newEvaluationContext
+        */
+//     public IEvaluationContext newEvaluationContext() {
+//
+//             return new EvaluationContextWrapper(new EvaluationContext(), this);
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public ITypeHierarchy newTypeHierarchy(
+//             IRegion region,
+//             IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             if (region == null) {
+//                     throw new IllegalArgumentException(Util.bind("hierarchy.nullRegion"));//$NON-NLS-1$
+//             }
+//             CreateTypeHierarchyOperation op =
+//                     new CreateTypeHierarchyOperation(null, region, this, true);
+//             runOperation(op, monitor);
+//             return op.getResult();
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public ITypeHierarchy newTypeHierarchy(
+//             IType type,
+//             IRegion region,
+//             IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             if (type == null) {
+//                     throw new IllegalArgumentException(Util.bind("hierarchy.nullFocusType"));//$NON-NLS-1$
+//             }
+//             if (region == null) {
+//                     throw new IllegalArgumentException(Util.bind("hierarchy.nullRegion"));//$NON-NLS-1$
+//             }
+//             CreateTypeHierarchyOperation op =
+//                     new CreateTypeHierarchyOperation(type, region, this, true);
+//             runOperation(op, monitor);
+//             return op.getResult();
+//     }
+
+       /**
+        * Open project if resource isn't closed
+        */
+//     protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
+//
+//             if (!this.fProject.isOpen()) {
+//                     throw newNotPresentException();
+//             } else {
+//                     super.openWhenClosed(pm);
+//             }
+//     }
+
+//     public String[] projectPrerequisites(IClasspathEntry[] entries)
+//             throws JavaModelException {
+//                     
+//             ArrayList prerequisites = new ArrayList();
+//             // need resolution
+//             entries = getResolvedClasspath(entries, null, true, false, null/*no reverse map*/);
+//             for (int i = 0, length = entries.length; i < length; i++) {
+//                     IClasspathEntry entry = entries[i];
+//                     if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+//                             prerequisites.add(entry.getPath().lastSegment());
+//                     }
+//             }
+//             int size = prerequisites.size();
+//             if (size == 0) {
+//                     return NO_PREREQUISITES;
+//             } else {
+//                     String[] result = new String[size];
+//                     prerequisites.toArray(result);
+//                     return result;
+//             }
+//     }
+
+
+       /**
+        * Reads the .classpath file from disk and returns the list of entries it contains (including output location entry)
+        * Returns null if .classfile is not present.
+        * Returns INVALID_CLASSPATH if it has a format problem.
+        */
+//     protected IClasspathEntry[] readClasspathFile(boolean createMarker, boolean logProblems) {
+//
+//             try {
+//                     String xmlClasspath = getSharedProperty(CLASSPATH_FILENAME);
+//                     if (xmlClasspath == null) return null;
+//                     return decodeClasspath(xmlClasspath, createMarker, logProblems);
+//             } catch(CoreException e) {
+//                     // file does not exist (or not accessible)
+//                     if (createMarker && this.getProject().isAccessible()) {
+//                                     this.createClasspathProblemMarker(new JavaModelStatus(
+//                                             IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+//                                             Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
+//                     }
+//                     if (logProblems) {
+//                             Util.log(e, 
+//                                     "Exception while retrieving "+ this.getPath() //$NON-NLS-1$
+//                                     +"/.classpath, will revert to default classpath"); //$NON-NLS-1$
+//                     }
+//             }
+//             return null;
+//     }
+
+       /**
+        * Removes the given builder from the build spec for the given project.
+        */
+       protected void removeFromBuildSpec(String builderID) throws CoreException {
+
+               IProjectDescription description = getProject().getDescription();
+               ICommand[] commands = description.getBuildSpec();
+               for (int i = 0; i < commands.length; ++i) {
+                       if (commands[i].getBuilderName().equals(builderID)) {
+                               ICommand[] newCommands = new ICommand[commands.length - 1];
+                               System.arraycopy(commands, 0, newCommands, 0, i);
+                               System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
+                               description.setBuildSpec(newCommands);
+                               getProject().setDescription(description, null);
+                               return;
+                       }
+               }
+       }
+
+
+       /**
+        * @see JavaElement#rootedAt(IJavaProject)
+        */
+       public IJavaElement rootedAt(IJavaProject project) {
+               return project;
+       
+       }
+       
+       /**
+        * Answers an ID which is used to distinguish project/entries during package
+        * fragment root computations
+        */
+       public String rootID(){
+               return "[PRJ]"+this.getProject().getFullPath(); //$NON-NLS-1$
+       }
+       
+       /**
+        * Saves the classpath in a shareable format (VCM-wise) only when necessary, that is, if  it is semantically different
+        * from the existing one in file. Will never write an identical one.
+        * 
+        * @return Return whether the .classpath file was modified.
+        */
+//     public boolean saveClasspath(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException {
+//
+//             if (!getProject().exists()) return false;
+//
+//             IClasspathEntry[] fileEntries = readClasspathFile(false /*don't create markers*/, false/*don't log problems*/);
+//             if (fileEntries != null && isClasspathEqualsTo(newClasspath, newOutputLocation, fileEntries)) {
+//                     // no need to save it, it is the same
+//                     return false;
+//             }
+//
+//             // actual file saving
+//             try {
+//                     setSharedProperty(CLASSPATH_FILENAME, encodeClasspath(newClasspath, newOutputLocation, true));
+//                     return true;
+//             } catch (CoreException e) {
+//                     throw new JavaModelException(e);
+//             }
+//     }
+
+       /**
+        * Save project custom preferences to shareable file (.jprefs)
+        */
+       private void savePreferences(Preferences preferences) {
+               
+               IProject project = getProject();
+               if (!JavaProject.hasJavaNature(project)) return; // ignore
+               
+               if (preferences == null || (!preferences.needsSaving() && preferences.propertyNames().length != 0)) {
+                       // nothing to save
+                       return;
+               }
+       
+               // preferences need to be saved
+               // the preferences file is located in the plug-in's state area
+               // at a well-known name (.jprefs)
+//             File prefFile = getProject().getLocation().append(PREF_FILENAME).toFile();
+               File prefFile = project.getPluginWorkingLocation(PHPCore.getPlugin().getDescriptor()).append(PREF_FILENAME).toFile();
+               if (preferences.propertyNames().length == 0) {
+                       // there are no preference settings
+                       // rather than write an empty file, just delete any existing file
+                       if (prefFile.exists()) {
+                               prefFile.delete(); // don't worry if delete unsuccessful
+                       }
+                       return;
+               }
+               
+               // write file, overwriting an existing one
+               OutputStream out = null;
+               try {
+                       // do it as carefully as we know how so that we don't lose/mangle
+                       // the setting in times of stress
+                       out = new BufferedOutputStream(new FileOutputStream(prefFile));
+                       preferences.store(out, null);
+               } catch (IOException e) { // problems saving preference store - quietly ignore
+               } finally {
+                       if (out != null) {
+                               try {
+                                       out.close();
+                               } catch (IOException e) { // ignore problems with close
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Update the Java command in the build spec (replace existing one if present,
+        * add one first if none).
+        */
+       private void setJavaCommand(
+               IProjectDescription description,
+               ICommand newCommand)
+               throws CoreException {
+
+               ICommand[] oldCommands = description.getBuildSpec();
+               ICommand oldJavaCommand = getJavaCommand(description);
+               ICommand[] newCommands;
+
+               if (oldJavaCommand == null) {
+                       // Add a Java build spec before other builders (1FWJK7I)
+                       newCommands = new ICommand[oldCommands.length + 1];
+                       System.arraycopy(oldCommands, 0, newCommands, 1, oldCommands.length);
+                       newCommands[0] = newCommand;
+               } else {
+                       for (int i = 0, max = oldCommands.length; i < max; i++) {
+                               if (oldCommands[i] == oldJavaCommand) {
+                                       oldCommands[i] = newCommand;
+                                       break;
+                               }
+                       }
+                       newCommands = oldCommands;
+               }
+
+               // Commit the spec change into the project
+               description.setBuildSpec(newCommands);
+               getProject().setDescription(description, null);
+       }
+
+       /**
+        * @see org.eclipse.jdt.core.IJavaProject#setOptions(Map)
+        */
+//     public void setOptions(Map newOptions) {
+//
+//             Preferences preferences;
+//             setPreferences(preferences = new Preferences()); // always reset (26255)
+//             if (newOptions != null){
+//                     Iterator keys = newOptions.keySet().iterator();
+//                     while (keys.hasNext()){
+//                             String key = (String)keys.next();
+//                             if (!JavaModelManager.OptionNames.contains(key)) continue; // unrecognized option
+//                             // no filtering for encoding (custom encoding for project is allowed)
+//                             String value = (String)newOptions.get(key);
+//                             preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251)
+//                             preferences.setValue(key, value);
+//                     }
+//             }
+//             
+//             // persist options
+//             savePreferences(preferences);   
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public void setOutputLocation(IPath path, IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             if (path == null) {
+//                     throw new IllegalArgumentException(Util.bind("path.nullpath")); //$NON-NLS-1$
+//             }
+//             if (path.equals(getOutputLocation())) {
+//                     return;
+//             }
+//             this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor);
+//     }
+
+       /*
+        * Set cached preferences, no preference file is saved, only info is updated
+        */
+//     public void setPreferences(Preferences preferences) {
+//             IProject project = getProject();
+//             if (!JavaProject.hasJavaNature(project)) return; // ignore
+//             JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(project, true);
+//             perProjectInfo.preferences = preferences;
+//     }
+
+       /**
+        * Sets the underlying kernel project of this Java project,
+        * and fills in its parent and name.
+        * Called by IProject.getNature().
+        *
+        * @see IProjectNature#setProject
+        */
+       public void setProject(IProject project) {
+
+               fProject = project;
+               fParent = JavaModelManager.getJavaModelManager().getJavaModel();
+               fName = project.getName();
+       }
+
+       /**
+        * @see IJavaProject
+        */
+//     public void setRawClasspath(
+//             IClasspathEntry[] entries,
+//             IPath outputLocation,
+//             IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             setRawClasspath(
+//                     entries, 
+//                     outputLocation, 
+//                     monitor, 
+//                     true, // canChangeResource (as per API contract)
+//                     getResolvedClasspath(true), // ignoreUnresolvedVariable
+//                     true, // needValidation
+//                     true); // need to save
+//     }
+
+//     public void setRawClasspath(
+//             IClasspathEntry[] newEntries,
+//             IPath newOutputLocation,
+//             IProgressMonitor monitor,
+//             boolean canChangeResource,
+//             IClasspathEntry[] oldResolvedPath,
+//             boolean needValidation,
+//             boolean needSave)
+//             throws JavaModelException {
+//
+//             JavaModelManager manager =
+//                     (JavaModelManager) JavaModelManager.getJavaModelManager();
+//             try {
+//                     IClasspathEntry[] newRawPath = newEntries;
+//                     if (newRawPath == null) { //are we already with the default classpath
+//                             newRawPath = defaultClasspath();
+//                     }
+//                     SetClasspathOperation op =
+//                             new SetClasspathOperation(
+//                                     this, 
+//                                     oldResolvedPath, 
+//                                     newRawPath, 
+//                                     newOutputLocation,
+//                                     canChangeResource, 
+//                                     needValidation,
+//                                     needSave);
+//                     runOperation(op, monitor);
+//                     
+//             } catch (JavaModelException e) {
+//                     manager.flush();
+//                     throw e;
+//             }
+//     }
+
+       /**
+        * @see IJavaProject
+        */
+//     public void setRawClasspath(
+//             IClasspathEntry[] entries,
+//             IProgressMonitor monitor)
+//             throws JavaModelException {
+//
+//             setRawClasspath(
+//                     entries, 
+//                     SetClasspathOperation.ReuseOutputLocation, 
+//                     monitor, 
+//                     true, // canChangeResource (as per API contract)
+//                     getResolvedClasspath(true), // ignoreUnresolvedVariable
+//                     true, // needValidation
+//                     true); // need to save
+//     }
+
+       /**
+        * NOTE: <code>null</code> specifies default classpath, and an empty
+        * array specifies an empty classpath.
+        *
+        * @exception NotPresentException if this project does not exist.
+        */
+//     protected void setRawClasspath0(IClasspathEntry[] rawEntries)
+//             throws JavaModelException {
+//
+//             JavaModelManager.PerProjectInfo info = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(fProject);
+//     
+//             synchronized (info) {
+//                     if (rawEntries != null) {
+//                             info.classpath = rawEntries;
+//                     }
+//                     
+//                     // clear cache of resolved classpath
+//                     info.lastResolvedClasspath = null;
+//                     info.resolvedPathToRawEntries = null;
+//             }
+//     }
+
+       /**
+        * Record a shared persistent property onto a project.
+        * Note that it is orthogonal to IResource persistent properties, and client code has to decide
+        * which form of storage to use appropriately. Shared properties produce real resource files which
+        * can be shared through a VCM onto a server. Persistent properties are not shareable.
+        * 
+        * shared properties end up in resource files, and thus cannot be modified during
+        * delta notifications (a CoreException would then be thrown).
+        * 
+        * @see JavaProject#getSharedProperty(String key)
+        */
+       public void setSharedProperty(String key, String value) throws CoreException {
+
+               IFile rscFile = getProject().getFile(key);
+               InputStream inputStream = new ByteArrayInputStream(value.getBytes());
+               // update the resource content
+               if (rscFile.exists()) {
+                       if (rscFile.isReadOnly()) {
+                               // provide opportunity to checkout read-only .classpath file (23984)
+                               ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{rscFile}, null);
+                       }
+                       rscFile.setContents(inputStream, IResource.FORCE, null);
+               } else {
+                       rscFile.create(inputStream, IResource.FORCE, null);
+               }
+       }
+
+       /**
+        * Update cycle markers for all java projects
+        */
+//     public static void updateAllCycleMarkers() throws JavaModelException {
+//
+//             //long start = System.currentTimeMillis();
+//
+//             JavaModelManager manager = JavaModelManager.getJavaModelManager();
+//             IJavaProject[] projects = manager.getJavaModel().getJavaProjects();
+//             IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+//
+//             HashSet cycleParticipants = new HashSet();
+//             HashSet traversed = new HashSet();
+//             int length = projects.length;
+//             
+//             // compute cycle participants
+//             ArrayList prereqChain = new ArrayList();
+//             for (int i = 0; i < length; i++){
+//                     JavaProject project = (JavaProject)projects[i];
+//                     if (!traversed.contains(project.getPath())){
+//                             prereqChain.clear();
+//                             project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed);
+//                     }
+//             }
+//             //System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms");
+//
+//             for (int i = 0; i < length; i++){
+//                     JavaProject project = (JavaProject)projects[i];
+//                     
+//                     if (cycleParticipants.contains(project.getPath())){
+//                             IMarker cycleMarker = project.getCycleMarker();
+//                             String circularCPOption = project.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true);
+//                             int circularCPSeverity = JavaCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING;
+//                             if (cycleMarker != null) {
+//                                     // update existing cycle marker if needed
+//                                     try {
+//                                             int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue();
+//                                             if (existingSeverity != circularCPSeverity) {
+//                                                     cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity);
+//                                             }
+//                                     } catch (CoreException e) {
+//                                             throw new JavaModelException(e);
+//                                     }
+//                             } else {
+//                                     // create new marker
+//                                     project.createClasspathProblemMarker(
+//                                             new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project)); 
+//                             }
+//                     } else {
+//                             project.flushClasspathProblemMarkers(true, false);
+//                     }                       
+//             }
+//     }
+//
+//     /**
+//      * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly),
+//      * no cycle if the set is empty (and started empty)
+//      */
+//     public void updateCycleParticipants(
+//                     IClasspathEntry[] preferredClasspath, 
+//                     ArrayList prereqChain, 
+//                     HashSet cycleParticipants, 
+//                     IWorkspaceRoot workspaceRoot,
+//                     HashSet traversed){
+//
+//             IPath path = this.getPath();
+//             prereqChain.add(path);
+//             traversed.add(path);
+//             try {
+//                     IClasspathEntry[] classpath = preferredClasspath == null ? getResolvedClasspath(true) : preferredClasspath;
+//                     for (int i = 0, length = classpath.length; i < length; i++) {
+//                             IClasspathEntry entry = classpath[i];
+//                             
+//                             if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){
+//                                     IPath prereqProjectPath = entry.getPath();
+//                                     int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath);
+//                                     if (index >= 0) { // refer to cycle, or in cycle itself
+//                                             for (int size = prereqChain.size(); index < size; index++) {
+//                                                     cycleParticipants.add(prereqChain.get(index)); 
+//                                             }
+//                                     } else {
+//                                             if (!traversed.contains(prereqProjectPath)) {
+//                                                     IResource member = workspaceRoot.findMember(prereqProjectPath);
+//                                                     if (member != null && member.getType() == IResource.PROJECT){
+//                                                             JavaProject project = (JavaProject)JavaCore.create((IProject)member);
+//                                                             project.updateCycleParticipants(null, prereqChain, cycleParticipants, workspaceRoot, traversed);
+//                                                     }
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             } catch(JavaModelException e){
+//             }
+//             prereqChain.remove(path);
+//     }
+       /**
+        * Reset the collection of package fragment roots (local ones) - only if opened.
+        * Need to check *all* package fragment roots in order to reset NameLookup
+        */
+//     public void updatePackageFragmentRoots(){
+//             
+//                     if (this.isOpen()) {
+//                             try {
+//                                     JavaProjectElementInfo info = getJavaProjectElementInfo();
+//
+//                                     IClasspathEntry[] classpath = getResolvedClasspath(true);
+//                                     NameLookup lookup = info.getNameLookup();
+//                                     if (lookup != null){
+//                                             IPackageFragmentRoot[] oldRoots = lookup.fPackageFragmentRoots;
+//                                             IPackageFragmentRoot[] newRoots = computePackageFragmentRoots(classpath, true);
+//                                             checkIdentical: { // compare all pkg fragment root lists
+//                                                     if (oldRoots.length == newRoots.length){
+//                                                             for (int i = 0, length = oldRoots.length; i < length; i++){
+//                                                                     if (!oldRoots[i].equals(newRoots[i])){
+//                                                                             break checkIdentical;
+//                                                                     }
+//                                                             }
+//                                                             return; // no need to update
+//                                                     }       
+//                                             }
+//                                             info.setNameLookup(null); // discard name lookup (hold onto roots)
+//                                     }                               
+//                                     info.setNonJavaResources(null);
+//                                     info.setChildren(
+//                                             computePackageFragmentRoots(classpath, false));         
+//
+//                             } catch(JavaModelException e){
+//                                     try {
+//                                             close(); // could not do better
+//                                     } catch(JavaModelException ex){
+//                                     }
+//                             }
+//                     }
+//     }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Openable.java
new file mode 100644 (file)
index 0000000..a8ed665
--- /dev/null
@@ -0,0 +1,529 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import net.sourceforge.phpdt.core.BufferChangedEvent;
+import net.sourceforge.phpdt.core.IBuffer;
+import net.sourceforge.phpdt.core.IBufferChangedListener;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IOpenable;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Abstract class for implementations of java elements which are IOpenable.
+ *
+ * @see IJavaElement
+ * @see IOpenable
+ */
+public abstract class Openable extends JavaElement implements IOpenable, IBufferChangedListener {
+
+protected Openable(int type, IJavaElement parent, String name) {
+       super(type, parent, name);
+}
+       /**
+        * The buffer associated with this element has changed. Registers
+        * this element as being out of synch with its buffer's contents.
+        * If the buffer has been closed, this element is set as NOT out of
+        * synch with the contents.
+        *
+        * @see IBufferChangedListener
+        */
+       public void bufferChanged(BufferChangedEvent event) {
+               if (event.getBuffer().isClosed()) {
+//                     JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+//                     getBufferManager().removeBuffer(event.getBuffer());
+               } else {
+//                     JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().put(this, this);
+               }
+       }       
+///**
+// * Updates the info objects for this element and all of its children by
+// * removing the current infos, generating new infos, and then placing
+// * the new infos into the Java Model cache tables.
+// */
+//protected void buildStructure(OpenableElementInfo info, IProgressMonitor monitor) throws JavaModelException {
+//
+//     if (monitor != null && monitor.isCanceled()) return;
+//     
+//     // remove existing (old) infos
+//     removeInfo();
+//     HashMap newElements = new HashMap(11);
+//     info.setIsStructureKnown(generateInfos(info, monitor, newElements, getResource()));
+//     JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+//     for (Iterator iter = newElements.keySet().iterator(); iter.hasNext();) {
+//             IJavaElement key = (IJavaElement) iter.next();
+//             Object value = newElements.get(key);
+//             JavaModelManager.getJavaModelManager().putInfo(key, value);
+//     }
+//             
+//     // add the info for this at the end, to ensure that a getInfo cannot reply null in case the LRU cache needs
+//     // to be flushed. Might lead to performance issues.
+//     // see PR 1G2K5S7: ITPJCORE:ALL - NPE when accessing source for a binary type
+//     JavaModelManager.getJavaModelManager().putInfo(this, info);     
+//}
+///**
+// * Close the buffer associated with this element, if any.
+// */
+//protected void closeBuffer(OpenableElementInfo info) {
+//     if (!hasBuffer()) return; // nothing to do
+//     IBuffer buffer = null;
+//     buffer = getBufferManager().getBuffer(this);
+//     if (buffer != null) {
+//             buffer.close();
+//             buffer.removeBufferChangedListener(this);
+//     }
+//}
+///**
+// * This element is being closed.  Do any necessary cleanup.
+// */
+//protected void closing(Object info) throws JavaModelException {
+//     OpenableElementInfo openableInfo = (OpenableElementInfo) info;
+//     closeBuffer(openableInfo);
+//     super.closing(info);
+//}
+///**
+// * @see ICodeAssist
+// */
+//protected void codeComplete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, ICompletionRequestor requestor) throws JavaModelException {
+//     if (requestor == null) {
+//             throw new IllegalArgumentException(Util.bind("codeAssist.nullRequestor")); //$NON-NLS-1$
+//     }
+//     IBuffer buffer = getBuffer();
+//     if (buffer == null) {
+//             return;
+//     }
+//     if (position < -1 || position > buffer.getLength()) {
+//             throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS));
+//     }
+//     JavaProject project = (JavaProject) getJavaProject();
+//     SearchableEnvironment environment = (SearchableEnvironment) project.getSearchableNameEnvironment();
+//     NameLookup nameLookup = project.getNameLookup();
+//     environment.unitToSkip = unitToSkip;
+//
+//     CompletionEngine engine = new CompletionEngine(environment, new CompletionRequestorWrapper(requestor,nameLookup), project.getOptions(true), project);
+//     engine.complete(cu, position, 0);
+//     environment.unitToSkip = null;
+//}
+///**
+// * @see ICodeAssist
+// */
+//protected IJavaElement[] codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length) throws JavaModelException {
+//     SelectionRequestor requestor= new SelectionRequestor(((JavaProject)getJavaProject()).getNameLookup(), this);
+//     this.codeSelect(cu, offset, length, requestor);
+//     return requestor.getElements();
+//}
+///**
+// * @see ICodeAssist
+// */
+//protected void codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, ISelectionRequestor requestor) throws JavaModelException {
+//     IBuffer buffer = getBuffer();
+//     if (buffer == null) {
+//             return;
+//     }
+//     int end= buffer.getLength();
+//     if (offset < 0 || length < 0 || offset + length > end ) {
+//             throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS));
+//     }
+//
+//     // fix for 1FVGGKF
+//     JavaProject project = (JavaProject)getJavaProject();
+//     ISearchableNameEnvironment environment = project.getSearchableNameEnvironment();
+//     
+//     // fix for 1FVXGDK
+//     SelectionEngine engine = new SelectionEngine(environment, requestor, project.getOptions(true));
+//     engine.select(cu, offset, offset + length - 1);
+//}
+///**
+// * Returns a new element info for this element.
+// */
+//protected OpenableElementInfo createElementInfo() {
+//     return new OpenableElementInfo();
+//}
+//
+///**
+// * Builds this element's structure and properties in the given
+// * info object, based on this element's current contents (reuse buffer
+// * contents if this element has an open buffer, or resource contents
+// * if this element does not have an open buffer). Children
+// * are placed in the given newElements table (note, this element
+// * has already been placed in the newElements table). Returns true
+// * if successful, or false if an error is encountered while determining
+// * the structure of this element.
+// */
+//protected abstract boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException;
+/**
+ * Note: a buffer with no unsaved changes can be closed by the Java Model
+ * since it has a finite number of buffers allowed open at one time. If this
+ * is the first time a request is being made for the buffer, an attempt is
+ * made to create and fill this element's buffer. If the buffer has been
+ * closed since it was first opened, the buffer is re-created.
+ * 
+ * @see IOpenable
+ */
+public IBuffer getBuffer() throws JavaModelException {
+       if (hasBuffer()) {
+               // ensure element is open
+               if (!isOpen()) {
+                       getElementInfo();
+               }
+               IBuffer buffer = getBufferManager().getBuffer(this);
+               if (buffer == null) {
+                       // try to (re)open a buffer
+                       buffer = openBuffer(null);
+               }
+               return buffer;
+       } else {
+               return null;
+       }
+}
+//
+///**
+// * Answers the buffer factory to use for creating new buffers
+// */
+//public IBufferFactory getBufferFactory(){
+//     return getBufferManager().getDefaultBufferFactory();
+//}
+//
+/**
+ * Returns the buffer manager for this element.
+ */
+protected BufferManager getBufferManager() {
+       return BufferManager.getDefaultBufferManager();
+}
+/**
+ * Return my underlying resource. Elements that may not have a
+ * corresponding resource must override this method.
+ *
+ * @see IJavaElement
+ */
+public IResource getCorrespondingResource() throws JavaModelException {
+       return getUnderlyingResource();
+}
+///*
+// * @see IJavaElement
+// */
+//public IOpenable getOpenable() {
+//     return this;    
+//}
+//
+//
+//
+/**
+ * @see IJavaElement
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+       IResource parentResource = fParent.getUnderlyingResource();
+       if (parentResource == null) {
+               return null;
+       }
+       int type = parentResource.getType();
+       if (type == IResource.FOLDER || type == IResource.PROJECT) {
+               IContainer folder = (IContainer) parentResource;
+               IResource resource = folder.findMember(fName);
+               if (resource == null) {
+                       throw newNotPresentException();
+               } else {
+                       return resource;
+               }
+       } else {
+               return parentResource;
+       }
+}
+
+//public boolean exists() {
+//     
+//     IPackageFragmentRoot root = this.getPackageFragmentRoot();
+//     if (root == null || root == this || !root.isArchive()) {
+//             return parentExists() && resourceExists();
+//     } else {
+//             return super.exists();
+//     }
+//}    
+
+/**
+ * Returns true if this element may have an associated source buffer,
+ * otherwise false. Subclasses must override as required.
+ */
+protected boolean hasBuffer() {
+       return false;
+}
+///**
+// * @see IParent 
+// */
+//public boolean hasChildren() throws JavaModelException {
+//     return getChildren().length > 0;
+//}
+///**
+// * @see IOpenable
+// */
+//public boolean hasUnsavedChanges() throws JavaModelException{
+//     
+//     if (isReadOnly() || !isOpen()) {
+//             return false;
+//     }
+//     IBuffer buf = this.getBuffer();
+//     if (buf != null && buf.hasUnsavedChanges()) {
+//             return true;
+//     }
+//     // for package fragments, package fragment roots, and projects must check open buffers
+//     // to see if they have an child with unsaved changes
+//     if (fLEType == PACKAGE_FRAGMENT ||
+//             fLEType == PACKAGE_FRAGMENT_ROOT ||
+//             fLEType == JAVA_PROJECT ||
+//             fLEType == JAVA_MODEL) { // fix for 1FWNMHH
+//             Enumeration openBuffers= getBufferManager().getOpenBuffers();
+//             while (openBuffers.hasMoreElements()) {
+//                     IBuffer buffer= (IBuffer)openBuffers.nextElement();
+//                     if (buffer.hasUnsavedChanges()) {
+//                             IJavaElement owner= (IJavaElement)buffer.getOwner();
+//                             if (isAncestorOf(owner)) {
+//                                     return true;
+//                             }
+//                     }
+//             }
+//     }
+//     
+//     return false;
+//}
+/**
+ * Subclasses must override as required.
+ *
+ * @see IOpenable
+ */
+public boolean isConsistent() throws JavaModelException {
+       return true;
+}
+/**
+ * 
+ * @see IOpenable
+ */
+public boolean isOpen() {
+       // TODO isOpen - Openable needs JavaModelManager
+//     synchronized(JavaModelManager.getJavaModelManager()){
+//             return JavaModelManager.getJavaModelManager().getInfo(this) != null;
+//     }
+  return false;
+}
+///**
+// * Returns true if this represents a source element.
+// * Openable source elements have an associated buffer created
+// * when they are opened.
+// */
+//protected boolean isSourceElement() {
+//     return false;
+//}
+///**
+// * @see IOpenable
+// */
+//public void makeConsistent(IProgressMonitor pm) throws JavaModelException {
+//     if (!isConsistent()) {
+//             buildStructure((OpenableElementInfo)getElementInfo(), pm);
+//     }
+//}
+///**
+// * @see IOpenable
+// */
+//public void open(IProgressMonitor pm) throws JavaModelException {
+//     if (!isOpen()) {
+//             // TODO: need to synchronize (IOpenable.open(IProgressMonitor) is API
+//             // TODO: could use getElementInfo instead
+//             this.openWhenClosed(pm);
+//     }
+//}
+//
+/**
+ * Opens a buffer on the contents of this element, and returns
+ * the buffer, or returns <code>null</code> if opening fails.
+ * By default, do nothing - subclasses that have buffers
+ * must override as required.
+ */
+protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
+       return null;
+}
+//
+///**
+// *   Open the parent element if necessary
+// * 
+// */
+//protected void openParent(IProgressMonitor pm) throws JavaModelException {
+//
+//     Openable openableParent = (Openable)getOpenableParent();
+//     if (openableParent != null) {
+//             if (!openableParent.isOpen()){
+//                     openableParent.openWhenClosed(pm);
+//             }
+//     }
+//}
+//
+///**
+// * Open an <code>Openable</code> that is known to be closed (no check for <code>isOpen()</code>).
+// */
+//protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
+//     try {
+//             
+//             if (JavaModelManager.VERBOSE){
+//                     System.out.println("OPENING Element ("+ Thread.currentThread()+"): " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
+//             }
+//             
+//             // 1) Parent must be open - open the parent if necessary
+//             openParent(pm);
+//
+//             // 2) create the new element info and open a buffer if needed
+//             OpenableElementInfo info = createElementInfo();
+//             if (isSourceElement()) {
+//                     this.openBuffer(pm);
+//             } 
+//
+//             // 3) build the structure of the openable
+//             buildStructure(info, pm);
+//
+//             // 4) anything special
+//             opening(info);
+//             
+//             if (JavaModelManager.VERBOSE) {
+//                     System.out.println("-> Package cache size = " + JavaModelManager.getJavaModelManager().cache.pkgSize()); //$NON-NLS-1$
+//                     System.out.println("-> Openable cache filling ratio = " + JavaModelManager.getJavaModelManager().cache.openableFillingRatio() + "%"); //$NON-NLS-1$//$NON-NLS-2$
+//             }
+//
+//             // if any problems occuring openning the element, ensure that it's info
+//             // does not remain in the cache (some elements, pre-cache their info
+//             // as they are being opened).
+//     } catch (JavaModelException e) {
+//             JavaModelManager.getJavaModelManager().removeInfo(this);
+//             throw e;
+//     }
+//}
+//
+///**
+// *  Answers true if the parent exists (null parent is answering true)
+// * 
+// */
+//protected boolean parentExists(){
+//     
+//     IJavaElement parent = this.getParent();
+//     if (parent == null) return true;
+//     return parent.exists();
+//}
+//
+///**
+// * Returns whether the corresponding resource or associated file exists
+// */
+//protected boolean resourceExists() {
+//     IWorkspace workspace = ResourcesPlugin.getWorkspace();
+//     if (workspace == null) return false; // workaround for http://bugs.eclipse.org/bugs/show_bug.cgi?id=34069
+//     return 
+//             JavaModel.getTarget(
+//                     workspace.getRoot(), 
+//                     this.getPath().makeRelative(), // ensure path is relative (see http://dev.eclipse.org/bugs/show_bug.cgi?id=22517)
+//                     true) != null;
+//}
+//
+///**
+// * @see IOpenable
+// */
+//public void save(IProgressMonitor pm, boolean force) throws JavaModelException {
+//     if (isReadOnly() || this.getResource().isReadOnly()) {
+//             throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+//     }
+//     IBuffer buf = getBuffer();
+//     if (buf != null) { // some Openables (like a JavaProject) don't have a buffer
+//             buf.save(pm, force);
+//             this.makeConsistent(pm); // update the element info of this element
+//     }
+//}
+//
+/**
+ * Find enclosing package fragment root if any
+ */
+public PackageFragmentRoot getPackageFragmentRoot() {
+       IJavaElement current = this;
+       do {
+               if (current instanceof PackageFragmentRoot) return (PackageFragmentRoot)current;
+               current = current.getParent();
+       } while(current != null);
+       return null;
+}
+///**
+// * @see ICodeAssist
+// * @deprecated - use codeComplete(ICompilationUnit, ICompilationUnit, int, ICompletionRequestor) instead
+// */
+//protected void codeComplete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip, int position, final ICodeCompletionRequestor requestor) throws JavaModelException {
+//
+//     if (requestor == null){
+//             codeComplete(cu, unitToSkip, position, (ICompletionRequestor)null);
+//             return;
+//     }
+//     codeComplete(
+//             cu,
+//             unitToSkip,
+//             position,
+//             new ICompletionRequestor(){
+//                     public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+//                     }
+//                     public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+//                             requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptError(IProblem error) {
+//                             if (true) return; // was disabled in 1.0
+//
+//                             try {
+//                                     IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
+//                                     marker.setAttribute(IJavaModelMarker.ID, error.getID());
+//                                     marker.setAttribute(IMarker.CHAR_START, error.getSourceStart());
+//                                     marker.setAttribute(IMarker.CHAR_END, error.getSourceEnd() + 1);
+//                                     marker.setAttribute(IMarker.LINE_NUMBER, error.getSourceLineNumber());
+//                                     marker.setAttribute(IMarker.MESSAGE, error.getMessage());
+//                                     marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+//                                     requestor.acceptError(marker);
+//                             } catch(CoreException e){
+//                             }
+//                     }
+//                     public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+//                             requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+//                             requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptKeyword(keywordName, completionStart, completionEnd);
+//                     }
+//                     public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptLabel(labelName, completionStart, completionEnd);
+//                     }
+//                     public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                             // ignore
+//                     }
+//                     public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                             // skip parameter names
+//                             requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
+//                     }
+//                     public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+//                             // ignore
+//                     }
+//                     public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptModifier(modifierName, completionStart, completionEnd);
+//                     }
+//                     public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
+//                     }
+//                     public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
+//                             requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
+//                     }
+//                     public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int completionEnd, int relevance){
+//                             // ignore
+//                     }
+//             });
+//}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragment.java
new file mode 100644 (file)
index 0000000..2b559f5
--- /dev/null
@@ -0,0 +1,366 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.JavaModelException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+
+/**
+ * @see IPackageFragment
+ */
+public class PackageFragment extends Openable implements IPackageFragment {
+               /**
+        * Constant empty list of compilation units
+        */
+       protected static ICompilationUnit[] fgEmptyCompilationUnitList= new ICompilationUnit[] {};
+/**
+ * Constructs a handle for a package fragment
+ *
+ * @see IPackageFragment
+ */
+protected PackageFragment(IPackageFragmentRoot root, String name) {
+       super(PACKAGE_FRAGMENT, null, name);
+}
+/**
+ * Compute the children of this package fragment.
+ *
+ * <p>Package fragments which are folders recognize files based on the
+ * type of the fragment
+ * <p>Package fragments which are in a jar only recognize .class files (
+ * @see JarPackageFragment).
+ */
+//protected boolean computeChildren(OpenableElementInfo info, IResource resource) throws JavaModelException {
+//     ArrayList vChildren = new ArrayList();
+//     int kind = getKind();
+//     String extType;
+//     if (kind == IPackageFragmentRoot.K_SOURCE) {
+//             extType = "java"; //$NON-NLS-1$
+//     } else {
+//             extType = "class"; //$NON-NLS-1$
+//     }
+//     try {
+//             char[][] exclusionPatterns = ((PackageFragmentRoot)getPackageFragmentRoot()).fullExclusionPatternChars();
+//             IResource[] members = ((IContainer) resource).members();
+//             for (int i = 0, max = members.length; i < max; i++) {
+//                     IResource child = members[i];
+//                     if (child.getType() != IResource.FOLDER
+//                                     && !Util.isExcluded(child, exclusionPatterns)) {
+//                             String extension = child.getProjectRelativePath().getFileExtension();
+//                             if (extension != null) {
+//                                     if (extension.equalsIgnoreCase(extType)) {
+//                                             IJavaElement childElement;
+//                                             if (kind == IPackageFragmentRoot.K_SOURCE && Util.isValidCompilationUnitName(child.getName())) {
+//                                                     childElement = getCompilationUnit(child.getName());
+//                                                     vChildren.add(childElement);
+//                                             } else if (Util.isValidClassFileName(child.getName())) {
+//                                                     childElement = getClassFile(child.getName());
+//                                                     vChildren.add(childElement);
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             }
+//     } catch (CoreException e) {
+//             throw new JavaModelException(e);
+//     }
+//     IJavaElement[] children = new IJavaElement[vChildren.size()];
+//     vChildren.toArray(children);
+//     info.setChildren(children);
+//     return true;
+//}
+/**
+ * Returns true if this fragment contains at least one java resource.
+ * Returns false otherwise.
+ */
+//public boolean containsJavaResources() throws JavaModelException {
+//     return ((PackageFragmentInfo) getElementInfo()).containsJavaResources();
+//}
+/**
+ * @see ISourceManipulation
+ */
+//public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (container == null) {
+//             throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+//     }
+//     IJavaElement[] elements= new IJavaElement[] {this};
+//     IJavaElement[] containers= new IJavaElement[] {container};
+//     IJavaElement[] siblings= null;
+//     if (sibling != null) {
+//             siblings= new IJavaElement[] {sibling};
+//     }
+//     String[] renamings= null;
+//     if (rename != null) {
+//             renamings= new String[] {rename};
+//     }
+//     getJavaModel().copy(elements, containers, siblings, renamings, force, monitor);
+//}
+/**
+ * @see IPackageFragment
+ */
+public ICompilationUnit createCompilationUnit(String name, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     CreateCompilationUnitOperation op= new CreateCompilationUnitOperation(this, name, contents, force);
+//     runOperation(op, monitor);
+//     return getCompilationUnit(name);
+    return null;
+}
+/**
+ * @see JavaElement
+ */
+//protected OpenableElementInfo createElementInfo() {
+//     return new PackageFragmentInfo();
+//}
+/**
+ * @see ISourceManipulation
+ */
+//public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     IJavaElement[] elements = new IJavaElement[] {this};
+//     getJavaModel().delete(elements, force, monitor);
+//}
+/**
+ * @see Openable
+ */
+//protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+//     
+//     return computeChildren(info, underlyingResource);
+//}
+///**
+// * @see IPackageFragment#getClassFile(String)
+// */
+//public IClassFile getClassFile(String name) {
+//     return new ClassFile(this, name);
+//}
+/**
+ * Returns a the collection of class files in this - a folder package fragment which has a root
+ * that has its kind set to <code>IPackageFragmentRoot.K_Source</code> does not
+ * recognize class files.
+ *
+ * @see IPackageFragment#getClassFiles()
+ */
+//public IClassFile[] getClassFiles() throws JavaModelException {
+//     if (getKind() == IPackageFragmentRoot.K_SOURCE) {
+//             return fgEmptyClassFileList;
+//     }
+//     
+//     ArrayList list = getChildrenOfType(CLASS_FILE);
+//     IClassFile[] array= new IClassFile[list.size()];
+//     list.toArray(array);
+//     return array;
+//}
+/**
+ * @see IPackageFragment#getCompilationUnit(String)
+ */
+public ICompilationUnit getCompilationUnit(String name) {
+       return new CompilationUnit(this, name);
+}
+/**
+ * @see IPackageFragment#getCompilationUnits()
+ */
+//public ICompilationUnit[] getCompilationUnits() throws JavaModelException {
+//     if (getKind() == IPackageFragmentRoot.K_BINARY) {
+//             return fgEmptyCompilationUnitList;
+//     }
+//     
+//     ArrayList list = getChildrenOfType(COMPILATION_UNIT);
+//     ICompilationUnit[] array= new ICompilationUnit[list.size()];
+//     list.toArray(array);
+//     return array;
+//}
+/**
+ * @see JavaElement#getHandleMementoDelimiter()
+ */
+protected char getHandleMementoDelimiter() {
+       return JavaElement.JEM_PACKAGEFRAGMENT;
+}
+/**
+ * @see IPackageFragment#getKind()
+ */
+//public int getKind() throws JavaModelException {
+//     return ((IPackageFragmentRoot)getParent()).getKind();
+//}
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+//public Object[] getNonJavaResources() throws JavaModelException {
+//     if (this.isDefaultPackage()) {
+//             // We don't want to show non java resources of the default package (see PR #1G58NB8)
+//             return JavaElementInfo.NO_NON_JAVA_RESOURCES;
+//     } else {
+//             return ((PackageFragmentInfo) getElementInfo()).getNonJavaResources(getResource(), (PackageFragmentRoot)getPackageFragmentRoot());
+//     }
+//}
+/**
+ * @see IJavaElement#getPath()
+ */
+//public IPath getPath() {
+//     PackageFragmentRoot root = this.getPackageFragmentRoot();
+//     if (root.isArchive()) {
+//             return root.getPath();
+//     } else {
+//             return root.getPath().append(this.getElementName().replace('.', '/'));
+//     }
+//}
+/**
+ * @see IJavaElement#getResource()
+ */
+public IResource getResource() {
+       PackageFragmentRoot root = this.getPackageFragmentRoot();
+       if (root.isArchive()) {
+               return root.getResource();
+       } else {
+               String elementName = this.getElementName();
+               if (elementName.length() == 0) {
+                       return root.getResource();
+               } else {
+                       return ((IContainer)root.getResource()).getFolder(new Path(this.getElementName().replace('.', '/')));
+               }
+       }
+}
+/**
+ * @see IJavaElement#getUnderlyingResource()
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+       IResource rootResource = fParent.getUnderlyingResource();
+       if (rootResource == null) {
+               //jar package fragment root that has no associated resource
+               return null;
+       }
+       // the underlying resource may be a folder or a project (in the case that the project folder
+       // is atually the package fragment root)
+//     if (rootResource.getType() == IResource.FOLDER || rootResource.getType() == IResource.PROJECT) {
+//             IContainer folder = (IContainer) rootResource;
+//             String[] segs = Signature.getSimpleNames(fName);
+//             for (int i = 0; i < segs.length; ++i) {
+//                     IResource child = folder.findMember(segs[i]);
+//                     if (child == null || child.getType() != IResource.FOLDER) {
+//                             throw newNotPresentException();
+//                     }
+//                     folder = (IFolder) child;
+//             }
+//             return folder;
+//     } else {
+               return rootResource;
+//     }
+}
+/**
+ * @see IPackageFragment#hasSubpackages()
+ */
+//public boolean hasSubpackages() throws JavaModelException {
+//     IJavaElement[] packages= ((IPackageFragmentRoot)getParent()).getChildren();
+//     String name = getElementName();
+//     int nameLength = name.length();
+//     String packageName = isDefaultPackage() ? name : name+"."; //$NON-NLS-1$
+//     for (int i= 0; i < packages.length; i++) {
+//             String otherName = packages[i].getElementName();
+//             if (otherName.length() > nameLength && otherName.startsWith(packageName)) {
+//                     return true;
+//             }
+//     }
+//     return false;
+//}
+/**
+ * @see IPackageFragment#isDefaultPackage()
+ */
+public boolean isDefaultPackage() {
+       return this.getElementName().length() == 0;
+}
+/**
+ * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
+ */
+//public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (container == null) {
+//             throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+//     }
+//     IJavaElement[] elements= new IJavaElement[] {this};
+//     IJavaElement[] containers= new IJavaElement[] {container};
+//     IJavaElement[] siblings= null;
+//     if (sibling != null) {
+//             siblings= new IJavaElement[] {sibling};
+//     }
+//     String[] renamings= null;
+//     if (rename != null) {
+//             renamings= new String[] {rename};
+//     }
+//     getJavaModel().move(elements, containers, siblings, renamings, force, monitor);
+//}
+//protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
+//     if (!this.resourceExists()) throw newNotPresentException();
+//     super.openWhenClosed(pm);
+//}
+/**
+ * Recomputes the children of this element, based on the current state
+ * of the workbench.
+ */
+//public void refreshChildren() {
+//     try {
+//             OpenableElementInfo info= (OpenableElementInfo)getElementInfo();
+//             computeChildren(info, getResource());
+//     } catch (JavaModelException e) {
+//             // do nothing.
+//     }
+//}
+/**
+ * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
+ */
+//public void rename(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     if (name == null) {
+//             throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+//     }
+//     IJavaElement[] elements= new IJavaElement[] {this};
+//     IJavaElement[] dests= new IJavaElement[] {this.getParent()};
+//     String[] renamings= new String[] {name};
+//     getJavaModel().rename(elements, dests, renamings, force, monitor);
+//}
+/*
+ * @see JavaElement#rootedAt(IJavaProject)
+ */
+public IJavaElement rootedAt(IJavaProject project) {
+       return
+               new PackageFragment(
+                       (IPackageFragmentRoot)((JavaElement)fParent).rootedAt(project), 
+                       fName);
+}
+/**
+ * Debugging purposes
+ */
+protected void toStringChildren(int tab, StringBuffer buffer, Object info) {
+       if (tab == 0) {
+               super.toStringChildren(tab, buffer, info);
+       }
+}
+/**
+ * Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+       buffer.append(this.tabString(tab));
+       if (getElementName().length() == 0) {
+               buffer.append("[default]"); //$NON-NLS-1$
+       } else {
+               buffer.append(getElementName());
+       }
+       if (info == null) {
+               buffer.append(" (not open)"); //$NON-NLS-1$
+       } else {
+               if (tab > 0) {
+                       buffer.append(" (...)"); //$NON-NLS-1$
+               }
+       }
+}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/PackageFragmentRoot.java
new file mode 100644 (file)
index 0000000..cf729bb
--- /dev/null
@@ -0,0 +1,838 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.QualifiedName;
+
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public class PackageFragmentRoot extends Openable implements IPackageFragmentRoot {
+
+       /**
+        * The delimiter between the source path and root path in the
+        * attachment server property.
+        */
+       protected final static char ATTACHMENT_PROPERTY_DELIMITER= '*';
+       /*
+        * No source attachment property
+        */
+       protected final static String NO_SOURCE_ATTACHMENT = ""; //$NON-NLS-1$
+       /*
+        * No source mapper singleton
+        */
+//     protected final static SourceMapper NO_SOURCE_MAPPER = new SourceMapper();
+
+       /**
+        * The resource associated with this root.
+        * (an IResource or a java.io.File (for external jar only))
+        */
+       protected Object resource;
+       
+/**
+ * Constructs a package fragment root which is the root of the java package
+ * directory hierarchy.
+ */
+protected PackageFragmentRoot(IResource resource, IJavaProject project, String name) {
+       super(PACKAGE_FRAGMENT_ROOT, project, name);
+       this.resource = resource;
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+//public void attachSource(IPath sourcePath, IPath rootPath, IProgressMonitor monitor) throws JavaModelException {
+//     try {
+//             verifyAttachSource(sourcePath);
+//             if (monitor != null) {
+//                     monitor.beginTask(Util.bind("element.attachingSource"), 2); //$NON-NLS-1$
+//             }
+//             SourceMapper oldMapper= getSourceMapper();
+//             IWorkspace workspace = ResourcesPlugin.getWorkspace();
+//             boolean rootNeedsToBeClosed= false;
+//
+//             if (sourcePath == null) {
+//                     //source being detached
+//                     rootNeedsToBeClosed= true;
+//                     setSourceMapper(null);
+//             /* Disable deltas (see 1GDTUSD)
+//                     // fire a delta to notify the UI about the source detachement.
+//                     JavaModelManager manager = (JavaModelManager) JavaModelManager.getJavaModelManager();
+//                     JavaModel model = (JavaModel) getJavaModel();
+//                     JavaElementDelta attachedSourceDelta = new JavaElementDelta(model);
+//                     attachedSourceDelta .sourceDetached(this); // this would be a PackageFragmentRoot
+//                     manager.registerResourceDelta(attachedSourceDelta );
+//                     manager.fire(); // maybe you want to fire the change later. Let us know about it.
+//             */
+//             } else {
+//             /*
+//                     // fire a delta to notify the UI about the source attachement.
+//                     JavaModelManager manager = (JavaModelManager) JavaModelManager.getJavaModelManager();
+//                     JavaModel model = (JavaModel) getJavaModel();
+//                     JavaElementDelta attachedSourceDelta = new JavaElementDelta(model);
+//                     attachedSourceDelta .sourceAttached(this); // this would be a PackageFragmentRoot
+//                     manager.registerResourceDelta(attachedSourceDelta );
+//                     manager.fire(); // maybe you want to fire the change later. Let us know about it.
+//              */
+//
+//                     //check if different from the current attachment
+//                     IPath storedSourcePath= getSourceAttachmentPath();
+//                     IPath storedRootPath= getSourceAttachmentRootPath();
+//                     if (monitor != null) {
+//                             monitor.worked(1);
+//                     }
+//                     if (storedSourcePath != null) {
+//                             if (!(storedSourcePath.equals(sourcePath) && (rootPath != null && rootPath.equals(storedRootPath)) || storedRootPath == null)) {
+//                                     rootNeedsToBeClosed= true;
+//                             }
+//                     }
+//                     // check if source path is valid
+//                     Object target = JavaModel.getTarget(workspace.getRoot(), sourcePath, false);
+//                     if (target == null) {
+//                             if (monitor != null) {
+//                                     monitor.done();
+//                             }
+//                             throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, sourcePath));
+//                     }
+//                     SourceMapper mapper = createSourceMapper(sourcePath, rootPath);
+//                     if (rootPath == null && mapper.rootPath != null) {
+//                             // as a side effect of calling the SourceMapper constructor, the root path was computed
+//                             rootPath = new Path(mapper.rootPath);
+//                     }
+//                     setSourceMapper(mapper);
+//             }
+//             if (sourcePath == null) {
+//                     setSourceAttachmentProperty(null); //remove the property
+//             } else {
+//                     //set the property to the path of the mapped source
+//                     setSourceAttachmentProperty(
+//                             sourcePath.toString() 
+//                             + (rootPath == null ? "" : (ATTACHMENT_PROPERTY_DELIMITER + rootPath.toString()))); //$NON-NLS-1$
+//             }
+//             if (rootNeedsToBeClosed) {
+//                     if (oldMapper != null) {
+//                             oldMapper.close();
+//                     }
+//                     BufferManager manager= BufferManager.getDefaultBufferManager();
+//                     Enumeration openBuffers= manager.getOpenBuffers();
+//                     while (openBuffers.hasMoreElements()) {
+//                             IBuffer buffer= (IBuffer) openBuffers.nextElement();
+//                             IOpenable possibleMember= buffer.getOwner();
+//                             if (isAncestorOf((IJavaElement) possibleMember)) {
+//                                     buffer.close();
+//                             }
+//                     }
+//                     if (monitor != null) {
+//                             monitor.worked(1);
+//                     }
+//             }
+//     } catch (JavaModelException e) {
+//             setSourceAttachmentProperty(null); // loose info - will be recomputed
+//             throw e;
+//     } finally {
+//             if (monitor != null) {
+//                     monitor.done();
+//             }
+//     }
+//}
+
+//SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) {
+//     SourceMapper mapper = new SourceMapper(
+//             sourcePath, 
+//             rootPath == null ? null : rootPath.toOSString(), 
+//             this.isExternal() ? JavaCore.getOptions() : this.getJavaProject().getOptions(true)); // only project options if associated with resource
+//     return mapper;
+//}
+/*
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot#delete
+ */
+//public void delete(
+//     int updateResourceFlags,
+//     int updateModelFlags,
+//     IProgressMonitor monitor)
+//     throws JavaModelException {
+//
+//     DeletePackageFragmentRootOperation op = new DeletePackageFragmentRootOperation(this, updateResourceFlags, updateModelFlags);
+//     runOperation(op, monitor);
+//}
+
+/**
+ * This root is being closed.  If this root has an associated source attachment, 
+ * close it too.
+ *
+ * @see JavaElement
+ */
+//protected void closing(Object info) throws JavaModelException { TODO remove after 2.1
+//     ((PackageFragmentRootInfo) info).sourceMapper = null;
+//     super.closing(info);
+//}
+/**
+ * Compute the package fragment children of this package fragment root.
+ * 
+ * @exception JavaModelException  The resource associated with this package fragment root does not exist
+ */
+//protected boolean computeChildren(OpenableElementInfo info) throws JavaModelException {
+//     try {
+//             // the underlying resource may be a folder or a project (in the case that the project folder
+//             // is actually the package fragment root)
+//             IResource resource = getResource();
+//             if (resource.getType() == IResource.FOLDER || resource.getType() == IResource.PROJECT) {
+//                     ArrayList vChildren = new ArrayList(5);
+//                     char[][] exclusionPatterns = fullExclusionPatternChars();
+//                     computeFolderChildren((IContainer) resource, "", vChildren, exclusionPatterns); //$NON-NLS-1$
+//                     IJavaElement[] children = new IJavaElement[vChildren.size()];
+//                     vChildren.toArray(children);
+//                     info.setChildren(children);
+//             }
+//     } catch (JavaModelException e) {
+//             //problem resolving children; structure remains unknown
+//             info.setChildren(new IJavaElement[]{});
+//             throw e;
+//     }
+//     return true;
+//}
+
+/**
+ * Starting at this folder, create package fragments and add the fragments that are not exclused
+ * to the collection of children.
+ * 
+ * @exception JavaModelException  The resource associated with this package fragment does not exist
+ */
+//protected void computeFolderChildren(IContainer folder, String prefix, ArrayList vChildren, char[][] exclusionPatterns) throws JavaModelException {
+//     IPackageFragment pkg = getPackageFragment(prefix);
+//     vChildren.add(pkg);
+//     try {
+//             JavaProject javaProject = (JavaProject)getJavaProject();
+//             IResource[] members = folder.members();
+//             for (int i = 0, max = members.length; i < max; i++) {
+//                     IResource member = members[i];
+//                     String memberName = member.getName();
+//                     if (member.getType() == IResource.FOLDER 
+//                             && Util.isValidFolderNameForPackage(memberName)
+//                             && !Util.isExcluded(member, exclusionPatterns)) {
+//                                     
+//                             // eliminate binary output only if nested inside direct subfolders
+//                             if (javaProject.contains(member)) {
+//                                     String newPrefix;
+//                                     if (prefix.length() == 0) {
+//                                             newPrefix = memberName;
+//                                     } else {
+//                                             newPrefix = prefix + "." + memberName; //$NON-NLS-1$
+//                                     }
+//                                     computeFolderChildren((IFolder) member, newPrefix, vChildren, exclusionPatterns);
+//                             }
+//                     }
+//             }
+//     } catch(IllegalArgumentException e){
+//             throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); // could be thrown by ElementTree when path is not found
+//     } catch (CoreException e) {
+//             throw new JavaModelException(e);
+//     }
+//}
+/*
+ * Computes and returns the source attachment root path for the given source attachment path.
+ * Returns <code>null</code> if none could be found.
+ * 
+ * @param sourceAttachmentPath the given absolute path to the source archive or folder
+ * @return the computed source attachment root path or <code>null</cde> if none could be found
+ * @throws JavaModelException
+ */
+//public IPath computeSourceAttachmentRootPath(IPath sourceAttachmentPath) throws JavaModelException {
+//     IPath sourcePath = this.getSourceAttachmentPath();
+//     if (sourcePath == null) return null;
+//     SourceMapper mapper = 
+//             new SourceMapper(
+//             sourcePath, 
+//             null, // detect root path
+//             this.isExternal() ? JavaCore.getOptions() : this.getJavaProject().getOptions(true) // only project options if associated with resource
+//     );
+//     if (mapper.rootPath == null) return null;
+//     return new Path(mapper.rootPath);
+//}
+/*
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot#copy
+ */
+//public void copy(
+//     IPath destination,
+//     int updateResourceFlags,
+//     int updateModelFlags,
+//     IClasspathEntry sibling,
+//     IProgressMonitor monitor)
+//     throws JavaModelException {
+//             
+//     CopyPackageFragmentRootOperation op = 
+//             new CopyPackageFragmentRootOperation(this, destination, updateResourceFlags, updateModelFlags, sibling);
+//     runOperation(op, monitor);
+//}
+
+
+
+/**
+ * Returns a new element info for this element.
+ */
+//protected OpenableElementInfo createElementInfo() {
+//     return new PackageFragmentRootInfo();
+//}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+//public IPackageFragment createPackageFragment(String name, boolean force, IProgressMonitor monitor) throws JavaModelException {
+//     CreatePackageFragmentOperation op = new CreatePackageFragmentOperation(this, name, force);
+//     runOperation(op, monitor);
+//     return getPackageFragment(name);
+//}
+
+/**
+ * Returns the root's kind - K_SOURCE or K_BINARY, defaults
+ * to K_SOURCE if it is not on the classpath.
+ *
+ * @exception NotPresentException if the project and root do
+ *             not exist.
+ */
+//protected int determineKind(IResource underlyingResource) throws JavaModelException {
+//     IClasspathEntry[] entries= ((JavaProject)getJavaProject()).getExpandedClasspath(true);
+//     for (int i= 0; i < entries.length; i++) {
+//             IClasspathEntry entry= entries[i];
+//             if (entry.getPath().equals(underlyingResource.getFullPath())) {
+//                     return entry.getContentKind();
+//             }
+//     }
+//     return IPackageFragmentRoot.K_SOURCE;
+//}
+
+/**
+ * Compares two objects for equality;
+ * for <code>PackageFragmentRoot</code>s, equality is having the
+ * same <code>JavaModel</code>, same resources, and occurrence count.
+ *
+ */
+public boolean equals(Object o) {
+       if (this == o)
+               return true;
+       if (!(o instanceof PackageFragmentRoot))
+               return false;
+       PackageFragmentRoot other = (PackageFragmentRoot) o;
+       return getJavaModel().equals(other.getJavaModel()) && 
+                       this.resource.equals(other.resource) &&
+                       fOccurrenceCount == other.fOccurrenceCount;
+}
+
+/**
+ * @see IJavaElement
+ */
+//public boolean exists() {
+//     return super.exists() 
+//                             && isOnClasspath();
+//}
+
+//public IClasspathEntry findSourceAttachmentRecommendation() {
+//     try {
+//             IPath rootPath = this.getPath();
+//             IClasspathEntry entry;
+//             IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+//             
+//             // try on enclosing project first
+//             JavaProject parentProject = (JavaProject) getJavaProject();
+//             try {
+//                     entry = parentProject.getClasspathEntryFor(rootPath);
+//                     if (entry != null){
+//                             Object target = JavaModel.getTarget(workspaceRoot, entry.getSourceAttachmentPath(), true);
+//                             if (target instanceof IFile){
+//                                     IFile file = (IFile) target;
+//                                     if (Util.isArchiveFileName(file.getName())){
+//                                             return entry;
+//                                     }
+//                             } else if (target instanceof IFolder) {
+//                                     return entry;
+//                             }
+//                             if (target instanceof java.io.File){
+//                                     java.io.File file = (java.io.File) target;
+//                                     if (file.isFile()) {
+//                                             if (Util.isArchiveFileName(file.getName())){
+//                                                     return entry;
+//                                             }
+//                                     } else {
+//                                             // external directory
+//                                             return entry;
+//                                     }
+//                             }
+//                     }
+//             } catch(JavaModelException e){
+//             }
+//             
+//             // iterate over all projects
+//             IJavaModel model = getJavaModel();
+//             IJavaProject[] jProjects = model.getJavaProjects();
+//             for (int i = 0, max = jProjects.length; i < max; i++){
+//                     JavaProject jProject = (JavaProject) jProjects[i];
+//                     if (jProject == parentProject) continue; // already done
+//                     try {
+//                             entry = jProject.getClasspathEntryFor(rootPath);
+//                             if (entry != null){
+//                                     Object target = JavaModel.getTarget(workspaceRoot, entry.getSourceAttachmentPath(), true);
+//                                     if (target instanceof IFile){
+//                                             IFile file = (IFile) target;
+//                                             if (Util.isArchiveFileName(file.getName())){
+//                                                     return entry;
+//                                             }
+//                                     } else if (target instanceof IFolder) {
+//                                             return entry;
+//                                     }
+//                                     if (target instanceof java.io.File){
+//                                             java.io.File file = (java.io.File) target;
+//                                             if (file.isFile()) {
+//                                                     if (Util.isArchiveFileName(file.getName())){
+//                                                             return entry;
+//                                                     }
+//                                             } else {
+//                                                     // external directory
+//                                                     return entry;
+//                                             }
+//                                     }
+//                             }
+//                     } catch(JavaModelException e){
+//                     }
+//             }
+//     } catch(JavaModelException e){
+//     }
+//
+//     return null;
+//}
+
+/*
+ * Returns the exclusion patterns from the classpath entry associated with this root.
+ */
+//char[][] fullExclusionPatternChars() {
+//     try {
+//             if (this.isOpen() && this.getKind() != IPackageFragmentRoot.K_SOURCE) return null;
+//             ClasspathEntry entry = (ClasspathEntry)getRawClasspathEntry();
+//             if (entry == null) {
+//                     return null;
+//             } else {
+//                     return entry.fullExclusionPatternChars();
+//             }
+//     } catch (JavaModelException e) { 
+//             return null;
+//     }
+//}            
+
+/**
+ * @see Openable
+ */
+//protected boolean generateInfos(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+//     
+//     ((PackageFragmentRootInfo) info).setRootKind(determineKind(underlyingResource));
+//     return computeChildren(info);
+//}
+
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+       return JavaElement.JEM_PACKAGEFRAGMENTROOT;
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+public String getHandleMemento(){
+       IPath path;
+       IResource resource = getResource();
+       if (resource != null) {
+               // internal jar or regular root
+               if (getResource().getProject().equals(getJavaProject().getProject())) {
+                       path = resource.getProjectRelativePath();
+               } else {
+                       path = resource.getFullPath();
+               }
+       } else {
+               // external jar
+               path = getPath();
+       }
+       StringBuffer buff= new StringBuffer(((JavaElement)getParent()).getHandleMemento());
+       buff.append(getHandleMementoDelimiter());
+       buff.append(path.toString()); 
+       return buff.toString();
+}
+/**
+ * @see IPackageFragmentRoot
+ */
+//public int getKind() throws JavaModelException {
+//     return ((PackageFragmentRootInfo)getElementInfo()).getRootKind();
+//}
+
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+//public Object[] getNonJavaResources() throws JavaModelException {
+//     return ((PackageFragmentRootInfo) getElementInfo()).getNonJavaResources(getJavaProject(), getResource(), this);
+//}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public IPackageFragment getPackageFragment(String packageName) {
+       if (packageName.indexOf(' ') != -1) { // tolerate package names with spaces (e.g. 'x . y') (http://bugs.eclipse.org/bugs/show_bug.cgi?id=21957)
+               char[][] compoundName = Util.toCompoundChars(packageName);
+               StringBuffer buffer = new StringBuffer(packageName.length());
+               for (int i = 0, length = compoundName.length; i < length; i++) {
+                       buffer.append(CharOperation.trim(compoundName[i]));
+                       if (i != length-1) {
+                               buffer.append('.');
+                       }
+               }
+               packageName = buffer.toString();
+       }
+       return new PackageFragment(this, packageName);
+}
+
+/**
+ * Returns the package name for the given folder
+ * (which is a decendent of this root).
+ */
+protected String getPackageName(IFolder folder) throws JavaModelException {
+       IPath myPath= getPath();
+       IPath pkgPath= folder.getFullPath();
+       int mySegmentCount= myPath.segmentCount();
+       int pkgSegmentCount= pkgPath.segmentCount();
+       StringBuffer name = new StringBuffer(IPackageFragment.DEFAULT_PACKAGE_NAME);
+       for (int i= mySegmentCount; i < pkgSegmentCount; i++) {
+               if (i > mySegmentCount) {
+                       name.append('.');
+               }
+               name.append(pkgPath.segment(i));
+       }
+       return name.toString();
+}
+
+/**
+ * @see IJavaElement
+ */
+public IPath getPath() {
+       return getResource().getFullPath();
+}
+
+/*
+ * @see IPackageFragmentRoot 
+ */
+//public IClasspathEntry getRawClasspathEntry() throws JavaModelException {
+//
+//     IClasspathEntry rawEntry = null;
+//     IJavaProject project = this.getJavaProject();
+//     project.getResolvedClasspath(true); // force the reverse rawEntry cache to be populated
+//     JavaModelManager.PerProjectInfo perProjectInfo = 
+//             JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(project.getProject());
+//     if (perProjectInfo != null && perProjectInfo.resolvedPathToRawEntries != null) {
+//             rawEntry = (IClasspathEntry) perProjectInfo.resolvedPathToRawEntries.get(this.getPath());
+//     }
+//     return rawEntry;
+//}
+
+/*
+ * @see IJavaElement
+ */
+public IResource getResource() {
+       return (IResource)this.resource;
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+//public IPath getSourceAttachmentPath() throws JavaModelException {
+//     if (getKind() != K_BINARY) return null;
+//     
+//     String serverPathString= getSourceAttachmentProperty();
+//     if (serverPathString == null) {
+//             return null;
+//     }
+//     int index= serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER);
+//     if (index < 0) {
+//             // no root path specified
+//             return new Path(serverPathString);
+//     } else {
+//             String serverSourcePathString= serverPathString.substring(0, index);
+//             return new Path(serverSourcePathString);
+//     }
+//}
+
+/**
+ * Returns the server property for this package fragment root's
+ * source attachement.
+ */
+//protected String getSourceAttachmentProperty() throws JavaModelException {
+//     String propertyString = null;
+//     QualifiedName qName= getSourceAttachmentPropertyName();
+//     try {
+//             propertyString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
+//             
+//             // if no existing source attachment information, then lookup a recommendation from classpath entries
+//             if (propertyString == null) {
+//                     IClasspathEntry recommendation = findSourceAttachmentRecommendation();
+//                     if (recommendation != null) {
+//                             IPath rootPath = recommendation.getSourceAttachmentRootPath();
+//                             propertyString = 
+//                                     recommendation.getSourceAttachmentPath().toString() 
+//                                             + ((rootPath == null) 
+//                                                     ? "" : //$NON-NLS-1$
+//                                                     (ATTACHMENT_PROPERTY_DELIMITER + rootPath.toString())); 
+//                             setSourceAttachmentProperty(propertyString);
+//                     } else {
+//                             // mark as being already looked up
+//                             setSourceAttachmentProperty(NO_SOURCE_ATTACHMENT);
+//                     }
+//             } else if (NO_SOURCE_ATTACHMENT.equals(propertyString)) {
+//                     // already looked up and no source attachment found
+//                     return null;
+//             }
+//             return propertyString;
+//     } catch (CoreException ce) {
+//             throw new JavaModelException(ce);
+//     }
+//}
+       
+/**
+ * Returns the qualified name for the source attachment property
+ * of this root.
+ */
+protected QualifiedName getSourceAttachmentPropertyName() throws JavaModelException {
+       return new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + this.getPath().toOSString()); //$NON-NLS-1$
+}
+
+public void setSourceAttachmentProperty(String property) {
+       try {
+               ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(this.getSourceAttachmentPropertyName(), property);
+       } catch (CoreException ce) {
+       }
+}
+
+/**
+ * For use by <code>AttachSourceOperation</code> only.
+ * Sets the source mapper associated with this root.
+ */
+//public void setSourceMapper(SourceMapper mapper) throws JavaModelException {
+//     ((PackageFragmentRootInfo) getElementInfo()).setSourceMapper(mapper);
+//}
+
+
+
+/**
+ * @see IPackageFragmentRoot
+ */
+//public IPath getSourceAttachmentRootPath() throws JavaModelException {
+//     if (getKind() != K_BINARY) return null;
+//     
+//     String serverPathString= getSourceAttachmentProperty();
+//     if (serverPathString == null) {
+//             return null;
+//     }
+//     int index = serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER);
+//     if (index == -1) return null;
+//     String serverRootPathString= IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
+//     if (index != serverPathString.length() - 1) {
+//             serverRootPathString= serverPathString.substring(index + 1);
+//     }
+//     return new Path(serverRootPathString);
+//}
+
+/**
+ * @see JavaElement
+ */
+//public SourceMapper getSourceMapper() {
+//     SourceMapper mapper;
+//     try {
+//             PackageFragmentRootInfo rootInfo = (PackageFragmentRootInfo) getElementInfo();
+//             mapper = rootInfo.getSourceMapper();
+//             if (mapper == null) {
+//                     // first call to this method
+//                     IPath sourcePath= getSourceAttachmentPath();
+//                     if (sourcePath != null) {
+//                             IPath rootPath= getSourceAttachmentRootPath();
+//                             mapper = this.createSourceMapper(sourcePath, rootPath);
+//                             if (rootPath == null && mapper.rootPath != null) {
+//                                     // as a side effect of calling the SourceMapper constructor, the root path was computed
+//                                     rootPath = new Path(mapper.rootPath);
+//                                     
+//                                     //set the property to the path of the mapped source
+//                                     this.setSourceAttachmentProperty(
+//                                             sourcePath.toString() 
+//                                             + ATTACHMENT_PROPERTY_DELIMITER 
+//                                             + rootPath.toString());
+//                             }
+//                             rootInfo.setSourceMapper(mapper);
+//                     } else {
+//                             // remember that no source is attached
+//                             rootInfo.setSourceMapper(NO_SOURCE_MAPPER);
+//                             mapper = null;
+//                     }
+//             } else if (mapper == NO_SOURCE_MAPPER) {
+//                     // a previous call to this method found out that no source was attached
+//                     mapper = null;
+//             }
+//     } catch (JavaModelException e) {
+//             // no source can be attached
+//             mapper = null;
+//     }
+//     return mapper;
+//}
+
+/**
+ * @see IJavaElement
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+       if (!exists()) throw newNotPresentException();
+       return getResource();
+}
+
+public int hashCode() {
+       return this.resource.hashCode();
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public boolean isArchive() {
+       return false;
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public boolean isExternal() {
+       return false;
+}
+
+/*
+ * Returns whether this package fragment root is on the classpath of its project.
+ */
+//protected boolean isOnClasspath() {
+//     if (this.getElementType() == IJavaElement.JAVA_PROJECT){
+//             return true;
+//     }
+//     
+//     IPath path = this.getPath();
+//     try {
+//             // check package fragment root on classpath of its project
+//             IJavaProject project = this.getJavaProject();
+//             IClasspathEntry[] classpath = project.getResolvedClasspath(true);       
+//             for (int i = 0, length = classpath.length; i < length; i++) {
+//                     IClasspathEntry entry = classpath[i];
+//                     if (entry.getPath().equals(path)) {
+//                             return true;
+//                     }
+//             }
+//     } catch(JavaModelException e){
+//             // could not read classpath, then assume it is outside
+//     }
+//     return false;
+//}
+/*
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot#move
+ */
+//public void move(
+//     IPath destination,
+//     int updateResourceFlags,
+//     int updateModelFlags,
+//     IClasspathEntry sibling,
+//     IProgressMonitor monitor)
+//     throws JavaModelException {
+//
+//     MovePackageFragmentRootOperation op = 
+//             new MovePackageFragmentRootOperation(this, destination, updateResourceFlags, updateModelFlags, sibling);
+//     runOperation(op, monitor);
+//}
+//
+//
+//protected void openWhenClosed(IProgressMonitor pm) throws JavaModelException {
+//     if (!this.resourceExists() 
+//                     || !this.isOnClasspath()) {
+//             throw newNotPresentException();
+//     }
+//     super.openWhenClosed(pm);
+//}
+
+/**
+ * Recomputes the children of this element, based on the current state
+ * of the workbench.
+ */
+//public void refreshChildren() {
+//     try {
+//             OpenableElementInfo info= (OpenableElementInfo)getElementInfo();
+//             computeChildren(info);
+//     } catch (JavaModelException e) {
+//             // do nothing.
+//     }
+//}
+
+/*
+ * @see JavaElement#rootedAt(IJavaProject)
+ */
+public IJavaElement rootedAt(IJavaProject project) {
+       return
+               new PackageFragmentRoot(
+                       getResource(),
+                       project, 
+                       fName);
+}
+
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+       buffer.append(this.tabString(tab));
+       if (getElementName().length() == 0) {
+               buffer.append("[project root]"); //$NON-NLS-1$
+       } else {
+               IPath path = getPath();
+               if (getJavaProject().getElementName().equals(path.segment(0))) {
+                       buffer.append(path.removeFirstSegments(1).makeRelative());
+               } else {
+                       buffer.append(path);
+               }
+       }
+       if (info == null) {
+               buffer.append(" (not open)"); //$NON-NLS-1$
+       }
+}
+
+/**
+ * Possible failures: <ul>
+ *  <li>ELEMENT_NOT_PRESENT - the root supplied to the operation
+ *      does not exist
+ *  <li>INVALID_ELEMENT_TYPES - the root is not of kind K_BINARY
+ *   <li>RELATIVE_PATH - the path supplied to this operation must be
+ *      an absolute path
+ *  </ul>
+ */
+//protected void verifyAttachSource(IPath sourcePath) throws JavaModelException {
+//     if (!exists()) {
+//             throw newNotPresentException();
+//     } else if (this.getKind() != K_BINARY) {
+//             throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
+//     } else if (sourcePath != null && !sourcePath.isAbsolute()) {
+//             throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, sourcePath));
+//     }
+//}
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Region.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/Region.java
new file mode 100644 (file)
index 0000000..45c3cc8
--- /dev/null
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IParent;
+import net.sourceforge.phpdt.core.IRegion;
+
+/**
+ * @see IRegion
+ */
+public class Region implements IRegion {
+
+       /**
+        * A collection of the top level elements
+        * that have been added to the region
+        */
+       protected ArrayList fRootElements;
+/**
+ * Creates an empty region.
+ *
+ * @see IRegion
+ */
+public Region() {
+       fRootElements = new ArrayList(1);
+}
+/**
+ * @see IRegion#add(IJavaElement)
+ */
+public void add(IJavaElement element) {
+       if (!contains(element)) {
+               //"new" element added to region
+               removeAllChildren(element);
+               fRootElements.add(element);
+               fRootElements.trimToSize();
+       }
+}
+/**
+ * @see IRegion
+ */
+public boolean contains(IJavaElement element) {
+       
+       int size = fRootElements.size();
+       ArrayList parents = getAncestors(element);
+       
+       for (int i = 0; i < size; i++) {
+               IJavaElement aTop = (IJavaElement) fRootElements.get(i);
+               if (aTop.equals(element)) {
+                       return true;
+               }
+               for (int j = 0, pSize = parents.size(); j < pSize; j++) {
+                       if (aTop.equals(parents.get(j))) {
+                               //an ancestor is already included
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+/**
+ * Returns a collection of all the parents of this element
+ * in bottom-up order.
+ *
+ */
+private ArrayList getAncestors(IJavaElement element) {
+       ArrayList parents = new ArrayList();
+       IJavaElement parent = element.getParent();
+       while (parent != null) {
+               parents.add(parent);
+               parent = parent.getParent();
+       }
+       parents.trimToSize();
+       return parents;
+}
+/**
+ * @see IRegion
+ */
+public IJavaElement[] getElements() {
+       int size= fRootElements.size();
+       IJavaElement[] roots= new IJavaElement[size];
+       for (int i = 0; i < size; i++) {
+               roots[i]= (IJavaElement) fRootElements.get(i);
+       }
+
+       return roots;
+}
+/**
+ * @see IRegion#remove(IJavaElement)
+ */
+public boolean remove(IJavaElement element) {
+
+       removeAllChildren(element);
+       return fRootElements.remove(element);
+}
+/**
+ * Removes any children of this element that are contained within this
+ * region as this parent is about to be added to the region.
+ *
+ * <p>Children are all children, not just direct children.
+ */
+private void removeAllChildren(IJavaElement element) {
+       if (element instanceof IParent) {
+               ArrayList newRootElements = new ArrayList();
+               for (int i = 0, size = fRootElements.size(); i < size; i++) {
+                       IJavaElement currentRoot = (IJavaElement)fRootElements.get(i);
+                       //walk the current root hierarchy
+                       IJavaElement parent = currentRoot.getParent();
+                       boolean isChild= false;
+                       while (parent != null) {
+                               if (parent.equals(element)) {
+                                       isChild= true;
+                                       break;
+                               }
+                               parent = parent.getParent();
+                       }
+                       if (!isChild) {
+                               newRootElements.add(currentRoot);
+                       }
+               }
+               fRootElements= newRootElements;
+       }
+}
+/**
+ * Returns a printable representation of this region.
+ */
+public String toString() {
+       StringBuffer buffer= new StringBuffer();
+       IJavaElement[] roots= getElements();
+       buffer.append('[');
+       for (int i= 0; i < roots.length; i++) {
+               buffer.append(roots[i].getElementName());
+               if (i < (roots.length - 1)) {
+                       buffer.append(", "); //$NON-NLS-1$
+               }
+       }
+       buffer.append(']');
+       return buffer.toString();
+}
+}
index 6e68873..93c2697 100644 (file)
@@ -1349,4 +1349,5 @@ public class Util {
                System.arraycopy(args, 0, args = new String[count], 0, count);
                return args;
        }
+       
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/PerThreadObject.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/PerThreadObject.java
new file mode 100644 (file)
index 0000000..0114c8c
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core.util;
+
+import java.util.Hashtable;
+
+/**
+ * Implementation of data structure remembering an Object value by thread. Its purpose is to ease
+ * writing multi-threaded algorithms by providing a per thread data structure.
+ */
+public class PerThreadObject {
+
+       private Hashtable internalMap = new Hashtable(3); // synchronized map
+       
+       /**
+        * Answer the current map for this thread
+        */
+       public Object getCurrent(){
+               return this.internalMap.get(Thread.currentThread());
+       }
+       
+       /**
+        * Set the map for this current thread - setting to null is equivalent to removing it
+        */
+       public void setCurrent(Object current){
+               if (current == null){
+                       this.internalMap.remove(Thread.currentThread());                        
+               } else {
+                       this.internalMap.put(Thread.currentThread(), current);
+               }
+       }
+}
+
index 59b8ca3..71db7ae 100644 (file)
@@ -1,9 +1,3 @@
-/*
- * Created on 20.09.2003
- *
- * To change the template for this generated file go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
- */
 package net.sourceforge.phpdt.internal.corext.phpdoc;
 
 import java.io.FileReader;
@@ -12,36 +6,79 @@ import java.io.IOException;
 import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
 
 /**
- * @author khartlage
- *
- * To change the template for this generated type comment go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ * Utility class for static PHPdoc helper mehods
  */
 public class PHPDocUtil {
-       
-       /**
-        * Generate a PHPDoc hover text if possible
-        * 
-        * @param hoverInfoBuffer
-        * @param filename
-        * @param location
-        */
+
+  /**
+   * Generate a PHPDoc hover text if possible
+   * 
+   * @param hoverInfoBuffer
+   * @param filename
+   * @param location
+   */
   public static void appendPHPDoc(StringBuffer hoverInfoBuffer, String filename, PHPIdentifierLocation location) {
+    FileReader phpFileReader;
     hoverInfoBuffer.append(location.toString());
-    hoverInfoBuffer.append('\n');
-    if (location.getPHPDocOffset() >= 0) {
-      FileReader phpdocFileReader;
-      try {
-        phpdocFileReader = new FileReader(filename);
+    hoverInfoBuffer.append(" - \n");
+    try {
+                       hoverInfoBuffer.append( getUsage(filename, location) );
+                       hoverInfoBuffer.append('\n');
 
-        char[] charArray = new char[location.getPHPDocLength()];
-        phpdocFileReader.skip(location.getPHPDocOffset());
-        phpdocFileReader.read(charArray, 0, location.getPHPDocLength());
-        PHPDocCharArrayCommentReader phpdocConverter = new PHPDocCharArrayCommentReader(charArray);
+      //       read the phpdoc for the function
+      if (location.getPHPDocOffset() >= 0) {
+        phpFileReader = new FileReader(filename);
+        char[] phpDocDeclarationCharArray = new char[location.getPHPDocLength()];
+        phpFileReader.skip(location.getPHPDocOffset());
+        phpFileReader.read(phpDocDeclarationCharArray, 0, location.getPHPDocLength());
+        PHPDocCharArrayCommentReader phpdocConverter = new PHPDocCharArrayCommentReader(phpDocDeclarationCharArray);
         hoverInfoBuffer.append(phpdocConverter.getString());
         hoverInfoBuffer.append('\n');
-      } catch (IOException e) {
+        phpFileReader.close();
+      }
+
+    } catch (IOException e) {
+      return;
+    }
+  }
+
+  public static String getUsage(String filename, PHPIdentifierLocation location) {
+    FileReader phpFileReader;
+    String usage = location.getUsage();
+    if (usage!=null) {
+       return usage;
+    }
+    usage = "";
+    try {
+                       
+      phpFileReader = new FileReader(filename);
+      // read the function declaration
+      if (location.getOffset() >= 0 && (location.isMethod() || location.isConstructor() || location.isFunction() || location.isDefine())) {
+        char[] functionDeclarationCharArray = new char[256];
+        int offset = location.getOffset();
+        phpFileReader.skip(offset);
+        int length = phpFileReader.read(functionDeclarationCharArray, 0, 256);
+        if (length == -1) {
+          length = 256;
+        }
+        for (int i = 0; i < length; i++) {
+          if (functionDeclarationCharArray[i] == ')') {
+            length = i + 1;
+            break;
+          }
+          if (functionDeclarationCharArray[i] == '{' || functionDeclarationCharArray[i] == '}') {
+            length = i;
+            break;
+          }
+        }
+                               usage = new String(functionDeclarationCharArray, 0, length);
       }
+      phpFileReader.close();
+    } catch (IOException e) {
+      // do nothing
     }
+    // cache the usage string:
+               location.setUsage(usage);
+    return usage;
   }
 }
index 1c6ccfb..8f2f29c 100644 (file)
@@ -441,4 +441,29 @@ ${cursor}
   <template name="White" description="White (Color Code)" context="html" enabled="true">#FFFFFF</template>
   <template name="Yelow" description="Yellow (Color Code)" context="html" enabled="true">#FFFF00</template>
 
+  <template name="{" description="{* *}(Smarty comment)" context="html" enabled="true">{* ${cursor} *}</template>
+  <template name="{capture" description="{capture }{/capture}(Smarty)" context="html" enabled="true">{capture name=${name}}
+  ${cursor}
+  {/capture}
+  </template>
+  <template name="{include" description="{include file=&quot;&quot;}(Smarty)" context="html" enabled="true">{include file="${filename}.tpl"}
+  ${cursor}
+  </template>
+  <template name="{if" description="{if }{/if}(Smarty)" context="html" enabled="true">{if ${cursor}}
+  {/if}
+  </template>
+  <template name="{if" description="{if }{else}{/if}(Smarty)" context="html" enabled="true">{if ${cursor}}
+  {else}
+  {/if}
+  </template>
+  <template name="{section" description="{section }{/section}(Smarty)" context="html" enabled="true">{section name=${nameAttr} loop=${loopAttr}}
+  ${cursor}
+  {/section}
+  </template>
+  <template name="{assign" description="{assign var= value= }(Smarty)" context="html" enabled="true">{assign var="${name}" values="${value}"}${cursor}</template>
+  <template name="{cycle" description="{cycle values= }(Smarty)" context="html" enabled="true">{cycle values="${values}"}${cursor}</template>
+  <template name="{counter" description="{counter start= skip= print= }(Smarty)" context="html" enabled="true">{counter start=${startValue} skip=${skipValue} print=false}${cursor}</template>
+  <template name="{counter" description="{counter}(Smarty)" context="html" enabled="true">{counter}${cursor}</template>
+  
+   
 </templates>
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitCompletion.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/CompilationUnitCompletion.java
new file mode 100644 (file)
index 0000000..2332163
--- /dev/null
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import net.sourceforge.phpdt.core.CompletionRequestorAdapter;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+
+
+
+/**
+ * A completion requestor to collect informations on local variables.
+ * This class is used for guessing variable names like arrays, collections, etc.
+ */
+class CompilationUnitCompletion extends CompletionRequestorAdapter {
+
+       static class LocalVariable {
+               String name;
+               String typePackageName;
+               String typeName;
+               
+               LocalVariable(String name, String typePackageName, String typeName) {
+                       this.name= name;
+                       this.typePackageName= typePackageName;
+                       this.typeName= typeName;
+               }
+       }
+
+       private ICompilationUnit fUnit;
+
+       private List fLocalVariables= new ArrayList();
+       private Map fTypes= new HashMap();
+
+
+       private boolean fError;
+
+       /**
+        * Creates a compilation unit completion.
+        * 
+        * @param unit the compilation unit, may be <code>null</code>.
+        */
+       public CompilationUnitCompletion(ICompilationUnit unit) {
+               reset(unit);
+       }
+       
+       /**
+        * Resets the completion requestor.
+        * 
+        * @param unit the compilation unit, may be <code>null</code>.
+        */
+       public void reset(ICompilationUnit unit) {
+               fUnit= unit;
+               
+               fLocalVariables.clear();
+               fTypes.clear();
+               
+               fError= false;
+       }
+
+       /*
+        * @see ICompletionRequestor#acceptError(IProblem)
+        */
+       public void acceptError(IProblem error) {
+               fError= true;
+       }
+
+
+       /*
+        * @see ICodeCompletionRequestor#acceptLocalVariable
+        */
+       public void acceptLocalVariable(char[] name, char[] typePackageName, char[] typeName,
+               int modifiers, int completionStart,     int completionEnd, int relevance)
+       {
+               fLocalVariables.add(new LocalVariable(
+                       new String(name), new String(typePackageName), new String(typeName)));
+       }
+
+
+       // ---
+
+       /**
+        * Tests if the code completion process produced errors.
+        */
+       public boolean hasErrors() {
+               return fError;
+       }
+       
+
+       boolean existsLocalName(String name) {
+               for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable = (LocalVariable) iterator.next();
+
+                       if (localVariable.name.equals(name))
+                               return true;
+               }
+
+               return false;
+       }
+       
+       String[] getLocalVariableNames() {
+               String[] res= new String[fLocalVariables.size()];
+               int i= 0;
+               for (Iterator iterator = fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable = (LocalVariable) iterator.next();
+                       res[i++]= localVariable.name;
+               }               
+               return res;
+       }       
+
+       LocalVariable[] findLocalArrays() {
+               Vector vector= new Vector();
+
+               for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable= (LocalVariable) iterator.next();
+
+                       if (isArray(localVariable.typeName))
+                               vector.add(localVariable);
+               }
+
+               return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
+       }
+       
+       LocalVariable[] findLocalCollections() throws JavaModelException {
+               Vector vector= new Vector();
+
+               for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable= (LocalVariable) iterator.next();
+
+                       String typeName= qualify(localVariable.typeName);
+                       
+                       if (typeName == null)
+                               continue;
+                                               
+                       if (isSubclassOf(typeName, "java.util.Collection")) //$NON-NLS-1$                       
+                               vector.add(localVariable);
+               }
+
+               return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
+       }
+
+       String simplifyTypeName(String qualifiedName) {
+               return (String) fTypes.get(qualifiedName);      
+       }
+
+       private LocalVariable[] findLocalIntegers() {
+               Vector vector= new Vector();
+
+               for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable= (LocalVariable) iterator.next();
+
+                       if (localVariable.typeName.equals("int")) //$NON-NLS-1$
+                               vector.add(localVariable);
+               }
+
+               return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
+       }
+
+       private LocalVariable[] findLocalIterator() throws JavaModelException {
+               Vector vector= new Vector();
+
+               for (Iterator iterator= fLocalVariables.iterator(); iterator.hasNext();) {
+                       LocalVariable localVariable= (LocalVariable) iterator.next();
+
+                       String typeName= qualify(localVariable.typeName);                       
+
+                       if (typeName == null)
+                               continue;
+
+                       if (isSubclassOf(typeName, "java.util.Iterator")) //$NON-NLS-1$
+                               vector.add(localVariable);
+               }
+
+               return (LocalVariable[]) vector.toArray(new LocalVariable[vector.size()]);
+       }       
+
+       private static boolean isArray(String type) {
+               return type.endsWith("[]"); //$NON-NLS-1$
+       }
+       
+       // returns fully qualified name if successful
+       private String qualify(String typeName) throws JavaModelException {
+               if (fUnit == null)
+                       return null;
+
+//             IType[] types= fUnit.getTypes();
+//
+//             if (types.length == 0)
+//                     return null;
+//             
+//             String[][] resolvedTypeNames= types[0].resolveType(typeName);
+//
+//             if (resolvedTypeNames == null)
+//                     return null;
+//                     
+//             return resolvedTypeNames[0][0] + '.' + resolvedTypeNames[0][1];
+    return null;
+       }       
+       
+       // type names must be fully qualified
+       private boolean isSubclassOf(String typeName0, String typeName1) throws JavaModelException {
+               if (typeName0.equals(typeName1))
+                       return true;
+
+               if (fUnit == null)
+                       return false;
+
+//             IJavaProject project= fUnit.getJavaProject();
+//             IType type0= project.findType(typeName0);
+//             IType type1= project.findType(typeName1);
+//
+//             ITypeHierarchy hierarchy= type0.newSupertypeHierarchy(null);
+//             IType[] superTypes= hierarchy.getAllSupertypes(type0);
+//             
+//             for (int i= 0; i < superTypes.length; i++)
+//                     if (superTypes[i].equals(type1))
+//                             return true;                    
+               
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.jdt.core.ICompletionRequestor#acceptClass(char[], char[], char[], int, int, int, int)
+        */
+       public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers,
+               int completionStart, int completionEnd, int relevance)
+       {
+               final String qualifiedName= createQualifiedTypeName(packageName, className);
+               fTypes.put(qualifiedName, String.valueOf(completionName));
+       }
+
+       /*
+        * @see org.eclipse.jdt.core.ICompletionRequestor#acceptInterface(char[], char[], char[], int, int, int, int)
+        */
+       public void acceptInterface(char[] packageName, char[] interfaceName, char[] completionName,
+               int modifiers, int completionStart, int completionEnd, int relevance)
+       {
+               final String qualifiedName= createQualifiedTypeName(packageName, interfaceName);
+               fTypes.put(qualifiedName, String.valueOf(completionName));
+       }
+
+       private static String createQualifiedTypeName(char[] packageName, char[] className) {
+               StringBuffer buffer= new StringBuffer();
+
+               if (packageName.length != 0) {
+                       buffer.append(packageName);
+                       buffer.append('.');
+               }
+               buffer.append(className);
+               
+               return buffer.toString();
+       }
+
+}
+
index afec8f5..136e438 100644 (file)
@@ -22,10 +22,17 @@ public class HTMLUnitContext extends DocumentTemplateContext {
   /** The platform default line delimiter. */
   private static final String PLATFORM_LINE_DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$
 
-  private static final String specialChars = "&<#";
+  /** special characters
+   * '&' for the start of HTML entities
+   * '<' for the start of HTML tags
+   * '#' for the start of colour attributes
+   * '{' for the start of smarty partitions inside HTML code
+   */
+  private static final String specialChars = "&<#{";
+
   /** The compilation unit, may be <code>null</code>. */
   //   private final ICompilationUnit fCompilationUnit;
-
+  protected boolean fForceEvaluation;
   /**
    * Creates a compilation unit context.
    * 
@@ -174,5 +181,10 @@ public class HTMLUnitContext extends DocumentTemplateContext {
   //                   return null;
   //           }       
   //   }
-
+  /**
+   * Forces evaluation.
+   */
+  public void setForceEvaluation(boolean evaluate) {
+    fForceEvaluation = evaluate;
+  }
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/php/JavaContext.java
new file mode 100644 (file)
index 0000000..2d50010
--- /dev/null
@@ -0,0 +1,472 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.template.php;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
+import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
+import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitCompletion.LocalVariable;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A context for java source.
+ */
+public class JavaContext extends PHPUnitContext {
+
+       /** The platform default line delimiter. */
+       private static final String PLATFORM_LINE_DELIMITER= System.getProperty("line.separator"); //$NON-NLS-1$
+
+       /** A code completion requestor for guessing local variable names. */
+       private CompilationUnitCompletion fCompletion;
+       
+       /**
+        * Creates a java template context.
+        * 
+        * @param type   the context type.
+        * @param document the document.
+        * @param completionOffset the completion offset within the document.
+        * @param completionLength the completion length.
+        * @param unit the compilation unit (may be <code>null</code>).
+        */
+       public JavaContext(ContextType type, IDocument document, int completionOffset, int completionLength,
+               ICompilationUnit compilationUnit)
+       {
+               super(type, document, completionOffset, completionLength); //, compilationUnit);
+       }
+       
+       /**
+        * Returns the indentation level at the position of code completion.
+        */
+       private int getIndentation() {
+//             int start= getStart();
+//             IDocument document= getDocument();
+//             try {
+//                     IRegion region= document.getLineInformationOfOffset(start);
+//                     String lineContent= document.get(region.getOffset(), region.getLength());
+//                     return Strings.computeIndent(lineContent, CodeFormatterUtil.getTabWidth());
+//             } catch (BadLocationException e) {
+//                     return 0;
+//             }
+return 0;
+       }       
+       
+       /*
+        * @see TemplateContext#evaluate(Template template)
+        */
+       public TemplateBuffer evaluate(Template template) throws CoreException {
+
+               if (!canEvaluate(template))
+                       return null;
+               
+               TemplateTranslator translator= new TemplateTranslator();
+               TemplateBuffer buffer= translator.translate(template.getPattern());
+
+               getContextType().edit(buffer, this);
+                       
+               String lineDelimiter= null;
+               try {
+                       lineDelimiter= getDocument().getLineDelimiter(0);
+               } catch (BadLocationException e) {
+               }
+
+               if (lineDelimiter == null)
+                       lineDelimiter= PLATFORM_LINE_DELIMITER;
+                       
+               IPreferenceStore prefs= PHPeclipsePlugin.getDefault().getPreferenceStore();
+//             boolean useCodeFormatter= prefs.getBoolean(PreferenceConstants.TEMPLATES_USE_CODEFORMATTER);                    
+//             
+//             ITemplateEditor formatter= new JavaFormatter(lineDelimiter, getIndentation(), useCodeFormatter);
+//             formatter.edit(buffer, this);
+
+               return buffer;
+       }
+       
+       /*
+        * @see TemplateContext#canEvaluate(Template templates)
+        */
+       public boolean canEvaluate(Template template) {
+               String key= getKey();
+
+               if (fForceEvaluation)
+                       return true;
+
+               return
+                       template.matches(key, getContextType().getName()) &&
+                       key.length() != 0 && template.getName().toLowerCase().startsWith(key.toLowerCase());
+       }
+
+       /*
+        * @see DocumentTemplateContext#getCompletionPosition();
+        */
+       public int getStart() {
+
+               try {
+                       IDocument document= getDocument();
+
+                       if (getCompletionLength() == 0) {
+
+                               int start= getCompletionOffset();               
+                               while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
+                                       start--;
+                                       
+                               if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
+                                       start--;
+               
+                               return start;
+                       
+                       } else {
+
+                               int start= getCompletionOffset();
+                               int end= getCompletionOffset() + getCompletionLength();
+                               
+                               while (start != 0 && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
+                                       start--;
+                               
+                               while (start != end && Character.isWhitespace(document.getChar(start)))
+                                       start++;
+                               
+                               if (start == end)
+                                       start= getCompletionOffset();   
+                               
+                               return start;   
+                       }
+
+               } catch (BadLocationException e) {
+                       return super.getStart();        
+               }
+       }
+
+       /*
+        * @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getEnd()
+        */
+       public int getEnd() {
+               
+               if (getCompletionLength() == 0)         
+                       return super.getEnd();
+
+               try {                   
+                       IDocument document= getDocument();
+
+                       int start= getCompletionOffset();
+                       int end= getCompletionOffset() + getCompletionLength();
+                       
+                       while (start != end && Character.isWhitespace(document.getChar(end - 1)))
+                               end--;
+                       
+                       return end;     
+
+               } catch (BadLocationException e) {
+                       return super.getEnd();
+               }               
+       }
+
+       /*
+        * @see org.eclipse.jdt.internal.corext.template.DocumentTemplateContext#getKey()
+        */
+       public String getKey() {
+
+               if (getCompletionLength() == 0)         
+                       return super.getKey();
+
+               try {
+                       IDocument document= getDocument();
+
+                       int start= getStart();
+                       int end= getCompletionOffset();
+                       return start <= end
+                               ? document.get(start, end - start)
+                               : ""; //$NON-NLS-1$
+                       
+               } catch (BadLocationException e) {
+                       return super.getKey();                  
+               }
+       }
+
+       /**
+        * Returns the character before start position of completion.
+        */
+       public char getCharacterBeforeStart() {
+               int start= getStart();
+               
+               try {
+                       return start == 0
+                               ? ' '
+                               : getDocument().getChar(start - 1);
+
+               } catch (BadLocationException e) {
+                       return ' ';
+               }
+       }
+
+       private CompilationUnitCompletion guessVariableNames() {
+//             ICompilationUnit unit= getCompilationUnit();
+//             int start= getStart();
+//             
+//             if (unit == null)
+//                     return null;
+//             
+//             try {
+//                     CompilationUnitCompletion collector= new CompilationUnitCompletion(unit);
+//                     unit.codeComplete(start, collector);                    
+//                     return collector;
+//             
+//             } catch (JavaModelException e) {
+//                     handleException(null, e);
+//                     return null;
+//             }
+    return null;
+       }       
+       
+       
+       private static void handleException(Shell shell, Exception e) {
+               String title= PHPTemplateMessages.getString("JavaContext.error.title"); //$NON-NLS-1$
+               if (e instanceof CoreException)
+                       ExceptionHandler.handle((CoreException)e, shell, title, null);
+               else if (e instanceof InvocationTargetException)
+                       ExceptionHandler.handle((InvocationTargetException)e, shell, title, null);
+               else {
+                       PHPeclipsePlugin.log(e);
+                       MessageDialog.openError(shell, title, e.getMessage());
+               }
+       }       
+
+       private CompilationUnitCompletion getCompletion() {
+//             ICompilationUnit compilationUnit= getCompilationUnit();
+//             if (fCompletion == null) {
+//                     fCompletion= new CompilationUnitCompletion(compilationUnit);
+//                     
+//                     if (compilationUnit != null) {
+//                             try {
+//                                     compilationUnit.codeComplete(getStart(), fCompletion);
+//                             } catch (JavaModelException e) {
+//                                     // ignore
+//                             }
+//                     }
+//             }
+//             
+//             return fCompletion;
+    return null;
+       }
+
+       /**
+        * Returns the name of a guessed local array, <code>null</code> if no local
+        * array exists.
+        */
+       public String guessArray() {
+               CompilationUnitCompletion completion= getCompletion();
+               LocalVariable[] localArrays= completion.findLocalArrays();
+                               
+               if (localArrays.length > 0)
+                       return localArrays[localArrays.length - 1].name;
+
+               return null;    
+       }
+       
+       /**
+        * Returns the name of the type of a local array, <code>null</code> if no local
+        * array exists.
+        */
+       public String guessArrayType() {
+               CompilationUnitCompletion completion= getCompletion();
+               LocalVariable[] localArrays= completion.findLocalArrays();
+                               
+               if (localArrays.length > 0) {
+                       LocalVariable localArray= localArrays[localArrays.length - 1];                  
+
+                       String arrayTypeName= localArray.typeName;
+                       String typeName= getScalarType(arrayTypeName);
+                       int dimension= getArrayDimension(arrayTypeName) - 1;
+                       Assert.isTrue(dimension >= 0);
+                       
+                       String qualifiedName= createQualifiedTypeName(localArray.typePackageName, typeName);
+                       String innerTypeName= completion.simplifyTypeName(qualifiedName);
+                       
+                       return innerTypeName == null
+                               ? createArray(typeName, dimension)
+                               : createArray(innerTypeName, dimension);
+               }
+               
+               return null;
+       }
+       
+       private static String createArray(String type, int dimension) {
+               StringBuffer buffer= new StringBuffer(type);
+               for (int i= 0; i < dimension; i++)
+                       buffer.append("[]"); //$NON-NLS-1$
+               return buffer.toString();
+       }
+
+       private static String getScalarType(String type) {
+               return type.substring(0, type.indexOf('['));
+       }
+       
+       private static int getArrayDimension(String type) {
+
+               int dimension= 0;               
+               int index= type.indexOf('[');
+
+               while (index != -1) {
+                       dimension++;
+                       index= type.indexOf('[', index + 1);    
+               }
+               
+               return dimension;               
+       }
+
+       private static String createQualifiedTypeName(String packageName, String className) {
+               StringBuffer buffer= new StringBuffer();
+
+               if (packageName.length() != 0) {
+                       buffer.append(packageName);
+                       buffer.append('.');
+               }
+               buffer.append(className);
+               
+               return buffer.toString();
+       }
+       
+       /**
+        * Returns a proposal for a variable name of a local array element, <code>null</code>
+        * if no local array exists.
+        */
+       public String guessArrayElement() {
+//             CompilationUnitCompletion completion= getCompletion();
+//             LocalVariable[] localArrays= completion.findLocalArrays();
+//             
+//             if (localArrays.length > 0) {
+//                     int idx= localArrays.length - 1;
+//                     
+//                     LocalVariable var= localArrays[idx];
+//                     
+//                     IJavaProject project= getCompilationUnit().getJavaProject();
+//                     String typeName= var.typeName;
+//                     String baseTypeName= typeName.substring(0, typeName.lastIndexOf('['));
+//
+//                     String[] proposals= NamingConventions.suggestLocalVariableNames(project, var.typePackageName, baseTypeName, 0, completion.getLocalVariableNames());
+//                     if (proposals.length > 0) {
+//                             return proposals[0];
+//                     }
+//             }
+
+               return null;
+       }
+
+       /**
+        * Returns an array index name. 'i', 'j', 'k' are tried until no name collision with
+        * an existing local variable occurs. If all names collide, <code>null</code> is returned.
+        */     
+       public String getIndex() {
+               CompilationUnitCompletion completion= getCompletion();
+               String[] proposals= {"i", "j", "k"};  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+               
+               for (int i= 0; i != proposals.length; i++) {
+                       String proposal = proposals[i];
+
+                       if (!completion.existsLocalName(proposal))
+                               return proposal;
+               }
+
+               return null;
+       }
+       
+       /**
+        * Returns the name of a local collection, <code>null</code> if no local collection
+        * exists.
+        */
+       public String guessCollection() {
+               CompilationUnitCompletion completion= getCompletion();
+               try {
+                       LocalVariable[] localCollections= completion.findLocalCollections();
+               
+                       if (localCollections.length > 0)
+                               return localCollections[localCollections.length - 1].name;
+
+               } catch (JavaModelException e) {
+                       PHPeclipsePlugin.log(e);
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns an iterator name ('iter'). If 'iter' already exists as local variable,
+        * <code>null</code> is returned.
+        */
+       public String getIterator() {
+               CompilationUnitCompletion completion= getCompletion();          
+               String[] proposals= {"iter"}; //$NON-NLS-1$
+               
+               for (int i= 0; i != proposals.length; i++) {
+                       String proposal = proposals[i];
+
+                       if (!completion.existsLocalName(proposal))
+                               return proposal;
+               }
+
+               return null;
+       }
+
+
+//     public void addIteratorImport() {
+//     
+//             try {
+//                     CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings();
+//                     ImportsStructure structure= new ImportsStructure(getCompilationUnit(), settings.importOrder, settings.importThreshold, true);
+//                     structure.addImport("java.util.Iterator"); //$NON-NLS-1$
+//                     structure.create(false, null);
+//
+//             } catch (CoreException e) {
+//                     handleException(null, e);
+//             }
+//     }
+       
+       /**
+        * Evaluates a 'java' template in thecontext of a compilation unit
+        */
+       public static String evaluateTemplate(Template template, ICompilationUnit compilationUnit, int position) throws CoreException {
+
+               ContextType contextType= ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
+               if (contextType == null)
+                       throw new CoreException(new Status(IStatus.ERROR, PHPeclipsePlugin.PLUGIN_ID, IStatus.ERROR, PHPTemplateMessages.getString("JavaContext.error.message"), null)); //$NON-NLS-1$
+
+               IDocument document= new Document();
+//             if (compilationUnit != null && compilationUnit.exists())
+//                     document.set(compilationUnit.getSource());
+
+               JavaContext context= new JavaContext(contextType, document, position, 0, compilationUnit);
+               context.setForceEvaluation(true);
+
+               TemplateBuffer buffer= context.evaluate(template);
+               if (buffer == null)
+                       return null;
+               return buffer.getString();
+       }
+
+}
+
index c769fee..56b2e96 100644 (file)
@@ -52,4 +52,4 @@ JavaContextType.variable.name.iterator=iterator
 JavaContextType.variable.name.arguments=Method arguments (evaluates to empty string)
 
 JavaContext.error.title=Template Error
-JavaContext.error.message=java context type missing
\ No newline at end of file
+JavaContext.error.message=PHP context type missing
\ No newline at end of file
index 762180d..8f9a0be 100644 (file)
@@ -25,7 +25,7 @@ public class PHPUnitContext extends DocumentTemplateContext {
   private static final String specialChars = "$";
   /** The compilation unit, may be <code>null</code>. */
   //   private final ICompilationUnit fCompilationUnit;
-
+       protected boolean fForceEvaluation;
   /**
    * Creates a compilation unit context.
    * 
@@ -40,7 +40,14 @@ public class PHPUnitContext extends DocumentTemplateContext {
     super(type, document, completionPosition, 0);
     // fCompilationUnit= compilationUnit;
   }
-
+       
+       protected PHPUnitContext(ContextType type, IDocument document, int completionPosition, int completionLength)
+               //,ICompilationUnit compilationUnit)
+               {
+                       super(type, document, completionPosition, completionLength);
+                       //      fCompilationUnit= compilationUnit;
+               }
+               
   /*
   * @see TemplateContext#canEvaluate(Template templates)
   */
@@ -58,7 +65,8 @@ public class PHPUnitContext extends DocumentTemplateContext {
     return
     //      fEnabled &&
     //      fContextTypeName.equals(contextTypeName) &&
-      (prefix.length() != 0) && identifier.toLowerCase().startsWith(prefix.toLowerCase());
+//      (prefix.length() != 0) && 
+      identifier.toLowerCase().startsWith(prefix.toLowerCase());
   }
 
   /*
@@ -130,6 +138,7 @@ public class PHPUnitContext extends DocumentTemplateContext {
       return ' ';
     }
   }
+  
   /**
    * Returns the compilation unit if one is associated with this context, <code>null</code> otherwise.
    */
@@ -157,4 +166,11 @@ public class PHPUnitContext extends DocumentTemplateContext {
   //           }       
   //   }
 
+  /**
+   * @param b
+   */
+  public void setForceEvaluation(boolean b) {
+    fForceEvaluation = b;
+  }
+
 }
index 51bda8a..3d70337 100644 (file)
@@ -23,7 +23,6 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.ConfigurableOption;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
-
 import net.sourceforge.phpdt.internal.formatter.impl.FormatterOptions;
 import net.sourceforge.phpdt.internal.formatter.impl.SplitLine;
 
@@ -1126,7 +1125,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       case TokenNameCOLON : // :
         return 50; // it's better cutting on ?: than on ;
       case TokenNameEQUAL_EQUAL : // == 
+      case TokenNameEQUAL_EQUAL_EQUAL : // === 
       case TokenNameNOT_EQUAL : // != 
+                       case TokenNameNOT_EQUAL_EQUAL : // != 
         return 60;
       case TokenNameLESS : // < 
       case TokenNameLESS_EQUAL : // <= 
@@ -1308,12 +1309,24 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       case TokenNameCOLON : // : (15.24)
         return ":"; //$NON-NLS-1$
 
+      case TokenNameCOLON_COLON : // : (15.24)
+        return "::"; //$NON-NLS-1$
+
       case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
         return "=="; //$NON-NLS-1$
 
+      case TokenNameEQUAL_EQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+        return "==="; //$NON-NLS-1$
+
+      case TokenNameEQUAL_GREATER : // -= (15.25.2)
+        return "=>"; //$NON-NLS-1$                             
+
       case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
         return "!="; //$NON-NLS-1$
 
+                       case TokenNameNOT_EQUAL_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+                               return "!=="; //$NON-NLS-1$
+                                                       
       case TokenNameLESS : // < (15.19.1)
         return "<"; //$NON-NLS-1$
 
@@ -1377,6 +1390,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       case TokenNameMINUS_EQUAL : // -= (15.25.2)
         return "-="; //$NON-NLS-1$
 
+      case TokenNameMINUS_GREATER : // -= (15.25.2)
+        return "->"; //$NON-NLS-1$
+
       case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
         return "<<="; //$NON-NLS-1$
 
@@ -2144,7 +2160,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           case TokenNameGREATER_EQUAL : // >= (15.19.1)
             //                         case TokenNameinstanceof : // instanceof
           case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+          case TokenNameEQUAL_EQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
           case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+                                       case TokenNameNOT_EQUAL_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
           case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
           case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
           case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
index 848c0cb..05721fa 100644 (file)
@@ -242,6 +242,7 @@ PHPEditorPreferencePage.description=PHP Editor settings:
 PHPEditorPreferencePage.font=Text Font:
 PHPEditorPreferencePage.multiLineComment=Multi-line comment
 PHPEditorPreferencePage.singleLineComment=Single-line comment
+PHPEditorPreferencePage.tags=PHP tags
 PHPEditorPreferencePage.keywords=Keywords
 PHPEditorPreferencePage.functionNames=Predefined function names
 PHPEditorPreferencePage.variables=Variables
index 651e9c0..f0d6b23 100644 (file)
@@ -39,6 +39,7 @@ public class PHPUiImages {
        protected static final String OVR_PREFIX = "ovr16";
        protected static final String CTOOL_PREFIX = "ctool16";
 
+       public static final String IMG_OBJS_GHOST= NAME_PREFIX + "ghost.gif";   
        public static final String IMG_CLASS = NAME_PREFIX + "class_obj.gif";
        public static final String IMG_DEFINE = NAME_PREFIX + "define_obj.gif";
        public static final String IMG_BUILTIN = NAME_PREFIX + "builtin_obj.gif";
@@ -49,6 +50,7 @@ public class PHPUiImages {
        public static final String IMG_OBJS_WARNING =
                NAME_PREFIX + "warning_obj.gif";
        public static final String IMG_OBJS_INFO = NAME_PREFIX + "info_obj.gif";
+       public static final String IMG_OBJS_INTERFACE= NAME_PREFIX + "int_obj.gif";                     //$NON-NLS-1$
        public static final String IMG_CTOOLS_PHP_PAGE =
                NAME_PREFIX + "php_page.gif";
        public static final String IMG_CTOOLS_PHP = NAME_PREFIX + "php.gif";
@@ -58,6 +60,8 @@ public class PHPUiImages {
 
        public static final String IMG_CLEAR = NAME_PREFIX + "clear.gif"; 
        
+       public static final ImageDescriptor DESC_OBJS_GHOST= createManaged(OBJ_PREFIX, IMG_OBJS_GHOST);
+       
        public static final ImageDescriptor DESC_CLASS =
                createManaged(OBJ_PREFIX, IMG_CLASS);
        public static final ImageDescriptor DESC_DEFINE =
@@ -86,7 +90,13 @@ public class PHPUiImages {
                
        public static final ImageDescriptor DESC_CLEAR =
                        createManaged(OBJ_PREFIX, IMG_CLEAR);
-
+       
+       private static final String T_OBJ= "obj16";             //$NON-NLS-1$
+       private static final String T_WIZBAN= "wizban";         //$NON-NLS-1$
+       
+       public static final ImageDescriptor DESC_WIZBAN_NEWCLASS= create(T_WIZBAN, "newclass_wiz.gif");                         //$NON-NLS-1$
+       public static final ImageDescriptor DESC_OBJS_INTERFACE= createManaged(T_OBJ, IMG_OBJS_INTERFACE);
+       
        /**
         * Returns the image managed under the given key in this registry.
         * 
index 5fa1dba..e43d264 100644 (file)
@@ -10,8 +10,6 @@
  ******************************************************************************/
 package net.sourceforge.phpdt.internal.ui.actions;
 
-import org.eclipse.swt.widgets.Shell;
-
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.util.Assert;
@@ -20,7 +18,7 @@ import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
-
+import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IWorkbenchSite;
 
 /**
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/WorkbenchRunnableAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/WorkbenchRunnableAdapter.java
new file mode 100644 (file)
index 0000000..7c4ae96
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpeclipse.PHPCore;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+
+
+/**
+ * An <code>IRunnableWithProgress</code> that adapts and  <code>IWorkspaceRunnable</code>
+ * so that is can be executed inside <code>IRunnableContext</code>. <code>OperationCanceledException</code> 
+ * thrown by the apapted runnabled are cought and rethrown as a <code>InterruptedException</code>.
+ */
+public class WorkbenchRunnableAdapter implements IRunnableWithProgress {
+       
+       private IWorkspaceRunnable fWorkspaceRunnable;
+       
+       public WorkbenchRunnableAdapter(IWorkspaceRunnable runnable) {
+               fWorkspaceRunnable= runnable;
+       }
+
+       /*
+        * @see IRunnableWithProgress#run(IProgressMonitor)
+        */
+       public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+               try {
+                       PHPCore.run(fWorkspaceRunnable, monitor);
+               } catch (OperationCanceledException e) {
+                       throw new InterruptedException(e.getMessage());
+               } catch (CoreException e) {
+                       throw new InvocationTargetException(e);
+               }
+       }
+
+}
+
@@ -1,19 +1,25 @@
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-package net.sourceforge.phpeclipse.mover.obfuscator;
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.phpdocexport;
 
 import java.text.MessageFormat;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
-public class ObfuscatorMessages {
+public class JavadocExportMessages {
 
-       private static final String RESOURCE_BUNDLE= ObfuscatorMessages.class.getName();
+       private static final String RESOURCE_BUNDLE= JavadocExportMessages.class.getName();
        private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
 
-       private ObfuscatorMessages() {
+       private JavadocExportMessages() {
        }
 
        public static String getString(String key) {
@@ -40,4 +46,6 @@ public class ObfuscatorMessages {
        public static String getFormattedString(String key, Object[] args) {
                return MessageFormat.format(getString(key), args);
        }
+
+
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/phpdocexport/JavadocExportMessages.properties
new file mode 100644 (file)
index 0000000..58866ea
--- /dev/null
@@ -0,0 +1,104 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+JavadocSpecificsWizardPage.description=Configure Javadoc arguments.
+
+
+JavadocSpecificsWizardPage.stylesheetbrowsedialog.title=Style sheet Selection
+JavadocSpecificsWizardPage.overviewbutton.label=&Overview:
+JavadocSpecificsWizardPage.overviewbrowse.label=Bro&wse...
+JavadocSpecificsWizardPage.extraoptionsfield.label=E&xtra Javadoc options (path names with white spaces must be enclosed in quotes):
+JavadocSpecificsWizardPage.overviewbrowsedialog.title=Select overview page
+JavadocSpecificsWizardPage.antscriptbutton.label=&Save the settings of this Javadoc export as an Ant script:
+JavadocSpecificsWizardPage.antscripttext.label=&Ant Script: 
+JavadocSpecificsWizardPage.antscriptbrowse.label=Brows&e...
+JavadocSpecificsWizardPage.openbrowserbutton.label=O&pen generated index file in browser
+JavadocSpecificsWizardPage.antscriptbrowsedialog.title=Destination Selection
+JavadocSpecificsWizardPage.antscriptbrowsedialog.label=&Select destination folder for ant script:
+
+JavadocSpecificsWizardPage.jdk14mode.label=JRE 1.4 source compatibility
+
+JavadocSpecificsWizardPage.overviewnotfound.error=Overview path not found.
+JavadocSpecificsWizardPage.overviewincorrect.error=Overview must be an html document.
+JavadocSpecificsWizardPage.antfileincorrect.error=Not a valid Ant file name.
+JavadocSpecificsWizardPage.antfileoverwrite.warning=The generated ant file will overwrite the existing ant file.
+JavadocTreeWizardPage.javadoctreewizardpage.description=Select types for Javadoc generation.
+JavadocTreeWizardPage.checkboxtreeandlistgroup.label=Select &types for which Javadoc will be generated:
+JavadocTreeWizardPage.visibilitygroup.label=Create Javadoc for members with visibility: 
+JavadocTreeWizardPage.privatebutton.label=Pr&ivate
+JavadocTreeWizardPage.packagebutton.label=P&ackage
+JavadocTreeWizardPage.protectedbutton.label=Pr&otected
+JavadocTreeWizardPage.publicbutton.label=P&ublic
+JavadocTreeWizardPage.standarddocletbutton.label=Use &Standard Doclet
+JavadocTreeWizardPage.destinationfield.label=&Destination: 
+JavadocTreeWizardPage.destinationbrowse.label=Bro&wse...
+JavadocTreeWizardPage.customdocletbutton.label=Use &Custom Doclet
+JavadocTreeWizardPage.docletnamefield.label=Doc&let name: 
+JavadocTreeWizardPage.docletpathfield.label=Doclet class &path: 
+JavadocTreeWizardPage.destinationbrowsedialog.title=Destination Selection
+JavadocTreeWizardPage.destinationbrowsedialog.label=&Select the Javadoc destination folder:
+JavadocTreeWizardPage.javadoccommand.error=Javadoc command location not specified on the Javadoc preference page.
+JavadocTreeWizardPage.nodocletname.error=Enter a doclet name.
+JavadocTreeWizardPage.invaliddocletname.error=Invalid doclet name.
+JavadocTreeWizardPage.invaliddocletpath.error=Not a valid doclet class path.
+JavadocTreeWizardPage.nodestination.error=Enter the destination folder.
+JavadocTreeWizardPage.invaliddestination.error=Not a valid folder.
+JavadocTreeWizardPage.invalidtreeselection.error=Select elements from tree.
+
+JavadocWizardPage.javadocwizardpage.description=Javadoc Generation
+JavadocWizard.javadocwizard.title=Generate Javadoc
+JavadocWizard.updatejavadoclocation.message=Do you want to update the Javadoc location for ''{0}'' with the chosen destination folder ''{1}''?
+JavadocWizard.updatejavadocdialog.label=Update Javadoc Location
+JavadocWizard.javadocprocess.label=Javadoc Generation
+JavadocWizard.saveresourcedialogCE.title=Save Resources
+JavadocWizard.saveresourcedialogCE.message=Saving resources failed.
+JavadocWizard.saveresourcedialogITE.title=Save Resources
+JavadocWizard.saveresourcedialogITE.message=Saving resources failed.
+JavadocWizard.savetask.name=Saving...
+JavadocWizard.launchconfig.name=Javadoc
+
+JavadocOptionsManager.antfileincorrectCE.warning=Unable to run wizard from Ant file, loading previous settings.
+JavadocOptionsManager.antfileincorrectIOE.warning=Error reading Ant file, loading previous settings.
+JavadocOptionsManager.antfileincorrectSAXE.warning=Error reading Ant file, loading previous settings.
+
+JavadcoStandardWizardPage.description=Configure Javadoc arguments for standard doclet.
+JavadcoStandardWizardPage.titlebutton.label=Document &title:
+JavadcoStandardWizardPage.basicgroup.label=Basic Options
+JavadcoStandardWizardPage.usebutton.label=Generate &use page
+JavadcoStandardWizardPage.hierarchybutton.label=Generate &hierarchy tree
+JavadcoStandardWizardPage.navigartorbutton.label=Generate navi&gator bar
+JavadcoStandardWizardPage.indexbutton.label=Generate &index
+JavadcoStandardWizardPage.seperateindexbutton.label=Separate index &per letter
+JavadcoStandardWizardPage.tagsgroup.label=Document these tags
+JavadcoStandardWizardPage.authorbutton.label=@&author
+JavadcoStandardWizardPage.versionbutton.label=@&version
+JavadcoStandardWizardPage.deprecatedbutton.label=@&deprecated
+JavadcoStandardWizardPage.deprecatedlistbutton.label=deprecated &list
+JavadcoStandardWizardPage.stylesheettext.label=St&yle sheet:
+JavadcoStandardWizardPage.selectallbutton.label=&Select All
+JavadcoStandardWizardPage.clearallbutton.label=&Clear All
+JavadcoStandardWizardPage.referencedclasses.label=Select &referenced classes to which Javadoc should create links:
+JavadcoStandardWizardPage.stylesheetnopath.error=Style sheet path not found.
+JavadcoStandardWizardPage.stylesheetnotcss.error=Style sheet must be a css document.
+JavadocStandardWizardPage.stylesheetbrowsebutton.label=Bro&wse...
+JavadocStandardWizardPage.configurebutton.label=Con&figure...
+JavadocStandardWizardPage.javadocpropertydialog.title=Configure Javadoc Location
+
+JavadocLinkDialogLabelProvider.configuredentry={0} - {1}
+JavadocLinkDialogLabelProvider.notconfiguredentry={0} - Not Configured
+JavadocTreeWizardPage.privatevisibilitydescription.label=Private: Generate Javadoc for all classes and members.
+JavadocTreeWizardPage.warning.mayoverwritefiles=Javadoc generation may overwrite existing files
+JavadocTreeWizardPage.packagevisibledescription.label=Package: Generate Javadoc for only package, protected, and public classes and members.
+JavadocTreeWizardPage.protectedvisibilitydescription.label=Protected: Generate Javadoc for only protected and public classes and members.
+JavadocTreeWizardPage.publicvisibilitydescription.label=Public: Generate Javadoc for only public classes and members.
+JavadocWizard.antInformationDialog.title=Javadoc Generation with Ant Scripts
+JavadocWizard.antInformationDialog.message=Ant file will be created.\nNote that to run the generated ant script, the operating system PATH must contain the Javadoc command.
index 7250029..2f7e150 100644 (file)
@@ -18,14 +18,11 @@ import net.sourceforge.phpdt.internal.ui.dialog.StatusUtil;
 import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout;
 import net.sourceforge.phpeclipse.PHPCore;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.source.SourceViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
index 3393159..836ca7c 100644 (file)
@@ -86,6 +86,8 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc
       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_BOLD),
       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR),
       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD),
+                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_JAVA_TAG_COLOR),
+                 new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_JAVA_TAG_BOLD),
       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR),
       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD),
       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR),
@@ -209,6 +211,8 @@ public class PHPEditorPreferencePage extends PreferencePage implements IWorkbenc
     {
       PHPUIMessages.getString("PHPEditorPreferencePage.singleLineComment"), PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR }, //$NON-NLS-1$
     {
+                       PHPUIMessages.getString("PHPEditorPreferencePage.tags"), PreferenceConstants.EDITOR_JAVA_TAG_COLOR }, //$NON-NLS-1$
+               {
       PHPUIMessages.getString("PHPEditorPreferencePage.keywords"), PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR }, //$NON-NLS-1$
     {
       PHPUIMessages.getString("PHPEditorPreferencePage.functionNames"), PreferenceConstants.EDITOR_PHP_FUNCTIONNAME_COLOR }, //$NON-NLS-1$
index 309f84d..8d65144 100644 (file)
@@ -9,8 +9,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.RGB;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpdt.ui.text.IColorManagerExtension;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
@@ -20,9 +20,8 @@ import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
 import org.eclipse.jface.text.rules.IRule;
 import org.eclipse.jface.text.rules.Token;
 import org.eclipse.jface.util.PropertyChangeEvent;
-
-import net.sourceforge.phpdt.ui.text.IColorManager;
-import net.sourceforge.phpdt.ui.text.IColorManagerExtension;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.RGB;
 
 
 /**
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaAnnotationHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaAnnotationHover.java
new file mode 100644 (file)
index 0000000..9f6f980
--- /dev/null
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
+import net.sourceforge.phpeclipse.phpeditor.IJavaAnnotation;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.externaltools.internal.ant.editor.derived.HTMLPrinter;
+
+// TODO: delete this class ? we use PHPAnnotationHover instead !
+/**
+ * Determines all markers for the given line and collects, concatenates, and formates
+ * their messages.
+ */
+public class JavaAnnotationHover implements IAnnotationHover {
+       
+       /**
+        * Returns the distance to the ruler line. 
+        */
+       protected int compareRulerLine(Position position, IDocument document, int line) {
+               
+               if (position.getOffset() > -1 && position.getLength() > -1) {
+                       try {
+                               int javaAnnotationLine= document.getLineOfOffset(position.getOffset());
+                               if (line == javaAnnotationLine)
+                                       return 1;
+                               if (javaAnnotationLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength()))
+                                       return 2;
+                       } catch (BadLocationException x) {
+                       }
+               }
+               
+               return 0;
+       }
+       
+       /**
+        * Selects a set of markers from the two lists. By default, it just returns
+        * the set of exact matches.
+        */
+       protected List select(List exactMatch, List including) {
+               return exactMatch;
+       }
+       
+       /**
+        * Returns one marker which includes the ruler's line of activity.
+        */
+       protected List getJavaAnnotationsForLine(ISourceViewer viewer, int line) {
+               
+               IDocument document= viewer.getDocument();
+               IAnnotationModel model= viewer.getAnnotationModel();
+               
+               if (model == null)
+                       return null;
+                       
+               List exact= new ArrayList();
+               List including= new ArrayList();
+               
+               Iterator e= model.getAnnotationIterator();
+               HashMap messagesAtPosition= new HashMap();
+               while (e.hasNext()) {
+                       Object o= e.next();
+                       if (o instanceof IJavaAnnotation) {
+                               IJavaAnnotation a= (IJavaAnnotation)o;
+                               if (!a.hasOverlay()) {
+                                       Position position= model.getPosition((Annotation)a);
+                                       if (position == null)
+                                               continue;
+
+                                       if (isDuplicateJavaAnnotation(messagesAtPosition, position, a.getMessage()))
+                                               continue;
+       
+                                       switch (compareRulerLine(position, document, line)) {
+                                               case 1:
+                                                       exact.add(a);
+                                                       break;
+                                               case 2:
+                                                       including.add(a);
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+               
+               return select(exact, including);
+       }
+
+       private boolean isDuplicateJavaAnnotation(Map messagesAtPosition, Position position, String message) {
+               if (messagesAtPosition.containsKey(position)) {
+                       Object value= messagesAtPosition.get(position);
+                       if (message.equals(value))
+                               return true;
+
+                       if (value instanceof List) {
+                               List messages= (List)value;
+                               if  (messages.contains(message))
+                                       return true;
+                               else
+                                       messages.add(message);
+                       } else {
+                               ArrayList messages= new ArrayList();
+                               messages.add(value);
+                               messages.add(message);
+                               messagesAtPosition.put(position, messages);
+                       }
+               } else
+                       messagesAtPosition.put(position, message);
+               return false;
+       }
+               
+       /*
+        * @see IVerticalRulerHover#getHoverInfo(ISourceViewer, int)
+        */
+       public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+               List javaAnnotations= getJavaAnnotationsForLine(sourceViewer, lineNumber);
+               if (javaAnnotations != null) {
+                       
+                       if (javaAnnotations.size() == 1) {
+                               
+                               // optimization
+                               IJavaAnnotation javaAnnotation= (IJavaAnnotation) javaAnnotations.get(0);
+                               String message= javaAnnotation.getMessage();
+                               if (message != null && message.trim().length() > 0)
+                                       return formatSingleMessage(message);
+                                       
+                       } else {
+                                       
+                               List messages= new ArrayList();
+                               
+                               Iterator e= javaAnnotations.iterator();
+                               while (e.hasNext()) {
+                                       IJavaAnnotation javaAnnotation= (IJavaAnnotation) e.next();
+                                       String message= javaAnnotation.getMessage();
+                                       if (message != null && message.trim().length() > 0)
+                                               messages.add(message.trim());
+                               }
+                               
+                               if (messages.size() == 1)
+                                       return formatSingleMessage((String) messages.get(0));
+                                       
+                               if (messages.size() > 1)
+                                       return formatMultipleMessages(messages);
+                       }
+               }
+               
+               return null;
+       }
+       
+       /*
+        * Formats a message as HTML text.
+        */
+       private String formatSingleMessage(String message) {
+               StringBuffer buffer= new StringBuffer();
+               HTMLPrinter.addPageProlog(buffer);
+               HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message));
+               HTMLPrinter.addPageEpilog(buffer);
+               return buffer.toString();
+       }
+       
+       /*
+        * Formats several message as HTML text.
+        */
+       private String formatMultipleMessages(List messages) {
+               StringBuffer buffer= new StringBuffer();
+               HTMLPrinter.addPageProlog(buffer);
+               HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(PHPUIMessages.getString("JavaAnnotationHover.multipleMarkersAtThisLine"))); //$NON-NLS-1$
+               
+               HTMLPrinter.startBulletList(buffer);
+               Iterator e= messages.iterator();
+               while (e.hasNext())
+                       HTMLPrinter.addBullet(buffer, HTMLPrinter.convertToHTMLContent((String) e.next()));
+               HTMLPrinter.endBulletList(buffer);      
+               
+               HTMLPrinter.addPageEpilog(buffer);
+               return buffer.toString();
+       }
+}
index 69d31c5..a7a462b 100644 (file)
@@ -9,13 +9,13 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpdt.ui.text.IColorManagerExtension;
+
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.widgets.Display;
 
-import net.sourceforge.phpdt.ui.text.IColorManager;
-import net.sourceforge.phpdt.ui.text.IColorManagerExtension;
-
 /**
  * Java color manager.
  */
index ce4a46d..4b27afe 100644 (file)
@@ -8,8 +8,8 @@ package net.sourceforge.phpdt.internal.ui.text;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.Reader;
-
 import java.text.BreakIterator;
+
 import org.eclipse.swt.graphics.GC;
 
 /*
@@ -1,5 +1,4 @@
-package net.sourceforge.phpeclipse.phpeditor;
-
+package net.sourceforge.phpdt.internal.ui.text;
 /**********************************************************************
 Copyright (c) 2000, 2002 IBM Corp. and others.
 All rights reserved. This program and the accompanying materials
@@ -12,9 +11,9 @@ Contributors:
     Klaus Hartlage - www.eclipseproject.de
 **********************************************************************/
 
-import java.util.List;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.jface.text.BadLocationException;
index a989296..311aa59 100644 (file)
@@ -7,11 +7,11 @@ package net.sourceforge.phpdt.internal.ui.text;
 
 import java.io.IOException;
 
+import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
+
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 
-import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
-
 /**
  * Reads from a document either forwards or backwards. May be configured to
  * skip comments and strings.
index 97a0edd..f66faaf 100644 (file)
@@ -11,11 +11,12 @@ import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.ICharacterPairMatcher;
 
 /**
  * Helper class for match pairs of characters.
  */
-public class PHPPairMatcher {
+public class PHPPairMatcher implements ICharacterPairMatcher {
        
        
        public static final int LEFT=      1;
@@ -37,6 +38,19 @@ public class PHPPairMatcher {
                fPairs= pairs;
        }
        
+       /*
+        * @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear()
+        */
+       public void clear() {
+               if (fReader != null) {
+                       try {
+                               fReader.close();
+                       } catch (IOException x) {
+                               // ignore
+                       }
+               }
+       }
+       
        public IRegion match(IDocument document, int offset) {
 
                fOffset= offset;
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IProblemRequestorExtension.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IProblemRequestorExtension.java
new file mode 100644 (file)
index 0000000..2ffc389
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+
+/**
+ * Extension to <code>IProblemRequestor</code>.
+ */
+public interface IProblemRequestorExtension {
+       
+       /**
+        * Sets the progress monitor to this problem requestor.
+        * 
+        * @param monitor the progress monitor to be used
+        */
+       void setProgressMonitor(IProgressMonitor monitor);
+       
+       /**
+        * Sets the active state of this problem requestor.
+        * 
+        * @param isActive the state of this problem requestor
+        */
+       void setIsActive(boolean isActive);
+}
index e2a9d52..264938e 100644 (file)
@@ -4,16 +4,15 @@
  */
 package net.sourceforge.phpdt.internal.ui.text.java;
 
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.formatter.IFormattingStrategy;
-import org.eclipse.jface.text.source.ISourceViewer;
-
 import net.sourceforge.phpdt.core.ICodeFormatter;
 import net.sourceforge.phpdt.core.ToolFactory;
-
 import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
 import net.sourceforge.phpdt.internal.corext.util.Strings;
-import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage; 
+import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.formatter.IFormattingStrategy;
+import org.eclipse.jface.text.source.ISourceViewer;
 
 public class JavaFormattingStrategy implements IFormattingStrategy {
        
index 147001f..8fa33ab 100644 (file)
@@ -107,7 +107,7 @@ public class BuiltInProposal extends AbstractProposal { // implements IPHPComple
    * @see ICompletionProposal#getAdditionalProposalInfo()
    */
   public String getAdditionalProposalInfo() {
-    return textToHTML(fFunction.getUsage() + "\n\n" + fFunction.getDescription()); // fTemplateBuffer.getString());
+    return textToHTML(fFunction.getDescription()); // fTemplateBuffer.getString());
   }
 
   /*
@@ -121,7 +121,7 @@ public class BuiltInProposal extends AbstractProposal { // implements IPHPComple
    * @see ICompletionProposal#getDisplayString()
    */
   public String getDisplayString() {
-    return fBuiltinFunctionName + TemplateMessages.getString("TemplateProposal.delimiter") + fBuiltinFunctionName; // $NON-NLS-1$ //$NON-NLS-1$
+    return fBuiltinFunctionName + TemplateMessages.getString("TemplateProposal.delimiter") + fFunction.getUsage(); // $NON-NLS-1$ //$NON-NLS-1$
     //         return fTemplate.getName() + ObfuscatorMessages.getString("TemplateProposal.delimiter") + fTemplate.getDescription(); // $NON-NLS-1$ //$NON-NLS-1$
   }
 
index fa9aba0..91ce5e7 100644 (file)
@@ -8,6 +8,7 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.SortedMap;
 
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.internal.corext.template.ContextType;
 import net.sourceforge.phpdt.internal.corext.template.php.CompilationUnitContextType;
 import net.sourceforge.phpdt.internal.corext.template.php.PHPUnitContext;
@@ -15,6 +16,7 @@ import net.sourceforge.phpdt.internal.ui.text.java.IPHPCompletionProposal;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
 
+import org.eclipse.core.resources.IFile;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
@@ -29,17 +31,27 @@ public class DeclarationEngine {
   private ContextType fContextType;
   /** The result proposals. */
   private ArrayList fProposals = new ArrayList();
-  /** Use only methods or variables inside a class*/
-  private boolean fUseClassEntries;
+  /** Token determines last which declarations are allowed for proposal */
+  private int fLastSignificantToken;
+
+  private IFile fFile;
+  private String fFileName;
 
   /**
    * Creates the template engine for a particular context type.
    * See <code>TemplateContext</code> for supported context types.
    */
-  public DeclarationEngine(ContextType contextType, boolean useClassEntries) {
+  public DeclarationEngine(ContextType contextType, int lastSignificantToken, IFile file) {
     // Assert.isNotNull(contextType);
     fContextType = contextType;
-               fUseClassEntries = useClassEntries;
+
+    fLastSignificantToken = lastSignificantToken;
+    fFile = file;
+    if (fFile != null) {
+      fFileName = fFile.getFullPath().toString();
+    } else {
+      fFileName = "";
+    }
   }
 
   /**
@@ -73,9 +85,10 @@ public class DeclarationEngine {
       return;
 
     Point selection = viewer.getSelectedRange();
+
     // remember selected text
     String selectedText = null;
-    
+
     if (selection.y != 0) {
       try {
         selectedText = document.get(selection.x, selection.y);
@@ -90,7 +103,7 @@ public class DeclarationEngine {
     int end = context.getEnd();
     String prefix = context.getKey();
     IRegion region = new Region(start, end - start);
-    
+
     String identifier = null;
 
     SortedMap subMap = map.subMap(prefix, prefix + '\255');
@@ -105,14 +118,29 @@ public class DeclarationEngine {
         for (int i = 0; i < list.size(); i++) {
           location = (PHPIdentifierLocation) list.get(i);
           int type = location.getType();
-          if (fUseClassEntries) {
-            if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
-              continue; // for loop
-            }
-          } else {
-            if (type == PHPIdentifierLocation.METHOD || type == PHPIdentifierLocation.VARIABLE) {
-              continue; // for loop
-            }
+          switch (fLastSignificantToken) {
+            case ITerminalSymbols.TokenNameMINUS_GREATER :
+              if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
+                continue; // for loop
+              }
+              break;
+            case ITerminalSymbols.TokenNamethis :
+              if (type != PHPIdentifierLocation.METHOD && type != PHPIdentifierLocation.VARIABLE) {
+                continue; // for loop
+              }
+              if (!fFileName.equals(location.getFilename())) {
+                continue; // for loop
+              }
+              break;
+            case ITerminalSymbols.TokenNamenew :
+              if (type != PHPIdentifierLocation.CLASS && type != PHPIdentifierLocation.CONSTRUCTOR) {
+                continue; // for loop
+              }
+              break;
+            default :
+              if (type == PHPIdentifierLocation.METHOD || type == PHPIdentifierLocation.CONSTRUCTOR || type == PHPIdentifierLocation.VARIABLE) {
+                continue; // for loop
+              }
           }
           if (maxProposals-- < 0) {
             return;
index 83b3253..238423d 100644 (file)
@@ -77,7 +77,9 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
         case PHPIdentifierLocation.FUNCTION :
           document.replace(start, end - start, fIdentifierName + "()");
           break;
-
+        case PHPIdentifierLocation.CONSTRUCTOR :
+          document.replace(start, end - start, fIdentifierName + "()");
+          break;
         case PHPIdentifierLocation.METHOD :
           document.replace(start, end - start, fIdentifierName + "()");
           break;
@@ -107,7 +109,9 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
         case PHPIdentifierLocation.FUNCTION :
           editor.setFinalCaretOffset(fIdentifierName.length() + start + 1);
           break;
-
+        case PHPIdentifierLocation.CONSTRUCTOR :
+          editor.setFinalCaretOffset(fIdentifierName.length() + start + 1);
+          break;
         case PHPIdentifierLocation.METHOD :
           editor.setFinalCaretOffset(fIdentifierName.length() + start + 1);
           break;
@@ -151,8 +155,9 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
    * @see ICompletionProposal#getDisplayString()
    */
   public String getDisplayString() {
-    return fIdentifierName + TemplateMessages.getString("TemplateProposal.delimiter") + fIdentifierName; // $NON-NLS-1$ //$NON-NLS-1$
-    //         return fTemplate.getName() + ObfuscatorMessages.getString("TemplateProposal.delimiter") + fTemplate.getDescription(); // $NON-NLS-1$ //$NON-NLS-1$
+    String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+    String filename = workspaceLocation + fLocation.getFilename();
+    return fIdentifierName + TemplateMessages.getString("TemplateProposal.delimiter") + PHPDocUtil.getUsage(filename, fLocation) + TemplateMessages.getString("TemplateProposal.delimiter") + filename; // $NON-NLS-1$ //$NON-NLS-1$
   }
 
   /*
@@ -164,6 +169,8 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
         return PHPUiImages.get(PHPUiImages.IMG_FUN);
       case PHPIdentifierLocation.CLASS :
         return PHPUiImages.get(PHPUiImages.IMG_CLASS);
+      case PHPIdentifierLocation.CONSTRUCTOR :
+        return PHPUiImages.get(PHPUiImages.IMG_CLASS);
       case PHPIdentifierLocation.METHOD :
         return PHPUiImages.get(PHPUiImages.IMG_FUN);
       case PHPIdentifierLocation.DEFINE :
@@ -188,7 +195,9 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
         case '\n' :
         case '\t' :
           return 90;
-
+        case '>' : // ->
+        case ':' : // ::
+          return 95;
         default :
           return 0;
       }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/TableLayoutComposite.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/util/TableLayoutComposite.java
new file mode 100644 (file)
index 0000000..7624ed6
--- /dev/null
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnPixelData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * A special composite to layout columns inside a table. The composite is needed since we have
+ * to layout the columns "before" the actual table gets layouted. Hence we can't use a normal
+ * layout manager.
+ */
+public class TableLayoutComposite extends Composite {
+
+       private List columns= new ArrayList();
+
+       /**
+        * Creates a new <code>TableLayoutComposite</code>.
+        */
+       public TableLayoutComposite(Composite parent, int style) {
+               super(parent, style);
+        addControlListener(new ControlAdapter() {
+            public void controlResized(ControlEvent e) {
+                Rectangle area= getClientArea();
+                Table table= (Table)getChildren()[0];
+                Point preferredSize= computeTableSize(table);
+                int width= area.width - 2 * table.getBorderWidth();
+                if (preferredSize.y > area.height) {
+                    // Subtract the scrollbar width from the total column width
+                    // if a vertical scrollbar will be required
+                    Point vBarSize = table.getVerticalBar().getSize();
+                    width -= vBarSize.x;
+                }
+                layoutTable(table, width, area, table.getSize().x < area.width);
+            }
+        });
+       }
+       
+       /**
+        * Adds a new column of data to this table layout.
+        *
+        * @param data the column layout data
+        */
+       public void addColumnData(ColumnLayoutData data) {
+               columns.add(data);
+       }
+       
+       //---- Helpers -------------------------------------------------------------------------------------
+       
+       private Point computeTableSize(Table table) {
+               Point result= table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+               
+               int width= 0;
+               int size= columns.size();
+               for (int i= 0; i < size; ++i) {
+                       ColumnLayoutData layoutData= (ColumnLayoutData) columns.get(i);
+                       if (layoutData instanceof ColumnPixelData) {
+                               ColumnPixelData col= (ColumnPixelData) layoutData;
+                               width += col.width;
+                       } else if (layoutData instanceof ColumnWeightData) {
+                               ColumnWeightData col= (ColumnWeightData) layoutData;
+                               width += col.minimumWidth;
+                       } else {
+                               Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+                       }
+               }
+               if (width > result.x)
+                       result.x= width;
+               return result;
+       }
+       
+       private void layoutTable(Table table, int width, Rectangle area, boolean increase) {
+               // XXX: Layout is being called with an invalid value the first time
+               // it is being called on Linux. This method resets the
+               // Layout to null so we make sure we run it only when
+               // the value is OK.
+               if (width <= 1)
+                       return;
+
+               TableColumn[] tableColumns= table.getColumns();
+               int size= Math.min(columns.size(), tableColumns.length);
+               int[] widths= new int[size];
+               int fixedWidth= 0;
+               int numberOfWeightColumns= 0;
+               int totalWeight= 0;
+
+               // First calc space occupied by fixed columns
+               for (int i= 0; i < size; i++) {
+                       ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+                       if (col instanceof ColumnPixelData) {
+                               int pixels= ((ColumnPixelData) col).width;
+                               widths[i]= pixels;
+                               fixedWidth += pixels;
+                       } else if (col instanceof ColumnWeightData) {
+                               ColumnWeightData cw= (ColumnWeightData) col;
+                               numberOfWeightColumns++;
+                               // first time, use the weight specified by the column data, otherwise use the actual width as the weight
+                               // int weight = firstTime ? cw.weight : tableColumns[i].getWidth();
+                               int weight= cw.weight;
+                               totalWeight += weight;
+                       } else {
+                               Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$
+                       }
+               }
+
+               // Do we have columns that have a weight
+               if (numberOfWeightColumns > 0) {
+                       // Now distribute the rest to the columns with weight.
+                       int rest= width - fixedWidth;
+                       int totalDistributed= 0;
+                       for (int i= 0; i < size; ++i) {
+                               ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+                               if (col instanceof ColumnWeightData) {
+                                       ColumnWeightData cw= (ColumnWeightData) col;
+                                       // calculate weight as above
+                                       // int weight = firstTime ? cw.weight : tableColumns[i].getWidth();
+                                       int weight= cw.weight;
+                                       int pixels= totalWeight == 0 ? 0 : weight * rest / totalWeight;
+                                       if (pixels < cw.minimumWidth)
+                                               pixels= cw.minimumWidth;
+                                       totalDistributed += pixels;
+                                       widths[i]= pixels;
+                               }
+                       }
+
+                       // Distribute any remaining pixels to columns with weight.
+                       int diff= rest - totalDistributed;
+                       for (int i= 0; diff > 0; ++i) {
+                               if (i == size)
+                                       i= 0;
+                               ColumnLayoutData col= (ColumnLayoutData) columns.get(i);
+                               if (col instanceof ColumnWeightData) {
+                                       ++widths[i];
+                                       --diff;
+                               }
+                       }
+               }
+               
+               if (increase) {
+                       table.setSize(area.width, area.height);
+               }
+               for (int i= 0; i < size; i++) {
+                       tableColumns[i].setWidth(widths[i]);
+               }
+               if (!increase) {
+                       table.setSize(area.width, area.height);
+               }
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewClassCreationWizard.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewClassCreationWizard.java
new file mode 100644 (file)
index 0000000..a98164c
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.wizards.NewClassWizardPage;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+
+public class NewClassCreationWizard extends NewElementWizard {
+
+       private NewClassWizardPage fPage;
+
+       public NewClassCreationWizard() {
+               super();
+               setDefaultPageImageDescriptor(PHPUiImages.DESC_WIZBAN_NEWCLASS);
+               setDialogSettings(PHPeclipsePlugin.getDefault().getDialogSettings());
+               setWindowTitle(NewWizardMessages.getString("NewClassCreationWizard.title")); //$NON-NLS-1$
+       }
+
+       /*
+        * @see Wizard#createPages
+        */     
+       public void addPages() {
+               super.addPages();
+               fPage= new NewClassWizardPage();
+               addPage(fPage);
+               fPage.init(getSelection());
+       }       
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jdt.internal.ui.wizards.NewElementWizard#finishPage(org.eclipse.core.runtime.IProgressMonitor)
+        */
+       protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException {
+//             fPage.createType(monitor); // use the full progress monitor
+//             ICompilationUnit cu= JavaModelUtil.toOriginal(fPage.getCreatedType().getCompilationUnit());
+//             if (cu != null) {
+//                     IResource resource= cu.getResource();
+//                     selectAndReveal(resource);
+//                     openResource((IFile) resource);
+//             }       
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.wizard.IWizard#performFinish()
+        */
+       public boolean performFinish() {
+//             warnAboutTypeCommentDeprecation();
+               return super.performFinish();
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewElementWizard.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewElementWizard.java
new file mode 100644 (file)
index 0000000..65bc255
--- /dev/null
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import net.sourceforge.phpdt.internal.ui.actions.WorkbenchRunnableAdapter;
+import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
+
+
+public abstract class NewElementWizard extends Wizard implements INewWizard {
+
+       private IWorkbench fWorkbench;
+       private IStructuredSelection fSelection;
+
+       public NewElementWizard() {
+               setNeedsProgressMonitor(true);
+       }
+                       
+       protected void openResource(final IFile resource) {
+               final IWorkbenchPage activePage= PHPeclipsePlugin.getActivePage();
+               if (activePage != null) {
+                       final Display display= getShell().getDisplay();
+                       if (display != null) {
+                               display.asyncExec(new Runnable() {
+                                       public void run() {
+                                               try {
+                                                       activePage.openEditor(resource);
+                                               } catch (PartInitException e) {
+                                                       PHPeclipsePlugin.log(e);
+                                               }
+                                       }
+                               });
+                       }
+               }
+       }
+       
+       /**
+        * Subclasses should override to perform the actions of the wizard.
+        * This method is run in the wizard container's context as a workspace runnable.
+        */
+       protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException {
+       }
+       
+       protected void handleFinishException(Shell shell, InvocationTargetException e) {
+               String title= NewWizardMessages.getString("NewElementWizard.op_error.title"); //$NON-NLS-1$
+               String message= NewWizardMessages.getString("NewElementWizard.op_error.message"); //$NON-NLS-1$
+               ExceptionHandler.handle(e, shell, title, message);
+       }
+       
+       /*
+        * @see Wizard#performFinish
+        */             
+       public boolean performFinish() {
+               IWorkspaceRunnable op= new IWorkspaceRunnable() {
+                       public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException {
+                               try {
+                                       finishPage(monitor);
+                               } catch (InterruptedException e) {
+                                       throw new OperationCanceledException(e.getMessage());
+                               }
+                       }
+               };
+               try {
+                       getContainer().run(false, true, new WorkbenchRunnableAdapter(op));
+               } catch (InvocationTargetException e) {
+                       handleFinishException(getShell(), e);
+                       return false;
+               } catch  (InterruptedException e) {
+                       return false;
+               }
+               return true;
+       }
+       
+//     protected void warnAboutTypeCommentDeprecation() {
+//             String key= IUIConstants.DIALOGSTORE_TYPECOMMENT_DEPRECATED;
+//             if (OptionalMessageDialog.isDialogEnabled(key)) {
+//                     Templates templates= Templates.getInstance();
+//                     boolean isOldWorkspace= templates.getTemplates("filecomment").length > 0 && templates.getTemplates("typecomment").length > 0; //$NON-NLS-1$ //$NON-NLS-2$
+//                     if (!isOldWorkspace) {
+//                             OptionalMessageDialog.setDialogEnabled(key, false);
+//                     }
+//                     String title= NewWizardMessages.getString("NewElementWizard.typecomment.deprecated.title"); //$NON-NLS-1$
+//                     String message= NewWizardMessages.getString("NewElementWizard.typecomment.deprecated.message"); //$NON-NLS-1$
+//                     OptionalMessageDialog.open(key, getShell(), title, OptionalMessageDialog.getDefaultImage(), message, OptionalMessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0);
+//             }
+//     }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
+        */
+       public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
+               fWorkbench= workbench;
+               fSelection= currentSelection;
+       }
+       
+       public IStructuredSelection getSelection() {
+               return fSelection;
+       }
+
+       public IWorkbench getWorkbench() {
+               return fWorkbench;
+       }
+
+       protected void selectAndReveal(IResource newResource) {
+               BasicNewResourceWizard.selectAndReveal(newResource, fWorkbench.getActiveWorkbenchWindow());
+       }
+
+}
@@ -1,21 +1,29 @@
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-package net.sourceforge.phpeclipse.mover.obfuscator;
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards;
+
 
 import java.text.MessageFormat;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
-public class ObfuscatorMessages {
 
-       private static final String RESOURCE_BUNDLE= ObfuscatorMessages.class.getName();
+public class NewWizardMessages {
+
+       private static final String RESOURCE_BUNDLE= NewWizardMessages.class.getName();
        private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
 
-       private ObfuscatorMessages() {
+       private NewWizardMessages() {
        }
-
+               
        public static String getString(String key) {
                try {
                        return fgResourceBundle.getString(key);
@@ -33,11 +41,11 @@ public class ObfuscatorMessages {
                return MessageFormat.format(getString(key), new Object[] { arg });
        }
 
-
        /**
         * Gets a string from the resource bundle and formats it with arguments
         */     
        public static String getFormattedString(String key, Object[] args) {
                return MessageFormat.format(getString(key), args);
        }
+
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/NewWizardMessages.properties
new file mode 100644 (file)
index 0000000..add51e7
--- /dev/null
@@ -0,0 +1,564 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# ------- AbstractOpenWizardAction ------- 
+
+AbstractOpenWizardAction.noproject.title=New
+AbstractOpenWizardAction.noproject.message=A project needs to be created first.\nOpen the 'New Project' wizard'?
+
+AbstractOpenWizardAction.createerror.title=Open Wizard
+AbstractOpenWizardAction.createerror.message=The wizard could not be opened. See log for details.
+
+# ------- NewElementWizard ------- 
+
+NewElementWizard.op_error.title=New
+NewElementWizard.op_error.message=Creation of element failed.
+
+NewElementWizard.typecomment.deprecated.title=Type Creation
+NewElementWizard.typecomment.deprecated.message=You can configure the default layout of newly created files and types on the 'code generation' preference page.  This was previously implemented on the template page in the templates 'filecomment' and 'typecomment'.
+# ------- NewContainerWizardPage ------- 
+
+NewContainerWizardPage.container.label=Source Fol&der:
+NewContainerWizardPage.container.button=Br&owse...
+
+NewContainerWizardPage.error.EnterContainerName=Folder name is empty.
+NewContainerWizardPage.error.ContainerIsBinary=''{0}'' is a JAR archive.
+NewContainerWizardPage.error.ContainerDoesNotExist=Folder ''{0}'' does not exist.
+NewContainerWizardPage.error.NotAFolder=''{0}'' must be a project or folder.
+NewContainerWizardPage.error.ProjectClosed=Project ''{0}'' must be accessible.
+
+NewContainerWizardPage.warning.NotAJavaProject=Folder is not a Java project.
+NewContainerWizardPage.warning.NotInAJavaProject=Folder is not in a Java project.
+NewContainerWizardPage.warning.NotOnClassPath=Folder is not on the Java build class path.
+
+NewContainerWizardPage.ChooseSourceContainerDialog.title=Folder Selection
+NewContainerWizardPage.ChooseSourceContainerDialog.description=&Choose a folder:
+
+# ------- NewPackageWizardPage ------- 
+
+NewPackageCreationWizard.title=New Java Package
+
+NewPackageWizardPage.package.label=&Name:
+
+
+NewPackageWizardPage.error.InvalidPackageName=Invalid package name. {0}
+NewPackageWizardPage.error.IsOutputFolder=Name conflict with output folder.
+
+NewPackageWizardPage.error.PackageExists=Package already exists.
+NewPackageWizardPage.error.EnterName=Enter a package name.
+NewPackageWizardPage.warning.PackageNotShown=Package already exists. Note: Views might filter empty parent packages.
+NewPackageWizardPage.warning.DiscouragedPackageName=Discouraged package name. {0}
+
+NewPackageWizardPage.title=Java Package
+NewPackageWizardPage.description=Create a Java package.
+NewPackageWizardPage.info=Creates folders corresponding to packages.
+# ------- NewTypeWizardPage ------- 
+
+NewTypeWizardPage.package.label=Pac&kage:
+NewTypeWizardPage.package.button=Bro&wse...
+
+NewTypeWizardPage.enclosing.selection.label=Enclosing t&ype:
+NewTypeWizardPage.enclosing.button=Bro&wse...
+
+NewTypeWizardPage.error.InvalidPackageName=Package name is not valid. {0}
+NewTypeWizardPage.error.ClashOutputLocation=Package clashes with project output folder.
+NewTypeWizardPage.warning.DiscouragedPackageName=This package name is discouraged. {0}
+
+NewTypeWizardPage.default=(default)
+
+NewTypeWizardPage.ChoosePackageDialog.title=Package Selection
+NewTypeWizardPage.ChoosePackageDialog.description=&Choose a folder:
+NewTypeWizardPage.ChoosePackageDialog.empty=Cannot find packages to select.
+
+NewTypeWizardPage.ChooseEnclosingTypeDialog.title=Enclosing Type Selection
+NewTypeWizardPage.ChooseEnclosingTypeDialog.description=&Choose a type to which the new class will be added:
+
+NewTypeWizardPage.error.EnclosingTypeEnterName=Name of enclosing type must be entered.
+NewTypeWizardPage.error.EnclosingTypeNotExists=Enclosing type does not exist.
+NewTypeWizardPage.error.EnclosingNotInCU=Enclosing type is binary.
+NewTypeWizardPage.error.EnclosingNotEditable=Enclosing type is not editable.
+NewTypeWizardPage.warning.EnclosingNotInSourceFolder=Enclosing type is not in specified source folder.
+
+NewTypeWizardPage.typename.label=Na&me:
+
+NewTypeWizardPage.superclass.label=&Superclass:
+NewTypeWizardPage.superclass.button=Brows&e...
+
+NewTypeWizardPage.interfaces.class.label=&Interfaces:
+NewTypeWizardPage.interfaces.ifc.label=Extended &interfaces:
+NewTypeWizardPage.interfaces.add=&Add...
+NewTypeWizardPage.interfaces.remove=&Remove
+
+NewTypeWizardPage.modifiers.acc.label=Modifiers:
+NewTypeWizardPage.modifiers.public=&public
+NewTypeWizardPage.modifiers.private=pri&vate
+NewTypeWizardPage.modifiers.protected=pro&tected
+NewTypeWizardPage.modifiers.default=defa&ult
+NewTypeWizardPage.modifiers.abstract=abs&tract
+NewTypeWizardPage.modifiers.final=fina&l
+NewTypeWizardPage.modifiers.static=stati&c
+
+NewTypeWizardPage.error.EnterTypeName=Type name is empty.
+NewTypeWizardPage.error.TypeNameExists=Type already exists.
+NewTypeWizardPage.error.InvalidTypeName=Type name is not valid. {0}
+NewTypeWizardPage.error.QualifiedName=Type name must not be qualified.
+NewTypeWizardPage.warning.TypeNameDiscouraged=Type name is discouraged. {0}
+
+NewTypeWizardPage.error.InvalidSuperClassName=Superclass name is not valid.
+NewTypeWizardPage.warning.SuperClassNotExists=Warning: Superclass does not exist in current project.
+NewTypeWizardPage.warning.SuperClassIsFinal=Warning: Superclass ''{0}'' is final.
+NewTypeWizardPage.warning.SuperClassIsNotVisible=Warning: Superclass ''{0}'' is not visible.
+NewTypeWizardPage.warning.SuperClassIsNotClass=Warning: Superclass ''{0}'' is an interface.
+
+NewTypeWizardPage.warning.InterfaceIsNotVisible=Extended interface ''{0}'' is not visible.
+NewTypeWizardPage.warning.InterfaceNotExists=Extended interface ''{0}'' does not exist in current project.
+NewTypeWizardPage.warning.InterfaceIsNotInterface=Extended interface ''{0}'' is not an interface.
+
+NewTypeWizardPage.error.ModifiersFinalAndAbstract=Class cannot be both final and abstract
+
+NewTypeWizardPage.SuperClassDialog.title=Superclass Selection
+NewTypeWizardPage.SuperClassDialog.message=&Choose a type:
+
+NewTypeWizardPage.InterfacesDialog.class.title= Implemented Interfaces Selection
+NewTypeWizardPage.InterfacesDialog.interface.title= Extended Interfaces Selection
+NewTypeWizardPage.InterfacesDialog.message=&Choose interfaces:
+
+NewTypeWizardPage.operationdesc=Creating type....
+
+# ------- SuperInterfaceSelectionDialog -----
+
+SuperInterfaceSelectionDialog.addButton.label=&Add
+SuperInterfaceSelectionDialog.interfaceadded.info=''{0}'' added.
+
+# ------- NewClassWizardPage ------- 
+
+NewClassCreationWizard.title=New Java Class
+
+NewClassWizardPage.title=Java Class
+NewClassWizardPage.description=Create a new Java class.
+
+NewClassWizardPage.methods.label=Which method stubs would you like to create?
+NewClassWizardPage.methods.main=public static void main(Strin&g[] args)
+NewClassWizardPage.methods.constructors=&Constructors from superclass
+NewClassWizardPage.methods.inherited=In&herited abstract methods
+
+
+# ------- NewInterfaceWizardPage -------
+
+NewInterfaceCreationWizard.title=New Java Interface
+
+NewInterfaceWizardPage.title=Java Interface
+NewInterfaceWizardPage.description=Create a new Java interface.
+
+# ------- JavaCapabilityWizard ------- 
+
+JavaCapabilityWizard.title=Configure Java Capability
+JavaCapabilityWizard.op_error.title=Error Configure Java Capability
+JavaCapabilityWizard.op_error.message=An error occurred while configuring the Java project
+
+# ------- JavaCapabilityConfigurationPage ------- 
+
+JavaCapabilityConfigurationPage.title=Java Settings
+JavaCapabilityConfigurationPage.description=Define the Java build settings.
+JavaCapabilityConfigurationPage.op_desc_java=Configuring Java project...
+
+
+# ------- NewProjectCreationWizard ------- 
+
+NewProjectCreationWizard.title=New Java Project
+NewProjectCreationWizard.op_error.title=Error Creating Java Project
+NewProjectCreationWizard.op_error_create.message=An error occurred while creating the Java project
+NewProjectCreationWizard.MainPage.title=Java Project
+NewProjectCreationWizard.MainPage.description=Create a new Java project.
+
+NewProjectCreationWizardPage.op_error.title=Error Creating Java Project
+NewProjectCreationWizardPage.op_error_remove.message=An error occurred while removing a temporary project
+NewProjectCreationWizardPage.EarlyCreationOperation.desc=Creating project and examining existing resources...
+NewProjectCreationWizardPage.EarlyCreationOperation.error.title=New Java Project
+NewProjectCreationWizardPage.EarlyCreationOperation.error.desc=An error occurred while creating project. Check log for details.
+NewProjectCreationWizardPage.createproject.desc=Creating project...
+NewProjectCreationWizardPage.removeproject.desc=Removing project...
+
+# ------- NewJavaProjectWizardPage------- 
+
+NewJavaProjectWizardPage.title=Java Settings
+NewJavaProjectWizardPage.description=Define the Java build settings.
+
+NewJavaProjectWizardPage.op_desc=Creating Java project...
+
+
+# ------- NewSourceFolderWizardPage-------
+
+NewSourceFolderCreationWizard.title=New Source Folder
+
+NewSourceFolderWizardPage.title=Source folder
+NewSourceFolderWizardPage.description=Add a new source folder
+
+NewSourceFolderWizardPage.root.label=Fol&der name:
+NewSourceFolderWizardPage.root.button=Br&owse...
+
+NewSourceFolderWizardPage.project.label=Project &name:
+NewSourceFolderWizardPage.project.button=Bro&wse...
+
+NewSourceFolderWizardPage.exclude.label=&Update exclusion filters in other source folders to solve nesting.
+
+NewSourceFolderWizardPage.ChooseExistingRootDialog.title=Existing Folder Selection
+NewSourceFolderWizardPage.ChooseExistingRootDialog.description=&Choose folder as source folder:
+
+NewSourceFolderWizardPage.ChooseProjectDialog.title=Project Selection
+NewSourceFolderWizardPage.ChooseProjectDialog.description=&Choose project for the new source folder:
+
+NewSourceFolderWizardPage.error.EnterRootName=Root name must be entered.
+NewSourceFolderWizardPage.error.InvalidRootName=Invalid folder name. {0}
+NewSourceFolderWizardPage.error.NotAFolder=Not a folder.
+NewSourceFolderWizardPage.error.AlreadyExisting=Already a source folder.
+
+NewSourceFolderWizardPage.error.EnterProjectName=Project name must be entered.
+NewSourceFolderWizardPage.error.InvalidProjectPath=Invalid project path.
+NewSourceFolderWizardPage.error.NotAJavaProject=Project is not a Java project.
+NewSourceFolderWizardPage.error.ProjectNotExists=Project does not exist.
+
+NewSourceFolderWizardPage.warning.ReplaceSFandOL=To avoid overlapping, the existing project source folder entry will be replaced and the output folder set to ''{0}''.
+NewSourceFolderWizardPage.warning.ReplaceOL=An exclusion pattern will be added to the project source folder entry and the output folder will be set to ''{0}''.
+NewSourceFolderWizardPage.warning.ReplaceSF=To avoid overlapping, the existing project source folder entry will be replaced.
+NewSourceFolderWizardPage.warning.AddedExclusions=Exclusion patterns of {0} source folder(s) updated to solve nesting.
+
+# ------- NewSnippetFileWizardPage------- 
+
+NewSnippetFileCreationWizard.title=New Scrapbook Page
+
+NewSnippetFileWizardPage.title=Create Java Scrapbook Page
+
+NewSnippetFileWizardPage.error.AlreadyExists=A resource with the specified path already exists.
+NewSnippetFileWizardPage.error.OnlyInJavaProject=The scrapbook page can only be created in a Java project.
+
+NewSnippetFileWizardPage.open_error.message=Error in NewScrapbookPage
+
+# ------- BuildPathsBlock ------- 
+
+BuildPathsBlock.tab.source=&Source
+BuildPathsBlock.tab.projects=&Projects
+BuildPathsBlock.tab.libraries=&Libraries
+BuildPathsBlock.tab.order=&Order and Export
+
+BuildPathsBlock.classpath.label=Build &class path order and exported entries:\n(Exported entries are contributed to dependent projects)
+
+BuildPathsBlock.classpath.up.button=&Up
+BuildPathsBlock.classpath.down.button=&Down
+BuildPathsBlock.classpath.checkall.button=Select &All
+BuildPathsBlock.classpath.uncheckall.button=D&eselect All
+
+BuildPathsBlock.buildpath.label=Defaul&t output folder:
+BuildPathsBlock.buildpath.button=Bro&wse...
+
+BuildPathsBlock.error.InvalidBuildPath=Invalid build output folder: ''{0}''
+BuildPathsBlock.error.EnterBuildPath=Build output folder must be entered.
+
+BuildPathsBlock.warning.EntryMissing=Build path entry is missing: {0}
+BuildPathsBlock.warning.EntriesMissing={0} build path entries are missing.
+
+BuildPathsBlock.operationdesc_project=Creating project...
+BuildPathsBlock.operationdesc_java=Setting build paths...
+
+BuildPathsBlock.ChooseOutputFolderDialog.title=Folder Selection
+BuildPathsBlock.ChooseOutputFolderDialog.description=&Choose the folder for the build output:
+
+BuildPathsBlock.RemoveBinariesDialog.title=Setting Build Paths
+BuildPathsBlock.RemoveBinariesDialog.description=The output folder has changed. OK to remove all generated resources from the old location ''{0}''?
+
+# ------- CPListLabelProvider ------- 
+
+CPListLabelProvider.new=(new)
+CPListLabelProvider.classcontainer=(class folder)
+CPListLabelProvider.twopart={0} - {1}
+CPListLabelProvider.willbecreated=(will be created)
+
+
+# ------- SourceContainerWorkbookPage------- 
+
+SourceContainerWorkbookPage.folders.label=Source folders on build pat&h:
+SourceContainerWorkbookPage.folders.remove.button=&Remove
+SourceContainerWorkbookPage.folders.add.button=&Add Folder...
+SourceContainerWorkbookPage.folders.edit.button=&Edit...
+
+SourceContainerWorkbookPage.folders.check=Allow output folders for sour&ce folders.
+
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.new.title=Source Folder Selection
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.new.description=&Choose source folders to be added to the build path:
+
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.edit.title=Source Folder Selection
+SourceContainerWorkbookPage.ExistingSourceFolderDialog.edit.description=&Select the source folder:
+
+SourceContainerWorkbookPage.NewSourceFolderDialog.new.title=New Source Folder
+SourceContainerWorkbookPage.NewSourceFolderDialog.edit.title=Edit Source Folder
+
+SourceContainerWorkbookPage.NewSourceFolderDialog.description=&Enter a path relative to ''{0}'':
+
+SourceContainerWorkbookPage.ChangeOutputLocationDialog.title=Source Folder Added
+SourceContainerWorkbookPage.ChangeOutputLocationDialog.project_and_output.message=Do you want to remove the project as source folder and update build output folder to ''{0}''?
+SourceContainerWorkbookPage.ChangeOutputLocationDialog.project.message=Do you want to remove the project as source folder?
+
+SourceContainerWorkbookPage.exclusion_added.title=Source Folder Added
+SourceContainerWorkbookPage.exclusion_added.message=Exclusion filters have been added to nesting folders.
+
+# ------- ProjectsWorkbookPage------- 
+
+ProjectsWorkbookPage.projects.label=&Required projects on the build path:
+ProjectsWorkbookPage.projects.checkall.button=Select &All
+ProjectsWorkbookPage.projects.uncheckall.button=&Deselect All
+
+# ------- LibrariesWorkbookPage------- 
+
+LibrariesWorkbookPage.libraries.label=JARs &and class folders on the build path:
+LibrariesWorkbookPage.libraries.remove.button=&Remove
+       
+LibrariesWorkbookPage.libraries.addjar.button=Add &JARs...
+LibrariesWorkbookPage.libraries.addextjar.button=Add E&xternal JARs...
+LibrariesWorkbookPage.libraries.addvariable.button=Add &Variable...
+LibrariesWorkbookPage.libraries.addlibrary.button=Add Li&brary...
+LibrariesWorkbookPage.libraries.addclassfolder.button=Add Class &Folder...
+
+
+LibrariesWorkbookPage.libraries.edit.button=&Edit...
+
+LibrariesWorkbookPage.ExistingClassFolderDialog.new.title=Class Folder Selection
+LibrariesWorkbookPage.ExistingClassFolderDialog.new.description=&Choose class folders to be added to the build path:
+
+LibrariesWorkbookPage.ExistingClassFolderDialog.edit.title=Edit Class Folder
+LibrariesWorkbookPage.ExistingClassFolderDialog.edit.description=&Select the class folder:
+
+LibrariesWorkbookPage.NewClassFolderDialog.new.title=New Class Folder
+LibrariesWorkbookPage.NewClassFolderDialog.edit.title=Edit Class Folder
+
+LibrariesWorkbookPage.NewClassFolderDialog.description=&Enter a path relative to ''{0}'':
+
+LibrariesWorkbookPage.JARArchiveDialog.new.title=JAR Selection
+LibrariesWorkbookPage.JARArchiveDialog.new.description=&Choose jar archives to be added to the build path:
+
+LibrariesWorkbookPage.JARArchiveDialog.edit.title=Edit JAR
+LibrariesWorkbookPage.JARArchiveDialog.edit.description=&Select the jar archive:
+
+LibrariesWorkbookPage.ContainerDialog.new.title=Add Library
+LibrariesWorkbookPage.ContainerDialog.edit.title=Edit Library
+
+LibrariesWorkbookPage.VariableSelectionDialog.new.title=New Variable Classpath Entry
+LibrariesWorkbookPage.VariableSelectionDialog.edit.title=Edit Variable Entry
+
+LibrariesWorkbookPage.ExtJARArchiveDialog.new.title=JAR Selection
+
+LibrariesWorkbookPage.ExtJARArchiveDialog.edit.title=Edit JAR
+
+LibrariesWorkbookPage.SourceAttachmentDialog.title=Source For ''{0}''
+LibrariesWorkbookPage.JavadocPropertyDialog.title=Javadoc For ''{0}''
+
+LibrariesWorkbookPage.AdvancedDialog.title=Add Classpath Entry
+LibrariesWorkbookPage.AdvancedDialog.description=Select the entry to add to the classpath:
+LibrariesWorkbookPage.AdvancedDialog.createfolder=Create &New Class Folder
+LibrariesWorkbookPage.AdvancedDialog.addfolder=Add &Existing Class Folder
+LibrariesWorkbookPage.AdvancedDialog.addcontainer=Add &Container:
+
+# ------- NewContainerDialog------- 
+
+NewContainerDialog.error.invalidpath=Invalid folder path: ''{0}''
+NewContainerDialog.error.enterpath=Folder name must be entered
+NewContainerDialog.error.pathexists=This folder is already in the list or it is an output folder.
+# ------- NewSourceFolderDialog------- 
+
+NewSourceFolderDialog.error.invalidpath=Invalid folder path: ''{0}''
+NewSourceFolderDialog.error.enterpath=Folder name must be entered.
+NewSourceFolderDialog.error.pathexists=The folder is already in the list.
+
+# ------- SourceAttachmentBlock------- 
+
+SourceAttachmentBlock.message=Select the location (folder, JAR or zip) containing the source for ''{0}'':
+SourceAttachmentBlock.filename.description=Source attachments for variable entries are defined by variable paths. The first segment of such a path describes a variable name, the rest is an optional path extension.
+
+SourceAttachmentBlock.filename.label=Lo&cation path:
+SourceAttachmentBlock.filename.externalfile.button=External &File...
+SourceAttachmentBlock.filename.externalfolder.button=External F&older...
+SourceAttachmentBlock.filename.internal.button=&Workspace...
+
+SourceAttachmentBlock.filename.varlabel=Lo&cation variable path:
+SourceAttachmentBlock.filename.variable.button=&Variable...
+SourceAttachmentBlock.filename.external.varbutton=&Extension....
+
+SourceAttachmentBlock.filename.error.notvalid=The archive path is not a valid path.
+SourceAttachmentBlock.filename.error.filenotexists=The path ''{0}'' does not exist.
+SourceAttachmentBlock.filename.error.varnotexists=Variable in the location path does not exist.
+SourceAttachmentBlock.filename.error.deviceinpath=Location must be described a variable path.
+SourceAttachmentBlock.filename.warning.varempty=Location variable path is empty.
+
+SourceAttachmentBlock.intjardialog.title=Source Location Selection
+SourceAttachmentBlock.intjardialog.message=&Select folder or JAR/zip archive containing the source:
+
+SourceAttachmentBlock.extvardialog.title=Variable Extension Selection
+SourceAttachmentBlock.extvardialog.description=Select source location:
+
+SourceAttachmentBlock.extjardialog.text=JAR/ZIP File Selection
+SourceAttachmentBlock.extfolderdialog.text=Folder Selection
+
+SourceAttachmentBlock.putoncpdialog.title=Setting Source Attachment
+SourceAttachmentBlock.putoncpdialog.message=Source can only be attached to libraries on the build path.\nDo you want to add the library to the build path?
+
+SourceAttachmentDialog.title=Source Attachment Configuration
+SourceAttachmentDialog.error.title=Error Attaching Source
+SourceAttachmentDialog.error.message=An error occurred while associating the source.
+
+# ------- EditVariableEntryDialog ------- 
+
+EditVariableEntryDialog.filename.varlabel=Edit classpath variable entry:
+EditVariableEntryDialog.filename.variable.button=&Variable...
+EditVariableEntryDialog.filename.external.varbutton=&Extension....
+
+EditVariableEntryDialog.extvardialog.title=Variable Extension Selection
+EditVariableEntryDialog.extvardialog.description=Select JAR archive:
+
+EditVariableEntryDialog.filename.error.notvalid=The archive path is not a valid path.
+EditVariableEntryDialog.filename.error.filenotexists=The path ''{0}'' does not point to an existing archive.
+EditVariableEntryDialog.filename.error.varnotexists=Variable in the archive path does not exist.
+EditVariableEntryDialog.filename.error.deviceinpath=The archive has to be described by a variable path.
+EditVariableEntryDialog.filename.warning.varempty=Archive variable path is empty.
+EditVariableEntryDialog.filename.error.alreadyexists=Classpath entry already exists.
+
+
+# ------- VariableBlock------- 
+
+VariableBlock.vars.label=Defined &classpath variables:
+VariableBlock.vars.add.button=Ne&w...
+VariableBlock.vars.edit.button=&Edit...
+VariableBlock.vars.remove.button=&Remove
+VariableBlock.operation_desc=Setting classpath variables...
+
+VariableBlock.operation_errror.title=Classpath Variables
+VariableBlock.operation_errror.message=Problem while setting classpath variable. See log for details.
+
+VariableBlock.needsbuild.title=Classpath Variables Changed
+VariableBlock.needsbuild.message=The classpath variables have changed. A full rebuild is recommended to make changes effective. Do the full build now?
+
+VariablePathDialogField.variabledialog.title=Variable Selection
+
+CPVariableElementLabelProvider.reserved=(reserved)
+CPVariableElementLabelProvider.empty=(empty)
+
+# ------- VariableCreationDialog------- 
+
+VariableCreationDialog.titlenew=New Variable Entry
+VariableCreationDialog.titleedit=Edit Variable Entry
+       
+VariableCreationDialog.name.label=&Name:
+VariableCreationDialog.path.label=&Path:
+VariableCreationDialog.path.file.button=&File...
+VariableCreationDialog.path.dir.button=F&older...
+
+VariableCreationDialog.error.entername=Variable name must be entered.
+VariableCreationDialog.error.invalidname=Invalid name: ''{0}''.
+VariableCreationDialog.error.nameexists=Variable name already exists.
+VariableCreationDialog.error.invalidpath=The path is invalid.
+
+VariableCreationDialog.warning.pathnotexists=Path does not exist.
+
+
+VariableCreationDialog.extjardialog.text=JAR Selection
+VariableCreationDialog.extdirdialog.text=Folder Selection
+VariableCreationDialog.extdirdialog.message=&Specify folder to be represented by the variable:
+
+# ------- NewVariableEntryDialog ------- 
+NewVariableEntryDialog.vars.extend=E&xtend...
+NewVariableEntryDialog.vars.config=&Edit...
+
+NewVariableEntryDialog.vars.label=Select &variables to add to build path:
+
+NewVariableEntryDialog.ExtensionDialog.title=Variable Extension
+NewVariableEntryDialog.ExtensionDialog.description=Choose extensions to ''{0}''.
+
+NewVariableEntryDialog.info.isfolder=Variable points to a folder: Click 'extend' to choose an archive inside the folder.
+NewVariableEntryDialog.info.noselection=Select variable(s) to add to the classpath.
+NewVariableEntryDialog.info.selected={0} variables selected.
+
+# ------- OutputLocationDialog ------- 
+
+OutputLocationDialog.title=Source Folder Output Location
+
+OutputLocationDialog.usedefault.label=Project's default output folder.
+OutputLocationDialog.usespecific.label=Specific output folder (path relative to ''{0}'').
+OutputLocationDialog.location.button=Bro&wse...
+
+OutputLocationDialog.error.existingisfile=Location is an existing file
+OutputLocationDialog.error.invalidpath=Invalid path: {0}
+
+OutputLocationDialog.ChooseOutputFolder.title=Folder Selection
+OutputLocationDialog.ChooseOutputFolder.description=&Choose the folder for the build output:
+
+# ------- ExclusionPatternDialog ------- 
+
+ExclusionPatternDialog.title=Source Folder Exclusion Patterns
+
+ExclusionPatternDialog.pattern.label=E&xclusion patterns for ''{0}'':
+ExclusionPatternDialog.pattern.add=A&dd...
+ExclusionPatternDialog.pattern.add.multiple=Add &Multiple...
+ExclusionPatternDialog.pattern.remove=&Remove
+ExclusionPatternDialog.pattern.edit=&Edit...
+
+ExclusionPatternDialog.ChooseExclusionPattern.title=Exclusion Pattern Selection
+ExclusionPatternDialog.ChooseExclusionPattern.description=&Choose folders or files to exclude:
+
+# ------- ExclusionPatternEntryDialog ------- 
+
+ExclusionPatternEntryDialog.add.title=Add Exclusion Pattern
+ExclusionPatternEntryDialog.edit.title=Edit Exclusion Pattern
+ExclusionPatternEntryDialog.description=Enter a pattern for excluding files from the source folder. Allowed wildcards are '*', '?' and '**'. Examples: 'java/util/A*.java', 'java/util/', '**/Test*'.
+
+ExclusionPatternEntryDialog.pattern.label=E&xclusion pattern (Path relative to ''{0}''):
+ExclusionPatternEntryDialog.pattern.button=Bro&wse...
+
+ExclusionPatternEntryDialog.error.empty=Enter a pattern.
+ExclusionPatternEntryDialog.error.notrelative=Pattern must be a relative path.
+ExclusionPatternEntryDialog.error.exists=Pattern already exists.
+
+ExclusionPatternEntryDialog.ChooseExclusionPattern.title=Exclusion Pattern Selection
+ExclusionPatternEntryDialog.ChooseExclusionPattern.description=&Choose a folder or file to exclude:
+
+# ------- ClasspathContainerDefaultPage------- 
+
+ClasspathContainerDefaultPage.title=Classpath Container
+ClasspathContainerDefaultPage.description=Select classpath container path. First segment is the container type.
+
+ClasspathContainerDefaultPage.path.label=&Classpath container path:
+
+ClasspathContainerDefaultPage.path.error.enterpath=Enter path.
+ClasspathContainerDefaultPage.path.error.invalidpath=Invalid path.
+ClasspathContainerDefaultPage.path.error.needssegment=Path needs at least one segment.
+ClasspathContainerDefaultPage.path.error.alreadyexists=Entry already exists.
+
+# ------- ClasspathContainerSelectionPage------- 
+
+ClasspathContainerSelectionPage.title=Add Library
+ClasspathContainerSelectionPage.description=Select the library type to add.
+
+# ------- ClasspathContainerWizard------- 
+
+ClasspathContainerWizard.pagecreationerror.title= Library Wizard
+ClasspathContainerWizard.pagecreationerror.message=Wizard page creation failed. Check log for details.
+
+
+FolderSelectionDialog.button=Create New Folder...
+CPListLabelProvider.none=(None)
+CPListLabelProvider.source_attachment.label=Source attachment: 
+CPListLabelProvider.source_attachment_root.label=Source attachment root: 
+CPListLabelProvider.javadoc_location.label=Javadoc location: 
+CPListLabelProvider.output_folder.label=Output folder: 
+CPListLabelProvider.default_output_folder.label=(Default output folder)
+CPListLabelProvider.exclusion_filter.label=Exclusion filter: 
+CPListLabelProvider.exclusion_filter_separator=; 
+CPListLabelProvider.unknown_element.label=unknown element
+NewSourceFolderDialog.useproject.button=&Project as source folder
+NewSourceFolderDialog.usefolder.button=&Folder as source folder
+NewSourceFolderDialog.sourcefolder.label=&Source folder name:
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/CheckedListDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/CheckedListDialogField.java
new file mode 100644 (file)
index 0000000..755815f
--- /dev/null
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * A list with checkboxes and a button bar. Typical buttons are 'Check All' and 'Uncheck All'.
+ * List model is independend of widget creation.
+ * DialogFields controls are: Label, List and Composite containing buttons.
+ */
+public class CheckedListDialogField extends ListDialogField {
+       
+       private int fCheckAllButtonIndex;
+       private int fUncheckAllButtonIndex;
+       
+       private List fCheckElements;
+
+       public CheckedListDialogField(IListAdapter adapter, String[] customButtonLabels, ILabelProvider lprovider) {
+               super(adapter, customButtonLabels, lprovider);
+               fCheckElements= new ArrayList();
+               
+               fCheckAllButtonIndex= -1;
+               fUncheckAllButtonIndex= -1;
+       }
+
+       /**
+        * Sets the index of the 'check' button in the button label array passed in the constructor.
+        * The behaviour of the button marked as the check button will then be handled internally.
+        * (enable state, button invocation behaviour)
+        */     
+       public void setCheckAllButtonIndex(int checkButtonIndex) {
+               Assert.isTrue(checkButtonIndex < fButtonLabels.length);
+               fCheckAllButtonIndex= checkButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'uncheck' button in the button label array passed in the constructor.
+        * The behaviour of the button marked as the uncheck button will then be handled internally.
+        * (enable state, button invocation behaviour)
+        */     
+       public void setUncheckAllButtonIndex(int uncheckButtonIndex) {
+               Assert.isTrue(uncheckButtonIndex < fButtonLabels.length);
+               fUncheckAllButtonIndex= uncheckButtonIndex;
+       }
+       
+
+       /*
+        * @see ListDialogField#createTableViewer
+        */
+       protected TableViewer createTableViewer(Composite parent) {
+               Table table= new Table(parent, SWT.CHECK + getListStyle());
+               CheckboxTableViewer tableViewer= new CheckboxTableViewer(table);
+               tableViewer.addCheckStateListener(new ICheckStateListener() {
+                       public void checkStateChanged(CheckStateChangedEvent e) {
+                               doCheckStateChanged(e);
+                       }
+               });
+               return tableViewer;
+       }               
+       
+       
+       /*
+        * @see ListDialogField#getListControl
+        */
+       public Control getListControl(Composite parent) {
+               Control control= super.getListControl(parent);
+               if (parent != null) {
+                       ((CheckboxTableViewer)fTable).setCheckedElements(fCheckElements.toArray());
+               }
+               return control;
+       }       
+       
+       /*
+        * @see DialogField#dialogFieldChanged
+        * Hooks in to get element changes to update check model.
+        */
+       public void dialogFieldChanged() {
+               for (int i= fCheckElements.size() -1; i >= 0; i--) {
+                       if (!fElements.contains(fCheckElements.get(i))) {
+                               fCheckElements.remove(i);
+                       }
+               }
+               super.dialogFieldChanged();
+       }       
+       
+       private void checkStateChanged() {
+               //call super and do not update check model
+               super.dialogFieldChanged();
+       }               
+
+       /**
+        * Gets the checked elements.
+        */
+       public List getCheckedElements() {
+               return new ArrayList(fCheckElements);
+       }
+       
+       /**
+        * Returns true if the element is checked.
+        */
+       public boolean isChecked(Object obj) {
+               return fCheckElements.contains(obj);
+       }       
+       
+       /**
+        * Sets the checked elements.
+        */     
+       public void setCheckedElements(List list) {
+               fCheckElements= new ArrayList(list);
+               if (fTable != null) {
+                       ((CheckboxTableViewer)fTable).setCheckedElements(list.toArray());
+               }
+               checkStateChanged();
+       }
+
+       /**
+        * Sets the checked state of an element.
+        */             
+       public void setChecked(Object object, boolean state) {
+               setCheckedWithoutUpdate(object, state);
+               checkStateChanged();
+       }
+       
+       /**
+        * Sets the checked state of an element. No dialog changed listener is informed.
+        */             
+       public void setCheckedWithoutUpdate(Object object, boolean state) {
+               if (!fCheckElements.contains(object)) {
+                       fCheckElements.add(object);
+               }
+               if (fTable != null) {
+                       ((CheckboxTableViewer)fTable).setChecked(object, state);
+               }
+       }
+
+       /**
+        * Sets the check state of all elements
+        */     
+       public void checkAll(boolean state) {
+               if (state) {
+                       fCheckElements= getElements();
+               } else {
+                       fCheckElements.clear();
+               }
+               if (fTable != null) {
+                       ((CheckboxTableViewer)fTable).setAllChecked(state);
+               }
+               checkStateChanged();
+       }
+       
+                       
+       private void doCheckStateChanged(CheckStateChangedEvent e) {
+               if (e.getChecked()) {
+                       fCheckElements.add(e.getElement());
+               } else {
+                       fCheckElements.remove(e.getElement());
+               }               
+               checkStateChanged();
+       }
+       
+       // ------ enable / disable management
+       
+       /*
+        * @see ListDialogField#getManagedButtonState
+        */
+       protected boolean getManagedButtonState(ISelection sel, int index) {
+               if (index == fCheckAllButtonIndex) {
+                       return !fElements.isEmpty();
+               } else if (index == fUncheckAllButtonIndex) {
+                       return !fElements.isEmpty();
+               }
+               return super.getManagedButtonState(sel, index);
+       }       
+
+       /*
+        * @see ListDialogField#extraButtonPressed
+        */     
+       protected boolean managedButtonPressed(int index) {
+               if (index == fCheckAllButtonIndex) {
+                       checkAll(true);
+               } else if (index == fUncheckAllButtonIndex) {
+                       checkAll(false);
+               } else {
+                       return super.managedButtonPressed(index);
+               }
+               return true;
+       }
+       
+                               
+       
+       
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ComboDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ComboDialogField.java
new file mode 100644 (file)
index 0000000..6803557
--- /dev/null
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Dialog field containing a label and a combo control.
+ */
+public class ComboDialogField extends DialogField {
+               
+       private String fText;
+       private int fSelectionIndex;
+       private String[] fItems;
+       private Combo fComboControl;
+       private ModifyListener fModifyListener;
+       private int fFlags;
+       
+       public ComboDialogField(int flags) {
+               super();
+               fText= ""; //$NON-NLS-1$
+               fItems= new String[0];
+               fFlags= flags;
+               fSelectionIndex= -1;
+       }
+                       
+       // ------- layout helpers
+               
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+               
+               Label label= getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Combo combo= getComboControl(parent);
+               combo.setLayoutData(gridDataForCombo(nColumns - 1));
+               
+               return new Control[] { label, combo };
+       } 
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 2;       
+       }
+       
+       protected static GridData gridDataForCombo(int span) {
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.horizontalSpan= span;
+               return gd;
+       }       
+       
+       // ------- focus methods
+       
+       /*
+        * @see DialogField#setFocus
+        */
+       public boolean setFocus() {
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setFocus();
+               }
+               return true;
+       }
+               
+       // ------- ui creation                  
+
+       /**
+        * Creates or returns the created combo control.
+        * @param parent The parent composite or <code>null</code> when the widget has
+        * already been created.
+        */             
+       public Combo getComboControl(Composite parent) {
+               if (fComboControl == null) {
+                       assertCompositeNotNull(parent);
+                       fModifyListener= new ModifyListener() {
+                               public void modifyText(ModifyEvent e) {
+                                       doModifyText(e);
+                               }
+                       };
+                       SelectionListener selectionListener= new SelectionListener() {
+                               public void widgetSelected(SelectionEvent e) {
+                                       doSelectionChanged(e);
+                               }
+                               
+                               public void widgetDefaultSelected(SelectionEvent e) {   };
+                       };
+                       
+                       fComboControl= new Combo(parent, fFlags);
+                       // moved up due to 1GEUNW2
+                       fComboControl.setItems(fItems);
+                       if (fSelectionIndex != -1) {
+                               fComboControl.select(fSelectionIndex);
+                       } else {
+                               fComboControl.setText(fText);
+                       }
+                       fComboControl.setFont(parent.getFont());
+                       fComboControl.addModifyListener(fModifyListener);
+                       fComboControl.addSelectionListener(selectionListener);
+                       fComboControl.setEnabled(isEnabled());
+               }
+               return fComboControl;
+       }       
+       
+       private void doModifyText(ModifyEvent e) {
+               if (isOkToUse(fComboControl)) {
+                       fText= fComboControl.getText();
+                       fSelectionIndex= fComboControl.getSelectionIndex();
+               }
+               dialogFieldChanged();
+       }
+       
+       private void doSelectionChanged(SelectionEvent e) {
+               if (isOkToUse(fComboControl)) {
+                       fItems= fComboControl.getItems();
+                       fText= fComboControl.getText();
+                       fSelectionIndex= fComboControl.getSelectionIndex();
+               }
+               dialogFieldChanged();   
+       }
+       
+       // ------ enable / disable management
+       
+       /*
+        * @see DialogField#updateEnableState
+        */             
+       protected void updateEnableState() {
+               super.updateEnableState();              
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setEnabled(isEnabled());
+               }       
+       }               
+               
+       // ------ text access 
+       
+       /**
+        * Gets the combo items.
+        */     
+       public String[] getItems() {
+               return fItems;
+       }
+       
+       /**
+        * Sets the combo items. Triggers a dialog-changed event.
+        */
+       public void setItems(String[] items) {
+               fItems= items;
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setItems(items);
+               }
+               dialogFieldChanged();
+       }
+       
+       /**
+        * Gets the text.
+        */     
+       public String getText() {
+               return fText;
+       }
+       
+       /**
+        * Sets the text. Triggers a dialog-changed event.
+        */
+       public void setText(String text) {
+               fText= text;
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.setText(text);
+               } else {
+                       dialogFieldChanged();
+               }       
+       }
+
+       /**
+        * Selects an item.
+        */     
+       public void selectItem(int index) {
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.select(index);
+               } else {
+                       if (index >= 0 && index < fItems.length) {
+                               fText= fItems[index];
+                               fSelectionIndex= index; 
+                       }
+               }
+               dialogFieldChanged();
+       }
+       
+       public int getSelectionIndex() {
+               return fSelectionIndex;
+       }
+       
+
+       /**
+        * Sets the text without triggering a dialog-changed event.
+        */
+       public void setTextWithoutUpdate(String text) {
+               fText= text;
+               if (isOkToUse(fComboControl)) {
+                       fComboControl.removeModifyListener(fModifyListener);
+                       fComboControl.setText(text);
+                       fComboControl.addModifyListener(fModifyListener);
+               }
+       }
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/DialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/DialogField.java
new file mode 100644 (file)
index 0000000..ac4f483
--- /dev/null
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Base class of all dialog fields.
+ * Dialog fields manage controls together with the model, independed
+ * from the creation time of the widgets.
+ * - support for automated layouting.
+ * - enable / disable, set focus a concept of the base class.
+ * 
+ * DialogField have a label.
+ */ 
+public class DialogField {
+
+       private Label fLabel;
+       protected String fLabelText;
+       
+       private IDialogFieldListener fDialogFieldListener;
+       
+       private boolean fEnabled;
+
+       public DialogField() {
+               fEnabled= true;
+               fLabel= null;
+               fLabelText= ""; //$NON-NLS-1$
+       }
+       
+       /**
+        * Sets the label of the dialog field.
+        */
+       public void setLabelText(String labeltext) {
+               fLabelText= labeltext;
+       }
+               
+       // ------ change listener
+       
+       /**
+        * Defines the listener for this dialog field.
+        */     
+       public final void setDialogFieldListener(IDialogFieldListener listener) {
+               fDialogFieldListener= listener;
+       }
+
+       /**
+        * Programatical invocation of a dialog field change.
+        */             
+       public void dialogFieldChanged() {
+               if (fDialogFieldListener != null) {
+                       fDialogFieldListener.dialogFieldChanged(this);
+               }
+       }       
+       
+       // ------- focus management
+       
+       /**
+        * Tries to set the focus to the dialog field.
+        * Returns <code>true</code> if the dialog field can take focus.
+        *      To be reimplemented by dialog field implementors.
+        */
+       public boolean setFocus() {
+               return false;
+       }
+
+       /**
+        * Posts <code>setFocus</code> to the display event queue.
+        */     
+       public void postSetFocusOnDialogField(Display display) {
+               if (display != null) {
+                       display.asyncExec(
+                               new Runnable() {
+                                       public void run() {
+                                               setFocus();
+                                       }
+                               }
+                       );
+               }
+       }               
+       
+       // ------- layout helpers
+       
+       /**
+        * Creates all controls of the dialog field and fills it to a composite.
+        * The composite is assumed to have <code>MGridLayout</code> as
+        * layout.
+        * The dialog field will adjust its controls' spans to the number of columns given.
+        *      To be reimplemented by dialog field implementors.
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+               
+               Label label= getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(nColumns));
+               
+               return new Control[] { label };
+       }
+       
+       /**
+        * Returns the number of columns of the dialog field.
+        *      To be reimplemented by dialog field implementors.
+        */
+       public int getNumberOfControls() {
+               return 1;       
+       }       
+       
+       protected static GridData gridDataForLabel(int span) {
+               GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+               gd.horizontalSpan= span;
+               return gd;
+       }
+       
+       // ------- ui creation
+
+       /**
+        * Creates or returns the created label widget.
+        * @param parent The parent composite or <code>null</code> if the widget has
+        * already been created.
+        */                     
+       public Label getLabelControl(Composite parent) {
+               if (fLabel == null) {
+                       assertCompositeNotNull(parent);
+                       
+                       fLabel= new Label(parent, SWT.LEFT | SWT.WRAP);
+                       fLabel.setFont(parent.getFont());
+                       fLabel.setEnabled(fEnabled);            
+                       if (fLabelText != null && !"".equals(fLabelText)) { //$NON-NLS-1$
+                               fLabel.setText(fLabelText);
+                       } else {
+                               // XXX: to avoid a 16 pixel wide empty label - revisit
+                               fLabel.setText("."); //$NON-NLS-1$
+                               fLabel.setVisible(false);
+                       }                       
+               }
+               return fLabel;
+       }
+
+       /**
+        * Creates a spacer control.
+        * @param parent The parent composite
+        */             
+       public static Control createEmptySpace(Composite parent) {
+               return createEmptySpace(parent, 1);
+       }
+
+       /**
+        * Creates a spacer control with the given span.
+        * The composite is assumed to have <code>MGridLayout</code> as
+        * layout.
+        * @param parent The parent composite
+        */                     
+       public static Control createEmptySpace(Composite parent, int span) {
+               Label label= new Label(parent, SWT.LEFT);
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.BEGINNING;
+               gd.grabExcessHorizontalSpace= false;
+               gd.horizontalSpan= span;
+               gd.horizontalIndent= 0;
+               gd.widthHint= 0;
+               gd.heightHint= 0;
+               label.setLayoutData(gd);
+               return label;
+       }
+       
+       /**
+        * Tests is the control is not <code>null</code> and not disposed.
+       */
+       protected final boolean isOkToUse(Control control) {
+               return (control != null) && !(control.isDisposed());
+       }
+       
+       // --------- enable / disable management
+       
+       /**
+        * Sets the enable state of the dialog field.
+        */
+       public final void setEnabled(boolean enabled) {
+               if (enabled != fEnabled) {
+                       fEnabled= enabled;
+                       updateEnableState();
+               }
+       }
+       
+       /**
+        * Called when the enable state changed.
+        * To be extended by dialog field implementors.
+        */
+       protected void updateEnableState() {
+               if (fLabel != null) {
+                       fLabel.setEnabled(fEnabled);
+               }
+       }
+
+       /**
+        * Gets the enable state of the dialog field.
+        */     
+       public final boolean isEnabled() {
+               return fEnabled;
+       }
+
+       protected final void assertCompositeNotNull(Composite comp) {
+               Assert.isNotNull(comp, "uncreated control requested with composite null"); //$NON-NLS-1$
+       }
+       
+       protected final void assertEnoughColumns(int nColumns) {
+               Assert.isTrue(nColumns >= getNumberOfControls(), "given number of columns is too small"); //$NON-NLS-1$
+       }
+       
+       
+
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IDialogFieldListener.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IDialogFieldListener.java
new file mode 100644 (file)
index 0000000..cbee35c
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+/**
+ * Change listener used by <code>DialogField</code>
+ */
+public interface IDialogFieldListener {
+       
+       /**
+        * The dialog field has changed.
+        */
+       void dialogFieldChanged(DialogField field);
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IListAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IListAdapter.java
new file mode 100644 (file)
index 0000000..79db768
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+/**
+ * Change listener used by <code>ListDialogField</code> and <code>CheckedListDialogField</code>
+ */
+public interface IListAdapter {
+       
+       /**
+        * A button from the button bar has been pressed.
+        */
+       void customButtonPressed(ListDialogField field, int index);
+       
+       /**
+        * The selection of the list has changed.
+        */     
+       void selectionChanged(ListDialogField field);
+       
+       /**
+        * En entry in the list has been double clicked
+        */
+       void doubleClicked(ListDialogField field);      
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IStringButtonAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/IStringButtonAdapter.java
new file mode 100644 (file)
index 0000000..81be1b9
--- /dev/null
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+/**
+ * Change listener used by <code>StringButtonDialogField</code>
+ */
+public interface IStringButtonAdapter {
+       
+       void changeControlPressed(DialogField field);
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ITreeListAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ITreeListAdapter.java
new file mode 100644 (file)
index 0000000..8aa130d
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.events.KeyEvent;
+
+/**
+ * Change listener used by <code>TreeListDialogField</code>
+ */
+public interface ITreeListAdapter {
+       
+       /**
+        * A button from the button bar has been pressed.
+        */
+       void customButtonPressed(TreeListDialogField field, int index);
+       
+       /**
+        * The selection of the list has changed.
+        */     
+       void selectionChanged(TreeListDialogField field);
+
+       /**
+        * The list has been double clicked
+        */
+       void doubleClicked(TreeListDialogField field);
+
+       /**
+        * A key has been pressed
+        */
+       void keyPressed(TreeListDialogField field, KeyEvent event);
+
+       Object[] getChildren(TreeListDialogField field, Object element);
+
+       Object getParent(TreeListDialogField field, Object element);
+
+       boolean hasChildren(TreeListDialogField field, Object element);
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/LayoutUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/LayoutUtil.java
new file mode 100644 (file)
index 0000000..2abec85
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public class LayoutUtil {
+       
+       /**
+        * Calculates the number of columns needed by field editors
+        */
+       public static int getNumberOfColumns(DialogField[] editors) {
+               int nCulumns= 0;
+               for (int i= 0; i < editors.length; i++) {
+                       nCulumns= Math.max(editors[i].getNumberOfControls(), nCulumns);
+               }
+               return nCulumns;
+       }
+       
+       /**
+        * Creates a composite and fills in the given editors.
+        * @param labelOnTop Defines if the label of all fields should be on top of the fields
+        */     
+       public static void doDefaultLayout(Composite parent, DialogField[] editors, boolean labelOnTop) {
+               doDefaultLayout(parent, editors, labelOnTop, 0, 0, 0, 0);
+       }
+
+       /**
+        * Creates a composite and fills in the given editors.
+        * @param labelOnTop Defines if the label of all fields should be on top of the fields
+        * @param minWidth The minimal width of the composite
+        * @param minHeight The minimal height of the composite 
+        */
+       public static void doDefaultLayout(Composite parent, DialogField[] editors, boolean labelOnTop, int minWidth, int minHeight) {
+               doDefaultLayout(parent, editors, labelOnTop, minWidth, minHeight, 0, 0);
+       }
+
+       /**
+        * Creates a composite and fills in the given editors.
+        * @param labelOnTop Defines if the label of all fields should be on top of the fields
+        * @param minWidth The minimal width of the composite
+        * @param minHeight The minimal height of the composite
+        * @param marginWidth The margin width to be used by the composite
+        * @param marginHeight The margin height to be used by the composite
+        * @deprecated
+        */     
+       public static void doDefaultLayout(Composite parent, DialogField[] editors, boolean labelOnTop, int minWidth, int minHeight, int marginWidth, int marginHeight) {
+               int nCulumns= getNumberOfColumns(editors);
+               Control[][] controls= new Control[editors.length][];
+               for (int i= 0; i < editors.length; i++) {
+                       controls[i]= editors[i].doFillIntoGrid(parent, nCulumns);
+               }
+               if (labelOnTop) {
+                       nCulumns--;
+                       modifyLabelSpans(controls, nCulumns);
+               }
+               GridLayout layout= new GridLayout();
+               if (marginWidth != SWT.DEFAULT) {
+                       layout.marginWidth= marginWidth;
+               }
+               if (marginHeight != SWT.DEFAULT) {
+                       layout.marginHeight= marginHeight;
+               }
+               layout.numColumns= nCulumns;            
+               parent.setLayout(layout);
+       }
+       
+       private static void modifyLabelSpans(Control[][] controls, int nCulumns) {
+               for (int i= 0; i < controls.length; i++) {
+                       setHorizontalSpan(controls[i][0], nCulumns);
+               }
+       }
+       
+       /**
+        * Sets the span of a control. Assumes that GridData is used.
+        */
+       public static void setHorizontalSpan(Control control, int span) {
+               Object ld= control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData)ld).horizontalSpan= span;
+               } else if (span != 1) {
+                       GridData gd= new GridData();
+                       gd.horizontalSpan= span;
+                       control.setLayoutData(gd);
+               }
+       }       
+
+       /**
+        * Sets the width hint of a control. Assumes that GridData is used.
+        */
+       public static void setWidthHint(Control control, int widthHint) {
+               Object ld= control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData)ld).widthHint= widthHint;
+               }
+       }
+       
+       /**
+        * Sets the heigthHint hint of a control. Assumes that GridData is used.
+        */
+       public static void setHeigthHint(Control control, int heigthHint) {
+               Object ld= control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData)ld).heightHint= heigthHint;
+               }
+       }       
+       
+       /**
+        * Sets the horizontal indent of a control. Assumes that GridData is used.
+        */
+       public static void setHorizontalIndent(Control control, int horizontalIndent) {
+               Object ld= control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData)ld).horizontalIndent= horizontalIndent;
+               }
+       }
+       
+       /**
+        * Sets the horizontal indent of a control. Assumes that GridData is used.
+        */
+       public static void setHorizontalGrabbing(Control control) {
+               Object ld= control.getLayoutData();
+               if (ld instanceof GridData) {
+                       ((GridData)ld).grabExcessHorizontalSpace= true;
+               }
+       }               
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ListDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/ListDialogField.java
new file mode 100644 (file)
index 0000000..32f3e6f
--- /dev/null
@@ -0,0 +1,894 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.internal.ui.util.TableLayoutComposite;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ColumnLayoutData;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * A list with a button bar.
+ * Typical buttons are 'Add', 'Remove', 'Up' and 'Down'.
+ * List model is independend of widget creation.
+ * DialogFields controls are: Label, List and Composite containing buttons.
+ */
+public class ListDialogField extends DialogField {
+       
+       public static class ColumnsDescription {
+               private ColumnLayoutData[] columns;
+               private String[] headers;
+               private boolean drawLines;
+               
+               public ColumnsDescription(ColumnLayoutData[] columns, String[] headers, boolean drawLines) {
+                       this.columns= columns;
+                       this.headers= headers;
+                       this.drawLines= drawLines;
+               }
+               
+               public ColumnsDescription(String[] headers, boolean drawLines) {
+                       this(createColumnWeightData(headers.length), headers, drawLines);
+               }
+               
+               public ColumnsDescription(int nColumns, boolean drawLines) {
+                       this(createColumnWeightData(nColumns), null, drawLines);
+               }
+               
+               private static ColumnLayoutData[] createColumnWeightData(int nColumns) {
+                       ColumnLayoutData[] data= new ColumnLayoutData[nColumns];
+                       for (int i= 0; i < nColumns; i++) {
+                               data[i]= new ColumnWeightData(1);
+                       }                       
+                       return data;
+               }
+       }
+       
+       protected TableViewer fTable;
+       protected ILabelProvider fLabelProvider;
+       protected ListViewerAdapter fListViewerAdapter;
+       protected List fElements;
+       protected ViewerSorter fViewerSorter;
+
+       protected String[] fButtonLabels;
+       private Button[] fButtonControls;
+       
+       private boolean[] fButtonsEnabled;
+       
+       private int fRemoveButtonIndex;
+       private int fUpButtonIndex;
+       private int fDownButtonIndex;
+       
+       private Label fLastSeparator;
+       
+       private Control fTableControl;
+       private Composite fButtonsControl;
+       private ISelection fSelectionWhenEnabled;
+       
+       private IListAdapter fListAdapter;
+       
+       private Object fParentElement;
+       
+       private ColumnsDescription fTableColumns;
+       
+
+       /**
+        * Creates the <code>ListDialogField</code>.
+        * @param adapter A listener for button invocation, selection changes. Can
+        * be <code>null</code>.
+        * @param buttonLabels The labels of all buttons: <code>null</code> is a valid array entry and
+        * marks a separator.
+        * @param lprovider The label provider to render the table entries
+        */     
+       public ListDialogField(IListAdapter adapter, String[] buttonLabels, ILabelProvider lprovider) {
+               super();
+               fListAdapter= adapter;
+
+               fLabelProvider= lprovider;
+               fListViewerAdapter= new ListViewerAdapter();
+               fParentElement= this;
+
+               fElements= new ArrayList(10);
+                                       
+               fButtonLabels= buttonLabels;
+               if (fButtonLabels != null) {
+                       int nButtons= fButtonLabels.length;
+                       fButtonsEnabled= new boolean[nButtons];
+                       for (int i= 0; i < nButtons; i++) {
+                               fButtonsEnabled[i]= true;
+                       }
+               }       
+                               
+               fTable= null;
+               fTableControl= null;
+               fButtonsControl= null;
+               fTableColumns= null;
+               
+               fRemoveButtonIndex= -1;
+               fUpButtonIndex= -1;
+               fDownButtonIndex= -1;
+       }
+               
+       /**
+        * Sets the index of the 'remove' button in the button label array passed in the constructor.
+        * The behaviour of the button marked as the 'remove' button will then be handled internally.
+        * (enable state, button invocation behaviour)
+        */     
+       public void setRemoveButtonIndex(int removeButtonIndex) {
+               Assert.isTrue(removeButtonIndex < fButtonLabels.length);
+               fRemoveButtonIndex= removeButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'up' button in the button label array passed in the constructor.
+        * The behaviour of the button marked as the 'up' button will then be handled internally.
+        * (enable state, button invocation behaviour)
+        */     
+       public void setUpButtonIndex(int upButtonIndex) {
+               Assert.isTrue(upButtonIndex < fButtonLabels.length);
+               fUpButtonIndex= upButtonIndex;
+       }
+
+       /**
+        * Sets the index of the 'down' button in the button label array passed in the constructor.
+        * The behaviour of the button marked as the 'down' button will then be handled internally.
+        * (enable state, button invocation behaviour)
+        */     
+       public void setDownButtonIndex(int downButtonIndex) {
+               Assert.isTrue(downButtonIndex < fButtonLabels.length);
+               fDownButtonIndex= downButtonIndex;
+       }
+       
+       /**
+        * Sets the viewerSorter.
+        * @param viewerSorter The viewerSorter to set
+        */
+       public void setViewerSorter(ViewerSorter viewerSorter) {
+               fViewerSorter= viewerSorter;
+       }
+       
+       public void setTableColumns(ColumnsDescription column) {
+               fTableColumns= column;
+       }
+       
+       
+       
+       // ------ adapter communication
+       
+       private void buttonPressed(int index) {
+               if (!managedButtonPressed(index) && fListAdapter != null) {
+                       fListAdapter.customButtonPressed(this, index);
+               }
+       }
+       
+       /**
+        * Checks if the button pressed is handled internally
+        * @return Returns true if button has been handled.
+        */
+       protected boolean managedButtonPressed(int index) {
+               if (index == fRemoveButtonIndex) {
+                       remove();
+               } else if (index == fUpButtonIndex) {
+                       up();
+               } else if (index == fDownButtonIndex) {
+                       down();
+               } else {
+                       return false;
+               }
+               return true;
+       }
+       
+
+       // ------ layout helpers
+       
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               PixelConverter converter= new PixelConverter(parent);
+               
+               assertEnoughColumns(nColumns);
+               
+               Label label= getLabelControl(parent);
+               GridData gd= gridDataForLabel(1);
+               gd.verticalAlignment= GridData.BEGINNING;
+               label.setLayoutData(gd);
+               
+               Control list= getListControl(parent);
+               gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.verticalAlignment= GridData.FILL;
+               gd.grabExcessVerticalSpace= true;
+               gd.horizontalSpan= nColumns - 2;
+               gd.widthHint= converter.convertWidthInCharsToPixels(50);
+               gd.heightHint= converter.convertHeightInCharsToPixels(6);
+
+               list.setLayoutData(gd);
+               
+               Composite buttons= getButtonBox(parent);
+               gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.verticalAlignment= GridData.FILL;
+               gd.grabExcessVerticalSpace= true;
+               gd.horizontalSpan= 1;
+               buttons.setLayoutData(gd);
+               
+               return new Control[] { label, list, buttons };
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */     
+       public int getNumberOfControls() {
+               return 3;       
+       }
+
+       /**
+        * Sets the minimal width of the buttons. Must be called after widget creation.
+        */             
+       public void setButtonsMinWidth(int minWidth) {
+               if (fLastSeparator != null) {
+                       ((GridData)fLastSeparator.getLayoutData()).widthHint= minWidth;
+               }
+       }
+       
+       
+       // ------ ui creation
+       
+       /**
+        * Returns the list control. When called the first time, the control will be created.
+        * @param The parent composite when called the first time, or <code>null</code>
+        * after.
+        */
+       public Control getListControl(Composite parent) {
+               if (fTableControl == null) {
+                       assertCompositeNotNull(parent);
+                       
+                       if (fTableColumns == null) {
+                               fTable= createTableViewer(parent);
+                               Table tableControl= fTable.getTable();
+                               
+                               fTableControl= tableControl;
+                               tableControl.setLayout(new TableLayout());
+                       } else {
+                               TableLayoutComposite composite= new TableLayoutComposite(parent, SWT.NONE);
+                               fTableControl= composite;
+                               
+                               fTable= createTableViewer(composite);
+                               Table tableControl= fTable.getTable();
+                                                               
+                               tableControl.setHeaderVisible(fTableColumns.headers != null);
+                               tableControl.setLinesVisible(fTableColumns.drawLines);
+                               ColumnLayoutData[] columns= fTableColumns.columns;
+                               for (int i= 0; i < columns.length; i++) {
+                                       composite.addColumnData(columns[i]);
+                                       TableColumn column= new TableColumn(tableControl, SWT.NONE);
+                                       //tableLayout.addColumnData(columns[i]);
+                                       if (fTableColumns.headers != null) {
+                                               column.setText(fTableColumns.headers[i]);
+                                       }
+                               }
+                       }
+
+                       fTable.getTable().addKeyListener(new KeyAdapter() {
+                               public void keyPressed(KeyEvent e) {
+                                       handleKeyPressed(e);
+                               }
+                       });
+                       
+                       //fTableControl.setLayout(tableLayout);                                         
+                       
+                       fTable.setContentProvider(fListViewerAdapter);
+                       fTable.setLabelProvider(fLabelProvider);
+                       fTable.addSelectionChangedListener(fListViewerAdapter);
+                       fTable.addDoubleClickListener(fListViewerAdapter);
+                       
+                       fTable.setInput(fParentElement);
+                       
+                       if (fViewerSorter != null) {
+                               fTable.setSorter(fViewerSorter);
+                       }
+                       
+                       fTableControl.setEnabled(isEnabled());
+                       if (fSelectionWhenEnabled != null) {
+                               postSetSelection(fSelectionWhenEnabled);
+                       }
+               }
+               return fTableControl;
+       }
+
+       /**
+        * Returns the internally used table viewer.
+        */             
+       public TableViewer getTableViewer() {
+               return fTable;
+       }
+       
+       /* 
+        * Subclasses may override to specify a different style.
+        */
+       protected int getListStyle(){
+               int style=  SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL ;
+               if (fTableColumns != null) {
+                       style |= SWT.FULL_SELECTION;
+               }
+               return style;           
+       }
+       
+       protected TableViewer createTableViewer(Composite parent) {
+               Table table= new Table(parent, getListStyle());
+               return new TableViewer(table);
+       }       
+       
+       protected Button createButton(Composite parent, String label, SelectionListener listener) {
+               Button button= new Button(parent, SWT.PUSH);
+               button.setText(label);
+               button.addSelectionListener(listener);
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= true;
+               gd.verticalAlignment= GridData.BEGINNING;
+               gd.heightHint = SWTUtil.getButtonHeigthHint(button);
+               gd.widthHint = SWTUtil.getButtonWidthHint(button);
+       
+               button.setLayoutData(gd);
+               return button;
+       }
+       
+       private Label createSeparator(Composite parent) {
+               Label separator= new Label(parent, SWT.NONE);
+               separator.setVisible(false);
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.verticalAlignment= GridData.BEGINNING;
+               gd.heightHint= 4;
+               separator.setLayoutData(gd);
+               return separator;
+       }                       
+
+       /**
+        * Returns the composite containing the buttons. When called the first time, the control
+        * will be created.
+        * @param The parent composite when called the first time, or <code>null</code>
+        * after.
+        */     
+       public Composite getButtonBox(Composite parent) {
+               if (fButtonsControl == null) {
+                       assertCompositeNotNull(parent);
+                       
+                       SelectionListener listener= new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+                               public void widgetSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+                       };
+                       
+                       Composite contents= new Composite(parent, SWT.NULL);
+                       GridLayout layout= new GridLayout();
+                       layout.marginWidth= 0;
+                       layout.marginHeight= 0;
+                       contents.setLayout(layout);
+                       
+                       if (fButtonLabels != null) {
+                               fButtonControls= new Button[fButtonLabels.length];
+                               for (int i= 0; i < fButtonLabels.length; i++) {
+                                       String currLabel= fButtonLabels[i];
+                                       if (currLabel != null) {
+                                               fButtonControls[i]= createButton(contents, currLabel, listener);
+                                               fButtonControls[i].setEnabled(isEnabled() && fButtonsEnabled[i]);
+                                       } else {
+                                               fButtonControls[i]= null;
+                                               createSeparator(contents);
+                                       }
+                               }
+                       }
+                                               
+                       fLastSeparator= createSeparator(contents);      
+       
+                       updateButtonState();
+                       fButtonsControl= contents;
+               }
+               
+               return fButtonsControl;
+       }
+       
+       private void doButtonSelected(SelectionEvent e) {
+               if (fButtonControls != null) {
+                       for (int i= 0; i < fButtonControls.length; i++) {
+                               if (e.widget == fButtonControls[i]) {
+                                       buttonPressed(i);
+                                       return;
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Handles key events in the table viewer. Specifically
+        * when the delete key is pressed.
+        */
+       protected void handleKeyPressed(KeyEvent event) {
+               if (event.character == SWT.DEL && event.stateMask == 0) {
+                       if (fRemoveButtonIndex != -1 && isButtonEnabled(fTable.getSelection(), fRemoveButtonIndex)) {
+                               managedButtonPressed(fRemoveButtonIndex);
+                       }
+               } 
+       }       
+       
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#dialogFieldChanged
+        */     
+       public void dialogFieldChanged() {
+               super.dialogFieldChanged();
+               updateButtonState();
+       }
+       
+       /*
+        * Updates the enable state of the all buttons
+        */ 
+       protected void updateButtonState() {
+               if (fButtonControls != null) {
+                       ISelection sel= fTable.getSelection();
+                       for (int i= 0; i < fButtonControls.length; i++) {
+                               Button button= fButtonControls[i];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(isButtonEnabled(sel, i));
+                               }                               
+                       }
+               }
+       }
+       
+       protected boolean getManagedButtonState(ISelection sel, int index) {
+               if (index == fRemoveButtonIndex) {
+                       return !sel.isEmpty();
+               } else if (index == fUpButtonIndex) {
+                       return !sel.isEmpty() && canMoveUp();
+               } else if (index == fDownButtonIndex) {
+                       return !sel.isEmpty() && canMoveDown();
+               }
+               return true;
+       }               
+
+       /*
+        * @see DialogField#updateEnableState
+        */     
+       protected void updateEnableState() {
+               super.updateEnableState();
+               
+               boolean enabled= isEnabled();
+               if (isOkToUse(fTableControl)) {
+                       if (!enabled) {
+                               fSelectionWhenEnabled= fTable.getSelection();
+                               selectElements(null);
+                       } else {
+                               selectElements(fSelectionWhenEnabled);
+                               fSelectionWhenEnabled= null;
+                       }
+                       fTableControl.setEnabled(enabled);
+               }
+               updateButtonState();
+       }
+
+       /**
+        * Sets a button enabled or disabled.
+        */     
+       public void enableButton(int index, boolean enable) {
+               if (fButtonsEnabled != null && index < fButtonsEnabled.length) {
+                       fButtonsEnabled[index]= enable;
+                       updateButtonState();
+               }
+       }
+       
+       private boolean isButtonEnabled(ISelection sel, int index) {
+               boolean extraState= getManagedButtonState(sel, index);
+               return isEnabled() && extraState && fButtonsEnabled[index];
+       }               
+       
+
+       // ------ model access
+       
+       /**
+        * Sets the elements shown in the list.
+        */
+       public void setElements(List elements) {
+               fElements= new ArrayList(elements);
+               if (fTable != null) {
+                       fTable.refresh();
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Gets the elements shown in the list.
+        * The list returned is a copy, so it can be modified by the user.
+        */     
+       public List getElements() {
+               return new ArrayList(fElements);
+       }
+
+       /**
+        * Gets the elements shown at the given index.
+        */             
+       public Object getElement(int index) {
+               return fElements.get(index);
+       }
+       
+       /**
+       * Gets the index of an element in the list or -1 if element is not in list.
+       */
+       public int getIndexOfElement(Object elem) {
+               return fElements.indexOf(elem);
+       }       
+
+       /**
+        * Replace an element.
+        */             
+       public void replaceElement(Object oldElement, Object newElement) throws IllegalArgumentException { 
+               int idx= fElements.indexOf(oldElement);
+               if (idx != -1) {
+                       fElements.set(idx, newElement);
+                       if (fTable != null) {
+                               List selected= getSelectedElements();
+                               if (selected.remove(oldElement)) {
+                                       selected.add(newElement);
+                               }
+                               fTable.refresh();
+                               selectElements(new StructuredSelection(selected));
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }       
+
+       /**
+        * Adds an element at the end of the list.
+        */             
+       public void addElement(Object element) {                
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(element);
+               if (fTable != null) {
+                       fTable.add(element);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+        * Adds elements at the end of the list.
+        */     
+       public void addElements(List elements) {
+               int nElements= elements.size();
+               
+               if (nElements > 0) {
+                       // filter duplicated
+                       ArrayList elementsToAdd= new ArrayList(nElements);
+                       
+                       for (int i= 0; i < nElements; i++) {
+                               Object elem= elements.get(i);
+                               if (!fElements.contains(elem)) {
+                                       elementsToAdd.add(elem);
+                               }       
+                       }
+                       fElements.addAll(elementsToAdd);
+                       if (fTable != null) {
+                               fTable.add(elementsToAdd.toArray());
+                       }
+                       dialogFieldChanged();
+               }
+       }       
+
+       /**
+        * Adds an element at a position.
+        */             
+       public void insertElementAt(Object element, int index) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(index, element);
+               if (fTable != null) {
+                       fTable.add(element);
+               }
+               
+               dialogFieldChanged();
+       }       
+
+
+       /**
+        * Adds an element at a position.
+        */     
+       public void removeAllElements() {
+               if (fElements.size() > 0) {
+                       fElements.clear();
+                       if (fTable != null) {
+                               fTable.refresh();
+                       }
+                       dialogFieldChanged();
+               }
+       }
+               
+       /**
+        * Removes an element from the list.
+        */             
+       public void removeElement(Object element) throws IllegalArgumentException {
+               if (fElements.remove(element)) {
+                       if (fTable != null) {
+                               fTable.remove(element);
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+        * Removes elements from the list.
+        */             
+       public void removeElements(List elements) {
+               if (elements.size() > 0) {
+                       fElements.removeAll(elements);
+                       if (fTable != null) {
+                               fTable.remove(elements.toArray());
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+        * Gets the number of elements
+        */             
+       public int getSize() {
+               return fElements.size();
+       }
+       
+
+       public void selectElements(ISelection selection) {
+               fSelectionWhenEnabled= selection;
+               if (fTable != null) {
+                       fTable.setSelection(selection, true);
+               }
+       }
+       
+       public void selectFirstElement() {
+               Object element= null;
+               if (fViewerSorter != null) {
+                       Object[] arr= fElements.toArray(); 
+                       fViewerSorter.sort(fTable, arr);
+                       if (arr.length > 0) {
+                               element= arr[0];
+                       }
+               } else {
+                       if (fElements.size() > 0) {
+                               element= fElements.get(0);
+                       }
+               }
+               if (element != null) {
+                       selectElements(new StructuredSelection(element));
+               }
+       }
+       
+               
+       public void postSetSelection(final ISelection selection) {
+               if (isOkToUse(fTableControl)) {
+                       Display d= fTableControl.getDisplay();
+                       d.asyncExec(new Runnable() {
+                               public void run() {
+                                       if (isOkToUse(fTableControl)) {
+                                               selectElements(selection);
+                                       }
+                               }
+                       });
+               }
+       }
+       
+       /**
+        * Refreshes the table.
+        */
+       public void refresh() {
+               if (fTable != null) {
+                       fTable.refresh();
+               }
+       }
+       
+       // ------- list maintenance
+       
+       private List moveUp(List elements, List move) {
+               int nElements= elements.size();
+               List res= new ArrayList(nElements);
+               Object floating= null;
+               for (int i= 0; i < nElements; i++) {
+                       Object curr= elements.get(i);
+                       if (move.contains(curr)) {
+                               res.add(curr);
+                       } else {
+                               if (floating != null) {
+                                       res.add(floating);
+                               }
+                               floating= curr;
+                       }
+               }
+               if (floating != null) {
+                       res.add(floating);
+               }
+               return res;
+       }       
+       
+       private void moveUp(List toMoveUp) {
+               if (toMoveUp.size() > 0) {
+                       setElements(moveUp(fElements, toMoveUp));
+                       fTable.reveal(toMoveUp.get(0));
+               }
+       }
+       
+       private void moveDown(List toMoveDown) {
+               if (toMoveDown.size() > 0) {
+                       setElements(reverse(moveUp(reverse(fElements), toMoveDown)));
+                       fTable.reveal(toMoveDown.get(toMoveDown.size() - 1));
+               }
+       }
+       
+       private List reverse(List p) {
+               List reverse= new ArrayList(p.size());
+               for (int i= p.size()-1; i >= 0; i--) {
+                       reverse.add(p.get(i));
+               }
+               return reverse;
+       }
+       
+       
+       private void remove() {
+               removeElements(getSelectedElements());
+       }
+       
+       private void up() {
+               moveUp(getSelectedElements());
+       }
+       
+       private void down() {
+               moveDown(getSelectedElements());
+       }
+       
+       private boolean canMoveUp() {
+               if (isOkToUse(fTableControl)) {
+                       int[] indc= fTable.getTable().getSelectionIndices();
+                       for (int i= 0; i < indc.length; i++) {
+                               if (indc[i] != i) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+       
+       private boolean canMoveDown() {
+               if (isOkToUse(fTableControl)) {
+                       int[] indc= fTable.getTable().getSelectionIndices();
+                       int k= fElements.size() - 1;
+                       for (int i= indc.length - 1; i >= 0 ; i--, k--) {
+                               if (indc[i] != k) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }       
+
+       /**
+        * Returns the selected elements.
+        */
+       public List getSelectedElements() {
+               List result= new ArrayList();
+               if (fTable != null) {
+                       ISelection selection= fTable.getSelection();
+                       if (selection instanceof IStructuredSelection) {
+                               Iterator iter= ((IStructuredSelection)selection).iterator();
+                               while (iter.hasNext()) {
+                                       result.add(iter.next());
+                               }
+                       }
+               }
+               return result;
+       }
+       
+       // ------- ListViewerAdapter
+       
+       private class ListViewerAdapter implements IStructuredContentProvider, ISelectionChangedListener, IDoubleClickListener {
+
+               // ------- ITableContentProvider Interface ------------
+       
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+                       // will never happen
+               }
+               
+               public boolean isDeleted(Object element) {
+                       return false;
+               }
+       
+               public void dispose() {
+               }
+               
+               public Object[] getElements(Object obj) {
+                       return fElements.toArray();
+               }
+       
+               // ------- ISelectionChangedListener Interface ------------
+               
+               public void selectionChanged(SelectionChangedEvent event) {
+                       doListSelected(event);
+               }
+               
+               /* (non-Javadoc)
+                * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
+                */
+               public void doubleClick(DoubleClickEvent event) {
+                       doDoubleClick(event);
+               }
+
+       }
+       
+       
+       protected void doListSelected(SelectionChangedEvent event) {
+               updateButtonState();
+               if (fListAdapter != null) {
+                       fListAdapter.selectionChanged(this);
+               }
+       }
+       
+       protected void doDoubleClick(DoubleClickEvent event) {
+               if (fListAdapter != null) {
+                       fListAdapter.doubleClicked(this);
+               }
+       }       
+
+
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogField.java
new file mode 100644 (file)
index 0000000..8572b44
--- /dev/null
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+
+
+/**
+ * Dialog Field containing a single button such as a radio or checkbox button.
+ */
+public class SelectionButtonDialogField extends DialogField {
+       
+       private Button fButton;
+       private boolean fIsSelected;
+       private DialogField[] fAttachedDialogFields;
+       private int fButtonStyle;
+
+       /**
+        * Creates a selection button.
+        * Allowed button styles: SWT.RADIO, SWT.CHECK, SWT.TOGGLE, SWT.PUSH
+        */
+       public SelectionButtonDialogField(int buttonStyle) {
+               super();
+               fIsSelected= false;
+               fAttachedDialogFields= null;
+               fButtonStyle= buttonStyle;
+       }
+       
+       /**
+        * Attaches a field to the selection state of the selection button.
+        * The attached field will be disabled if the selection button is not selected.
+        */
+       public void attachDialogField(DialogField dialogField) {
+               attachDialogFields(new DialogField[] { dialogField });
+       }
+
+       /**
+        * Attaches fields to the selection state of the selection button.
+        * The attached fields will be disabled if the selection button is not selected.
+        */     
+       public void attachDialogFields(DialogField[] dialogFields) {
+               fAttachedDialogFields= dialogFields;
+               for (int i= 0; i < dialogFields.length; i++) {
+                       dialogFields[i].setEnabled(fIsSelected);
+               }
+       }       
+       
+       /**
+        * Returns <code>true</code> is  teh gived field is attached to the selection button.
+        */
+       public boolean isAttached(DialogField editor) {
+               if (fAttachedDialogFields != null) {
+                       for (int i=0; i < fAttachedDialogFields.length; i++) {
+                               if (fAttachedDialogFields[i] == editor) {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+       
+       // ------- layout helpers
+       
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+               
+               Button button= getSelectionButton(parent);
+               GridData gd= new GridData();
+               gd.horizontalSpan= nColumns;
+               gd.horizontalAlignment= GridData.FILL;
+               if (fButtonStyle == SWT.PUSH) {
+                       gd.heightHint = SWTUtil.getButtonHeigthHint(button);
+                       gd.widthHint = SWTUtil.getButtonWidthHint(button);
+               }                       
+               
+               button.setLayoutData(gd);
+               
+               return new Control[] { button };
+       }       
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */     
+       public int getNumberOfControls() {
+               return 1;       
+       }       
+       
+       // ------- ui creation                  
+
+       /**
+        * Returns the selection button widget. When called the first time, the widget will be created.
+        * @param The parent composite when called the first time, or <code>null</code>
+        * after.
+        */             
+       public Button getSelectionButton(Composite group) {
+               if (fButton == null) {
+                       assertCompositeNotNull(group);
+                       
+                       fButton= new Button(group, fButtonStyle);
+                       fButton.setFont(group.getFont());                       
+                       fButton.setText(fLabelText);
+                       fButton.setEnabled(isEnabled());
+                       fButton.setSelection(fIsSelected);
+                       fButton.addSelectionListener(new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+                               public void widgetSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+                       });                             
+               }
+               return fButton;
+       }
+       
+       private void doWidgetSelected(SelectionEvent e) {
+               if (isOkToUse(fButton)) {
+                       changeValue(fButton.getSelection());
+               }
+       }       
+       
+       private void changeValue(boolean newState) {
+               if (fIsSelected != newState) {
+                       fIsSelected= newState;                  
+                       if (fAttachedDialogFields != null) {
+                               boolean focusSet= false;
+                               for (int i= 0; i < fAttachedDialogFields.length; i++) {         
+                                       fAttachedDialogFields[i].setEnabled(fIsSelected);
+                                       if (fIsSelected && !focusSet) {
+                                               focusSet= fAttachedDialogFields[i].setFocus();
+                                       }
+                               }
+                       }
+                       dialogFieldChanged();
+               } else if (fButtonStyle == SWT.PUSH) {
+                       dialogFieldChanged();
+               }
+       }               
+
+       // ------ model access  
+       
+       /**
+        * Returns the selection state of the button.
+        */
+       public boolean isSelected() {
+               return fIsSelected;
+       }
+
+       /**
+        * Sets the selection state of the button.
+        */     
+       public void setSelection(boolean selected) {
+               changeValue(selected);
+               if (isOkToUse(fButton)) {
+                       fButton.setSelection(selected);
+               }
+       }
+
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#updateEnableState
+        */     
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fButton)) {
+                       fButton.setEnabled(isEnabled());
+               }               
+       }
+       
+       
+       
+               
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogFieldGroup.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/SelectionButtonDialogFieldGroup.java
new file mode 100644 (file)
index 0000000..e846b67
--- /dev/null
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Dialog field describing a group with buttons (Checkboxes, radio buttons..)
+ */
+public class SelectionButtonDialogFieldGroup extends DialogField {
+       
+       private Composite fButtonComposite;
+       
+       private Button[] fButtons;
+       private String[] fButtonNames;
+       private boolean[] fButtonsSelected;
+       private boolean[] fButtonsEnabled;
+       
+       private int fGroupBorderStyle;
+       private int fGroupNumberOfColumns;
+       private int fButtonsStyle;      
+               
+       /**
+        * Creates a group without border.
+        */
+       public SelectionButtonDialogFieldGroup(int buttonsStyle, String[] buttonNames, int nColumns) {
+               this(buttonsStyle, buttonNames, nColumns, SWT.NONE);            
+       }       
+       
+       
+       /**
+        * Creates a group with border (label in border).
+        * Accepted button styles are: SWT.RADIO, SWT.CHECK, SWT.TOGGLE
+        * For border styles see <code>Group</code>
+        */     
+       public SelectionButtonDialogFieldGroup(int buttonsStyle, String[] buttonNames, int nColumns, int borderStyle) {
+               super();
+               
+               Assert.isTrue(buttonsStyle == SWT.RADIO || buttonsStyle == SWT.CHECK || buttonsStyle == SWT.TOGGLE);
+               fButtonNames= buttonNames;
+               
+               int nButtons= buttonNames.length;
+               fButtonsSelected= new boolean[nButtons];
+               fButtonsEnabled= new boolean[nButtons];
+               for (int i= 0; i < nButtons; i++) {
+                       fButtonsSelected[i]= false;
+                       fButtonsEnabled[i]= true;
+               }
+               if (fButtonsStyle == SWT.RADIO) {
+                       fButtonsSelected[0]= true;
+               }
+               
+               fGroupBorderStyle= borderStyle;
+               fGroupNumberOfColumns= (nColumns <= 0) ? nButtons : nColumns;
+               
+               fButtonsStyle= buttonsStyle;
+               
+       }
+       
+       // ------- layout helpers
+               
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+                               
+               if (fGroupBorderStyle == SWT.NONE) {
+                       Label label= getLabelControl(parent);
+                       label.setLayoutData(gridDataForLabel(1));
+               
+                       Composite buttonsgroup= getSelectionButtonsGroup(parent);
+                       GridData gd= new GridData();
+                       gd.horizontalSpan= nColumns - 1;
+                       buttonsgroup.setLayoutData(gd);
+                       
+                       return new Control[] { label, buttonsgroup };
+               } else {
+                       Composite buttonsgroup= getSelectionButtonsGroup(parent);
+                       GridData gd= new GridData();
+                       gd.horizontalSpan= nColumns;
+                       buttonsgroup.setLayoutData(gd);
+               
+                       return new Control[] { buttonsgroup };
+               }
+       }       
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */     
+       public int getNumberOfControls() {
+               return (fGroupBorderStyle == SWT.NONE) ? 2 : 1;
+       }
+       
+       // ------- ui creation
+       
+       private Button createSelectionButton(int index, Composite group, SelectionListener listener) {
+               Button button= new Button(group, fButtonsStyle | SWT.LEFT);
+               button.setFont(group.getFont());                        
+               button.setText(fButtonNames[index]);
+               button.setEnabled(isEnabled() && fButtonsEnabled[index]);
+               button.setSelection(fButtonsSelected[index]);
+               button.addSelectionListener(listener);
+               button.setLayoutData(new GridData());
+               return button;
+       }
+
+       /**
+        * Returns the group widget. When called the first time, the widget will be created.
+        * @param The parent composite when called the first time, or <code>null</code>
+        * after.
+        */
+       public Composite getSelectionButtonsGroup(Composite parent) {
+               if (fButtonComposite == null) {
+                       assertCompositeNotNull(parent);
+                       
+                       GridLayout layout= new GridLayout();
+                       layout.makeColumnsEqualWidth= true;
+                       layout.numColumns= fGroupNumberOfColumns;                       
+                       
+                       if (fGroupBorderStyle != SWT.NONE) {
+                               Group group= new Group(parent, fGroupBorderStyle);
+                               if (fLabelText != null && fLabelText.length() > 0) {
+                                       group.setText(fLabelText);
+                               }
+                               fButtonComposite= group;
+                       } else {
+                               fButtonComposite= new Composite(parent, SWT.NULL);
+                               layout.marginHeight= 0;
+                               layout.marginWidth= 0;
+                       }
+
+                       fButtonComposite.setLayout(layout);
+                       
+                       SelectionListener listener= new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+                               public void widgetSelected(SelectionEvent e) {
+                                       doWidgetSelected(e);
+                               }
+                       };      
+                       int nButtons= fButtonNames.length;
+                       fButtons= new Button[nButtons]; 
+                       for (int i= 0; i < nButtons; i++) {
+                               fButtons[i]= createSelectionButton(i, fButtonComposite, listener);
+                       }
+                       int nRows= nButtons / fGroupNumberOfColumns;
+                       int nFillElements= nRows * fGroupNumberOfColumns - nButtons;
+                       for (int i= 0; i < nFillElements; i++) {
+                               createEmptySpace(fButtonComposite);
+                       }
+               }
+               return fButtonComposite;
+       }
+
+       /**
+        * Returns a button from the group or <code>null</code> if not yet created.
+        */     
+       public Button getSelectionButton(int index) {
+               if (index >= 0 && index < fButtons.length) {
+                       return fButtons[index];
+               }
+               return null;
+       }
+       
+       private void doWidgetSelected(SelectionEvent e) {
+               Button button= (Button)e.widget;
+               for (int i= 0; i < fButtons.length; i++) {
+                       if (fButtons[i] == button) {
+                               fButtonsSelected[i]= button.getSelection();
+                               dialogFieldChanged();
+                               return;
+                       }
+               }
+       }       
+       
+       // ------ model access  
+
+       /**
+        * Returns the selection state of a button contained in the group.
+        * @param The index of the button
+        */
+       public boolean isSelected(int index) {
+               if (index >= 0 && index < fButtonsSelected.length) {
+                       return fButtonsSelected[index];
+               }
+               return false;
+       }
+       
+       /**
+        * Sets the selection state of a button contained in the group.
+        */
+       public void setSelection(int index, boolean selected) {
+               if (index >= 0 && index < fButtonsSelected.length) {
+                       if (fButtonsSelected[index] != selected) {
+                               fButtonsSelected[index]= selected;
+                               if (fButtons != null) {
+                                       Button button= fButtons[index];
+                                       if (isOkToUse(button)) {
+                                               button.setSelection(selected);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // ------ enable / disable management
+       
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (fButtons != null) {
+                       boolean enabled= isEnabled();
+                       for (int i= 0; i < fButtons.length; i++) {
+                               Button button= fButtons[i];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(enabled && fButtonsEnabled[i]);
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Sets the enable state of a button contained in the group.
+        */     
+       public void enableSelectionButton(int index, boolean enable) {
+               if (index >= 0 && index < fButtonsEnabled.length) {
+                       fButtonsEnabled[index]= enable;
+                       if (fButtons != null) {
+                               Button button= fButtons[index];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(isEnabled() && enable);
+                               }
+                       }
+               }
+       }       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/Separator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/Separator.java
new file mode 100644 (file)
index 0000000..08f587d
--- /dev/null
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * Dialog field describing a separator.
+ */
+public class Separator extends DialogField {
+       
+       private Label fSeparator;
+       private int fStyle;
+       
+       public Separator() {
+               this(SWT.NONE);
+       }       
+       
+       /**
+        * @param style of the separator. See <code>Label</code> for possible
+        * styles.
+        */
+       public Separator(int style) {
+               super();
+               fStyle= style;
+       }
+                       
+       // ------- layout helpers
+
+       /**
+        * Creates the separator and fills it in a MGridLayout.
+        * @param height The heigth of the separator
+        */             
+       public Control[] doFillIntoGrid(Composite parent, int nColumns, int height) {
+               assertEnoughColumns(nColumns);
+               
+               Control separator= getSeparator(parent);
+               separator.setLayoutData(gridDataForSeperator(nColumns, height));
+               
+               return new Control[] { separator };
+       }
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */     
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               return doFillIntoGrid(parent, nColumns, 4);
+       }
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */     
+       public int getNumberOfControls() {
+               return 1;       
+       }
+       
+       protected static GridData gridDataForSeperator(int span, int height) {
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.verticalAlignment= GridData.BEGINNING;
+               gd.heightHint= height;          
+               gd.horizontalSpan= span;
+               return gd;
+       }
+       
+       // ------- ui creation  
+
+       /**
+        * Creates or returns the created separator.
+        * @param parent The parent composite or <code>null</code> if the widget has
+        * already been created.
+        */     
+       public Control getSeparator(Composite parent) {
+               if (fSeparator == null) {
+                       assertCompositeNotNull(parent);
+                       fSeparator= new Label(parent, fStyle);
+               }       
+               return fSeparator;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonDialogField.java
new file mode 100644 (file)
index 0000000..34f3a06
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * Dialog field containing a label, text control and a button control.
+ */
+public class StringButtonDialogField extends StringDialogField {
+               
+       private Button fBrowseButton;
+       private String fBrowseButtonLabel;
+       private IStringButtonAdapter fStringButtonAdapter;
+       
+       private boolean fButtonEnabled;
+       
+       public StringButtonDialogField(IStringButtonAdapter adapter) {
+               super();
+               fStringButtonAdapter= adapter;
+               fBrowseButtonLabel= "!Browse...!"; //$NON-NLS-1$
+               fButtonEnabled= true;
+       }
+
+       /**
+        * Sets the label of the button.
+        */
+       public void setButtonLabel(String label) {
+               fBrowseButtonLabel= label;
+       }
+       
+       // ------ adapter communication
+
+       /**
+        * Programmatical pressing of the button
+        */     
+       public void changeControlPressed() {
+               fStringButtonAdapter.changeControlPressed(this);
+       }
+       
+       // ------- layout helpers
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */             
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+               
+               Label label= getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Text text= getTextControl(parent);
+               text.setLayoutData(gridDataForText(nColumns - 2));
+               Button button= getChangeControl(parent);
+               button.setLayoutData(gridDataForButton(button, 1));
+       
+               return new Control[] { label, text, button };
+       }       
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */             
+       public int getNumberOfControls() {
+               return 3;       
+       }
+       
+       protected static GridData gridDataForButton(Button button, int span) {
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.horizontalSpan= span;
+               gd.heightHint = SWTUtil.getButtonHeigthHint(button);
+               gd.widthHint = SWTUtil.getButtonWidthHint(button);              
+               return gd;
+       }               
+       
+       // ------- ui creation  
+
+       /**
+        * Creates or returns the created buttom widget.
+        * @param parent The parent composite or <code>null</code> if the widget has
+        * already been created.
+        */             
+       public Button getChangeControl(Composite parent) {
+               if (fBrowseButton == null) {
+                       assertCompositeNotNull(parent);
+                       
+                       fBrowseButton= new Button(parent, SWT.PUSH);
+                       fBrowseButton.setText(fBrowseButtonLabel);
+                       fBrowseButton.setEnabled(isEnabled() && fButtonEnabled);
+                       fBrowseButton.addSelectionListener(new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       changeControlPressed();
+                               }
+                               public void widgetSelected(SelectionEvent e) {
+                                       changeControlPressed();
+                               }
+                       });     
+                       
+               }
+               return fBrowseButton;
+       }
+       
+       // ------ enable / disable management
+       
+       /**
+        * Sets the enable state of the button.
+        */
+       public void enableButton(boolean enable) {
+               if (isOkToUse(fBrowseButton)) {
+                       fBrowseButton.setEnabled(isEnabled() && enable);
+               }
+               fButtonEnabled= enable;
+       }
+
+       /*
+        * @see DialogField#updateEnableState
+        */     
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fBrowseButton)) {
+                       fBrowseButton.setEnabled(isEnabled() && fButtonEnabled);
+               }
+       }       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonStatusDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringButtonStatusDialogField.java
new file mode 100644 (file)
index 0000000..53a8a5f
--- /dev/null
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog field containing a label, text control, status label and a button control.
+ * The status label can be either a image or text label, and can be usd to give
+ * additional information about the current element chosen.
+ */
+public class StringButtonStatusDialogField extends StringButtonDialogField {
+               
+       private Label fStatusLabelControl;
+       private Object fStatus;  // String or ImageDescriptor
+       
+       private String fWidthHintString;
+       private int fWidthHint; 
+       
+       public StringButtonStatusDialogField(IStringButtonAdapter adapter) {
+               super(adapter);
+               fStatus= null;
+               fWidthHintString= null;
+               fWidthHint= -1;
+       }
+       
+       // ------ set status
+
+       /**
+        * Sets the status string.
+        */     
+       public void setStatus(String status) {
+               if (isOkToUse(fStatusLabelControl)) {
+                       fStatusLabelControl.setText(status);
+               }
+               fStatus= status;                
+       }
+       
+       /**
+        * Sets the status image.
+        * Caller is responsible to dispose image
+        */
+       public void setStatus(Image image) {
+               if (isOkToUse(fStatusLabelControl)) {
+                       if (image == null) {
+                               fStatusLabelControl.setImage(null);
+                       } else {
+                               fStatusLabelControl.setImage(image);
+                       }
+               }
+               fStatus= image;         
+       }       
+
+       /**
+        * Sets the staus string hint of the status label.
+        * The string is used to calculate the size of the status label.
+        */             
+       public void setStatusWidthHint(String widthHintString) {
+               fWidthHintString= widthHintString;
+               fWidthHint= -1;
+       }
+       
+       /**
+        * Sets the width hint of the status label.
+        */
+       public void setStatusWidthHint(int widthHint) {
+               fWidthHint= widthHint;
+               fWidthHintString= null;
+       }
+       
+       // ------- layout helpers       
+
+       /*
+        * @see DialogField#doFillIntoGrid
+        */             
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+               
+               Label label= getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Text text= getTextControl(parent);
+               text.setLayoutData(gridDataForText(nColumns - 3));
+               Label status= getStatusLabelControl(parent);
+               status.setLayoutData(gridDataForStatusLabel(parent, 1));
+               Button button= getChangeControl(parent);
+               button.setLayoutData(gridDataForButton(button, 1));
+               
+               return new Control[] { label, text, status, button };
+       }
+       
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 4;       
+       }
+       
+       protected GridData gridDataForStatusLabel(Control aControl, int span) {
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.BEGINNING;
+               gd.grabExcessHorizontalSpace= false;
+               gd.horizontalIndent= 0;
+               if (fWidthHintString != null) {
+                       GC gc= new GC(aControl);
+                       gc.setFont(JFaceResources.getDialogFont());
+                       gd.widthHint= gc.textExtent(fWidthHintString).x;
+                       gc.dispose();
+               } else if (fWidthHint != -1) {
+                       gd.widthHint= fWidthHint;
+               } else {
+                       gd.widthHint= SWT.DEFAULT;
+               }               
+               return gd;
+       }
+       
+       // ------- ui creation  
+
+       /**
+        * Creates or returns the created status label widget.
+        * @param parent The parent composite or <code>null</code> when the widget has
+        * already been created.
+        */                     
+       public Label getStatusLabelControl(Composite parent) {
+               if (fStatusLabelControl == null) {
+                       assertCompositeNotNull(parent);                 
+                       fStatusLabelControl= new Label(parent, SWT.LEFT);
+                       fStatusLabelControl.setFont(parent.getFont());
+                       fStatusLabelControl.setEnabled(isEnabled());
+                       if (fStatus instanceof Image) {
+                               fStatusLabelControl.setImage((Image)fStatus);
+                       } else if (fStatus instanceof String) {
+                               fStatusLabelControl.setText((String)fStatus);
+                       } else {
+                               // must be null
+                       }
+               }
+               return fStatusLabelControl;
+       }
+       
+       // ------ enable / disable management
+
+       /*
+        * @see DialogField#updateEnableState
+        */     
+       protected void updateEnableState() {
+               super.updateEnableState();
+               if (isOkToUse(fStatusLabelControl)) {
+                       fStatusLabelControl.setEnabled(isEnabled());
+               }
+       }       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/StringDialogField.java
new file mode 100644 (file)
index 0000000..6176a28
--- /dev/null
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog field containing a label and a text control.
+ */
+public class StringDialogField extends DialogField {
+               
+       private String fText;
+       private Text fTextControl;
+       private ModifyListener fModifyListener;
+       
+       public StringDialogField() {
+               super();
+               fText= ""; //$NON-NLS-1$
+       }
+                       
+       // ------- layout helpers
+               
+       /*
+        * @see DialogField#doFillIntoGrid
+        */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               assertEnoughColumns(nColumns);
+               
+               Label label= getLabelControl(parent);
+               label.setLayoutData(gridDataForLabel(1));
+               Text text= getTextControl(parent);
+               text.setLayoutData(gridDataForText(nColumns - 1));
+               
+               return new Control[] { label, text };
+       } 
+
+       /*
+        * @see DialogField#getNumberOfControls
+        */
+       public int getNumberOfControls() {
+               return 2;       
+       }
+       
+       protected static GridData gridDataForText(int span) {
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.horizontalSpan= span;
+               return gd;
+       }       
+       
+       // ------- focus methods
+       
+       /*
+        * @see DialogField#setFocus
+        */
+       public boolean setFocus() {
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.setFocus();
+                       fTextControl.setSelection(0, fTextControl.getText().length());
+               }
+               return true;
+       }
+               
+       // ------- ui creation                  
+
+       /**
+        * Creates or returns the created text control.
+        * @param parent The parent composite or <code>null</code> when the widget has
+        * already been created.
+        */             
+       public Text getTextControl(Composite parent) {
+               if (fTextControl == null) {
+                       assertCompositeNotNull(parent);
+                       fModifyListener= new ModifyListener() {
+                               public void modifyText(ModifyEvent e) {
+                                       doModifyText(e);
+                               }
+                       };
+                       
+                       fTextControl= new Text(parent, SWT.SINGLE | SWT.BORDER);
+                       // moved up due to 1GEUNW2
+                       fTextControl.setText(fText);
+                       fTextControl.setFont(parent.getFont());
+                       fTextControl.addModifyListener(fModifyListener);
+                       
+                       fTextControl.setEnabled(isEnabled());
+               }
+               return fTextControl;
+       }
+       
+       private void doModifyText(ModifyEvent e) {
+               if (isOkToUse(fTextControl)) {
+                       fText= fTextControl.getText();
+               }
+               dialogFieldChanged();
+       }               
+       
+       // ------ enable / disable management
+       
+       /*
+        * @see DialogField#updateEnableState
+        */             
+       protected void updateEnableState() {
+               super.updateEnableState();              
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.setEnabled(isEnabled());
+               }       
+       }               
+               
+       // ------ text access 
+       
+       /**
+        * Gets the text. Can not be <code>null</code>
+        */     
+       public String getText() {
+               return fText;
+       }
+       
+       /**
+        * Sets the text. Triggers a dialog-changed event.
+        */
+       public void setText(String text) {
+               fText= text;
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.setText(text);
+               } else {
+                       dialogFieldChanged();
+               }       
+       }
+
+       /**
+        * Sets the text without triggering a dialog-changed event.
+        */
+       public void setTextWithoutUpdate(String text) {
+               fText= text;
+               if (isOkToUse(fTextControl)) {
+                       fTextControl.removeModifyListener(fModifyListener);
+                       fTextControl.setText(text);
+                       fTextControl.addModifyListener(fModifyListener);
+               }
+       }
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/TreeListDialogField.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/wizards/dialogfields/TreeListDialogField.java
new file mode 100644 (file)
index 0000000..d1ae767
--- /dev/null
@@ -0,0 +1,896 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.wizards.dialogfields;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Tree;
+
+
+/**
+ * A list with a button bar.
+ * Typical buttons are 'Add', 'Remove', 'Up' and 'Down'.
+ * List model is independend of widget creation.
+ * DialogFields controls are: Label, List and Composite containing buttons.
+ */
+public class TreeListDialogField extends DialogField {
+
+       protected TreeViewer fTree;
+       protected ILabelProvider fLabelProvider;
+       protected TreeViewerAdapter fTreeViewerAdapter;
+       protected List fElements;
+       protected ViewerSorter fViewerSorter;
+
+       protected String[] fButtonLabels;
+       private Button[] fButtonControls;
+
+       private boolean[] fButtonsEnabled;
+
+       private int fRemoveButtonIndex;
+       private int fUpButtonIndex;
+       private int fDownButtonIndex;
+
+       private Label fLastSeparator;
+
+       private Tree fTreeControl;
+       private Composite fButtonsControl;
+       private ISelection fSelectionWhenEnabled;
+
+       private ITreeListAdapter fTreeAdapter;
+
+       private Object fParentElement;
+       private int fTreeExpandLevel;
+
+       /**
+        * @param adapter Can be <code>null</code>.
+        */
+       public TreeListDialogField(ITreeListAdapter adapter, String[] buttonLabels, ILabelProvider lprovider) {
+               super();
+               fTreeAdapter= adapter;
+
+               fLabelProvider= lprovider;
+               fTreeViewerAdapter= new TreeViewerAdapter();
+               fParentElement= this;
+
+               fElements= new ArrayList(10);
+
+               fButtonLabels= buttonLabels;
+               if (fButtonLabels != null) {
+                       int nButtons= fButtonLabels.length;
+                       fButtonsEnabled= new boolean[nButtons];
+                       for (int i= 0; i < nButtons; i++) {
+                               fButtonsEnabled[i]= true;
+                       }
+               }
+
+               fTree= null;
+               fTreeControl= null;
+               fButtonsControl= null;
+
+               fRemoveButtonIndex= -1;
+               fUpButtonIndex= -1;
+               fDownButtonIndex= -1;
+               
+               fTreeExpandLevel= 0;
+       }
+
+       /**
+       * Sets the index of the 'remove' button in the button label array passed in
+       * the constructor. The behaviour of the button marked as the 'remove' button
+       * will then behandled internally. (enable state, button invocation
+       * behaviour)
+       */
+       public void setRemoveButtonIndex(int removeButtonIndex) {
+               Assert.isTrue(removeButtonIndex < fButtonLabels.length);
+               fRemoveButtonIndex= removeButtonIndex;
+       }
+
+       /**
+       * Sets the index of the 'up' button in the button label array passed in the
+       * constructor. The behaviour of the button marked as the 'up' button will
+       * then behandled internally.
+       * (enable state, button invocation behaviour)
+       */
+       public void setUpButtonIndex(int upButtonIndex) {
+               Assert.isTrue(upButtonIndex < fButtonLabels.length);
+               fUpButtonIndex= upButtonIndex;
+       }
+
+       /**
+       * Sets the index of the 'down' button in the button label array passed in
+       * the constructor. The behaviour of the button marked as the 'down' button
+       * will then be handled internally. (enable state, button invocation
+       * behaviour)
+       */
+       public void setDownButtonIndex(int downButtonIndex) {
+               Assert.isTrue(downButtonIndex < fButtonLabels.length);
+               fDownButtonIndex= downButtonIndex;
+       }
+
+       /**
+       * Sets the viewerSorter.
+       * @param viewerSorter The viewerSorter to set
+       */
+       public void setViewerSorter(ViewerSorter viewerSorter) {
+               fViewerSorter= viewerSorter;
+       }
+       
+       /**
+       * Sets the viewerSorter.
+       * @param viewerSorter The viewerSorter to set
+       */
+       public void setTreeExpansionLevel(int level) {
+               fTreeExpandLevel= level;
+               if (fTree != null) {
+                       fTree.expandToLevel(level);
+               }
+       }       
+
+       // ------ adapter communication
+
+       private void buttonPressed(int index) {
+               if (!managedButtonPressed(index) && fTreeAdapter != null) {
+                       fTreeAdapter.customButtonPressed(this, index);
+               }
+       }
+
+       /**
+       * Checks if the button pressed is handled internally
+       * @return Returns true if button has been handled.
+       */
+       protected boolean managedButtonPressed(int index) {
+               if (index == fRemoveButtonIndex) {
+                       remove();
+               } else if (index == fUpButtonIndex) {
+                       up();
+               } else if (index == fDownButtonIndex) {
+                       down();
+               } else {
+                       return false;
+               }
+               return true;
+       }
+
+       // ------ layout helpers
+
+       /*
+       * @see DialogField#doFillIntoGrid
+       */
+       public Control[] doFillIntoGrid(Composite parent, int nColumns) {
+               PixelConverter converter= new PixelConverter(parent);
+
+               assertEnoughColumns(nColumns);
+
+               Label label= getLabelControl(parent);
+               GridData gd= gridDataForLabel(1);
+               gd.verticalAlignment= GridData.BEGINNING;
+               label.setLayoutData(gd);
+
+               Control list= getTreeControl(parent);
+               gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.verticalAlignment= GridData.FILL;
+               gd.grabExcessVerticalSpace= true;
+               gd.horizontalSpan= nColumns - 2;
+               gd.widthHint= converter.convertWidthInCharsToPixels(50);
+               gd.heightHint= converter.convertHeightInCharsToPixels(6);
+
+               list.setLayoutData(gd);
+
+               Composite buttons= getButtonBox(parent);
+               gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= false;
+               gd.verticalAlignment= GridData.FILL;
+               gd.grabExcessVerticalSpace= true;
+               gd.horizontalSpan= 1;
+               buttons.setLayoutData(gd);
+
+               return new Control[] { label, list, buttons };
+       }
+
+       /*
+       * @see DialogField#getNumberOfControls
+       */
+       public int getNumberOfControls() {
+               return 3;
+       }
+
+       /**
+       * Sets the minimal width of the buttons. Must be called after widget creation.
+       */
+       public void setButtonsMinWidth(int minWidth) {
+               if (fLastSeparator != null) {
+                       ((GridData) fLastSeparator.getLayoutData()).widthHint= minWidth;
+               }
+       }
+
+       // ------ ui creation
+
+       /**
+       * Returns the tree control. When called the first time, the control will be
+       * created.
+       * @param The parent composite when called the first time, or <code>null</code>
+       * after.
+       */
+       public Control getTreeControl(Composite parent) {
+               if (fTreeControl == null) {
+                       assertCompositeNotNull(parent);
+
+                       fTree= createTreeViewer(parent);
+
+                       fTreeControl= (Tree) fTree.getControl();
+                       fTreeControl.addKeyListener(new KeyAdapter() {
+                               public void keyPressed(KeyEvent e) {
+                                       handleKeyPressed(e);
+                               }
+                       });
+                       fTree.setAutoExpandLevel(99);
+                       fTree.setContentProvider(fTreeViewerAdapter);
+                       fTree.setLabelProvider(fLabelProvider);
+                       fTree.addSelectionChangedListener(fTreeViewerAdapter);
+                       fTree.addDoubleClickListener(fTreeViewerAdapter);
+
+                       fTree.setInput(fParentElement);
+                       fTree.expandToLevel(fTreeExpandLevel);
+
+                       if (fViewerSorter != null) {
+                               fTree.setSorter(fViewerSorter);
+                       }
+
+                       fTreeControl.setEnabled(isEnabled());
+                       if (fSelectionWhenEnabled != null) {
+                               postSetSelection(fSelectionWhenEnabled);
+                       }
+               }
+               return fTreeControl;
+       }
+
+       /**
+       * Returns the internally used table viewer.
+       */
+       public TreeViewer getTreeViewer() {
+               return fTree;
+       }
+
+       /*
+       * Subclasses may override to specify a different style.
+       */
+       protected int getTreeStyle() {
+               int style= SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
+               return style;
+       }
+
+       protected TreeViewer createTreeViewer(Composite parent) {
+               Tree tree= new Tree(parent, getTreeStyle());
+               return new TreeViewer(tree);
+       }
+
+       protected Button createButton(Composite parent, String label, SelectionListener listener) {
+               Button button= new Button(parent, SWT.PUSH);
+               button.setText(label);
+               button.addSelectionListener(listener);
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.grabExcessHorizontalSpace= true;
+               gd.verticalAlignment= GridData.BEGINNING;
+               gd.heightHint= SWTUtil.getButtonHeigthHint(button);
+               gd.widthHint= SWTUtil.getButtonWidthHint(button);
+
+               button.setLayoutData(gd);
+               return button;
+       }
+
+       private Label createSeparator(Composite parent) {
+               Label separator= new Label(parent, SWT.NONE);
+               separator.setVisible(false);
+               GridData gd= new GridData();
+               gd.horizontalAlignment= GridData.FILL;
+               gd.verticalAlignment= GridData.BEGINNING;
+               gd.heightHint= 4;
+               separator.setLayoutData(gd);
+               return separator;
+       }
+
+       /**
+       * Returns the composite containing the buttons. When called the first time, the control
+       * will be created.
+       * @param The parent composite when called the first time, or <code>null</code>
+       * after.
+       */
+       public Composite getButtonBox(Composite parent) {
+               if (fButtonsControl == null) {
+                       assertCompositeNotNull(parent);
+
+                       SelectionListener listener= new SelectionListener() {
+                               public void widgetDefaultSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+                               public void widgetSelected(SelectionEvent e) {
+                                       doButtonSelected(e);
+                               }
+                       };
+
+                       Composite contents= new Composite(parent, SWT.NULL);
+                       GridLayout layout= new GridLayout();
+                       layout.marginWidth= 0;
+                       layout.marginHeight= 0;
+                       contents.setLayout(layout);
+
+                       if (fButtonLabels != null) {
+                               fButtonControls= new Button[fButtonLabels.length];
+                               for (int i= 0; i < fButtonLabels.length; i++) {
+                                       String currLabel= fButtonLabels[i];
+                                       if (currLabel != null) {
+                                               fButtonControls[i]= createButton(contents, currLabel, listener);
+                                               fButtonControls[i].setEnabled(isEnabled() && fButtonsEnabled[i]);
+                                       } else {
+                                               fButtonControls[i]= null;
+                                               createSeparator(contents);
+                                       }
+                               }
+                       }
+
+                       fLastSeparator= createSeparator(contents);
+
+                       updateButtonState();
+                       fButtonsControl= contents;
+               }
+
+               return fButtonsControl;
+       }
+
+       private void doButtonSelected(SelectionEvent e) {
+               if (fButtonControls != null) {
+                       for (int i= 0; i < fButtonControls.length; i++) {
+                               if (e.widget == fButtonControls[i]) {
+                                       buttonPressed(i);
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       /**
+       * Handles key events in the table viewer. Specifically
+       * when the delete key is pressed.
+       */
+       protected void handleKeyPressed(KeyEvent event) {
+               if (event.character == SWT.DEL && event.stateMask == 0) {
+                       if (fRemoveButtonIndex != -1 && isButtonEnabled(fTree.getSelection(), fRemoveButtonIndex)) {
+                               managedButtonPressed(fRemoveButtonIndex);
+                               return;
+                       }
+               }
+               fTreeAdapter.keyPressed(this, event);
+       }
+
+       // ------ enable / disable management
+
+       /*
+       * @see DialogField#dialogFieldChanged
+       */
+       public void dialogFieldChanged() {
+               super.dialogFieldChanged();
+               updateButtonState();
+       }
+
+       /*
+       * Updates the enable state of the all buttons
+       */
+       protected void updateButtonState() {
+               if (fButtonControls != null) {
+                       ISelection sel= fTree.getSelection();
+                       for (int i= 0; i < fButtonControls.length; i++) {
+                               Button button= fButtonControls[i];
+                               if (isOkToUse(button)) {
+                                       button.setEnabled(isButtonEnabled(sel, i));
+                               }
+                       }
+               }
+       }
+       
+       
+       protected boolean containsAttributes(List selected) {
+               for (int i= 0; i < selected.size(); i++) {
+                       if (!fElements.contains(selected.get(i))) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+
+       protected boolean getManagedButtonState(ISelection sel, int index) {
+               List selected= getSelectedElements();
+               boolean hasAttributes= containsAttributes(selected);
+               if (index == fRemoveButtonIndex) {
+                       return !selected.isEmpty() && !hasAttributes;
+               } else if (index == fUpButtonIndex) {
+                       return !sel.isEmpty() && !hasAttributes && canMoveUp(selected);
+               } else if (index == fDownButtonIndex) {
+                       return !sel.isEmpty() && !hasAttributes && canMoveDown(selected);
+               }
+               return true;
+       }
+
+       /*
+       * @see DialogField#updateEnableState
+       */
+       protected void updateEnableState() {
+               super.updateEnableState();
+
+               boolean enabled= isEnabled();
+               if (isOkToUse(fTreeControl)) {
+                       if (!enabled) {
+                               fSelectionWhenEnabled= fTree.getSelection();
+                               selectElements(null);
+                       } else {
+                               selectElements(fSelectionWhenEnabled);
+                               fSelectionWhenEnabled= null;
+                       }
+                       fTreeControl.setEnabled(enabled);
+               }
+               updateButtonState();
+       }
+
+       /**
+       * Sets a button enabled or disabled.
+       */
+       public void enableButton(int index, boolean enable) {
+               if (fButtonsEnabled != null && index < fButtonsEnabled.length) {
+                       fButtonsEnabled[index]= enable;
+                       updateButtonState();
+               }
+       }
+
+       private boolean isButtonEnabled(ISelection sel, int index) {
+               boolean extraState= getManagedButtonState(sel, index);
+               return isEnabled() && extraState && fButtonsEnabled[index];
+       }
+
+       // ------ model access
+
+       /**
+       * Sets the elements shown in the list.
+       */
+       public void setElements(List elements) {
+               fElements= new ArrayList(elements);
+               refresh();
+               if (fTree != null) {
+                       fTree.expandToLevel(fTreeExpandLevel);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+       * Gets the elements shown in the list.
+       * The list returned is a copy, so it can be modified by the user.
+       */
+       public List getElements() {
+               return new ArrayList(fElements);
+       }
+
+       /**
+       * Gets the element shown at the given index.
+       */
+       public Object getElement(int index) {
+               return fElements.get(index);
+       }
+       
+       /**
+       * Gets the index of an element in the list or -1 if element is not in list.
+    */
+       public int getIndexOfElement(Object elem) {
+               return fElements.indexOf(elem);
+       }       
+
+       /**
+       * Replace an element.
+       */
+       public void replaceElement(Object oldElement, Object newElement) throws IllegalArgumentException {
+               int idx= fElements.indexOf(oldElement);
+               if (idx != -1) {
+                       fElements.set(idx, newElement);
+                       if (fTree != null) {
+                               List selected= getSelectedElements();
+                               if (selected.remove(oldElement)) {
+                                       selected.add(newElement);
+                               }
+                               boolean isExpanded= fTree.getExpandedState(oldElement);
+                               fTree.remove(oldElement);
+                               fTree.add(fParentElement, newElement);
+                               if (isExpanded) {
+                                       fTree.expandToLevel(newElement, fTreeExpandLevel);
+                               }
+                               selectElements(new StructuredSelection(selected));
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+       * Adds an element at the end of the tree list.
+       */
+       public void addElement(Object element) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(element);
+               if (fTree != null) {
+                       fTree.add(fParentElement, element);
+                       fTree.expandToLevel(element, fTreeExpandLevel);
+               }
+               dialogFieldChanged();
+       }
+
+       /**
+       * Adds elements at the end of the tree list.
+       */
+       public void addElements(List elements) {
+               int nElements= elements.size();
+
+               if (nElements > 0) {
+                       // filter duplicated
+                       ArrayList elementsToAdd= new ArrayList(nElements);
+
+                       for (int i= 0; i < nElements; i++) {
+                               Object elem= elements.get(i);
+                               if (!fElements.contains(elem)) {
+                                       elementsToAdd.add(elem);
+                               }
+                       }
+                       fElements.addAll(elementsToAdd);
+                       if (fTree != null) {
+                               fTree.add(fParentElement, elementsToAdd.toArray());
+                               for (int i= 0; i < elementsToAdd.size(); i++) {
+                                       fTree.expandToLevel(elementsToAdd.get(i), fTreeExpandLevel);
+                               }
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+       * Adds an element at a position.
+       */
+       public void insertElementAt(Object element, int index) {
+               if (fElements.contains(element)) {
+                       return;
+               }
+               fElements.add(index, element);
+               if (fTree != null) {
+                       fTree.add(fParentElement, element);
+                       if (fTreeExpandLevel != -1) {
+                               fTree.expandToLevel(element, fTreeExpandLevel);
+                       }
+               }
+
+               dialogFieldChanged();
+       }
+
+       /**
+       * Adds an element at a position.
+       */
+       public void removeAllElements() {
+               if (fElements.size() > 0) {
+                       fElements.clear();
+                       refresh();
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+       * Removes an element from the list.
+       */
+       public void removeElement(Object element) throws IllegalArgumentException {
+               if (fElements.remove(element)) {
+                       if (fTree != null) {
+                               fTree.remove(element);
+                       }
+                       dialogFieldChanged();
+               } else {
+                       throw new IllegalArgumentException();
+               }
+       }
+
+       /**
+       * Removes elements from the list.
+       */
+       public void removeElements(List elements) {
+               if (elements.size() > 0) {
+                       fElements.removeAll(elements);
+                       if (fTree != null) {
+                               fTree.remove(elements.toArray());
+                       }
+                       dialogFieldChanged();
+               }
+       }
+
+       /**
+       * Gets the number of elements
+       */
+       public int getSize() {
+               return fElements.size();
+       }
+
+       public void selectElements(ISelection selection) {
+               fSelectionWhenEnabled= selection;
+               if (fTree != null) {
+                       fTree.setSelection(selection, true);
+               }
+       }
+
+       public void selectFirstElement() {
+               Object element= null;
+               if (fViewerSorter != null) {
+                       Object[] arr= fElements.toArray();
+                       fViewerSorter.sort(fTree, arr);
+                       if (arr.length > 0) {
+                               element= arr[0];
+                       }
+               } else {
+                       if (fElements.size() > 0) {
+                               element= fElements.get(0);
+                       }
+               }
+               if (element != null) {
+                       selectElements(new StructuredSelection(element));
+               }
+       }
+
+       public void postSetSelection(final ISelection selection) {
+               if (isOkToUse(fTreeControl)) {
+                       Display d= fTreeControl.getDisplay();
+                       d.asyncExec(new Runnable() {
+                               public void run() {
+                                       if (isOkToUse(fTreeControl)) {
+                                               selectElements(selection);
+                                       }
+                               }
+                       });
+               }
+       }
+
+       /**
+       * Refreshes the tree.
+       */
+       public void refresh() {
+               if (fTree != null) {
+                       fTree.refresh();
+               }
+       }
+       
+       /**
+       * Refreshes the tree.
+       */
+       public void refresh(Object element) {
+               if (fTree != null) {
+                       fTree.refresh(element);
+               }
+       }       
+
+       // ------- list maintenance
+
+       private List moveUp(List elements, List move) {
+               int nElements= elements.size();
+               List res= new ArrayList(nElements);
+               Object floating= null;
+               for (int i= 0; i < nElements; i++) {
+                       Object curr= elements.get(i);
+                       if (move.contains(curr)) {
+                               res.add(curr);
+                       } else {
+                               if (floating != null) {
+                                       res.add(floating);
+                               }
+                               floating= curr;
+                       }
+               }
+               if (floating != null) {
+                       res.add(floating);
+               }
+               return res;
+       }
+
+       private void moveUp(List toMoveUp) {
+               if (toMoveUp.size() > 0) {
+                       setElements(moveUp(fElements, toMoveUp));
+                       fTree.reveal(toMoveUp.get(0));
+               }
+       }
+
+       private void moveDown(List toMoveDown) {
+               if (toMoveDown.size() > 0) {
+                       setElements(reverse(moveUp(reverse(fElements), toMoveDown)));
+                       fTree.reveal(toMoveDown.get(toMoveDown.size() - 1));
+               }
+       }
+
+       private List reverse(List p) {
+               List reverse= new ArrayList(p.size());
+               for (int i= p.size() - 1; i >= 0; i--) {
+                       reverse.add(p.get(i));
+               }
+               return reverse;
+       }
+
+       private void remove() {
+               removeElements(getSelectedElements());
+       }
+
+       private void up() {
+               moveUp(getSelectedElements());
+       }
+
+       private void down() {
+               moveDown(getSelectedElements());
+       }
+
+       private boolean canMoveUp(List selectedElements) {
+               if (isOkToUse(fTreeControl)) {
+                       int nSelected= selectedElements.size();
+                       int nElements= fElements.size();
+                       for (int i= 0; i < nElements && nSelected > 0; i++) {
+                               if (!selectedElements.contains(fElements.get(i))) {
+                                       return true;
+                               }
+                               nSelected--;
+                       }
+               }
+               return false;
+       }
+
+       private boolean canMoveDown(List selectedElements) {
+               if (isOkToUse(fTreeControl)) {
+                       int nSelected= selectedElements.size();                 
+                       for (int i= fElements.size() - 1; i >= 0 && nSelected > 0; i--) {
+                               if (!selectedElements.contains(fElements.get(i))) {
+                                       return true;
+                               }
+                               nSelected--;                            
+                       }
+               }
+               return false;
+       }
+
+       /**
+       * Returns the selected elements.
+       */
+       public List getSelectedElements() {
+               ArrayList result= new ArrayList();
+               if (fTree != null) {
+                       ISelection selection= fTree.getSelection();
+                       if (selection instanceof IStructuredSelection) {
+                               Iterator iter= ((IStructuredSelection)selection).iterator();
+                               while (iter.hasNext()) {
+                                       result.add(iter.next());
+                               }
+                       }
+               }
+               return result;
+       }
+       
+       public void expandElement(Object element, int level) {
+               if (fTree != null) {
+                       fTree.expandToLevel(element, level);
+               }
+       }
+       
+
+       // ------- TreeViewerAdapter
+
+       private class TreeViewerAdapter implements ITreeContentProvider, ISelectionChangedListener, IDoubleClickListener {
+
+               private final Object[] NO_ELEMENTS= new Object[0];
+
+               // ------- ITreeContentProvider Interface ------------
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+                       // will never happen
+               }
+
+               public boolean isDeleted(Object element) {
+                       return false;
+               }
+
+               public void dispose() {
+               }
+
+               public Object[] getElements(Object obj) {
+                       return fElements.toArray();
+               }
+               
+               public Object[] getChildren(Object element) {
+                       if (fTreeAdapter != null) {
+                               return fTreeAdapter.getChildren(TreeListDialogField.this, element);
+                       }
+                       return NO_ELEMENTS;
+               }
+
+               public Object getParent(Object element) {
+                       if (!fElements.contains(element) && fTreeAdapter != null) {
+                               return fTreeAdapter.getParent(TreeListDialogField.this, element);
+                       }
+                       return fParentElement;
+               }
+
+               public boolean hasChildren(Object element) {
+                       if (fTreeAdapter != null) {
+                               return fTreeAdapter.hasChildren(TreeListDialogField.this, element);
+                       }
+                       return false;
+               }               
+
+               // ------- ISelectionChangedListener Interface ------------
+
+               public void selectionChanged(SelectionChangedEvent event) {
+                       doListSelected(event);
+               }
+               
+               /* (non-Javadoc)
+                * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
+                */
+               public void doubleClick(DoubleClickEvent event) {
+                       doDoubleClick(event);
+               }               
+
+       }
+
+       protected void doListSelected(SelectionChangedEvent event) {
+               updateButtonState();
+               if (fTreeAdapter != null) {
+                       fTreeAdapter.selectionChanged(this);
+               }
+       }
+       
+       protected void doDoubleClick(DoubleClickEvent event) {
+               if (fTreeAdapter != null) {
+                       fTreeAdapter.doubleClicked(this);
+               }
+       }
+
+       
+
+}
index 6a43c31..58b13a2 100644 (file)
@@ -10,7 +10,6 @@
  ******************************************************************************/
 package net.sourceforge.phpdt.ui;
 
-import net.sourceforge.phpdt.ui.text.IJavaColorConstants;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
@@ -794,7 +793,7 @@ public class PreferenceConstants {
    * @since 2.1
    */
   public final static String EDITOR_CLOSE_BRACKETS_HTML = "closeBracketsHTML"; //$NON-NLS-1$
-  
+
   /**
    * A named preference that controls whether the 'smart home-end' feature is
    * enabled.
@@ -943,6 +942,27 @@ public class PreferenceConstants {
    */
   public final static String EDITOR_SINGLE_LINE_COMMENT_BOLD = IPreferenceConstants.PHP_SINGLELINE_COMMENT + EDITOR_BOLD_SUFFIX;
 
+       /**
+                * A named preference that holds the color used to render php start and stop tags.
+                * <p>
+                * Value is of type <code>String</code>. A RGB color value encoded as a string
+                * using class <code>PreferenceConverter</code>
+                * </p>
+                * 
+                * @see org.eclipse.jface.resource.StringConverter
+                * @see org.eclipse.jface.preference.PreferenceConverter
+                */
+               public final static String EDITOR_JAVA_TAG_COLOR = IPreferenceConstants.PHP_TAG;
+
+               /**
+                * A named preference that controls whether php start and stop tags are rendered in bold.
+                * <p>
+                * Value is of type <code>Boolean</code>.
+                * </p>
+                */
+               public final static String EDITOR_JAVA_TAG_BOLD = IPreferenceConstants.PHP_TAG + EDITOR_BOLD_SUFFIX;
+
+
   /**
    * A named preference that holds the color used to render php keywords.
    * <p>
@@ -1325,6 +1345,25 @@ public class PreferenceConstants {
    * </p>
    */
   public static final String EDITOR_SHOW_SEGMENTS = "net.sourceforge.phpdt.ui.editor.showSegments"; //$NON-NLS-1$
+  /**
+        * A named preference that controls if browser like links are turned on or off.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * </p>
+        * 
+        * @since 2.1
+        */
+  public static final String EDITOR_BROWSER_LIKE_LINKS = "browserLikeLinks"; //$NON-NLS-1$
+
+  /**
+   * A named preference that controls the key modifier for browser like links.
+   * <p>
+   * Value is of type <code>String</code>.
+   * </p>
+   * 
+   * @since 2.1
+   */
+  public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER = "browserLikeLinksKeyModifier"; //$NON-NLS-1$
 
   /**
    * A named preference that controls if the Java code assist gets auto activated.
@@ -1437,7 +1476,6 @@ public class PreferenceConstants {
    */
   public final static String CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVADOC = "content_assist_autoactivation_triggers_phpdoc"; //$NON-NLS-1$
 
-
   /**
    * A named preference that holds the characters that auto activate code assist
    * in HTML.
@@ -1616,6 +1654,19 @@ public class PreferenceConstants {
    */
   public static final String TEMPLATES_USE_CODEFORMATTER = "net.sourceforge.phpdt.ui.template.format"; //$NON-NLS-1$
 
+  /**
+   * A named preference that controls the key modifier mask for browser like links.
+   * The value is only used if the value of <code>EDITOR_BROWSER_LIKE_LINKS</code>
+   * cannot be resolved to valid SWT modifier bits.
+   * <p>
+   * Value is of type <code>String</code>.
+   * </p>
+   * 
+   * @see #EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER
+   * @since 2.1.1
+   */
+  public static final String EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = "browserLikeLinksKeyModifierMask"; //$NON-NLS-1$
+
   public static void initializeDefaultValues(IPreferenceStore store) {
     store.setDefault(PreferenceConstants.EDITOR_SHOW_SEGMENTS, false);
 
@@ -1752,6 +1803,9 @@ public class PreferenceConstants {
     PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR, new RGB(63, 127, 95));
     store.setDefault(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD, false);
 
+               PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_JAVA_TAG_COLOR, new RGB(255, 0, 128));
+         store.setDefault(PreferenceConstants.EDITOR_JAVA_TAG_BOLD, true);
+                               
     PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR, new RGB(127, 0, 85));
     store.setDefault(PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD, true);
 
@@ -1818,7 +1872,7 @@ public class PreferenceConstants {
 
     store.setDefault(PreferenceConstants.EDITOR_CLOSE_STRINGS_HTML, true);
     store.setDefault(PreferenceConstants.EDITOR_CLOSE_BRACKETS_HTML, true);
-    
+
     // store.setDefault(PreferenceConstants.EDITOR_DEFAULT_HOVER, JavaPlugin.ID_BESTMATCH_HOVER);
     store.setDefault(PreferenceConstants.EDITOR_NONE_HOVER, PreferenceConstants.EDITOR_DEFAULT_HOVER_CONFIGURED_ID);
     //         store.setDefault(PreferenceConstants.EDITOR_CTRL_HOVER, JavaPlugin.ID_SOURCE_HOVER);
index 72fc67e..f61a0d9 100644 (file)
@@ -1,21 +1,33 @@
 package net.sourceforge.phpdt.ui.actions;
 
 public interface PHPEditorActionDefinitionIds {
-       /**
-        * Value: net.sourceforge.phpeclipse.phpeditor.comment\r  */
-       public static final String COMMENT= "net.sourceforge.phpdt.ui.actions.comment";
+  /**
+   * Value: net.sourceforge.phpeclipse.phpeditor.comment
+   */
+  public static final String COMMENT = "net.sourceforge.phpdt.ui.actions.comment";
+
+  /**
+   * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
+   */
+  public static final String UNCOMMENT = "net.sourceforge.phpdt.ui.actions.uncomment";
 
-       /**
-        * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
-        */
-       public static final String UNCOMMENT = "net.sourceforge.phpdt.ui.actions.uncomment";
-       
   // navigate
-       
+
   /**
    * Action definition ID of the navigate -> open action
    * (value <code>"org.phpeclipse.phpdt.ui.edit.text.php.open.editor"</code>).
    */
-  public static final String OPEN_EDITOR= "net.sourceforge.phpeclipse.ui.edit.text.php.open.editor"; //$NON-NLS-1$
+  public static final String OPEN_EDITOR = "net.sourceforge.phpeclipse.ui.edit.text.php.open.editor"; //$NON-NLS-1$
+  /**
+        * Action definition ID of the toggle presentation toolbar button action
+        * (value <code>"org.eclipse.jdt.ui.edit.text.java.toggle.presentation"</code>).
+        */
+  public static final String TOGGLE_PRESENTATION = "net.sourceforge.phpeclipse.ui.edit.text.java.toggle.presentation"; //$NON-NLS-1$
+
+  /**
+   * Action definition ID of the toggle text hover toolbar button action
+   * (value <code>"org.eclipse.jdt.ui.edit.text.java.toggle.text.hover"</code>).
+   */
+  public static final String TOGGLE_TEXT_HOVER = "net.sourceforge.phpeclipse.ui.edit.text.java.toggle.text.hover"; //$NON-NLS-1$
 
 }
index 8961a41..8db5028 100644 (file)
@@ -10,6 +10,7 @@
  ******************************************************************************/
 package net.sourceforge.phpdt.ui.text;
 
+import org.eclipse.jface.text.source.ISharedTextColors;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.RGB;
 
@@ -25,7 +26,7 @@ import org.eclipse.swt.graphics.RGB;
  *
  * @see IJavaColorConstants
  */
-public interface IColorManager {
+public interface IColorManager extends ISharedTextColors {
        
        /**
         * Returns a color object for the given key. The color objects 
index e920473..6d4f394 100644 (file)
@@ -11,6 +11,8 @@ import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
 import net.sourceforge.phpeclipse.phpeditor.php.HTMLCodeScanner;
 import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.text.IDocumentPartitioner;
@@ -27,7 +29,6 @@ import org.eclipse.jface.util.PropertyChangeEvent;
 //import org.phpeclipse.phpdt.internal.ui.text.php.JavaCodeScanner;
 //import org.phpeclipse.phpdt.internal.ui.text.phpdoc.JavaDocScanner;
 
-
 /**
  * Tools required to configure a Java text viewer. 
  * The color manager and all scanner exist only one time, i.e.
@@ -38,114 +39,119 @@ import org.eclipse.jface.util.PropertyChangeEvent;
  * </p>
  */
 public class JavaTextTools {
-       
-       private class PreferenceListener implements IPropertyChangeListener {
-               public void propertyChange(PropertyChangeEvent event) {
-                       adaptToPreferenceChange(event);
-               }
-       };
-               
-       /** The color manager */
-       private JavaColorManager fColorManager;
-       /** The PHP source code scanner */
-       private PHPCodeScanner fCodeScanner;
-       /** The PHP multiline comment scanner */
-       private SingleTokenPHPScanner fMultilineCommentScanner;
-       /** The Java singleline comment scanner */
-       private SingleTokenPHPScanner fSinglelineCommentScanner;
-       /** The Java string scanner */
-       private SingleTokenPHPScanner fStringScanner;
-       /** The PHPDoc scanner */
-       private PHPDocCodeScanner fJavaDocScanner;
+
+  private class PreferenceListener implements IPropertyChangeListener {
+    public void propertyChange(PropertyChangeEvent event) {
+      adaptToPreferenceChange(event);
+    }
+  };
+
+  /** The color manager */
+  private JavaColorManager fColorManager;
+  /** The PHP source code scanner */
+  private PHPCodeScanner fCodeScanner;
+  /** The PHP multiline comment scanner */
+  private SingleTokenPHPScanner fMultilineCommentScanner;
+  /** The Java singleline comment scanner */
+  private SingleTokenPHPScanner fSinglelineCommentScanner;
+  /** The Java string scanner */
+  private SingleTokenPHPScanner fStringScanner;
+  /** The PHPDoc scanner */
+  private PHPDocCodeScanner fPHPDocScanner;
   /** The HTML scanner */
   private HTMLCodeScanner fHTMLScanner;
-       /** The Java partitions scanner */
-       private FastJavaPartitionScanner fPartitionScanner;     
-       
-       /** The preference store */
-       private IPreferenceStore fPreferenceStore;
-       /** The preference change listener */
-       private PreferenceListener fPreferenceListener= new PreferenceListener();
+  /** The Smarty scanner */
+  private SmartyCodeScanner fSmartyScanner;
+  /** The SmartyDoc scanner */
+  private SmartyDocCodeScanner fSmartyDocScanner;
+  /** The Java partitions scanner */
+  private FastJavaPartitionScanner fPartitionScanner;
+
+  /** The preference store */
+  private IPreferenceStore fPreferenceStore;
+  /** The preference change listener */
+  private PreferenceListener fPreferenceListener = new PreferenceListener();
+
+  /**
+   * Creates a new Java text tools collection.
+   * 
+   * @param store the preference store to initialize the text tools. The text tool
+   * instance installs a listener on the passed preference store to adapt itself to 
+   * changes in the preference store. In general <code>PreferenceConstants.
+   * getPreferenceStore()</code> shoould be used to initialize the text tools.
+   * 
+   * @see org.phpeclipse.phpdt.ui.PreferenceConstants#getPreferenceStore()
+   * @since 2.0
+   */
+  public JavaTextTools(IPreferenceStore store) {
+    fPreferenceStore = store;
+    fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
 
-       
-       /**
-        * Creates a new Java text tools collection.
-        * 
-        * @param store the preference store to initialize the text tools. The text tool
-        * instance installs a listener on the passed preference store to adapt itself to 
-        * changes in the preference store. In general <code>PreferenceConstants.
-        * getPreferenceStore()</code> shoould be used to initialize the text tools.
-        * 
-        * @see org.phpeclipse.phpdt.ui.PreferenceConstants#getPreferenceStore()
-        * @since 2.0
-        */
-       public JavaTextTools(IPreferenceStore store) {
-               fPreferenceStore= store;
-               fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
-               
-               fColorManager= new JavaColorManager();
-               fCodeScanner= new PHPCodeScanner(fColorManager, store);
-               fMultilineCommentScanner= new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT);
-               fSinglelineCommentScanner= new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT);
-               fStringScanner= new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING);
-               fJavaDocScanner= new PHPDocCodeScanner(fColorManager, store);
-    fHTMLScanner= new HTMLCodeScanner(fColorManager, store);
-               fPartitionScanner= new FastJavaPartitionScanner();
-       }
-       
-       /**
-        * Disposes all the individual tools of this tools collection.
-        */
-       public void dispose() {
-               
-               fCodeScanner= null;
-               fMultilineCommentScanner= null;
-               fSinglelineCommentScanner= null;
-               fStringScanner= null;
-               fJavaDocScanner= null;
-               fPartitionScanner= null;
-               
-               if (fColorManager != null) {
-                       fColorManager.dispose();
-                       fColorManager= null;
-               }
-               
-               if (fPreferenceStore != null) {
-                       fPreferenceStore.removePropertyChangeListener(fPreferenceListener);
-                       fPreferenceStore= null;
-                       fPreferenceListener= null;
-               }
-       }
-       
-       /**
-        * Returns the color manager which is used to manage
-        * any Java-specific colors needed for such things like syntax highlighting.
-        *
-        * @return the color manager to be used for Java text viewers
-        */
-       public JavaColorManager getColorManager() {
-               return fColorManager;
-       }
-       
-       /**
-        * Returns a scanner which is configured to scan Java source code.
-        *
-        * @return a Java source code scanner
-        */
-       public RuleBasedScanner getCodeScanner() {
-               return fCodeScanner;
-       }
-       
-       /**
-        * Returns a scanner which is configured to scan Java multiline comments.
-        *
-        * @return a Java multiline comment scanner
-        * 
-        * @since 2.0
-        */
-       public RuleBasedScanner getMultilineCommentScanner() {
-               return fMultilineCommentScanner;
-       }
+    fColorManager = new JavaColorManager();
+    fCodeScanner = new PHPCodeScanner(fColorManager, store);
+    fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT);
+    fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT);
+    fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING);
+    fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store);
+    fHTMLScanner = new HTMLCodeScanner(fColorManager, store);
+    fSmartyScanner = new SmartyCodeScanner(fColorManager, store);
+    fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store);
+    fPartitionScanner = new FastJavaPartitionScanner();
+  }
+
+  /**
+   * Disposes all the individual tools of this tools collection.
+   */
+  public void dispose() {
+
+    fCodeScanner = null;
+    fMultilineCommentScanner = null;
+    fSinglelineCommentScanner = null;
+    fStringScanner = null;
+    fPHPDocScanner = null;
+    fPartitionScanner = null;
+
+    if (fColorManager != null) {
+      fColorManager.dispose();
+      fColorManager = null;
+    }
+
+    if (fPreferenceStore != null) {
+      fPreferenceStore.removePropertyChangeListener(fPreferenceListener);
+      fPreferenceStore = null;
+      fPreferenceListener = null;
+    }
+  }
+
+  /**
+   * Returns the color manager which is used to manage
+   * any Java-specific colors needed for such things like syntax highlighting.
+   *
+   * @return the color manager to be used for Java text viewers
+   */
+  public IColorManager getColorManager() {
+    return fColorManager;
+  }
+
+  /**
+   * Returns a scanner which is configured to scan Java source code.
+   *
+   * @return a Java source code scanner
+   */
+  public RuleBasedScanner getCodeScanner() {
+    return fCodeScanner;
+  }
+
+  /**
+   * Returns a scanner which is configured to scan Java multiline comments.
+   *
+   * @return a Java multiline comment scanner
+   * 
+   * @since 2.0
+   */
+  public RuleBasedScanner getMultilineCommentScanner() {
+    return fMultilineCommentScanner;
+  }
 
   /**
    * Returns a scanner which is configured to scan HTML code.
@@ -156,118 +162,139 @@ public class JavaTextTools {
    */
   public RuleBasedScanner getHTMLScanner() {
     return fHTMLScanner;
-  } 
-  
-       /**
-        * Returns a scanner which is configured to scan Java singleline comments.
-        *
-        * @return a Java singleline comment scanner
-        * 
-        * @since 2.0
-        */
-       public RuleBasedScanner getSinglelineCommentScanner() {
-               return fSinglelineCommentScanner;
-       }
-       
-       /**
-        * Returns a scanner which is configured to scan Java strings.
-        *
-        * @return a Java string scanner
-        * 
-        * @since 2.0
-        */
-       public RuleBasedScanner getStringScanner() {
-               return fStringScanner;
-       }
-       
-       /**
-        * Returns a scanner which is configured to scan JavaDoc compliant comments.
-        * Notes that the start sequence "/**" and the corresponding end sequence
-        * are part of the JavaDoc comment.
-        *
-        * @return a JavaDoc scanner
-        */
-       public RuleBasedScanner getJavaDocScanner() {
-               return fJavaDocScanner;
-       }
-       
-       /**
-        * Returns a scanner which is configured to scan 
-        * Java-specific partitions, which are multi-line comments,
-        * JavaDoc comments, and regular Java source code.
-        *
-        * @return a Java partition scanner
-        */
-       public IPartitionTokenScanner getPartitionScanner() {
-               return fPartitionScanner;
-       }
-       
-       /**
-        * Factory method for creating a Java-specific document partitioner
-        * using this object's partitions scanner. This method is a 
-        * convenience method.
-        *
-        * @return a newly created Java document partitioner
-        */
-       public IDocumentPartitioner createDocumentPartitioner() {
-               
-               String[] types= new String[] {
-      FastJavaPartitionScanner.JAVA_DOC,
-      FastJavaPartitionScanner.JAVA_MULTI_LINE_COMMENT,
-      FastJavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT,
-      FastJavaPartitionScanner.JAVA_STRING
-               };
+  }
 
-               return new DefaultPartitioner(getPartitionScanner(), types);
-       }
-       
-       /**
-        * Returns the names of the document position categories used by the document
-        * partitioners created by this object to manage their partition information.
-        * If the partitioners don't use document position categories, the returned
-        * result is <code>null</code>.
-        *
-        * @return the partition managing position categories or <code>null</code> 
-        *                      if there is none
-        */
-       public String[] getPartitionManagingPositionCategories() {
-               return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
-       }
-       
-       /**
-        * Determines whether the preference change encoded by the given event
-        * changes the behavior of one its contained components.
-        * 
-        * @param event the event to be investigated
-        * @return <code>true</code> if event causes a behavioral change
-        * 
-        * @since 2.0
-        */
-       public boolean affectsBehavior(PropertyChangeEvent event) {
-               return fCodeScanner.affectsBehavior(event) ||
-                                       fMultilineCommentScanner.affectsBehavior(event) ||
-                                       fSinglelineCommentScanner.affectsBehavior(event) ||
-                                       fStringScanner.affectsBehavior(event) ||
-                                       fJavaDocScanner.affectsBehavior(event);
-       }
-       
-       /**
-        * Adapts the behavior of the contained components to the change
-        * encoded in the given event.
-        * 
-        * @param event the event to which to adapt
-        * @since 2.0
-        */
-       protected void adaptToPreferenceChange(PropertyChangeEvent event) {
-               if (fCodeScanner.affectsBehavior(event))
-                       fCodeScanner.adaptToPreferenceChange(event);
-               if (fMultilineCommentScanner.affectsBehavior(event))
-                       fMultilineCommentScanner.adaptToPreferenceChange(event);
-               if (fSinglelineCommentScanner.affectsBehavior(event))
-                       fSinglelineCommentScanner.adaptToPreferenceChange(event);
-               if (fStringScanner.affectsBehavior(event))
-                       fStringScanner.adaptToPreferenceChange(event);
-               if (fJavaDocScanner.affectsBehavior(event))
-                       fJavaDocScanner.adaptToPreferenceChange(event);
-       }
+  /**
+   * Returns a scanner which is configured to scan Smarty code.
+   *
+   * @return a Smarty scanner
+   * 
+   * @since 2.0
+   */
+  public RuleBasedScanner getSmartyScanner() {
+    return fSmartyScanner;
+  }
+
+  /**
+        * Returns a scanner which is configured to scan Smarty code.
+        *
+        * @return a Smarty scanner
+        * 
+        * @since 2.0
+        */
+  public RuleBasedScanner getSmartyDocScanner() {
+    return fSmartyDocScanner;
+  }
+  /**
+   * Returns a scanner which is configured to scan Java singleline comments.
+   *
+   * @return a Java singleline comment scanner
+   * 
+   * @since 2.0
+   */
+  public RuleBasedScanner getSinglelineCommentScanner() {
+    return fSinglelineCommentScanner;
+  }
+
+  /**
+   * Returns a scanner which is configured to scan Java strings.
+   *
+   * @return a Java string scanner
+   * 
+   * @since 2.0
+   */
+  public RuleBasedScanner getStringScanner() {
+    return fStringScanner;
+  }
+
+  /**
+   * Returns a scanner which is configured to scan JavaDoc compliant comments.
+   * Notes that the start sequence "/**" and the corresponding end sequence
+   * are part of the JavaDoc comment.
+   *
+   * @return a JavaDoc scanner
+   */
+  public RuleBasedScanner getJavaDocScanner() {
+    return fPHPDocScanner;
+  }
+
+  /**
+   * Returns a scanner which is configured to scan 
+   * Java-specific partitions, which are multi-line comments,
+   * JavaDoc comments, and regular Java source code.
+   *
+   * @return a Java partition scanner
+   */
+  public IPartitionTokenScanner getPartitionScanner() {
+    return fPartitionScanner;
+  }
+
+  /**
+   * Factory method for creating a Java-specific document partitioner
+   * using this object's partitions scanner. This method is a 
+   * convenience method.
+   *
+   * @return a newly created Java document partitioner
+   */
+  public IDocumentPartitioner createDocumentPartitioner() {
+
+    String[] types =
+      new String[] {
+        FastJavaPartitionScanner.JAVA_DOC,
+        FastJavaPartitionScanner.JAVA_MULTI_LINE_COMMENT,
+        FastJavaPartitionScanner.JAVA_SINGLE_LINE_COMMENT,
+        FastJavaPartitionScanner.JAVA_STRING };
+
+    return new DefaultPartitioner(getPartitionScanner(), types);
+  }
+
+  /**
+   * Returns the names of the document position categories used by the document
+   * partitioners created by this object to manage their partition information.
+   * If the partitioners don't use document position categories, the returned
+   * result is <code>null</code>.
+   *
+   * @return the partition managing position categories or <code>null</code> 
+   *                   if there is none
+   */
+  public String[] getPartitionManagingPositionCategories() {
+    return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
+  }
+
+  /**
+   * Determines whether the preference change encoded by the given event
+   * changes the behavior of one its contained components.
+   * 
+   * @param event the event to be investigated
+   * @return <code>true</code> if event causes a behavioral change
+   * 
+   * @since 2.0
+   */
+  public boolean affectsBehavior(PropertyChangeEvent event) {
+    return fCodeScanner.affectsBehavior(event)
+      || fMultilineCommentScanner.affectsBehavior(event)
+      || fSinglelineCommentScanner.affectsBehavior(event)
+      || fStringScanner.affectsBehavior(event)
+      || fPHPDocScanner.affectsBehavior(event);
+  }
+
+  /**
+   * Adapts the behavior of the contained components to the change
+   * encoded in the given event.
+   * 
+   * @param event the event to which to adapt
+   * @since 2.0
+   */
+  protected void adaptToPreferenceChange(PropertyChangeEvent event) {
+    if (fCodeScanner.affectsBehavior(event))
+      fCodeScanner.adaptToPreferenceChange(event);
+    if (fMultilineCommentScanner.affectsBehavior(event))
+      fMultilineCommentScanner.adaptToPreferenceChange(event);
+    if (fSinglelineCommentScanner.affectsBehavior(event))
+      fSinglelineCommentScanner.adaptToPreferenceChange(event);
+    if (fStringScanner.affectsBehavior(event))
+      fStringScanner.adaptToPreferenceChange(event);
+    if (fPHPDocScanner.affectsBehavior(event))
+      fPHPDocScanner.adaptToPreferenceChange(event);
+  }
 }
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewClassWizardPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewClassWizardPage.java
new file mode 100644 (file)
index 0000000..2db3c31
--- /dev/null
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.internal.ui.wizards.NewWizardMessages;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogFieldGroup;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Wizard page to  create a new class. 
+ * <p>
+ * Note: This class is not intended to be subclassed. To implement a different kind of 
+ * a new class wizard page, extend <code>NewTypeWizardPage</code>.
+ * </p>
+ * 
+ * @since 2.0
+ */
+public class NewClassWizardPage extends NewTypeWizardPage {
+
+  private final static String PAGE_NAME = "NewClassWizardPage"; //$NON-NLS-1$
+
+  private final static String SETTINGS_CREATEMAIN = "create_main"; //$NON-NLS-1$
+  private final static String SETTINGS_CREATECONSTR = "create_constructor"; //$NON-NLS-1$
+  private final static String SETTINGS_CREATEUNIMPLEMENTED = "create_unimplemented"; //$NON-NLS-1$
+
+  private SelectionButtonDialogFieldGroup fMethodStubsButtons;
+
+  /**
+   * Creates a new <code>NewClassWizardPage</code>
+   */
+  public NewClassWizardPage() {
+    super(true, PAGE_NAME);
+
+    setTitle(NewWizardMessages.getString("NewClassWizardPage.title")); //$NON-NLS-1$
+    setDescription(NewWizardMessages.getString("NewClassWizardPage.description")); //$NON-NLS-1$
+
+    String[] buttonNames3 = new String[] { NewWizardMessages.getString("NewClassWizardPage.methods.main"), NewWizardMessages.getString("NewClassWizardPage.methods.constructors"), //$NON-NLS-1$ //$NON-NLS-2$
+      NewWizardMessages.getString("NewClassWizardPage.methods.inherited") //$NON-NLS-1$
+    };
+    fMethodStubsButtons = new SelectionButtonDialogFieldGroup(SWT.CHECK, buttonNames3, 1);
+    fMethodStubsButtons.setLabelText(NewWizardMessages.getString("NewClassWizardPage.methods.label")); //$NON-NLS-1$
+  }
+
+  // -------- Initialization ---------
+
+  /**
+   * The wizard owning this page is responsible for calling this method with the
+   * current selection. The selection is used to initialize the fields of the wizard 
+   * page.
+   * 
+   * @param selection used to initialize the fields
+   */
+  public void init(IStructuredSelection selection) {
+    IJavaElement jelem = getInitialJavaElement(selection);
+    initContainerPage(jelem);
+    initTypePage(jelem);
+    doStatusUpdate();
+
+    boolean createMain = false;
+    boolean createConstructors = false;
+    boolean createUnimplemented = true;
+    IDialogSettings section = getDialogSettings().getSection(PAGE_NAME);
+    if (section != null) {
+      createMain = section.getBoolean(SETTINGS_CREATEMAIN);
+      createConstructors = section.getBoolean(SETTINGS_CREATECONSTR);
+      createUnimplemented = section.getBoolean(SETTINGS_CREATEUNIMPLEMENTED);
+    }
+
+    setMethodStubSelection(createMain, createConstructors, createUnimplemented, true);
+  }
+
+  // ------ validation --------
+  private void doStatusUpdate() {
+    // status of all used components
+    IStatus[] status =
+      new IStatus[] {
+        fContainerStatus,
+        isEnclosingTypeSelected() ? fEnclosingTypeStatus : fPackageStatus,
+        fTypeNameStatus,
+        fModifierStatus,
+      //                       fSuperClassStatus,
+      //                       fSuperInterfacesStatus
+    };
+
+    // the mode severe status will be displayed and the ok button enabled/disabled.
+    updateStatus(status);
+  }
+
+  /*
+   * @see NewContainerWizardPage#handleFieldChanged
+   */
+  protected void handleFieldChanged(String fieldName) {
+    super.handleFieldChanged(fieldName);
+
+    doStatusUpdate();
+  }
+
+  // ------ ui --------
+
+  /*
+   * @see WizardPage#createControl
+   */
+  public void createControl(Composite parent) {
+    initializeDialogUnits(parent);
+
+    Composite composite = new Composite(parent, SWT.NONE);
+
+    int nColumns = 4;
+
+    GridLayout layout = new GridLayout();
+    layout.numColumns = nColumns;
+    composite.setLayout(layout);
+
+    // pick & choose the wanted UI components
+
+    createContainerControls(composite, nColumns);
+    createPackageControls(composite, nColumns);
+    createEnclosingTypeControls(composite, nColumns);
+
+    createSeparator(composite, nColumns);
+
+    createTypeNameControls(composite, nColumns);
+    createModifierControls(composite, nColumns);
+
+    createSuperClassControls(composite, nColumns);
+    createSuperInterfacesControls(composite, nColumns);
+
+    createMethodStubSelectionControls(composite, nColumns);
+
+    setControl(composite);
+
+    Dialog.applyDialogFont(composite);
+    //         WorkbenchHelp.setHelp(composite, IJavaHelpContextIds.NEW_CLASS_WIZARD_PAGE);    
+  }
+
+  /*
+   * @see WizardPage#becomesVisible
+   */
+  public void setVisible(boolean visible) {
+    super.setVisible(visible);
+    if (visible) {
+      setFocus();
+    }
+  }
+
+  private void createMethodStubSelectionControls(Composite composite, int nColumns) {
+    Control labelControl = fMethodStubsButtons.getLabelControl(composite);
+    LayoutUtil.setHorizontalSpan(labelControl, nColumns);
+
+    DialogField.createEmptySpace(composite);
+
+    Control buttonGroup = fMethodStubsButtons.getSelectionButtonsGroup(composite);
+    LayoutUtil.setHorizontalSpan(buttonGroup, nColumns - 1);
+  }
+
+  /**
+   * Returns the current selection state of the 'Create Main' checkbox.
+   * 
+   * @return the selection state of the 'Create Main' checkbox
+   */
+  public boolean isCreateMain() {
+    return fMethodStubsButtons.isSelected(0);
+  }
+
+  /**
+   * Returns the current selection state of the 'Create Constructors' checkbox.
+   * 
+   * @return the selection state of the 'Create Constructors' checkbox
+   */
+  public boolean isCreateConstructors() {
+    return fMethodStubsButtons.isSelected(1);
+  }
+
+  /**
+   * Returns the current selection state of the 'Create inherited abstract methods' 
+   * checkbox.
+   * 
+   * @return the selection state of the 'Create inherited abstract methods' checkbox
+   */
+  public boolean isCreateInherited() {
+    return fMethodStubsButtons.isSelected(2);
+  }
+
+  /**
+   * Sets the selection state of the method stub checkboxes.
+   * 
+   * @param createMain initial selection state of the 'Create Main' checkbox.
+   * @param createConstructors initial selection state of the 'Create Constructors' checkbox.
+   * @param createInherited initial selection state of the 'Create inherited abstract methods' checkbox.
+   * @param canBeModified if <code>true</code> the method stub checkboxes can be changed by 
+   * the user. If <code>false</code> the buttons are "read-only"
+   */
+  public void setMethodStubSelection(
+    boolean createMain,
+    boolean createConstructors,
+    boolean createInherited,
+    boolean canBeModified) {
+    fMethodStubsButtons.setSelection(0, createMain);
+    fMethodStubsButtons.setSelection(1, createConstructors);
+    fMethodStubsButtons.setSelection(2, createInherited);
+
+    fMethodStubsButtons.setEnabled(canBeModified);
+  }
+
+  // ---- creation ----------------
+
+  /*
+   * @see NewTypeWizardPage#createTypeMembers
+   */
+  //   protected void createTypeMembers(IType type, ImportsManager imports, IProgressMonitor monitor) throws CoreException {
+  //           boolean doMain= isCreateMain();
+  //           boolean doConstr= isCreateConstructors();
+  //           boolean doInherited= isCreateInherited();
+  //           createInheritedMethods(type, doConstr, doInherited, imports, new SubProgressMonitor(monitor, 1));
+  //
+  //           if (doMain) {
+  //                   StringBuffer buf= new StringBuffer();
+  //                   buf.append("public static void main("); //$NON-NLS-1$
+  //                   buf.append(imports.addImport("java.lang.String")); //$NON-NLS-1$
+  //                   buf.append("[] args) {}"); //$NON-NLS-1$
+  //                   type.createMethod(buf.toString(), null, false, null);
+  //           }
+  //           
+  //           IDialogSettings section= getDialogSettings().getSection(PAGE_NAME);
+  //           if (section == null) {
+  //                   section= getDialogSettings().addNewSection(PAGE_NAME);
+  //           }
+  //           section.put(SETTINGS_CREATEMAIN, doMain);
+  //           section.put(SETTINGS_CREATECONSTR, doConstr);
+  //           section.put(SETTINGS_CREATEUNIMPLEMENTED, doInherited);
+  //           
+  //           if (monitor != null) {
+  //                   monitor.done();
+  //           }       
+  //   }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewContainerWizardPage.java
new file mode 100644 (file)
index 0000000..4460b0b
--- /dev/null
@@ -0,0 +1,433 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IJavaProject;
+import net.sourceforge.phpdt.core.IPackageFragmentRoot;
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
+import net.sourceforge.phpdt.internal.ui.wizards.NewWizardMessages;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+
+/**
+ * Wizard page that acts as a base class for wizard pages that create new Java elements. 
+ * The class provides a input field for source folders (called container in this class) and
+ * API to validate the enter source folder name.
+ * 
+ * @since 2.0
+ */
+public abstract class NewContainerWizardPage extends NewElementWizardPage {
+       
+       /** Id of the container field */
+       protected static final String CONTAINER= "NewContainerWizardPage.container"; //$NON-NLS-1$
+
+       /** The status of the last validation. */
+       protected IStatus fContainerStatus;
+
+       private StringButtonDialogField fContainerDialogField;
+               
+       /*
+        * package fragment root corresponding to the input type (can be null)
+        */
+       private IPackageFragmentRoot fCurrRoot;
+       
+       private IWorkspaceRoot fWorkspaceRoot;
+       
+       /**
+        * Create a new <code>NewContainerWizardPage</code>
+        * 
+        * @param name the wizard page's name
+        */
+       public NewContainerWizardPage(String name) {
+               super(name);
+               fWorkspaceRoot= ResourcesPlugin.getWorkspace().getRoot();       
+               ContainerFieldAdapter adapter= new ContainerFieldAdapter();
+               
+               fContainerDialogField= new StringButtonDialogField(adapter);
+               fContainerDialogField.setDialogFieldListener(adapter);
+               fContainerDialogField.setLabelText(NewWizardMessages.getString("NewContainerWizardPage.container.label")); //$NON-NLS-1$
+               fContainerDialogField.setButtonLabel(NewWizardMessages.getString("NewContainerWizardPage.container.button")); //$NON-NLS-1$
+               
+               fContainerStatus= new StatusInfo();
+               fCurrRoot= null;
+       }
+                       
+       /**
+        * Initializes the source folder field with a valid package fragement root.
+        * The package fragement root is computed from the given Java element.
+        * 
+        * @param elem the Java element used to compute the initial package
+        *    fragment root used as the source folder
+        */
+       protected void initContainerPage(IJavaElement elem) {
+               IPackageFragmentRoot initRoot= null;
+//             if (elem != null) {
+//                     initRoot= JavaModelUtil.getPackageFragmentRoot(elem);
+//                     if (initRoot == null || initRoot.isArchive()) {
+//                             IJavaProject jproject= elem.getJavaProject();
+//                             if (jproject != null) {
+//                                     try {
+//                                             initRoot= null;
+//                                             if (jproject.exists()) {
+//                                                     IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
+//                                                     for (int i= 0; i < roots.length; i++) {
+//                                                             if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
+//                                                                     initRoot= roots[i];
+//                                                                     break;
+//                                                             }
+//                                                     }                                                       
+//                                             }
+//                                     } catch (JavaModelException e) {
+//                                             PHPeclipsePlugin.log(e);
+//                                     }
+//                                     if (initRoot == null) {
+//                                             initRoot= jproject.getPackageFragmentRoot(jproject.getResource());
+//                                     }
+//                             }
+//                     }
+//             }       
+//             setPackageFragmentRoot(initRoot, true);
+       }
+       
+       /**
+        * Utility method to inspect a selection to find a Java element. 
+        * 
+        * @param selection the selection to be inspected
+        * @return a Java element to be used as the initial selection, or <code>null</code>,
+        * if no Java element exists in the given selection
+        */
+       protected IJavaElement getInitialJavaElement(IStructuredSelection selection) {
+               IJavaElement jelem= null;
+               if (selection != null && !selection.isEmpty()) {
+                       Object selectedElement= selection.getFirstElement();
+                       if (selectedElement instanceof IAdaptable) {
+                               IAdaptable adaptable= (IAdaptable) selectedElement;                     
+                               
+                               jelem= (IJavaElement) adaptable.getAdapter(IJavaElement.class);
+                               if (jelem == null) {
+                                       IResource resource= (IResource) adaptable.getAdapter(IResource.class);
+                                       if (resource != null && resource.getType() != IResource.ROOT) {
+                                               while (jelem == null && resource.getType() != IResource.PROJECT) {
+                                                       resource= resource.getParent();
+                                                       jelem= (IJavaElement) resource.getAdapter(IJavaElement.class);
+                                               }
+                                               if (jelem == null) {
+                                                       jelem= JavaCore.create(resource); // java project
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if (jelem == null) {
+                       IWorkbenchPart part= PHPeclipsePlugin.getActivePage().getActivePart();
+                       if (part instanceof ContentOutline) {
+                               part= PHPeclipsePlugin.getActivePage().getActiveEditor();
+                       }
+                       
+                       if (part instanceof IViewPartInputProvider) {
+                               Object elem= ((IViewPartInputProvider)part).getViewPartInput();
+                               if (elem instanceof IJavaElement) {
+                                       jelem= (IJavaElement) elem;
+                               }
+                       }
+               }
+
+               if (jelem == null || jelem.getElementType() == IJavaElement.JAVA_MODEL) {
+                       try {
+                               IJavaProject[] projects= JavaCore.create(getWorkspaceRoot()).getJavaProjects();
+                               if (projects.length == 1) {
+                                       jelem= projects[0];
+                               }
+                       } catch (JavaModelException e) {
+                               PHPeclipsePlugin.log(e);
+                       }
+               }
+               return jelem;
+       }
+       
+       /**
+        * Returns the recommended maximum width for text fields (in pixels). This
+        * method requires that createContent has been called before this method is
+        * call. Subclasses may override to change the maximum width for text 
+        * fields.
+        * 
+        * @return the recommended maximum width for text fields.
+        */
+       protected int getMaxFieldWidth() {
+               return convertWidthInCharsToPixels(40);
+       }
+       
+       
+       /**
+        * Creates the necessary controls (label, text field and browse button) to edit
+        * the source folder location. The method expects that the parent composite
+        * uses a <code>GridLayout</code> as its layout manager and that the
+        * grid layout has at least 3 columns.
+        * 
+        * @param parent the parent composite
+        * @param nColumns the number of columns to span. This number must be
+        *  greater or equal three
+        */
+       protected void createContainerControls(Composite parent, int nColumns) {
+               fContainerDialogField.doFillIntoGrid(parent, nColumns);
+               LayoutUtil.setWidthHint(fContainerDialogField.getTextControl(null), getMaxFieldWidth());
+       }
+
+       /**
+        * Sets the focus to the source folder's text field.
+        */     
+       protected void setFocusOnContainer() {
+               fContainerDialogField.setFocus();
+       }
+
+       // -------- ContainerFieldAdapter --------
+
+       private class ContainerFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {
+
+               // -------- IStringButtonAdapter
+               public void changeControlPressed(DialogField field) {
+                       containerChangeControlPressed(field);
+               }
+               
+               // -------- IDialogFieldListener
+               public void dialogFieldChanged(DialogField field) {
+                       containerDialogFieldChanged(field);
+               }
+       }
+       
+       private void containerChangeControlPressed(DialogField field) {
+               // take the current jproject as init element of the dialog
+//             IPackageFragmentRoot root= getPackageFragmentRoot();
+//             root= chooseSourceContainer(root);
+//             if (root != null) {
+//                     setPackageFragmentRoot(root, true);
+//             }
+       }
+       
+       private void containerDialogFieldChanged(DialogField field) {
+               if (field == fContainerDialogField) {
+                       fContainerStatus= containerChanged();
+               }
+               // tell all others
+               handleFieldChanged(CONTAINER);
+       }
+       
+       // ----------- validation ----------
+                       
+       /**
+        * This method is a hook which gets called after the source folder's
+        * text input field has changed. This default implementation updates
+        * the model and returns an error status. The underlying model
+        * is only valid if the returned status is OK.
+        * 
+        * @return the model's error status
+        */
+       protected IStatus containerChanged() {
+               StatusInfo status= new StatusInfo();
+               
+               fCurrRoot= null;
+               String str= getPackageFragmentRootText();
+               if (str.length() == 0) {
+                       status.setError(NewWizardMessages.getString("NewContainerWizardPage.error.EnterContainerName")); //$NON-NLS-1$
+                       return status;
+               }
+               IPath path= new Path(str);
+               IResource res= fWorkspaceRoot.findMember(path);
+               if (res != null) {
+                       int resType= res.getType();
+                       if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
+                               IProject proj= res.getProject();
+                               if (!proj.isOpen()) {
+                                       status.setError(NewWizardMessages.getFormattedString("NewContainerWizardPage.error.ProjectClosed", proj.getFullPath().toString())); //$NON-NLS-1$
+                                       return status;
+                               }                               
+                               IJavaProject jproject= JavaCore.create(proj);
+//                             fCurrRoot= jproject.getPackageFragmentRoot(res);
+//                             if (res.exists()) {
+//                                     try {
+//                                             if (!proj.hasNature(JavaCore.NATURE_ID)) {
+//                                                     if (resType == IResource.PROJECT) {
+//                                                             status.setError(NewWizardMessages.getString("NewContainerWizardPage.warning.NotAJavaProject")); //$NON-NLS-1$
+//                                                     } else {
+//                                                             status.setWarning(NewWizardMessages.getString("NewContainerWizardPage.warning.NotInAJavaProject")); //$NON-NLS-1$
+//                                                     }
+//                                                     return status;
+//                                             }
+//                                     } catch (CoreException e) {
+//                                             status.setWarning(NewWizardMessages.getString("NewContainerWizardPage.warning.NotAJavaProject")); //$NON-NLS-1$
+//                                     }
+//                                     if (!jproject.isOnClasspath(fCurrRoot)) {
+//                                             status.setWarning(NewWizardMessages.getFormattedString("NewContainerWizardPage.warning.NotOnClassPath", str)); //$NON-NLS-1$
+//                                     }               
+//                                     if (fCurrRoot.isArchive()) {
+//                                             status.setError(NewWizardMessages.getFormattedString("NewContainerWizardPage.error.ContainerIsBinary", str)); //$NON-NLS-1$
+//                                             return status;
+//                                     }
+//                             }
+                               return status;
+                       } else {
+                               status.setError(NewWizardMessages.getFormattedString("NewContainerWizardPage.error.NotAFolder", str)); //$NON-NLS-1$
+                               return status;
+                       }
+               } else {
+                       status.setError(NewWizardMessages.getFormattedString("NewContainerWizardPage.error.ContainerDoesNotExist", str)); //$NON-NLS-1$
+                       return status;
+               }
+       }
+               
+       // -------- update message ----------------
+       
+       /**
+        * Hook method that gets called when a field on this page has changed. For this page the 
+        * method gets called when the source folder field changes.
+        * <p>
+        * Every sub type is responsible to call this method when a field on its page has changed.
+        * Subtypes override (extend) the method to add verification when a own field has a
+        * dependency to an other field. For example the class name input must be verified
+        * again when the package field changes (check for duplicated class names).
+        * 
+        * @param fieldName The name of the field that has changed (field id). For the
+        * source folder the field id is <code>CONTAINER</code>
+        */
+       protected void handleFieldChanged(String fieldName) {
+       }       
+       
+       
+       // ---- get ----------------
+       
+       /**
+        * Returns the workspace root.
+        * 
+        * @return the workspace root
+        */ 
+       protected IWorkspaceRoot getWorkspaceRoot() {
+               return fWorkspaceRoot;
+       }       
+       
+       /**
+        * Returns the <code>IPackageFragmentRoot</code> that corresponds to the current
+        * value of the source folder field.
+        * 
+        * @return the IPackageFragmentRoot or <code>null</code> if the current source
+        * folder value is not a valid package fragment root
+        * 
+        */ 
+       public IPackageFragmentRoot getPackageFragmentRoot() {
+               return fCurrRoot;
+       }
+
+       /**
+        * Returns the current text of source folder text field.
+        * 
+        * @return the text of the source folder text field
+        */     
+       public String getPackageFragmentRootText() {
+               return fContainerDialogField.getText();
+       }
+       
+       
+       /**
+        * Sets the current source folder (model and text field) to the given package
+        * fragment root.
+        * 
+        * @param canBeModified if <code>false</code> the source folder field can 
+        * not be changed by the user. If <code>true</code> the field is editable
+        */ 
+//     public void setPackageFragmentRoot(IPackageFragmentRoot root, boolean canBeModified) {
+//             fCurrRoot= root;
+//             String str= (root == null) ? "" : root.getPath().makeRelative().toString(); //$NON-NLS-1$
+//             fContainerDialogField.setText(str);
+//             fContainerDialogField.setEnabled(canBeModified);
+//     }       
+               
+       // ------------- choose source container dialog
+       
+//     private IPackageFragmentRoot chooseSourceContainer(IJavaElement initElement) {
+//             Class[] acceptedClasses= new Class[] { IPackageFragmentRoot.class, IJavaProject.class };
+//             TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, false) {
+//                     public boolean isSelectedValid(Object element) {
+//                             try {
+//                                     if (element instanceof IJavaProject) {
+//                                             IJavaProject jproject= (IJavaProject)element;
+//                                             IPath path= jproject.getProject().getFullPath();
+//                                             return (jproject.findPackageFragmentRoot(path) != null);
+//                                     } else if (element instanceof IPackageFragmentRoot) {
+//                                             return (((IPackageFragmentRoot)element).getKind() == IPackageFragmentRoot.K_SOURCE);
+//                                     }
+//                                     return true;
+//                             } catch (JavaModelException e) {
+//                                     PHPeclipsePlugin.log(e.getStatus()); // just log, no ui in validation
+//                             }
+//                             return false;
+//                     }
+//             };
+//             
+//             acceptedClasses= new Class[] { IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class };
+//             ViewerFilter filter= new TypedViewerFilter(acceptedClasses) {
+//                     public boolean select(Viewer viewer, Object parent, Object element) {
+//                             if (element instanceof IPackageFragmentRoot) {
+//                                     try {
+//                                             return (((IPackageFragmentRoot)element).getKind() == IPackageFragmentRoot.K_SOURCE);
+//                                     } catch (JavaModelException e) {
+//                                             PHPeclipsePlugin.log(e.getStatus()); // just log, no ui in validation
+//                                             return false;
+//                                     }
+//                             }
+//                             return super.select(viewer, parent, element);
+//                     }
+//             };              
+//
+//             StandardJavaElementContentProvider provider= new StandardJavaElementContentProvider();
+//             ILabelProvider labelProvider= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT); 
+//             ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
+//             dialog.setValidator(validator);
+//             dialog.setSorter(new JavaElementSorter());
+//             dialog.setTitle(NewWizardMessages.getString("NewContainerWizardPage.ChooseSourceContainerDialog.title")); //$NON-NLS-1$
+//             dialog.setMessage(NewWizardMessages.getString("NewContainerWizardPage.ChooseSourceContainerDialog.description")); //$NON-NLS-1$
+//             dialog.addFilter(filter);
+//             dialog.setInput(JavaCore.create(fWorkspaceRoot));
+//             dialog.setInitialSelection(initElement);
+//             
+//             if (dialog.open() == ElementTreeSelectionDialog.OK) {
+//                     Object element= dialog.getFirstResult();
+//                     if (element instanceof IJavaProject) {
+//                             IJavaProject jproject= (IJavaProject)element;
+//                             return jproject.getPackageFragmentRoot(jproject.getProject());
+//                     } else if (element instanceof IPackageFragmentRoot) {
+//                             return (IPackageFragmentRoot)element;
+//                     }
+//                     return null;
+//             }
+//             return null;
+//     }       
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewElementWizardPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewElementWizardPage.java
new file mode 100644 (file)
index 0000000..7d98fbf
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.dialog.StatusUtil;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.wizard.WizardPage;
+
+/**
+ * Base class for wizard page responsible to create PHP elements. The class
+ * provides API to update the wizard's statis line and OK button according to
+ * the value of a <code>IStatus</code> object.
+ * 
+ * @since 2.0
+ */
+public abstract class NewElementWizardPage extends WizardPage {
+
+       private IStatus fCurrStatus;
+       
+       private boolean fPageVisible;
+
+       /**
+        * Creates a <code>NewElementWizardPage</code>.
+        * 
+        * @param name the wizard page's name
+        */     
+       public NewElementWizardPage(String name) {
+               super(name);
+               fPageVisible= false;
+               fCurrStatus=  new StatusInfo();
+       }
+               
+       // ---- WizardPage ----------------
+       
+       /*
+        * @see WizardPage#becomesVisible
+        */
+       public void setVisible(boolean visible) {
+               super.setVisible(visible);
+               fPageVisible= visible;
+               // policy: wizards are not allowed to come up with an error message
+               if (visible && fCurrStatus.matches(IStatus.ERROR)) {
+                       StatusInfo status= new StatusInfo();
+                       status.setError("");  //$NON-NLS-1$
+                       fCurrStatus= status;
+               } 
+               updateStatus(fCurrStatus);
+       }       
+
+       /**
+        * Updates the status line and the ok button according to the given status
+        * 
+        * @param status status to apply
+        */
+       protected void updateStatus(IStatus status) {
+               fCurrStatus= status;
+               setPageComplete(!status.matches(IStatus.ERROR));
+               if (fPageVisible) {
+                       StatusUtil.applyToStatusLine(this, status);
+               }
+       }
+       
+       /**
+        * Updates the status line and the ok button according to the status evaluate from
+        * an array of status. The most severe error is taken.  In case that two status with 
+        * the same severity exists, the status with lower index is taken.
+        * 
+        * @param status the array of status
+        */
+       protected void updateStatus(IStatus[] status) {
+               updateStatus(StatusUtil.getMostSevere(status));
+       }       
+                       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewTypeWizardPage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/wizards/NewTypeWizardPage.java
new file mode 100644 (file)
index 0000000..6fa222c
--- /dev/null
@@ -0,0 +1,1703 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IPackageFragment;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.ToolFactory;
+import net.sourceforge.phpdt.core.compiler.IScanner;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.externaltools.internal.ui.StatusInfo;
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.Templates;
+import net.sourceforge.phpdt.internal.corext.template.php.JavaContext;
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.NewWizardMessages;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IListAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ListDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogFieldGroup;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.Separator;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringButtonStatusDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.StringDialogField;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * The class <code>NewTypeWizardPage</code> contains controls and validation routines 
+ * for a 'New Type WizardPage'. Implementors decide which components to add and to enable. 
+ * Implementors can also customize the validation code. <code>NewTypeWizardPage</code> 
+ * is intended to serve as base class of all wizards that create types like applets, servlets, classes, 
+ * interfaces, etc.
+ * <p>
+ * See <code>NewClassWizardPage</code> or <code>NewInterfaceWizardPage</code> for an
+ * example usage of <code>NewTypeWizardPage</code>.
+ * </p>
+ * 
+ * @see org.eclipse.jdt.ui.wizards.NewClassWizardPage
+ * @see org.eclipse.jdt.ui.wizards.NewInterfaceWizardPage
+ * 
+ * @since 2.0
+ */
+public abstract class NewTypeWizardPage extends NewContainerWizardPage {
+
+  /**
+   * Class used in stub creation routines to add needed imports to a 
+   * compilation unit.
+   */
+  //   public static class ImportsManager {
+  //
+  //           private IImportsStructure fImportsStructure;
+  //
+  //           /* package */ ImportsManager(IImportsStructure structure) {
+  //                   fImportsStructure= structure;
+  //           }
+  //
+  //           /* package */ IImportsStructure getImportsStructure() {
+  //                   return fImportsStructure;
+  //           }
+  //                           
+  //           /**
+  //            * Adds a new import declaration that is sorted in the existing imports.
+  //            * If an import already exists or the import would conflict with another import
+  //            * of an other type with the same simple name  the import is not added.
+  //            * 
+  //            * @param qualifiedTypeName The fully qualified name of the type to import
+  //            * (dot separated)
+  //            * @return Returns the simple type name that can be used in the code or the
+  //            * fully qualified type name if an import conflict prevented the import
+  //            */                             
+  //           public String addImport(String qualifiedTypeName) {
+  //                   return fImportsStructure.addImport(qualifiedTypeName);
+  //           }
+  //   }
+
+  /** Public access flag. See The Java Virtual Machine Specification for more details. */
+  public int F_PUBLIC = Flags.AccPublic;
+  /** Private access flag. See The Java Virtual Machine Specification for more details. */
+  public int F_PRIVATE = Flags.AccPrivate;
+  /**  Protected access flag. See The Java Virtual Machine Specification for more details. */
+  public int F_PROTECTED = Flags.AccProtected;
+  /** Static access flag. See The Java Virtual Machine Specification for more details. */
+  public int F_STATIC = Flags.AccStatic;
+  /** Final access flag. See The Java Virtual Machine Specification for more details. */
+  public int F_FINAL = Flags.AccFinal;
+  /** Abstract property flag. See The Java Virtual Machine Specification for more details. */
+  //   public int F_ABSTRACT = Flags.AccAbstract;
+
+  private final static String PAGE_NAME = "NewTypeWizardPage"; //$NON-NLS-1$
+
+  /** Field ID of the package input field */
+  protected final static String PACKAGE = PAGE_NAME + ".package"; //$NON-NLS-1$
+  /** Field ID of the eclosing type input field */
+  protected final static String ENCLOSING = PAGE_NAME + ".enclosing"; //$NON-NLS-1$
+  /** Field ID of the enclosing type checkbox */
+  protected final static String ENCLOSINGSELECTION = ENCLOSING + ".selection"; //$NON-NLS-1$
+  /** Field ID of the type name input field */
+  protected final static String TYPENAME = PAGE_NAME + ".typename"; //$NON-NLS-1$
+  /** Field ID of the super type input field */
+  protected final static String SUPER = PAGE_NAME + ".superclass"; //$NON-NLS-1$
+  /** Field ID of the super interfaces input field */
+  protected final static String INTERFACES = PAGE_NAME + ".interfaces"; //$NON-NLS-1$
+  /** Field ID of the modifier checkboxes */
+  protected final static String MODIFIERS = PAGE_NAME + ".modifiers"; //$NON-NLS-1$
+  /** Field ID of the method stubs checkboxes */
+  protected final static String METHODS = PAGE_NAME + ".methods"; //$NON-NLS-1$
+
+  private class InterfacesListLabelProvider extends LabelProvider {
+
+    private Image fInterfaceImage;
+
+    public InterfacesListLabelProvider() {
+      super();
+      fInterfaceImage = PHPUiImages.get(PHPUiImages.IMG_OBJS_INTERFACE);
+    }
+
+    public Image getImage(Object element) {
+      return fInterfaceImage;
+    }
+  }
+
+  private StringButtonStatusDialogField fPackageDialogField;
+
+  private SelectionButtonDialogField fEnclosingTypeSelection;
+  private StringButtonDialogField fEnclosingTypeDialogField;
+
+  private boolean fCanModifyPackage;
+  private boolean fCanModifyEnclosingType;
+
+  private IPackageFragment fCurrPackage;
+
+  //   private IType fCurrEnclosingType;       
+  private StringDialogField fTypeNameDialogField;
+
+  private StringButtonDialogField fSuperClassDialogField;
+  private ListDialogField fSuperInterfacesDialogField;
+
+  //   private IType fSuperClass;
+
+  private SelectionButtonDialogFieldGroup fAccMdfButtons;
+  private SelectionButtonDialogFieldGroup fOtherMdfButtons;
+
+  //   private IType fCreatedType;
+
+  protected IStatus fEnclosingTypeStatus;
+  protected IStatus fPackageStatus;
+  protected IStatus fTypeNameStatus;
+  //   protected IStatus fSuperClassStatus;
+  protected IStatus fModifierStatus;
+  //   protected IStatus fSuperInterfacesStatus;       
+
+  private boolean fIsClass;
+  private int fStaticMdfIndex;
+
+  private final int PUBLIC_INDEX = 0, DEFAULT_INDEX = 1, PRIVATE_INDEX = 2, PROTECTED_INDEX = 3;
+  private final int ABSTRACT_INDEX = 0, FINAL_INDEX = 1;
+
+  /**
+   * Creates a new <code>NewTypeWizardPage</code>
+   * 
+   * @param isClass <code>true</code> if a new class is to be created; otherwise
+   * an interface is to be created
+   * @param pageName the wizard page's name
+   */
+  public NewTypeWizardPage(boolean isClass, String pageName) {
+    super(pageName);
+    //         fCreatedType= null;
+
+    fIsClass = isClass;
+
+    TypeFieldsAdapter adapter = new TypeFieldsAdapter();
+
+    fPackageDialogField = new StringButtonStatusDialogField(adapter);
+    fPackageDialogField.setDialogFieldListener(adapter);
+    fPackageDialogField.setLabelText(NewWizardMessages.getString("NewTypeWizardPage.package.label")); //$NON-NLS-1$
+    fPackageDialogField.setButtonLabel(NewWizardMessages.getString("NewTypeWizardPage.package.button")); //$NON-NLS-1$
+    fPackageDialogField.setStatusWidthHint(NewWizardMessages.getString("NewTypeWizardPage.default")); //$NON-NLS-1$
+
+    fEnclosingTypeSelection = new SelectionButtonDialogField(SWT.CHECK);
+    fEnclosingTypeSelection.setDialogFieldListener(adapter);
+    fEnclosingTypeSelection.setLabelText(NewWizardMessages.getString("NewTypeWizardPage.enclosing.selection.label")); //$NON-NLS-1$
+
+    fEnclosingTypeDialogField = new StringButtonDialogField(adapter);
+    fEnclosingTypeDialogField.setDialogFieldListener(adapter);
+    fEnclosingTypeDialogField.setButtonLabel(NewWizardMessages.getString("NewTypeWizardPage.enclosing.button")); //$NON-NLS-1$
+
+    fTypeNameDialogField = new StringDialogField();
+    fTypeNameDialogField.setDialogFieldListener(adapter);
+    fTypeNameDialogField.setLabelText(NewWizardMessages.getString("NewTypeWizardPage.typename.label")); //$NON-NLS-1$
+
+    fSuperClassDialogField = new StringButtonDialogField(adapter);
+    fSuperClassDialogField.setDialogFieldListener(adapter);
+    fSuperClassDialogField.setLabelText(NewWizardMessages.getString("NewTypeWizardPage.superclass.label")); //$NON-NLS-1$
+    fSuperClassDialogField.setButtonLabel(NewWizardMessages.getString("NewTypeWizardPage.superclass.button")); //$NON-NLS-1$
+
+    String[] addButtons = new String[] {
+      /* 0 */
+      NewWizardMessages.getString("NewTypeWizardPage.interfaces.add"), //$NON-NLS-1$
+      /* 1 */
+      null,
+      /* 2 */
+      NewWizardMessages.getString("NewTypeWizardPage.interfaces.remove") //$NON-NLS-1$
+    };
+    fSuperInterfacesDialogField = new ListDialogField(adapter, addButtons, new InterfacesListLabelProvider());
+    fSuperInterfacesDialogField.setDialogFieldListener(adapter);
+    String interfaceLabel = fIsClass ? NewWizardMessages.getString("NewTypeWizardPage.interfaces.class.label") : NewWizardMessages.getString("NewTypeWizardPage.interfaces.ifc.label"); //$NON-NLS-1$ //$NON-NLS-2$
+    fSuperInterfacesDialogField.setLabelText(interfaceLabel);
+    fSuperInterfacesDialogField.setRemoveButtonIndex(2);
+
+    String[] buttonNames1 = new String[] {
+      /* 0 == PUBLIC_INDEX */
+      NewWizardMessages.getString("NewTypeWizardPage.modifiers.public"), //$NON-NLS-1$
+      /* 1 == DEFAULT_INDEX */
+      NewWizardMessages.getString("NewTypeWizardPage.modifiers.default"), //$NON-NLS-1$
+      /* 2 == PRIVATE_INDEX */
+      NewWizardMessages.getString("NewTypeWizardPage.modifiers.private"), //$NON-NLS-1$
+      /* 3 == PROTECTED_INDEX*/
+      NewWizardMessages.getString("NewTypeWizardPage.modifiers.protected") //$NON-NLS-1$
+    };
+    fAccMdfButtons = new SelectionButtonDialogFieldGroup(SWT.RADIO, buttonNames1, 4);
+    fAccMdfButtons.setDialogFieldListener(adapter);
+    fAccMdfButtons.setLabelText(NewWizardMessages.getString("NewTypeWizardPage.modifiers.acc.label")); //$NON-NLS-1$
+    fAccMdfButtons.setSelection(0, true);
+
+    String[] buttonNames2;
+    if (fIsClass) {
+      buttonNames2 = new String[] {
+        /* 0 == ABSTRACT_INDEX */
+        NewWizardMessages.getString("NewTypeWizardPage.modifiers.abstract"), //$NON-NLS-1$
+        /* 1 == FINAL_INDEX */
+        NewWizardMessages.getString("NewTypeWizardPage.modifiers.final"), //$NON-NLS-1$
+        /* 2 */
+        NewWizardMessages.getString("NewTypeWizardPage.modifiers.static") //$NON-NLS-1$
+      };
+      fStaticMdfIndex = 2; // index of the static checkbox is 2
+    } else {
+      buttonNames2 = new String[] { NewWizardMessages.getString("NewTypeWizardPage.modifiers.static") //$NON-NLS-1$
+      };
+      fStaticMdfIndex = 0; // index of the static checkbox is 0
+    }
+
+    fOtherMdfButtons = new SelectionButtonDialogFieldGroup(SWT.CHECK, buttonNames2, 4);
+    fOtherMdfButtons.setDialogFieldListener(adapter);
+
+    fAccMdfButtons.enableSelectionButton(PRIVATE_INDEX, false);
+    fAccMdfButtons.enableSelectionButton(PROTECTED_INDEX, false);
+    fOtherMdfButtons.enableSelectionButton(fStaticMdfIndex, false);
+
+    fPackageStatus = new StatusInfo();
+    fEnclosingTypeStatus = new StatusInfo();
+
+    fCanModifyPackage = true;
+    fCanModifyEnclosingType = true;
+    updateEnableState();
+
+    fTypeNameStatus = new StatusInfo();
+    //         fSuperClassStatus= new StatusInfo();
+    //         fSuperInterfacesStatus= new StatusInfo();
+    fModifierStatus = new StatusInfo();
+  }
+
+  /**
+   * Initializes all fields provided by the page with a given selection.
+   * 
+   * @param elem the selection used to intialize this page or <code>
+   * null</code> if no selection was available
+   */
+  protected void initTypePage(IJavaElement elem) {
+    String initSuperclass = "java.lang.Object"; //$NON-NLS-1$
+    ArrayList initSuperinterfaces = new ArrayList(5);
+
+    IPackageFragment pack = null;
+    IType enclosingType = null;
+
+    if (elem != null) {
+      // evaluate the enclosing type
+      pack = (IPackageFragment) elem.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
+      IType typeInCU = (IType) elem.getAncestor(IJavaElement.TYPE);
+      if (typeInCU != null) {
+        if (typeInCU.getCompilationUnit() != null) {
+          enclosingType = typeInCU;
+        }
+      } else {
+        ICompilationUnit cu = (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
+        if (cu != null) {
+          //                                   enclosingType= cu.findPrimaryType();
+        }
+      }
+
+      //                       try {
+      //                               IType type= null;
+      //                               if (elem.getElementType() == IJavaElement.TYPE) {
+      //                                       type= (IType)elem;
+      //                                       if (type.exists()) {
+      //                                               String superName= JavaModelUtil.getFullyQualifiedName(type);
+      //                                               if (type.isInterface()) {
+      //                                                       initSuperinterfaces.add(superName);
+      //                                               } else {
+      //                                                       initSuperclass= superName;
+      //                                               }
+      //                                       }
+      //                               }
+      //                       } catch (JavaModelException e) {
+      //                               PHPeclipsePlugin.log(e);
+      //                               // ignore this exception now
+      //                       }
+    }
+
+    setPackageFragment(pack, true);
+    //         setEnclosingType(enclosingType, true);
+    setEnclosingTypeSelection(false, true);
+
+    setTypeName("", true); //$NON-NLS-1$
+    setSuperClass(initSuperclass, true);
+    setSuperInterfaces(initSuperinterfaces, true);
+  }
+
+  // -------- UI Creation ---------
+
+  /**
+   * Creates a separator line. Expects a <code>GridLayout</code> with at least 1 column.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createSeparator(Composite composite, int nColumns) {
+    (new Separator(SWT.SEPARATOR | SWT.HORIZONTAL)).doFillIntoGrid(composite, nColumns, convertHeightInCharsToPixels(1));
+  }
+
+  /**
+   * Creates the controls for the package name field. Expects a <code>GridLayout</code> with at 
+   * least 4 columns.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createPackageControls(Composite composite, int nColumns) {
+    fPackageDialogField.doFillIntoGrid(composite, nColumns);
+    LayoutUtil.setWidthHint(fPackageDialogField.getTextControl(null), getMaxFieldWidth());
+    LayoutUtil.setHorizontalGrabbing(fPackageDialogField.getTextControl(null));
+  }
+
+  /**
+   * Creates the controls for the enclosing type name field. Expects a <code>GridLayout</code> with at 
+   * least 4 columns.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createEnclosingTypeControls(Composite composite, int nColumns) {
+    // #6891
+    Composite tabGroup = new Composite(composite, SWT.NONE);
+    GridLayout layout = new GridLayout();
+    layout.marginWidth = 0;
+    layout.marginHeight = 0;
+    tabGroup.setLayout(layout);
+
+    fEnclosingTypeSelection.doFillIntoGrid(tabGroup, 1);
+
+    Control c = fEnclosingTypeDialogField.getTextControl(composite);
+    GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+    gd.widthHint = getMaxFieldWidth();
+    gd.horizontalSpan = 2;
+    c.setLayoutData(gd);
+
+    Button button = fEnclosingTypeDialogField.getChangeControl(composite);
+    gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+    gd.heightHint = SWTUtil.getButtonHeigthHint(button);
+    gd.widthHint = SWTUtil.getButtonWidthHint(button);
+    button.setLayoutData(gd);
+  }
+
+  /**
+   * Creates the controls for the type name field. Expects a <code>GridLayout</code> with at 
+   * least 2 columns.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createTypeNameControls(Composite composite, int nColumns) {
+    fTypeNameDialogField.doFillIntoGrid(composite, nColumns - 1);
+    DialogField.createEmptySpace(composite);
+
+    LayoutUtil.setWidthHint(fTypeNameDialogField.getTextControl(null), getMaxFieldWidth());
+  }
+
+  /**
+   * Creates the controls for the modifiers radio/ceckbox buttons. Expects a 
+   * <code>GridLayout</code> with at least 3 columns.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createModifierControls(Composite composite, int nColumns) {
+    LayoutUtil.setHorizontalSpan(fAccMdfButtons.getLabelControl(composite), 1);
+
+    Control control = fAccMdfButtons.getSelectionButtonsGroup(composite);
+    GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+    gd.horizontalSpan = nColumns - 2;
+    control.setLayoutData(gd);
+
+    DialogField.createEmptySpace(composite);
+
+    DialogField.createEmptySpace(composite);
+
+    control = fOtherMdfButtons.getSelectionButtonsGroup(composite);
+    gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+    gd.horizontalSpan = nColumns - 2;
+    control.setLayoutData(gd);
+
+    DialogField.createEmptySpace(composite);
+  }
+
+  /**
+   * Creates the controls for the superclass name field. Expects a <code>GridLayout</code> 
+   * with at least 3 columns.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createSuperClassControls(Composite composite, int nColumns) {
+    fSuperClassDialogField.doFillIntoGrid(composite, nColumns);
+    LayoutUtil.setWidthHint(fSuperClassDialogField.getTextControl(null), getMaxFieldWidth());
+  }
+
+  /**
+   * Creates the controls for the superclass name field. Expects a <code>GridLayout</code> with 
+   * at least 3 columns.
+   * 
+   * @param composite the parent composite
+   * @param nColumns number of columns to span
+   */
+  protected void createSuperInterfacesControls(Composite composite, int nColumns) {
+    fSuperInterfacesDialogField.doFillIntoGrid(composite, nColumns);
+    GridData gd = (GridData) fSuperInterfacesDialogField.getListControl(null).getLayoutData();
+    if (fIsClass) {
+      gd.heightHint = convertHeightInCharsToPixels(3);
+    } else {
+      gd.heightHint = convertHeightInCharsToPixels(6);
+    }
+    gd.grabExcessVerticalSpace = false;
+    gd.widthHint = getMaxFieldWidth();
+  }
+
+  /**
+   * Sets the focus on the type name input field.
+   */
+  protected void setFocus() {
+    fTypeNameDialogField.setFocus();
+  }
+
+  // -------- TypeFieldsAdapter --------
+
+  private class TypeFieldsAdapter implements IStringButtonAdapter, IDialogFieldListener, IListAdapter {
+
+    // -------- IStringButtonAdapter
+    public void changeControlPressed(DialogField field) {
+      //                       typePageChangeControlPressed(field);
+    }
+
+    // -------- IListAdapter
+    public void customButtonPressed(ListDialogField field, int index) {
+      //                       typePageCustomButtonPressed(field, index);
+    }
+
+    public void selectionChanged(ListDialogField field) {
+    }
+
+    // -------- IDialogFieldListener
+    public void dialogFieldChanged(DialogField field) {
+      typePageDialogFieldChanged(field);
+    }
+
+    public void doubleClicked(ListDialogField field) {
+    }
+  }
+
+  //   private void typePageChangeControlPressed(DialogField field) {
+  //           if (field == fPackageDialogField) {
+  //                   IPackageFragment pack= choosePackage(); 
+  //                   if (pack != null) {
+  //                           fPackageDialogField.setText(pack.getElementName());
+  //                   }
+  //           } else if (field == fEnclosingTypeDialogField) {
+  //                   IType type= chooseEnclosingType();
+  //                   if (type != null) {
+  //                           fEnclosingTypeDialogField.setText(JavaModelUtil.getFullyQualifiedName(type));
+  //                   }
+  //           } else if (field == fSuperClassDialogField) {
+  //                   IType type= chooseSuperType();
+  //                   if (type != null) {
+  //                           fSuperClassDialogField.setText(JavaModelUtil.getFullyQualifiedName(type));
+  //                   }
+  //           }
+  //   }
+
+  //   private void typePageCustomButtonPressed(DialogField field, int index) {                
+  //           if (field == fSuperInterfacesDialogField) {
+  //                   chooseSuperInterfaces();
+  //           }
+  //   }
+
+  /*
+   * A field on the type has changed. The fields' status and all dependend
+   * status are updated.
+   */
+  private void typePageDialogFieldChanged(DialogField field) {
+    String fieldName = null;
+    if (field == fPackageDialogField) {
+      fPackageStatus = packageChanged();
+      updatePackageStatusLabel();
+      fTypeNameStatus = typeNameChanged();
+      //                       fSuperClassStatus= superClassChanged();                 
+      fieldName = PACKAGE;
+    } else if (field == fEnclosingTypeDialogField) {
+      //                       fEnclosingTypeStatus= enclosingTypeChanged();
+      fTypeNameStatus = typeNameChanged();
+      //                       fSuperClassStatus= superClassChanged();                         
+      fieldName = ENCLOSING;
+    } else if (field == fEnclosingTypeSelection) {
+      updateEnableState();
+      boolean isEnclosedType = isEnclosingTypeSelected();
+      if (!isEnclosedType) {
+        if (fAccMdfButtons.isSelected(PRIVATE_INDEX) || fAccMdfButtons.isSelected(PROTECTED_INDEX)) {
+          fAccMdfButtons.setSelection(PRIVATE_INDEX, false);
+          fAccMdfButtons.setSelection(PROTECTED_INDEX, false);
+          fAccMdfButtons.setSelection(PUBLIC_INDEX, true);
+        }
+        if (fOtherMdfButtons.isSelected(fStaticMdfIndex)) {
+          fOtherMdfButtons.setSelection(fStaticMdfIndex, false);
+        }
+      }
+      fAccMdfButtons.enableSelectionButton(PRIVATE_INDEX, isEnclosedType && fIsClass);
+      fAccMdfButtons.enableSelectionButton(PROTECTED_INDEX, isEnclosedType && fIsClass);
+      fOtherMdfButtons.enableSelectionButton(fStaticMdfIndex, isEnclosedType);
+      fTypeNameStatus = typeNameChanged();
+      //                       fSuperClassStatus= superClassChanged();
+      fieldName = ENCLOSINGSELECTION;
+    } else if (field == fTypeNameDialogField) {
+      fTypeNameStatus = typeNameChanged();
+      fieldName = TYPENAME;
+    } else if (field == fSuperClassDialogField) {
+      //                       fSuperClassStatus= superClassChanged();
+      fieldName = SUPER;
+    } else if (field == fSuperInterfacesDialogField) {
+      //                       fSuperInterfacesStatus= superInterfacesChanged();
+      fieldName = INTERFACES;
+    } else if (field == fOtherMdfButtons) {
+      fModifierStatus = modifiersChanged();
+      fieldName = MODIFIERS;
+    } else {
+      fieldName = METHODS;
+    }
+    // tell all others
+    handleFieldChanged(fieldName);
+  }
+
+  // -------- update message ----------------          
+
+  /*
+   * @see org.eclipse.jdt.ui.wizards.NewContainerWizardPage#handleFieldChanged(String)
+   */
+  protected void handleFieldChanged(String fieldName) {
+    super.handleFieldChanged(fieldName);
+    if (fieldName == CONTAINER) {
+      fPackageStatus = packageChanged();
+      //                       fEnclosingTypeStatus= enclosingTypeChanged();                   
+      fTypeNameStatus = typeNameChanged();
+      //                       fSuperClassStatus= superClassChanged();
+      //                       fSuperInterfacesStatus= superInterfacesChanged();
+    }
+  }
+
+  // ---- set / get ----------------
+
+  /**
+   * Returns the text of the package input field.
+   * 
+   * @return the text of the package input field
+   */
+  public String getPackageText() {
+    return fPackageDialogField.getText();
+  }
+
+  /**
+   * Returns the text of the enclosing type input field.
+   * 
+   * @return the text of the enclosing type input field
+   */
+  public String getEnclosingTypeText() {
+    return fEnclosingTypeDialogField.getText();
+  }
+
+  /**
+   * Returns the package fragment corresponding to the current input.
+   * 
+   * @return a package fragement or <code>null</code> if the input 
+   * could not be resolved.
+   */
+  public IPackageFragment getPackageFragment() {
+    if (!isEnclosingTypeSelected()) {
+      return fCurrPackage;
+    } else {
+      //                       if (fCurrEnclosingType != null) {
+      //                               return fCurrEnclosingType.getPackageFragment();
+      //                       }
+    }
+    return null;
+  }
+
+  /**
+   * Sets the package fragment to the given value. The method updates the model 
+   * and the text of the control.
+   * 
+   * @param pack the package fragement to be set
+   * @param canBeModified if <code>true</code> the package fragment is
+   * editable; otherwise it is read-only.
+   */
+  public void setPackageFragment(IPackageFragment pack, boolean canBeModified) {
+    fCurrPackage = pack;
+    fCanModifyPackage = canBeModified;
+    String str = (pack == null) ? "" : pack.getElementName(); //$NON-NLS-1$
+    fPackageDialogField.setText(str);
+    updateEnableState();
+  }
+
+  /**
+   * Returns the enclosing type corresponding to the current input.
+   * 
+   * @return the enclosing type or <code>null</code> if the enclosing type is 
+   * not selected or the input could not be resolved
+   */
+  public IType getEnclosingType() {
+    //         if (isEnclosingTypeSelected()) {
+    //                 return fCurrEnclosingType;
+    //         }
+    return null;
+  }
+
+  /**
+   * Sets the enclosing type. The method updates the underlying model 
+   * and the text of the control.
+   * 
+   * @param type the enclosing type
+   * @param canBeModified if <code>true</code> the enclosing type field is
+   * editable; otherwise it is read-only.
+   */
+  //   public void setEnclosingType(IType type, boolean canBeModified) {
+  //           fCurrEnclosingType= type;
+  //           fCanModifyEnclosingType= canBeModified;
+  //           String str= (type == null) ? "" : JavaModelUtil.getFullyQualifiedName(type); //$NON-NLS-1$
+  //           fEnclosingTypeDialogField.setText(str);
+  //           updateEnableState();
+  //   }
+
+  /**
+   * Returns the selection state of the enclosing type checkbox.
+   * 
+   * @return the seleciton state of the enclosing type checkbox
+   */
+  public boolean isEnclosingTypeSelected() {
+    return fEnclosingTypeSelection.isSelected();
+  }
+
+  /**
+   * Sets the enclosing type checkbox's selection state.
+   * 
+   * @param isSelected the checkbox's selection state
+   * @param canBeModified if <code>true</code> the enclosing type checkbox is
+   * modifiable; otherwise it is read-only.
+   */
+  public void setEnclosingTypeSelection(boolean isSelected, boolean canBeModified) {
+    fEnclosingTypeSelection.setSelection(isSelected);
+    fEnclosingTypeSelection.setEnabled(canBeModified);
+    updateEnableState();
+  }
+
+  /**
+   * Returns the type name entered into the type input field.
+   * 
+   * @return the type name
+   */
+  public String getTypeName() {
+    return fTypeNameDialogField.getText();
+  }
+
+  /**
+   * Sets the type name input field's text to the given value. Method doesn't update
+   * the model.
+   * 
+   * @param name the new type name
+   * @param canBeModified if <code>true</code> the enclosing type name field is
+   * editable; otherwise it is read-only.
+   */
+  public void setTypeName(String name, boolean canBeModified) {
+    fTypeNameDialogField.setText(name);
+    fTypeNameDialogField.setEnabled(canBeModified);
+  }
+
+  /**
+   * Returns the selected modifiers.
+   * 
+   * @return the selected modifiers
+   * @see Flags 
+   */
+  public int getModifiers() {
+    int mdf = 0;
+    if (fAccMdfButtons.isSelected(PUBLIC_INDEX)) {
+      mdf += F_PUBLIC;
+    } else if (fAccMdfButtons.isSelected(PRIVATE_INDEX)) {
+      mdf += F_PRIVATE;
+    } else if (fAccMdfButtons.isSelected(PROTECTED_INDEX)) {
+      mdf += F_PROTECTED;
+    }
+    //         if (fOtherMdfButtons.isSelected(ABSTRACT_INDEX) && (fStaticMdfIndex != 0)) {    
+    //                 mdf+= F_ABSTRACT;
+    //         }
+    if (fOtherMdfButtons.isSelected(FINAL_INDEX)) {
+      mdf += F_FINAL;
+    }
+    if (fOtherMdfButtons.isSelected(fStaticMdfIndex)) {
+      mdf += F_STATIC;
+    }
+    return mdf;
+  }
+
+  /**
+   * Sets the modifiers.
+   * 
+   * @param modifiers <code>F_PUBLIC</code>, <code>F_PRIVATE</code>, 
+   * <code>F_PROTECTED</code>, <code>F_ABSTRACT, F_FINAL</code>
+   * or <code>F_STATIC</code> or, a valid combination.
+   * @param canBeModified if <code>true</code> the modifier fields are
+   * editable; otherwise they are read-only
+   * @see Flags 
+   */
+  public void setModifiers(int modifiers, boolean canBeModified) {
+    if (Flags.isPublic(modifiers)) {
+      fAccMdfButtons.setSelection(PUBLIC_INDEX, true);
+    } else if (Flags.isPrivate(modifiers)) {
+      fAccMdfButtons.setSelection(PRIVATE_INDEX, true);
+    } else if (Flags.isProtected(modifiers)) {
+      fAccMdfButtons.setSelection(PROTECTED_INDEX, true);
+    } else {
+      fAccMdfButtons.setSelection(DEFAULT_INDEX, true);
+    }
+    //         if (Flags.isAbstract(modifiers)) {
+    //                 fOtherMdfButtons.setSelection(ABSTRACT_INDEX, true);
+    //         }
+    if (Flags.isFinal(modifiers)) {
+      fOtherMdfButtons.setSelection(FINAL_INDEX, true);
+    }
+    if (Flags.isStatic(modifiers)) {
+      fOtherMdfButtons.setSelection(fStaticMdfIndex, true);
+    }
+
+    fAccMdfButtons.setEnabled(canBeModified);
+    fOtherMdfButtons.setEnabled(canBeModified);
+  }
+
+  /**
+   * Returns the content of the superclass input field.
+   * 
+   * @return the superclass name
+   */
+  public String getSuperClass() {
+    return fSuperClassDialogField.getText();
+  }
+
+  /**
+   * Sets the super class name.
+   * 
+   * @param name the new superclass name
+   * @param canBeModified  if <code>true</code> the superclass name field is
+   * editable; otherwise it is read-only.
+   */
+  public void setSuperClass(String name, boolean canBeModified) {
+    fSuperClassDialogField.setText(name);
+    fSuperClassDialogField.setEnabled(canBeModified);
+  }
+
+  /**
+   * Returns the chosen super interfaces.
+   * 
+   * @return a list of chosen super interfaces. The list's elements
+   * are of type <code>String</code>
+   */
+  public List getSuperInterfaces() {
+    return fSuperInterfacesDialogField.getElements();
+  }
+
+  /**
+   * Sets the super interfaces.
+   * 
+   * @param interfacesNames a list of super interface. The method requires that
+   * the list's elements are of type <code>String</code>
+   * @param canBeModified if <code>true</code> the super interface field is
+   * editable; otherwise it is read-only.
+   */
+  public void setSuperInterfaces(List interfacesNames, boolean canBeModified) {
+    fSuperInterfacesDialogField.setElements(interfacesNames);
+    fSuperInterfacesDialogField.setEnabled(canBeModified);
+  }
+
+  // ----------- validation ----------
+
+  /**
+   * A hook method that gets called when the package field has changed. The method 
+   * validates the package name and returns the status of the validation. The validation
+   * also updates the package fragment model.
+   * <p>
+   * Subclasses may extend this method to perform their own validation.
+   * </p>
+   * 
+   * @return the status of the validation
+   */
+  protected IStatus packageChanged() {
+    StatusInfo status = new StatusInfo();
+    fPackageDialogField.enableButton(getPackageFragmentRoot() != null);
+
+    //         String packName= getPackageText();
+    //         if (packName.length() > 0) {
+    //                 IStatus val= JavaConventions.validatePackageName(packName);
+    //                 if (val.getSeverity() == IStatus.ERROR) {
+    //                         status.setError(NewWizardMessages.getFormattedString("NewTypeWizardPage.error.InvalidPackageName", val.getMessage())); //$NON-NLS-1$
+    //                         return status;
+    //                 } else if (val.getSeverity() == IStatus.WARNING) {
+    //                         status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.DiscouragedPackageName", val.getMessage())); //$NON-NLS-1$
+    //                         // continue
+    //                 }
+    //         }
+
+    //         IPackageFragmentRoot root= getPackageFragmentRoot();
+    //         if (root != null) {
+    //                 if (root.getJavaProject().exists() && packName.length() > 0) {
+    //                         try {
+    //                                 IPath rootPath= root.getPath();
+    //                                 IPath outputPath= root.getJavaProject().getOutputLocation();
+    //                                 if (rootPath.isPrefixOf(outputPath) && !rootPath.equals(outputPath)) {
+    //                                         // if the bin folder is inside of our root, dont allow to name a package
+    //                                         // like the bin folder
+    //                                         IPath packagePath= rootPath.append(packName.replace('.', '/'));
+    //                                         if (outputPath.isPrefixOf(packagePath)) {
+    //                                                 status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.ClashOutputLocation")); //$NON-NLS-1$
+    //                                                 return status;
+    //                                         }
+    //                                 }
+    //                         } catch (JavaModelException e) {
+    //                                 PHPeclipsePlugin.log(e);
+    //                                 // let pass                     
+    //                         }
+    //                 }
+    //                 
+    //                 fCurrPackage= root.getPackageFragment(packName);
+    //         } else {
+    //                 status.setError(""); //$NON-NLS-1$
+    //         }
+    return status;
+  }
+
+  /*
+   * Updates the 'default' label next to the package field.
+   */
+  private void updatePackageStatusLabel() {
+    String packName = getPackageText();
+
+    if (packName.length() == 0) {
+      fPackageDialogField.setStatus(NewWizardMessages.getString("NewTypeWizardPage.default")); //$NON-NLS-1$
+    } else {
+      fPackageDialogField.setStatus(""); //$NON-NLS-1$
+    }
+  }
+
+  /*
+   * Updates the enable state of buttons related to the enclosing type selection checkbox.
+   */
+  private void updateEnableState() {
+    boolean enclosing = isEnclosingTypeSelected();
+    fPackageDialogField.setEnabled(fCanModifyPackage && !enclosing);
+    fEnclosingTypeDialogField.setEnabled(fCanModifyEnclosingType && enclosing);
+  }
+
+  /**
+   * Hook method that gets called when the enclosing type name has changed. The method 
+   * validates the enclosing type and returns the status of the validation. It also updates the 
+   * enclosing type model.
+   * <p>
+   * Subclasses may extend this method to perform their own validation.
+   * </p>
+   * 
+   * @return the status of the validation
+   */
+  //   protected IStatus enclosingTypeChanged() {
+  //           StatusInfo status= new StatusInfo();
+  //           fCurrEnclosingType= null;
+  //           
+  //           IPackageFragmentRoot root= getPackageFragmentRoot();
+  //           
+  //           fEnclosingTypeDialogField.enableButton(root != null);
+  //           if (root == null) {
+  //                   status.setError(""); //$NON-NLS-1$
+  //                   return status;
+  //           }
+  //           
+  //           String enclName= getEnclosingTypeText();
+  //           if (enclName.length() == 0) {
+  //                   status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingTypeEnterName")); //$NON-NLS-1$
+  //                   return status;
+  //           }
+  //           try {
+  //                   IType type= findType(root.getJavaProject(), enclName);
+  //                   if (type == null) {
+  //                           status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingTypeNotExists")); //$NON-NLS-1$
+  //                           return status;
+  //                   }
+  //
+  //                   if (type.getCompilationUnit() == null) {
+  //                           status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingNotInCU")); //$NON-NLS-1$
+  //                           return status;
+  //                   }
+  //                   if (!JavaModelUtil.isEditable(type.getCompilationUnit())) {
+  //                           status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingNotEditable")); //$NON-NLS-1$
+  //                           return status;                  
+  //                   }
+  //                   
+  //                   fCurrEnclosingType= type;
+  //                   IPackageFragmentRoot enclosingRoot= JavaModelUtil.getPackageFragmentRoot(type);
+  //                   if (!enclosingRoot.equals(root)) {
+  //                           status.setWarning(NewWizardMessages.getString("NewTypeWizardPage.warning.EnclosingNotInSourceFolder")); //$NON-NLS-1$
+  //                   }
+  //                   return status;
+  //           } catch (JavaModelException e) {
+  //                   status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnclosingTypeNotExists")); //$NON-NLS-1$
+  //                   PHPeclipsePlugin.log(e);
+  //                   return status;
+  //           }
+  //   }
+
+  /**
+   * Hook method that gets called when the type name has changed. The method validates the 
+   * type name and returns the status of the validation.
+   * <p>
+   * Subclasses may extend this method to perform their own validation.
+   * </p>
+   * 
+   * @return the status of the validation
+   */
+  protected IStatus typeNameChanged() {
+    StatusInfo status = new StatusInfo();
+    String typeName = getTypeName();
+    // must not be empty
+    if (typeName.length() == 0) {
+      status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.EnterTypeName")); //$NON-NLS-1$
+      return status;
+    }
+    if (typeName.indexOf('.') != -1) {
+      status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.QualifiedName")); //$NON-NLS-1$
+      return status;
+    }
+    //         IStatus val= JavaConventions.validateJavaTypeName(typeName);
+    //         if (val.getSeverity() == IStatus.ERROR) {
+    //                 status.setError(NewWizardMessages.getFormattedString("NewTypeWizardPage.error.InvalidTypeName", val.getMessage())); //$NON-NLS-1$
+    //                 return status;
+    //         } else if (val.getSeverity() == IStatus.WARNING) {
+    //                 status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.TypeNameDiscouraged", val.getMessage())); //$NON-NLS-1$
+    //                 // continue checking
+    //         }               
+
+    // must not exist
+    if (!isEnclosingTypeSelected()) {
+      IPackageFragment pack = getPackageFragment();
+      if (pack != null) {
+        ICompilationUnit cu = pack.getCompilationUnit(typeName + ".java"); //$NON-NLS-1$
+        if (cu.getResource().exists()) {
+          status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.TypeNameExists")); //$NON-NLS-1$
+          return status;
+        }
+      }
+    } else {
+      IType type = getEnclosingType();
+      if (type != null) {
+        IType member = type.getType(typeName);
+        if (member.exists()) {
+          status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.TypeNameExists")); //$NON-NLS-1$
+          return status;
+        }
+      }
+    }
+    return status;
+  }
+
+  /**
+   * Hook method that gets called when the superclass name has changed. The method 
+   * validates the superclass name and returns the status of the validation.
+   * <p>
+   * Subclasses may extend this method to perform their own validation.
+   * </p>
+   * 
+   * @return the status of the validation
+   */
+  //   protected IStatus superClassChanged() {
+  //           StatusInfo status= new StatusInfo();
+  //           IPackageFragmentRoot root= getPackageFragmentRoot();
+  //           fSuperClassDialogField.enableButton(root != null);
+  //           
+  //           fSuperClass= null;
+  //           
+  //           String sclassName= getSuperClass();
+  //           if (sclassName.length() == 0) {
+  //                   // accept the empty field (stands for java.lang.Object)
+  //                   return status;
+  //           }
+  //           IStatus val= JavaConventions.validateJavaTypeName(sclassName);
+  //           if (val.getSeverity() == IStatus.ERROR) {
+  //                   status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.InvalidSuperClassName")); //$NON-NLS-1$
+  //                   return status;
+  //           } 
+  //           if (root != null) {
+  //                   try {           
+  //                           IType type= resolveSuperTypeName(root.getJavaProject(), sclassName);
+  //                           if (type == null) {
+  //                                   status.setWarning(NewWizardMessages.getString("NewTypeWizardPage.warning.SuperClassNotExists")); //$NON-NLS-1$
+  //                                   return status;
+  //                           } else {
+  //                                   if (type.isInterface()) {
+  //                                           status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.SuperClassIsNotClass", sclassName)); //$NON-NLS-1$
+  //                                           return status;
+  //                                   }
+  //                                   int flags= type.getFlags();
+  //                                   if (Flags.isFinal(flags)) {
+  //                                           status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.SuperClassIsFinal", sclassName)); //$NON-NLS-1$
+  //                                           return status;
+  //                                   } else if (!JavaModelUtil.isVisible(type, getPackageFragment())) {
+  //                                           status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.SuperClassIsNotVisible", sclassName)); //$NON-NLS-1$
+  //                                           return status;
+  //                                   }
+  //                           }
+  //                           fSuperClass= type;
+  //                   } catch (JavaModelException e) {
+  //                           status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.InvalidSuperClassName")); //$NON-NLS-1$
+  //                           PHPeclipsePlugin.log(e);
+  //                   }                                                       
+  //           } else {
+  //                   status.setError(""); //$NON-NLS-1$
+  //           }
+  //           return status;
+  //           
+  //   }
+
+  //   private IType resolveSuperTypeName(IJavaProject jproject, String sclassName) throws JavaModelException {
+  //           if (!jproject.exists()) {
+  //                   return null;
+  //           }
+  //           IType type= null;
+  //           if (isEnclosingTypeSelected()) {
+  //                   // search in the context of the enclosing type
+  //                   IType enclosingType= getEnclosingType();
+  //                   if (enclosingType != null) {
+  //                           String[][] res= enclosingType.resolveType(sclassName);
+  //                           if (res != null && res.length > 0) {
+  //                                   type= jproject.findType(res[0][0], res[0][1]);
+  //                           }
+  //                   }
+  //           } else {
+  //                   IPackageFragment currPack= getPackageFragment();
+  //                   if (type == null && currPack != null) {
+  //                           String packName= currPack.getElementName();
+  //                           // search in own package
+  //                           if (!currPack.isDefaultPackage()) {
+  //                                   type= jproject.findType(packName, sclassName);
+  //                           }
+  //                           // search in java.lang
+  //                           if (type == null && !"java.lang".equals(packName)) { //$NON-NLS-1$
+  //                                   type= jproject.findType("java.lang", sclassName); //$NON-NLS-1$
+  //                           }
+  //                   }
+  //                   // search fully qualified
+  //                   if (type == null) {
+  //                           type= jproject.findType(sclassName);
+  //                   }
+  //           }
+  //           return type;
+  //   }
+
+  //   private IType findType(IJavaProject project, String typeName) throws JavaModelException {
+  //           if (project.exists()) {
+  //                   return project.findType(typeName);
+  //           }
+  //           return null;
+  //   }
+
+  /**
+   * Hook method that gets called when the list of super interface has changed. The method 
+   * validates the superinterfaces and returns the status of the validation.
+   * <p>
+   * Subclasses may extend this method to perform their own validation.
+   * </p>
+   * 
+   * @return the status of the validation
+   */
+  //   protected IStatus superInterfacesChanged() {
+  //           StatusInfo status= new StatusInfo();
+  //           
+  //           IPackageFragmentRoot root= getPackageFragmentRoot();
+  //           fSuperInterfacesDialogField.enableButton(0, root != null);
+  //                                           
+  //           if (root != null) {
+  //                   List elements= fSuperInterfacesDialogField.getElements();
+  //                   int nElements= elements.size();
+  //                   for (int i= 0; i < nElements; i++) {
+  //                           String intfname= (String)elements.get(i);
+  //                           try {
+  //                                   IType type= findType(root.getJavaProject(), intfname);
+  //                                   if (type == null) {
+  //                                           status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.InterfaceNotExists", intfname)); //$NON-NLS-1$
+  //                                           return status;
+  //                                   } else {
+  //                                           if (type.isClass()) {
+  //                                                   status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.InterfaceIsNotInterface", intfname)); //$NON-NLS-1$
+  //                                                   return status;
+  //                                           }
+  //                                           if (!JavaModelUtil.isVisible(type, getPackageFragment())) {
+  //                                                   status.setWarning(NewWizardMessages.getFormattedString("NewTypeWizardPage.warning.InterfaceIsNotVisible", intfname)); //$NON-NLS-1$
+  //                                                   return status;
+  //                                           }
+  //                                   }
+  //                           } catch (JavaModelException e) {
+  //                                   PHPeclipsePlugin.log(e);
+  //                                   // let pass, checking is an extra
+  //                           }                                       
+  //                   }                               
+  //           }
+  //           return status;
+  //   }
+
+  /**
+   * Hook method that gets called when the modifiers have changed. The method validates 
+   * the modifiers and returns the status of the validation.
+   * <p>
+   * Subclasses may extend this method to perform their own validation.
+   * </p>
+   * 
+   * @return the status of the validation
+   */
+  protected IStatus modifiersChanged() {
+    StatusInfo status = new StatusInfo();
+    int modifiers = getModifiers();
+    //         if (Flags.isFinal(modifiers) && Flags.isAbstract(modifiers)) {
+    //                 status.setError(NewWizardMessages.getString("NewTypeWizardPage.error.ModifiersFinalAndAbstract")); //$NON-NLS-1$
+    //         }
+    return status;
+  }
+
+  // selection dialogs
+
+  //   private IPackageFragment choosePackage() {
+  //           IPackageFragmentRoot froot= getPackageFragmentRoot();
+  //           IJavaElement[] packages= null;
+  //           try {
+  //                   if (froot != null && froot.exists()) {
+  //                           packages= froot.getChildren();
+  //                   }
+  //           } catch (JavaModelException e) {
+  //                   PHPeclipsePlugin.log(e);
+  //           }
+  //           if (packages == null) {
+  //                   packages= new IJavaElement[0];
+  //           }
+  //           
+  //           ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT));
+  //           dialog.setIgnoreCase(false);
+  //           dialog.setTitle(NewWizardMessages.getString("NewTypeWizardPage.ChoosePackageDialog.title")); //$NON-NLS-1$
+  //           dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.ChoosePackageDialog.description")); //$NON-NLS-1$
+  //           dialog.setEmptyListMessage(NewWizardMessages.getString("NewTypeWizardPage.ChoosePackageDialog.empty")); //$NON-NLS-1$
+  //           dialog.setElements(packages);
+  //           IPackageFragment pack= getPackageFragment();
+  //           if (pack != null) {
+  //                   dialog.setInitialSelections(new Object[] { pack });
+  //           }
+  //
+  //           if (dialog.open() == ElementListSelectionDialog.OK) {
+  //                   return (IPackageFragment) dialog.getFirstResult();
+  //           }
+  //           return null;
+  //   }
+
+  //   private IType chooseEnclosingType() {
+  //           IPackageFragmentRoot root= getPackageFragmentRoot();
+  //           if (root == null) {
+  //                   return null;
+  //           }
+  //           
+  //           IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaElement[] { root });
+  //   
+  //           TypeSelectionDialog dialog= new TypeSelectionDialog(getShell(), getWizard().getContainer(), IJavaSearchConstants.TYPE, scope);
+  //           dialog.setTitle(NewWizardMessages.getString("NewTypeWizardPage.ChooseEnclosingTypeDialog.title")); //$NON-NLS-1$
+  //           dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.ChooseEnclosingTypeDialog.description")); //$NON-NLS-1$
+  //           dialog.setFilter(Signature.getSimpleName(getEnclosingTypeText()));
+  //           
+  //           if (dialog.open() == TypeSelectionDialog.OK) {  
+  //                   return (IType) dialog.getFirstResult();
+  //           }
+  //           return null;
+  //   }       
+
+  //   private IType chooseSuperType() {
+  //           IPackageFragmentRoot root= getPackageFragmentRoot();
+  //           if (root == null) {
+  //                   return null;
+  //           }       
+  //           
+  //           IJavaElement[] elements= new IJavaElement[] { root.getJavaProject() };
+  //           IJavaSearchScope scope= SearchEngine.createJavaSearchScope(elements);
+  //
+  //           TypeSelectionDialog dialog= new TypeSelectionDialog(getShell(), getWizard().getContainer(), IJavaSearchConstants.CLASS, scope);
+  //           dialog.setTitle(NewWizardMessages.getString("NewTypeWizardPage.SuperClassDialog.title")); //$NON-NLS-1$
+  //           dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.SuperClassDialog.message")); //$NON-NLS-1$
+  //           dialog.setFilter(getSuperClass());
+  //
+  //           if (dialog.open() == TypeSelectionDialog.OK) {
+  //                   return (IType) dialog.getFirstResult();
+  //           }
+  //           return null;
+  //   }
+
+  //   private void chooseSuperInterfaces() {
+  //           IPackageFragmentRoot root= getPackageFragmentRoot();
+  //           if (root == null) {
+  //                   return;
+  //           }       
+  //
+  //           IJavaProject project= root.getJavaProject();
+  //           SuperInterfaceSelectionDialog dialog= new SuperInterfaceSelectionDialog(getShell(), getWizard().getContainer(), fSuperInterfacesDialogField, project);
+  //           dialog.setTitle(fIsClass ? NewWizardMessages.getString("NewTypeWizardPage.InterfacesDialog.class.title") : NewWizardMessages.getString("NewTypeWizardPage.InterfacesDialog.interface.title")); //$NON-NLS-1$ //$NON-NLS-2$
+  //           dialog.setMessage(NewWizardMessages.getString("NewTypeWizardPage.InterfacesDialog.message")); //$NON-NLS-1$
+  //           dialog.open();
+  //           return;
+  //   }       
+
+  // ---- creation ----------------
+
+  /**
+   * Creates the new type using the entered field values.
+   * 
+   * @param monitor a progress monitor to report progress.
+   */
+//  public void createType(IProgressMonitor monitor) throws CoreException, InterruptedException {
+//    if (monitor == null) {
+//      monitor = new NullProgressMonitor();
+//    }
+//
+//    monitor.beginTask(NewWizardMessages.getString("NewTypeWizardPage.operationdesc"), 10); //$NON-NLS-1$
+//    ICompilationUnit createdWorkingCopy = null;
+//    try {
+//      IPackageFragmentRoot root = getPackageFragmentRoot();
+//      IPackageFragment pack = getPackageFragment();
+//      if (pack == null) {
+//        pack = root.getPackageFragment(""); //$NON-NLS-1$
+//      }
+//
+//      if (!pack.exists()) {
+//        String packName = pack.getElementName();
+//        pack = root.createPackageFragment(packName, true, null);
+//      }
+//
+//      monitor.worked(1);
+//
+//      String clName = getTypeName();
+//
+//      boolean isInnerClass = isEnclosingTypeSelected();
+//
+//      IType createdType;
+//      ImportsStructure imports;
+//      int indent = 0;
+//
+//      IPreferenceStore store = PreferenceConstants.getPreferenceStore();
+//      String[] prefOrder = JavaPreferencesSettings.getImportOrderPreference(store);
+//      int threshold = JavaPreferencesSettings.getImportNumberThreshold(store);
+//
+//      String lineDelimiter = null;
+//      if (!isInnerClass) {
+//        lineDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+//
+//        ICompilationUnit parentCU = pack.createCompilationUnit(clName + ".java", "", false, new SubProgressMonitor(monitor, 2)); //$NON-NLS-1$ //$NON-NLS-2$
+//        createdWorkingCopy = (ICompilationUnit) parentCU.getSharedWorkingCopy(null, JavaUI.getBufferFactory(), null);
+//
+//        imports = new ImportsStructure(createdWorkingCopy, prefOrder, threshold, false);
+//        // add an import that will be removed again. Having this import solves 14661
+//        imports.addImport(pack.getElementName(), getTypeName());
+//
+//        String typeContent = constructTypeStub(new ImportsManager(imports), lineDelimiter);
+//
+//        String cuContent = constructCUContent(parentCU, typeContent, lineDelimiter);
+//
+//        createdWorkingCopy.getBuffer().setContents(cuContent);
+//
+//        createdType = createdWorkingCopy.getType(clName);
+//      } else {
+//        IType enclosingType = getEnclosingType();
+//
+//        // if we are working on a enclosed type that is open in an editor,
+//        // then replace the enclosing type with its working copy
+//        IType workingCopy = (IType) EditorUtility.getWorkingCopy(enclosingType);
+//        if (workingCopy != null) {
+//          enclosingType = workingCopy;
+//        }
+//
+//        ICompilationUnit parentCU = enclosingType.getCompilationUnit();
+//        imports = new ImportsStructure(parentCU, prefOrder, threshold, true);
+//
+//        // add imports that will be removed again. Having the imports solves 14661
+//        IType[] topLevelTypes = parentCU.getTypes();
+//        for (int i = 0; i < topLevelTypes.length; i++) {
+//          imports.addImport(topLevelTypes[i].getFullyQualifiedName('.'));
+//        }
+//
+//        lineDelimiter = StubUtility.getLineDelimiterUsed(enclosingType);
+//        StringBuffer content = new StringBuffer();
+//        String comment = getTypeComment(parentCU);
+//        if (comment != null) {
+//          content.append(comment);
+//          content.append(lineDelimiter);
+//        }
+//        content.append(constructTypeStub(new ImportsManager(imports), lineDelimiter));
+//        IJavaElement[] elems = enclosingType.getChildren();
+//        IJavaElement sibling = elems.length > 0 ? elems[0] : null;
+//
+//        createdType = enclosingType.createType(content.toString(), sibling, false, new SubProgressMonitor(monitor, 1));
+//
+//        indent = StubUtility.getIndentUsed(enclosingType) + 1;
+//      }
+//
+//      // add imports for superclass/interfaces, so types can be resolved correctly
+//      imports.create(false, new SubProgressMonitor(monitor, 1));
+//
+//      ICompilationUnit cu = createdType.getCompilationUnit();
+//      synchronized (cu) {
+//        cu.reconcile();
+//      }
+//      createTypeMembers(createdType, new ImportsManager(imports), new SubProgressMonitor(monitor, 1));
+//
+//      // add imports
+//      imports.create(false, new SubProgressMonitor(monitor, 1));
+//
+//      synchronized (cu) {
+//        cu.reconcile();
+//      }
+//      ISourceRange range = createdType.getSourceRange();
+//
+//      IBuffer buf = cu.getBuffer();
+//      String originalContent = buf.getText(range.getOffset(), range.getLength());
+//      String formattedContent = StubUtility.codeFormat(originalContent, indent, lineDelimiter);
+//      buf.replace(range.getOffset(), range.getLength(), formattedContent);
+//      if (!isInnerClass) {
+//        String fileComment = getFileComment(cu);
+//        if (fileComment != null && fileComment.length() > 0) {
+//          buf.replace(0, 0, fileComment + lineDelimiter);
+//        }
+//        cu.commit(false, new SubProgressMonitor(monitor, 1));
+//      } else {
+//        monitor.worked(1);
+//      }
+//      fCreatedType = createdType;
+//    } finally {
+//      if (createdWorkingCopy != null) {
+//        createdWorkingCopy.destroy();
+//      }
+//      monitor.done();
+//    }
+//  }
+
+  /**
+   * Uses the New Java file template from the code template page to generate a
+   * compilation unit with the given type content.
+   * @param cu The new created compilation unit
+   * @param typeContent The content of the type, including signature and type
+   * body.
+   * @param lineDelimiter The line delimiter to be used.
+   * @return String Returns the result of evaluating the new file template
+   * with the given type content.
+   * @throws CoreException
+   * @since 2.1
+   */
+  //   protected String constructCUContent(ICompilationUnit cu, String typeContent, String lineDelimiter) throws CoreException {
+  //           StringBuffer typeQualifiedName= new StringBuffer();
+  //           if (isEnclosingTypeSelected()) {
+  //                   typeQualifiedName.append(JavaModelUtil.getTypeQualifiedName(getEnclosingType())).append('.');
+  //           }
+  //           typeQualifiedName.append(getTypeName());
+  //           String typeComment= CodeGeneration.getTypeComment(cu, typeQualifiedName.toString(), lineDelimiter);
+  //           IPackageFragment pack= (IPackageFragment) cu.getParent();
+  //           String content= CodeGeneration.getCompilationUnitContent(cu, typeComment, typeContent, lineDelimiter);
+  //           if (content != null) {
+  //                   CompilationUnit unit= AST.parseCompilationUnit(content.toCharArray());
+  //                   if ((pack.isDefaultPackage() || unit.getPackage() != null) && !unit.types().isEmpty()) {
+  //                           return content;
+  //                   }
+  //           }
+  //           StringBuffer buf= new StringBuffer();
+  //           if (!pack.isDefaultPackage()) {
+  //                   buf.append("package ").append(pack.getElementName()).append(';'); //$NON-NLS-1$
+  //           }
+  //           buf.append(lineDelimiter).append(lineDelimiter);
+  //           if (typeComment != null) {
+  //                   buf.append(typeComment).append(lineDelimiter);
+  //           }
+  //           buf.append(typeContent);
+  //           return buf.toString();
+  //   }
+
+  /**
+   * Returns the created type. The method only returns a valid type 
+   * after <code>createType</code> has been called.
+   * 
+   * @return the created type
+   * @see #createType(IProgressMonitor)
+   */
+  //   public IType getCreatedType() {
+  //           return fCreatedType;
+  //   }
+
+  // ---- construct cu body----------------
+
+  //   private void writeSuperClass(StringBuffer buf, ImportsManager imports) {
+  //           String typename= getSuperClass();
+  //           if (fIsClass && typename.length() > 0 && !"java.lang.Object".equals(typename)) { //$NON-NLS-1$
+  //                   buf.append(" extends "); //$NON-NLS-1$
+  //                   
+  //                   String qualifiedName= fSuperClass != null ? JavaModelUtil.getFullyQualifiedName(fSuperClass) : typename; 
+  //                   buf.append(imports.addImport(qualifiedName));
+  //           }
+  //   }
+
+  //   private void writeSuperInterfaces(StringBuffer buf, ImportsManager imports) {
+  //           List interfaces= getSuperInterfaces();
+  //           int last= interfaces.size() - 1;
+  //           if (last >= 0) {
+  //                   if (fIsClass) {
+  //                           buf.append(" implements "); //$NON-NLS-1$
+  //                   } else {
+  //                           buf.append(" extends "); //$NON-NLS-1$
+  //                   }
+  //                   for (int i= 0; i <= last; i++) {
+  //                           String typename= (String) interfaces.get(i);
+  //                           buf.append(imports.addImport(typename));
+  //                           if (i < last) {
+  //                                   buf.append(',');
+  //                           }
+  //                   }
+  //           }
+  //   }
+
+  /*
+   * Called from createType to construct the source for this type
+   */
+  //   private String constructTypeStub(ImportsManager imports, String lineDelimiter) {        
+  //           StringBuffer buf= new StringBuffer();
+  //                   
+  //           int modifiers= getModifiers();
+  //           buf.append(Flags.toString(modifiers));
+  //           if (modifiers != 0) {
+  //                   buf.append(' ');
+  //           }
+  //           buf.append(fIsClass ? "class " : "interface "); //$NON-NLS-2$ //$NON-NLS-1$
+  //           buf.append(getTypeName());
+  //           writeSuperClass(buf, imports);
+  //           writeSuperInterfaces(buf, imports);     
+  //           buf.append('{');
+  //           buf.append(lineDelimiter);
+  //           buf.append(lineDelimiter);
+  //           buf.append('}');
+  //           buf.append(lineDelimiter);
+  //           return buf.toString();
+  //   }
+
+  /**
+   * @deprecated Overwrite createTypeMembers(IType, IImportsManager, IProgressMonitor) instead
+   */
+  //   protected void createTypeMembers(IType newType, IImportsStructure imports, IProgressMonitor monitor) throws CoreException {
+  //           //deprecated
+  //   }
+
+  /**
+   * Hook method that gets called from <code>createType</code> to support adding of 
+   * unanticipated methods, fields, and inner types to the created type.
+   * <p>
+   * Implementers can use any methods defined on <code>IType</code> to manipulate the
+   * new type.
+   * </p>
+   * <p>
+   * The source code of the new type will be formtted using the platform's formatter. Needed 
+   * imports are added by the wizard at the end of the type creation process using the given 
+   * import manager.
+   * </p>
+   * 
+   * @param newType the new type created via <code>createType</code>
+   * @param imports an import manager which can be used to add new imports
+   * @param monitor a progress monitor to report progress. Must not be <code>null</code>
+   * 
+   * @see #createType(IProgressMonitor)
+   */
+  //   protected void createTypeMembers(IType newType, ImportsManager imports, IProgressMonitor monitor) throws CoreException {
+  //           // call for compatibility
+  //           createTypeMembers(newType, ((ImportsManager)imports).getImportsStructure(), monitor);
+  //           
+  //           // default implementation does nothing
+  //           // example would be
+  //           // String mainMathod= "public void foo(Vector vec) {}"
+  //           // createdType.createMethod(main, null, false, null);
+  //           // imports.addImport("java.lang.Vector");
+  //   }       
+
+  /**
+   * @deprecated Instead of file templates, the new type code template
+   * specifies the stub for a compilation unit.
+   */
+  protected String getFileComment(ICompilationUnit parentCU) {
+    return null;
+  }
+
+  private boolean isValidComment(String template) {
+    IScanner scanner = ToolFactory.createScanner(true, false, false); //, false);
+    scanner.setSource(template.toCharArray());
+    try {
+      int next = scanner.getNextToken();
+      while (next == ITerminalSymbols.TokenNameCOMMENT_LINE
+        || next == ITerminalSymbols.TokenNameCOMMENT_PHPDOC
+        || next == ITerminalSymbols.TokenNameCOMMENT_BLOCK) {
+        next = scanner.getNextToken();
+      }
+      return next == ITerminalSymbols.TokenNameEOF;
+    } catch (InvalidInputException e) {
+    }
+    return false;
+  }
+
+  /**
+   * Hook method that gets called from <code>createType</code> to retrieve 
+   * a type comment. This default implementation returns the content of the 
+   * 'typecomment' template.
+   * 
+   * @return the type comment or <code>null</code> if a type comment 
+   * is not desired
+   */
+  //   protected String getTypeComment(ICompilationUnit parentCU) {
+  //           if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.CODEGEN_ADD_COMMENTS)) {
+  //                   try {
+  //                           StringBuffer typeName= new StringBuffer();
+  //                           if (isEnclosingTypeSelected()) {
+  //                                   typeName.append(JavaModelUtil.getTypeQualifiedName(getEnclosingType())).append('.');
+  //                           }
+  //                           typeName.append(getTypeName());
+  //                           String comment= CodeGeneration.getTypeComment(parentCU, typeName.toString(), String.valueOf('\n'));
+  //                           if (comment != null && isValidComment(comment)) {
+  //                                   return comment;
+  //                           }
+  //                   } catch (CoreException e) {
+  //                           PHPeclipsePlugin.log(e);
+  //                   }
+  //           }
+  //           return null;
+  //   }
+
+  /**
+   * @deprecated Use getTemplate(String,ICompilationUnit,int)
+   */
+  protected String getTemplate(String name, ICompilationUnit parentCU) {
+    return getTemplate(name, parentCU, 0);
+  }
+
+  /**
+   * Returns the string resulting from evaluation the given template in
+   * the context of the given compilation unit. This accesses the normal
+   * template page, not the code templates. To use code templates use
+   * <code>constructCUContent</code> to construct a compilation unit stub or
+   * getTypeComment for the comment of the type.
+   * 
+   * @param name the template to be evaluated
+   * @param parentCU the templates evaluation context
+   * @param pos a source offset into the parent compilation unit. The
+   * template is evalutated at the given source offset
+   */
+  protected String getTemplate(String name, ICompilationUnit parentCU, int pos) {
+    try {
+      Template[] templates = Templates.getInstance().getTemplates(name);
+      if (templates.length > 0) {
+        return JavaContext.evaluateTemplate(templates[0], parentCU, pos);
+      }
+    } catch (CoreException e) {
+      PHPeclipsePlugin.log(e);
+    }
+    return null;
+  }
+
+  /**
+   * @deprecated Use createInheritedMethods(IType,boolean,boolean,IImportsManager,IProgressMonitor)
+   */
+  //   protected IMethod[] createInheritedMethods(IType type, boolean doConstructors, boolean doUnimplementedMethods, IImportsStructure imports, IProgressMonitor monitor) throws CoreException {
+  //           return createInheritedMethods(type, doConstructors, doUnimplementedMethods, new ImportsManager(imports), monitor);
+  //   }
+
+  /**
+   * Creates the bodies of all unimplemented methods and constructors and adds them to the type.
+   * Method is typically called by implementers of <code>NewTypeWizardPage</code> to add
+   * needed method and constructors.
+   * 
+   * @param type the type for which the new methods and constructor are to be created
+   * @param doConstructors if <code>true</code> unimplemented constructors are created
+   * @param doUnimplementedMethods if <code>true</code> unimplemented methods are created
+   * @param imports an import manager to add all neded import statements
+   * @param monitor a progress monitor to report progress
+   */
+  //   protected IMethod[] createInheritedMethods(IType type, boolean doConstructors, boolean doUnimplementedMethods, ImportsManager imports, IProgressMonitor monitor) throws CoreException {
+  //           ArrayList newMethods= new ArrayList();
+  //           ITypeHierarchy hierarchy= null;
+  //           CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings();
+  //
+  //           if (doConstructors) {
+  //                   hierarchy= type.newSupertypeHierarchy(monitor);
+  //                   IType superclass= hierarchy.getSuperclass(type);
+  //                   if (superclass != null) {
+  //                           String[] constructors= StubUtility.evalConstructors(type, superclass, settings, imports.getImportsStructure());
+  //                           if (constructors != null) {
+  //                                   for (int i= 0; i < constructors.length; i++) {
+  //                                           newMethods.add(constructors[i]);
+  //                                   }
+  //                           }
+  //                   
+  //                   }
+  //           }
+  //           if (doUnimplementedMethods) {
+  //                   if (hierarchy == null) {
+  //                           hierarchy= type.newSupertypeHierarchy(monitor);
+  //                   }                       
+  //                   String[] unimplemented= StubUtility.evalUnimplementedMethods(type, hierarchy, false, settings, null, imports.getImportsStructure());
+  //                   if (unimplemented != null) {
+  //                           for (int i= 0; i < unimplemented.length; i++) {
+  //                                   newMethods.add(unimplemented[i]);                                       
+  //                           }
+  //                   }
+  //           }
+  //           IMethod[] createdMethods= new IMethod[newMethods.size()];
+  //           for (int i= 0; i < newMethods.size(); i++) {
+  //                   String content= (String) newMethods.get(i) + '\n'; // content will be formatted, ok to use \n
+  //                   createdMethods[i]= type.createMethod(content, null, false, null);
+  //           }
+  //           return createdMethods;
+  //   }
+
+  // ---- creation ----------------
+
+  /**
+   * Returns the runnable that creates the type using the current settings.
+   * The returned runnable must be executed in the UI thread.
+   * 
+   * @return the runnable to create the new type
+   */
+  //   public IRunnableWithProgress getRunnable() {                            
+  //           return new IRunnableWithProgress() {
+  //                   public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+  //                           try {
+  //                                   if (monitor == null) {
+  //                                           monitor= new NullProgressMonitor();
+  //                                   }
+  //                                   createType(monitor);
+  //                           } catch (CoreException e) {
+  //                                   throw new InvocationTargetException(e);
+  //                           }                               
+  //                   }
+  //           };
+  //   }       
+
+}
index 3e9e8ad..7524705 100644 (file)
@@ -45,6 +45,10 @@ public interface IPreferenceConstants {
   public static final String PHP_SINGLELINE_COMMENT_BOLD = "_php_singlelineComment_bold";
   public static final String PHP_SINGLELINE_COMMENT_ITALIC = "_php_singlelineComment_italic";
   public static final String PHP_SINGLELINE_COMMENT_UNDERLINE = "_php_singlelineComment_underline";
+       public static final String PHP_TAG = "_php_tag";
+       public static final String PHP_TAG_BOLD = "_php_tag_bold";
+       public static final String PHP_TAG_ITALIC = "_php_tag_italic";
+       public static final String PHP_TAG_UNDERLINE = "_php_tag_underline";
   public static final String PHP_KEYWORD = "_php_keyword";
   public static final String PHP_KEYWORD_BOLD = "_php_keyword_bold";
   public static final String PHP_KEYWORD_ITALIC = "_php_keyword_italic";
index 52d906b..a7e866e 100644 (file)
@@ -6,12 +6,15 @@ import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
 
+import net.sourceforge.phpdt.internal.core.BatchOperation;
 import net.sourceforge.phpeclipse.resourcesview.PHPFile;
 import net.sourceforge.phpeclipse.resourcesview.PHPProject;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -155,7 +158,7 @@ public class PHPCore {
    * @since 2.1
    */
   public static final String CLEAN = "clean"; //$NON-NLS-1$
-       
+
   /**
    * Returns a table of all known configurable options with their default values.
    * These options allow to configure the behaviour of the underlying components.
@@ -550,9 +553,7 @@ public class PHPCore {
     for (int i = 0; i < defaultPropertyNames.length; i++) {
       String propertyName = defaultPropertyNames[i];
       if (optionNames.contains(propertyName)) {
-        defaultOptions.put(
-          propertyName,
-          preferences.getDefaultString(propertyName));
+        defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
       }
     }
     // get preferences not set to their default
@@ -560,9 +561,7 @@ public class PHPCore {
     for (int i = 0; i < propertyNames.length; i++) {
       String propertyName = propertyNames[i];
       if (optionNames.contains(propertyName)) {
-        defaultOptions.put(
-          propertyName,
-          preferences.getDefaultString(propertyName));
+        defaultOptions.put(propertyName, preferences.getDefaultString(propertyName));
       }
     }
     // get encoding through resource plugin
@@ -672,8 +671,7 @@ public class PHPCore {
   }
   public static IProject[] getPHPProjects() {
     List phpProjectsList = new ArrayList();
-    IProject[] workspaceProjects =
-      PHPeclipsePlugin.getWorkspace().getRoot().getProjects();
+    IProject[] workspaceProjects = PHPeclipsePlugin.getWorkspace().getRoot().getProjects();
 
     for (int i = 0; i < workspaceProjects.length; i++) {
       IProject iProject = workspaceProjects[i];
@@ -686,8 +684,7 @@ public class PHPCore {
   }
 
   public static PHPProject getPHPProject(String name) {
-    IProject aProject =
-      PHPeclipsePlugin.getWorkspace().getRoot().getProject(name);
+    IProject aProject = PHPeclipsePlugin.getWorkspace().getRoot().getProject(name);
     if (isPHPProject(aProject)) {
       PHPProject thePHPProject = new PHPProject();
       thePHPProject.setProject(aProject);
@@ -730,15 +727,13 @@ public class PHPCore {
         return project;
       }
     } catch (CoreException e) {
-      System.err.println(
-        "Exception occurred in PHPCore#create(IProject): " + e.toString());
+      System.err.println("Exception occurred in PHPCore#create(IProject): " + e.toString());
     }
 
     return null;
   }
 
-  public static void addPHPNature(IProject project, IProgressMonitor monitor)
-    throws CoreException {
+  public static void addPHPNature(IProject project, IProgressMonitor monitor) throws CoreException {
     if (!project.hasNature(PHPeclipsePlugin.PHP_NATURE_ID)) {
       IProjectDescription description = project.getDescription();
       String[] prevNatures = description.getNatureIds();
@@ -758,175 +753,212 @@ public class PHPCore {
   public static Plugin getPlugin() {
     return PHPeclipsePlugin.getDefault();
   }
-  
-/**
-   * Initializes the default preferences settings for this plug-in.
-   */
+
+  /**
+     * Initializes the default preferences settings for this plug-in.
+     */
   protected static void initializeDefaultPluginPreferences() {
-               
+
     Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
     HashSet optionNames = OptionNames;
-               
-//    // Compiler settings
-//    preferences.setDefault(COMPILER_LOCAL_VARIABLE_ATTR, GENERATE);
-//    optionNames.add(COMPILER_LOCAL_VARIABLE_ATTR);
-//
-//    preferences.setDefault(COMPILER_LINE_NUMBER_ATTR, GENERATE); 
-//    optionNames.add(COMPILER_LINE_NUMBER_ATTR);
-//
-//    preferences.setDefault(COMPILER_SOURCE_FILE_ATTR, GENERATE); 
-//    optionNames.add(COMPILER_SOURCE_FILE_ATTR);
-//
-//    preferences.setDefault(COMPILER_CODEGEN_UNUSED_LOCAL, PRESERVE); 
-//    optionNames.add(COMPILER_CODEGEN_UNUSED_LOCAL);
-//
-//    preferences.setDefault(COMPILER_CODEGEN_TARGET_PLATFORM, VERSION_1_1); 
-//    optionNames.add(COMPILER_CODEGEN_TARGET_PLATFORM);
-//
-//    preferences.setDefault(COMPILER_PB_UNREACHABLE_CODE, ERROR); 
-//    optionNames.add(COMPILER_PB_UNREACHABLE_CODE);
-//
-//    preferences.setDefault(COMPILER_PB_INVALID_IMPORT, ERROR); 
-//    optionNames.add(COMPILER_PB_INVALID_IMPORT);
-//
-//    preferences.setDefault(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, WARNING); 
-//    optionNames.add(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD);
-//
-//    preferences.setDefault(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, WARNING); 
-//    optionNames.add(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME);
-//
-//    preferences.setDefault(COMPILER_PB_DEPRECATION, WARNING);
-//    optionNames.add(COMPILER_PB_DEPRECATION);
-//
-//    preferences.setDefault(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, DISABLED);
-//    optionNames.add(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE);
-//
-//    preferences.setDefault(COMPILER_PB_HIDDEN_CATCH_BLOCK, WARNING); 
-//    optionNames.add(COMPILER_PB_HIDDEN_CATCH_BLOCK);
-//
-//    preferences.setDefault(COMPILER_PB_UNUSED_LOCAL, IGNORE); 
-//    optionNames.add(COMPILER_PB_UNUSED_LOCAL);
-//
-//    preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER, IGNORE); 
-//    optionNames.add(COMPILER_PB_UNUSED_PARAMETER);
-//
-//    preferences.setDefault(COMPILER_PB_UNUSED_IMPORT, WARNING); 
-//    optionNames.add(COMPILER_PB_UNUSED_IMPORT);
-//
-//    preferences.setDefault(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, IGNORE); 
-//    optionNames.add(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION);
-//
-//    preferences.setDefault(COMPILER_PB_NON_NLS_STRING_LITERAL, IGNORE); 
-//    optionNames.add(COMPILER_PB_NON_NLS_STRING_LITERAL);
-//
-//    preferences.setDefault(COMPILER_PB_ASSERT_IDENTIFIER, IGNORE); 
-//    optionNames.add(COMPILER_PB_ASSERT_IDENTIFIER);
-//
-//    preferences.setDefault(COMPILER_PB_STATIC_ACCESS_RECEIVER, WARNING); 
-//    optionNames.add(COMPILER_PB_STATIC_ACCESS_RECEIVER);
-//
-//    preferences.setDefault(COMPILER_PB_NO_EFFECT_ASSIGNMENT, WARNING); 
-//    optionNames.add(COMPILER_PB_NO_EFFECT_ASSIGNMENT);
-//
-//    preferences.setDefault(COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
-//    optionNames.add(COMPILER_TASK_TAGS);
-//
-//    preferences.setDefault(COMPILER_TASK_PRIORITIES, ""); //$NON-NLS-1$
-//    optionNames.add(COMPILER_TASK_PRIORITIES);
-//
-//    preferences.setDefault(COMPILER_SOURCE, VERSION_1_3);
-//    optionNames.add(COMPILER_SOURCE);
-//
-//    preferences.setDefault(COMPILER_COMPLIANCE, VERSION_1_3); 
-//    optionNames.add(COMPILER_COMPLIANCE);
-//
-//    preferences.setDefault(COMPILER_PB_MAX_PER_UNIT, "100"); //$NON-NLS-1$
-//    optionNames.add(COMPILER_PB_MAX_PER_UNIT);
-//             
-//    // Builder settings
-//    preferences.setDefault(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
-//    optionNames.add(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER);
-//
-//    preferences.setDefault(CORE_JAVA_BUILD_INVALID_CLASSPATH, ABORT); 
-//    optionNames.add(CORE_JAVA_BUILD_INVALID_CLASSPATH);
-//     
-//    preferences.setDefault(CORE_JAVA_BUILD_DUPLICATE_RESOURCE, WARNING); 
-//    optionNames.add(CORE_JAVA_BUILD_DUPLICATE_RESOURCE);
-//             
-//    preferences.setDefault(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, CLEAN); 
-//    optionNames.add(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER);
-//
-//    // JavaCore settings
-//    preferences.setDefault(CORE_JAVA_BUILD_ORDER, IGNORE); 
-//    optionNames.add(CORE_JAVA_BUILD_ORDER);
-//     
-//    preferences.setDefault(CORE_CIRCULAR_CLASSPATH, ERROR); 
-//    optionNames.add(CORE_CIRCULAR_CLASSPATH);
-//             
-//    preferences.setDefault(CORE_INCOMPLETE_CLASSPATH, ERROR); 
-//    optionNames.add(CORE_INCOMPLETE_CLASSPATH);
-               
+
+    //    // Compiler settings
+    //    preferences.setDefault(COMPILER_LOCAL_VARIABLE_ATTR, GENERATE);
+    //    optionNames.add(COMPILER_LOCAL_VARIABLE_ATTR);
+    //
+    //    preferences.setDefault(COMPILER_LINE_NUMBER_ATTR, GENERATE); 
+    //    optionNames.add(COMPILER_LINE_NUMBER_ATTR);
+    //
+    //    preferences.setDefault(COMPILER_SOURCE_FILE_ATTR, GENERATE); 
+    //    optionNames.add(COMPILER_SOURCE_FILE_ATTR);
+    //
+    //    preferences.setDefault(COMPILER_CODEGEN_UNUSED_LOCAL, PRESERVE); 
+    //    optionNames.add(COMPILER_CODEGEN_UNUSED_LOCAL);
+    //
+    //    preferences.setDefault(COMPILER_CODEGEN_TARGET_PLATFORM, VERSION_1_1); 
+    //    optionNames.add(COMPILER_CODEGEN_TARGET_PLATFORM);
+    //
+    //    preferences.setDefault(COMPILER_PB_UNREACHABLE_CODE, ERROR); 
+    //    optionNames.add(COMPILER_PB_UNREACHABLE_CODE);
+    //
+    //    preferences.setDefault(COMPILER_PB_INVALID_IMPORT, ERROR); 
+    //    optionNames.add(COMPILER_PB_INVALID_IMPORT);
+    //
+    //    preferences.setDefault(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD, WARNING); 
+    //    optionNames.add(COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD);
+    //
+    //    preferences.setDefault(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME, WARNING); 
+    //    optionNames.add(COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME);
+    //
+    //    preferences.setDefault(COMPILER_PB_DEPRECATION, WARNING);
+    //    optionNames.add(COMPILER_PB_DEPRECATION);
+    //
+    //    preferences.setDefault(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, DISABLED);
+    //    optionNames.add(COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE);
+    //
+    //    preferences.setDefault(COMPILER_PB_HIDDEN_CATCH_BLOCK, WARNING); 
+    //    optionNames.add(COMPILER_PB_HIDDEN_CATCH_BLOCK);
+    //
+    //    preferences.setDefault(COMPILER_PB_UNUSED_LOCAL, IGNORE); 
+    //    optionNames.add(COMPILER_PB_UNUSED_LOCAL);
+    //
+    //    preferences.setDefault(COMPILER_PB_UNUSED_PARAMETER, IGNORE); 
+    //    optionNames.add(COMPILER_PB_UNUSED_PARAMETER);
+    //
+    //    preferences.setDefault(COMPILER_PB_UNUSED_IMPORT, WARNING); 
+    //    optionNames.add(COMPILER_PB_UNUSED_IMPORT);
+    //
+    //    preferences.setDefault(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION, IGNORE); 
+    //    optionNames.add(COMPILER_PB_SYNTHETIC_ACCESS_EMULATION);
+    //
+    //    preferences.setDefault(COMPILER_PB_NON_NLS_STRING_LITERAL, IGNORE); 
+    //    optionNames.add(COMPILER_PB_NON_NLS_STRING_LITERAL);
+    //
+    //    preferences.setDefault(COMPILER_PB_ASSERT_IDENTIFIER, IGNORE); 
+    //    optionNames.add(COMPILER_PB_ASSERT_IDENTIFIER);
+    //
+    //    preferences.setDefault(COMPILER_PB_STATIC_ACCESS_RECEIVER, WARNING); 
+    //    optionNames.add(COMPILER_PB_STATIC_ACCESS_RECEIVER);
+    //
+    //    preferences.setDefault(COMPILER_PB_NO_EFFECT_ASSIGNMENT, WARNING); 
+    //    optionNames.add(COMPILER_PB_NO_EFFECT_ASSIGNMENT);
+    //
+    //    preferences.setDefault(COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+    //    optionNames.add(COMPILER_TASK_TAGS);
+    //
+    //    preferences.setDefault(COMPILER_TASK_PRIORITIES, ""); //$NON-NLS-1$
+    //    optionNames.add(COMPILER_TASK_PRIORITIES);
+    //
+    //    preferences.setDefault(COMPILER_SOURCE, VERSION_1_3);
+    //    optionNames.add(COMPILER_SOURCE);
+    //
+    //    preferences.setDefault(COMPILER_COMPLIANCE, VERSION_1_3); 
+    //    optionNames.add(COMPILER_COMPLIANCE);
+    //
+    //    preferences.setDefault(COMPILER_PB_MAX_PER_UNIT, "100"); //$NON-NLS-1$
+    //    optionNames.add(COMPILER_PB_MAX_PER_UNIT);
+    //         
+    //    // Builder settings
+    //    preferences.setDefault(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
+    //    optionNames.add(CORE_JAVA_BUILD_RESOURCE_COPY_FILTER);
+    //
+    //    preferences.setDefault(CORE_JAVA_BUILD_INVALID_CLASSPATH, ABORT); 
+    //    optionNames.add(CORE_JAVA_BUILD_INVALID_CLASSPATH);
+    // 
+    //    preferences.setDefault(CORE_JAVA_BUILD_DUPLICATE_RESOURCE, WARNING); 
+    //    optionNames.add(CORE_JAVA_BUILD_DUPLICATE_RESOURCE);
+    //         
+    //    preferences.setDefault(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, CLEAN); 
+    //    optionNames.add(CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER);
+    //
+    //    // JavaCore settings
+    //    preferences.setDefault(CORE_JAVA_BUILD_ORDER, IGNORE); 
+    //    optionNames.add(CORE_JAVA_BUILD_ORDER);
+    // 
+    //    preferences.setDefault(CORE_CIRCULAR_CLASSPATH, ERROR); 
+    //    optionNames.add(CORE_CIRCULAR_CLASSPATH);
+    //         
+    //    preferences.setDefault(CORE_INCOMPLETE_CLASSPATH, ERROR); 
+    //    optionNames.add(CORE_INCOMPLETE_CLASSPATH);
+
     // encoding setting comes from resource plug-in
     optionNames.add(CORE_ENCODING);
-               
+
     // Formatter settings
-    preferences.setDefault(FORMATTER_NEWLINE_OPENING_BRACE, DO_NOT_INSERT); 
+    preferences.setDefault(FORMATTER_NEWLINE_OPENING_BRACE, DO_NOT_INSERT);
     optionNames.add(FORMATTER_NEWLINE_OPENING_BRACE);
 
     preferences.setDefault(FORMATTER_NEWLINE_CONTROL, DO_NOT_INSERT);
     optionNames.add(FORMATTER_NEWLINE_CONTROL);
 
-    preferences.setDefault(FORMATTER_CLEAR_BLANK_LINES, PRESERVE_ONE); 
+    preferences.setDefault(FORMATTER_CLEAR_BLANK_LINES, PRESERVE_ONE);
     optionNames.add(FORMATTER_CLEAR_BLANK_LINES);
 
     preferences.setDefault(FORMATTER_NEWLINE_ELSE_IF, DO_NOT_INSERT);
     optionNames.add(FORMATTER_NEWLINE_ELSE_IF);
 
-    preferences.setDefault(FORMATTER_NEWLINE_EMPTY_BLOCK, INSERT); 
+    preferences.setDefault(FORMATTER_NEWLINE_EMPTY_BLOCK, INSERT);
     optionNames.add(FORMATTER_NEWLINE_EMPTY_BLOCK);
 
     preferences.setDefault(FORMATTER_LINE_SPLIT, "80"); //$NON-NLS-1$
     optionNames.add(FORMATTER_LINE_SPLIT);
 
-    preferences.setDefault(FORMATTER_COMPACT_ASSIGNMENT, NORMAL); 
+    preferences.setDefault(FORMATTER_COMPACT_ASSIGNMENT, NORMAL);
     optionNames.add(FORMATTER_COMPACT_ASSIGNMENT);
 
-    preferences.setDefault(FORMATTER_TAB_CHAR, TAB); 
+    preferences.setDefault(FORMATTER_TAB_CHAR, TAB);
     optionNames.add(FORMATTER_TAB_CHAR);
 
     preferences.setDefault(FORMATTER_TAB_SIZE, "4"); //$NON-NLS-1$ 
     optionNames.add(FORMATTER_TAB_SIZE);
-               
+
     // CodeAssist settings
-//    preferences.setDefault(CODEASSIST_VISIBILITY_CHECK, DISABLED); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_VISIBILITY_CHECK);
-//
-//    preferences.setDefault(CODEASSIST_IMPLICIT_QUALIFICATION, DISABLED); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_IMPLICIT_QUALIFICATION);
-//             
-//    preferences.setDefault(CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_FIELD_PREFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_STATIC_FIELD_PREFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_LOCAL_PREFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_ARGUMENT_PREFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_FIELD_SUFFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_STATIC_FIELD_SUFFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_LOCAL_SUFFIXES);
-//             
-//    preferences.setDefault(CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
-//    optionNames.add(CODEASSIST_ARGUMENT_SUFFIXES);
-               
+    //    preferences.setDefault(CODEASSIST_VISIBILITY_CHECK, DISABLED); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_VISIBILITY_CHECK);
+    //
+    //    preferences.setDefault(CODEASSIST_IMPLICIT_QUALIFICATION, DISABLED); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_IMPLICIT_QUALIFICATION);
+    //         
+    //    preferences.setDefault(CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_FIELD_PREFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_STATIC_FIELD_PREFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_LOCAL_PREFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_ARGUMENT_PREFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_FIELD_SUFFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_STATIC_FIELD_SUFFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_LOCAL_SUFFIXES);
+    //         
+    //    preferences.setDefault(CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
+    //    optionNames.add(CODEASSIST_ARGUMENT_SUFFIXES);
+
+  }
+  /**
+        * Runs the given action as an atomic Java model operation.
+        * <p>
+        * After running a method that modifies Java elements,
+        * registered listeners receive after-the-fact notification of
+        * what just transpired, in the form of a element changed event.
+        * This method allows clients to call a number of
+        * methods that modify java elements and only have element
+        * changed event notifications reported at the end of the entire
+        * batch.
+        * </p>
+        * <p>
+        * If this method is called outside the dynamic scope of another such
+        * call, this method runs the action and then reports a single
+        * element changed event describing the net effect of all changes
+        * done to java elements by the action.
+        * </p>
+        * <p>
+        * If this method is called in the dynamic scope of another such
+        * call, this method simply runs the action.
+        * </p>
+        *
+        * @param action the action to perform
+        * @param monitor a progress monitor, or <code>null</code> if progress
+        *    reporting and cancellation are not desired
+        * @exception CoreException if the operation failed.
+        * @since 2.1
+        */
+  public static void run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException {
+    IWorkspace workspace = ResourcesPlugin.getWorkspace();
+    if (workspace.isTreeLocked()) {
+      new BatchOperation(action).run(monitor);
+    } else {
+      // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode
+      workspace.run(new BatchOperation(action), monitor);
+    }
   }
 }
\ No newline at end of file
index 6460f92..0d3ecae 100644 (file)
@@ -2,7 +2,6 @@ package net.sourceforge.phpeclipse;
 
 import net.sourceforge.phpeclipse.preferences.PHPPreferencesMessages;
 
-import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferencePage;
 import org.eclipse.jface.preference.RadioGroupFieldEditor;
index 30019d3..2fe7605 100644 (file)
@@ -59,8 +59,10 @@ public class PHPPerspectiveFactory implements IPerspectiveFactory {
     layout.addShowViewShortcut(IPageLayout.ID_BOOKMARKS);
 
     // new actions - PHP project creation wizards
-    layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder"); //$NON-NLS-1$
-    layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file"); //$NON-NLS-1$
+               layout.addNewWizardShortcut("org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard"); //$NON-NLS-1$
+               layout.addNewWizardShortcut("net.sourceforge.phpeclipse.wizards.PHPFileWizard");         //$NON-NLS-1$
+               layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");//$NON-NLS-1$
+               layout.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");//$NON-NLS-1$
   }
 
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPSyntaxEditorPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPSyntaxEditorPreferencePage.java
deleted file mode 100644 (file)
index 5574982..0000000
+++ /dev/null
@@ -1,562 +0,0 @@
-package net.sourceforge.phpeclipse;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import net.sourceforge.phpeclipse.preferences.ColorEditor;
-import net.sourceforge.phpeclipse.preferences.OverlayPreferenceStore;
-import net.sourceforge.phpeclipse.preferences.PHPPreferencesMessages;
-
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.jface.preference.BooleanFieldEditor;
-import org.eclipse.jface.preference.FileFieldEditor;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.preference.IntegerFieldEditor;
-import org.eclipse.jface.preference.PreferenceConverter;
-import org.eclipse.jface.preference.PreferencePage;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.List;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchPreferencePage;
-
-/*
- * The preference page for setting the PHP Editor options.
- */
-public class PHPSyntaxEditorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
-
-  public final OverlayPreferenceStore.OverlayKey[] Keys =
-    new OverlayPreferenceStore.OverlayKey[] {
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_MULTILINE_COMMENT),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_MULTILINE_COMMENT_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_MULTILINE_COMMENT_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_MULTILINE_COMMENT_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_SINGLELINE_COMMENT),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_SINGLELINE_COMMENT_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_SINGLELINE_COMMENT_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_SINGLELINE_COMMENT_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_KEYWORD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_KEYWORD_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_KEYWORD_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_KEYWORD_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_VARIABLE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_VARIABLE_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_VARIABLE_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_VARIABLE_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_TYPE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_TYPE_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_TYPE_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_TYPE_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_CONSTANT),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_CONSTANT_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_CONSTANT_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_CONSTANT_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_FUNCTIONNAME),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_FUNCTIONNAME_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_FUNCTIONNAME_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_FUNCTIONNAME_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_STRING),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_STRING_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_STRING_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_STRING_UNDERLINE),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_DEFAULT),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_DEFAULT_BOLD),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_DEFAULT_ITALIC),
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHP_DEFAULT_UNDERLINE),
-      
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_KEYWORD),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_KEYWORD_BOLD),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_KEYWORD_ITALIC),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_KEYWORD_UNDERLINE),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_TAG),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_TAG_BOLD),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_TAG_ITALIC),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_TAG_UNDERLINE),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_LINK),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_LINK_BOLD),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_LINK_ITALIC),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_LINK_UNDERLINE),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHPDOC_DEFAULT),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_DEFAULT_BOLD),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_DEFAULT_ITALIC),
-                       new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, IPreferenceConstants.PHPDOC_DEFAULT_UNDERLINE),
-      
-      new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_USERDEF_XMLFILE),
-  //    new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, IPreferenceConstants.PHP_EDITOR_BACKGROUND)
-  };
-
-  private final String[][] SyntaxColorListModel =
-    new String[][] {
-      {
-        PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.multiLineComment"),
-        IPreferenceConstants.PHP_MULTILINE_COMMENT },
-      {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.singleLineComment"),
-        IPreferenceConstants.PHP_SINGLELINE_COMMENT },
-        {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.keywords"), IPreferenceConstants.PHP_KEYWORD }, {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.variables"), IPreferenceConstants.PHP_VARIABLE }, {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.types"), IPreferenceConstants.PHP_TYPE }, {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.functions"), IPreferenceConstants.PHP_FUNCTIONNAME }, {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.constants"), IPreferenceConstants.PHP_CONSTANT }, {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.strings"), IPreferenceConstants.PHP_STRING }, {
-      PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.others"), IPreferenceConstants.PHP_DEFAULT }, {
-                       PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_keywords"), IPreferenceConstants.PHPDOC_KEYWORD }, {
-                       PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_tags"), IPreferenceConstants.PHPDOC_TAG }, {
-                       PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_links"), IPreferenceConstants.PHPDOC_LINK }, {
-                       PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.phpdoc_others"), IPreferenceConstants.PHPDOC_DEFAULT }
-  };
-
-  private OverlayPreferenceStore OverlayStore;
-
-  private Map ColorButtons = new HashMap();
-  private SelectionListener ColorButtonListener = new SelectionListener() {
-    public void widgetDefaultSelected(SelectionEvent e) {
-    }
-    public void widgetSelected(SelectionEvent e) {
-      ColorEditor editor = (ColorEditor) e.widget.getData();
-      PreferenceConverter.setValue(OverlayStore, (String) ColorButtons.get(editor), editor.getColorValue());
-    }
-  };
-
-  private Map CheckBoxes = new HashMap();
-  private SelectionListener CheckBoxListener = new SelectionListener() {
-    public void widgetDefaultSelected(SelectionEvent e) {
-    }
-    public void widgetSelected(SelectionEvent e) {
-      Button button = (Button) e.widget;
-      OverlayStore.setValue((String) CheckBoxes.get(button), button.getSelection());
-    }
-  };
-
-  private List SyntaxColorList;
-  /** The ColorEditor that choose the foreground color. */
-  private ColorEditor SyntaxForegroundColorEditor;
-  private Button BoldCheckBox;
-  private Button ItalicCheckBox;
-  private Button UnderlineCheckBox;
-  private FileFieldEditor userdefPHPSyntaxFileFFE;
-  // private BooleanFieldEditor showLineNumber;
-  // private IntegerFieldEditor formatterTabSize;
-  // private BooleanFieldEditor spacesForTabs;
-
-  public PHPSyntaxEditorPreferencePage() {
-    setDescription(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.description")); //$NON-NLS-1$
-    setPreferenceStore(PHPeclipsePlugin.getDefault().getPreferenceStore());
-    OverlayStore = new OverlayPreferenceStore(getPreferenceStore(), Keys);
-  }
-
-  public void init(IWorkbench workbench) {
-  }
-
-  public void createControl(Composite parent) {
-    super.createControl(parent);
-  }
-
-  private void handleSyntaxColorListSelection() {
-    int i = SyntaxColorList.getSelectionIndex();
-    String key = SyntaxColorListModel[i][1];
-    RGB rgb = PreferenceConverter.getColor(OverlayStore, key);
-    SyntaxForegroundColorEditor.setColorValue(rgb);
-    BoldCheckBox.setSelection(OverlayStore.getBoolean(key + "_bold"));
-    ItalicCheckBox.setSelection(OverlayStore.getBoolean(key + "_italic"));
-    UnderlineCheckBox.setSelection(OverlayStore.getBoolean(key + "_underline"));
-  }
-
-  /**
-   * Create the group of options for other parameters (background color for example).
-   * @param parent the parent component
-   */
-  private void backgroundOptionPage(Composite parent) {
-    Label label = new Label(parent, SWT.LEFT);
-    label.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.color")); //$NON-NLS-1$
-    GridData gd = new GridData();
-    gd.horizontalAlignment = GridData.BEGINNING;
-    label.setLayoutData(gd);
-//    final ColorEditor syntaxBackgroundColorEditor = new ColorEditor(parent);
-//    RGB rgb = PreferenceConverter.getColor(OverlayStore, IPreferenceConstants.PHP_EDITOR_BACKGROUND);
-//    syntaxBackgroundColorEditor.setColorValue(rgb);
-//    Button backgroundColorButton = syntaxBackgroundColorEditor.getButton();
-//    gd = new GridData(GridData.FILL_HORIZONTAL);
-//    gd.horizontalAlignment = GridData.BEGINNING;
-//    backgroundColorButton.setLayoutData(gd);
-//    backgroundColorButton.addSelectionListener(new SelectionListener() {
-//      public void widgetDefaultSelected(SelectionEvent e) {
-//        // do nothing
-//      }
-//      public void widgetSelected(SelectionEvent e) {
-//        PreferenceConverter.setValue(OverlayStore, IPreferenceConstants.PHP_EDITOR_BACKGROUND, syntaxBackgroundColorEditor.getColorValue());
-//      }
-//    });
-  }
-
-  /**
-   * Create the group of options for the syntax parameters.
-   * @param parent the parent component
-   * @return
-   */
-  private Control createSyntaxPage(Composite parent) {
-
-    Composite colorComposite = new Composite(parent, SWT.NULL);
-    colorComposite.setLayout(new GridLayout());
-
-    Label label = new Label(colorComposite, SWT.LEFT);
-    label.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.syntax")); //$NON-NLS-1$
-    label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-    Composite editorComposite = new Composite(colorComposite, SWT.NONE);
-    GridLayout layout = new GridLayout();
-    layout.numColumns = 2;
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    editorComposite.setLayout(layout);
-    GridData gd = new GridData(GridData.FILL_BOTH);
-    editorComposite.setLayoutData(gd);
-
-    SyntaxColorList = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
-    gd = new GridData(GridData.FILL_BOTH);
-    gd.heightHint = convertHeightInCharsToPixels(5);
-    SyntaxColorList.setLayoutData(gd);
-
-    Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
-    layout = new GridLayout();
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    layout.numColumns = 2;
-    stylesComposite.setLayout(layout);
-    stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-    label = new Label(stylesComposite, SWT.LEFT);
-    label.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.color")); //$NON-NLS-1$
-    gd = new GridData();
-    gd.horizontalAlignment = GridData.BEGINNING;
-    label.setLayoutData(gd);
-
-    SyntaxForegroundColorEditor = new ColorEditor(stylesComposite);
-    Button foregroundColorButton = SyntaxForegroundColorEditor.getButton();
-    gd = new GridData(GridData.FILL_HORIZONTAL);
-    gd.horizontalAlignment = GridData.BEGINNING;
-    foregroundColorButton.setLayoutData(gd);
-
-    BoldCheckBox = new Button(stylesComposite, SWT.CHECK);
-    BoldCheckBox.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.bold")); //$NON-NLS-1$
-    gd = new GridData(GridData.FILL_HORIZONTAL);
-    gd.horizontalAlignment = GridData.BEGINNING;
-    gd.horizontalSpan = 2;
-    BoldCheckBox.setLayoutData(gd);
-
-    ItalicCheckBox = new Button(stylesComposite, SWT.CHECK);
-    ItalicCheckBox.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.italic")); //$NON-NLS-1$
-    ItalicCheckBox.setEnabled(false);
-    gd = new GridData(GridData.FILL_HORIZONTAL);
-    gd.horizontalAlignment = GridData.BEGINNING;
-    gd.horizontalSpan = 2;
-    ItalicCheckBox.setLayoutData(gd);
-
-    UnderlineCheckBox = new Button(stylesComposite, SWT.CHECK);
-    UnderlineCheckBox.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.underline")); //$NON-NLS-1$
-    UnderlineCheckBox.setEnabled(false);
-    gd = new GridData(GridData.FILL_HORIZONTAL);
-    gd.horizontalAlignment = GridData.BEGINNING;
-    gd.horizontalSpan = 2;
-    UnderlineCheckBox.setLayoutData(gd);
-
-    Composite customSyntaxComposite = new Composite(colorComposite, SWT.NONE);
-    layout = new GridLayout();
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    layout.numColumns = 3;
-    stylesComposite.setLayout(layout);
-    stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-    userdefPHPSyntaxFileFFE =
-      new FileFieldEditor(
-        IPreferenceConstants.PHP_USERDEF_XMLFILE,
-        PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.syntaxdialog"),
-        colorComposite);
-    userdefPHPSyntaxFileFFE.setPreferencePage(this);
-    userdefPHPSyntaxFileFFE.setPreferenceStore(getPreferenceStore());
-    userdefPHPSyntaxFileFFE.load();
-
-    SyntaxColorList.addSelectionListener(new SelectionListener() {
-      public void widgetDefaultSelected(SelectionEvent e) {
-        // do nothing
-      }
-      public void widgetSelected(SelectionEvent e) {
-        handleSyntaxColorListSelection();
-      }
-    });
-
-    foregroundColorButton.addSelectionListener(new SelectionListener() {
-      public void widgetDefaultSelected(SelectionEvent e) {
-        // do nothing
-      }
-      public void widgetSelected(SelectionEvent e) {
-        int i = SyntaxColorList.getSelectionIndex();
-        String key = SyntaxColorListModel[i][1];
-
-        PreferenceConverter.setValue(OverlayStore, key, SyntaxForegroundColorEditor.getColorValue());
-      }
-    });
-    BoldCheckBox.addSelectionListener(new SelectionListener() {
-      public void widgetDefaultSelected(SelectionEvent e) {
-        // do nothing
-      }
-      public void widgetSelected(SelectionEvent e) {
-        int i = SyntaxColorList.getSelectionIndex();
-        String key = SyntaxColorListModel[i][1];
-        OverlayStore.setValue(key + "_bold", BoldCheckBox.getSelection());
-      }
-    });
-
-    ItalicCheckBox.addSelectionListener(new SelectionListener() {
-      public void widgetDefaultSelected(SelectionEvent e) {
-        // do nothing
-      }
-      public void widgetSelected(SelectionEvent e) {
-        int i = SyntaxColorList.getSelectionIndex();
-        String key = SyntaxColorListModel[i][1];
-        OverlayStore.setValue(key + "_italic", ItalicCheckBox.getSelection());
-      }
-    });
-
-    UnderlineCheckBox.addSelectionListener(new SelectionListener() {
-      public void widgetDefaultSelected(SelectionEvent e) {
-        // do nothing
-      }
-      public void widgetSelected(SelectionEvent e) {
-        int i = SyntaxColorList.getSelectionIndex();
-        String key = SyntaxColorListModel[i][1];
-        OverlayStore.setValue(key + "_underline", UnderlineCheckBox.getSelection());
-      }
-    });
-    return colorComposite;
-  }
-
-  private void initializeViewerColors(ISourceViewer viewer) {
-
-    IPreferenceStore store = OverlayStore;
-    if (store != null) {
-
-      StyledText styledText = viewer.getTextWidget();
-    }
-  }
-
-  private Color createColor(IPreferenceStore store, String key, Display display) {
-    RGB rgb = null;
-    if (store.contains(key)) {
-      if (store.isDefault(key))
-        rgb = PreferenceConverter.getDefaultColor(store, key);
-      else
-        rgb = PreferenceConverter.getColor(store, key);
-      if (rgb != null)
-        return new Color(display, rgb);
-    }
-    return null;
-  }
-
-  private static void setEnabled(Control control, boolean enable) {
-    control.setEnabled(enable);
-    if (control instanceof Composite) {
-      Composite composite = (Composite) control;
-      Control[] children = composite.getChildren();
-      for (int i = 0; i < children.length; i++)
-        setEnabled(children[i], enable);
-    }
-  }
-
-  private static void indent(Control control) {
-    GridData gridData = new GridData();
-    gridData.horizontalIndent = 20;
-    control.setLayoutData(gridData);
-  }
-
-  private static void createDependency(final Button master, final Control slave) {
-    indent(slave);
-    master.addSelectionListener(new SelectionListener() {
-      public void widgetSelected(SelectionEvent e) {
-        slave.setEnabled(master.getSelection());
-      }
-
-      public void widgetDefaultSelected(SelectionEvent e) {
-      }
-    });
-  }
-
-  protected Control createContents(Composite parent) {
-    OverlayStore.load();
-    OverlayStore.start();
-    //Create overall composite
-    Composite composite = new Composite(parent, SWT.NONE);
-    GridLayout layout = new GridLayout();
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    composite.setLayout(layout);
-    Composite syntaxComposite = new Composite(composite, SWT.NULL);
-    syntaxComposite.setLayout(new GridLayout());
-    layout = new GridLayout();
-    layout.numColumns = 3;
-    Group syntaxGroup = new Group(syntaxComposite, SWT.NONE);
-    syntaxGroup.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.foreground"));
-    syntaxGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-    syntaxGroup.setLayout(layout);
-    createSyntaxPage(syntaxGroup);
-
-    Composite backgroundOptions = new Composite(composite,SWT.NULL);
-    backgroundOptions.setLayout(new GridLayout());
-    layout = new GridLayout();
-    layout.numColumns = 3;
-    Group backgroundOptionsGroup = new Group(backgroundOptions,SWT.NONE);
-    backgroundOptionsGroup.setText(PHPPreferencesMessages.getString("PHPEditorSyntaxPreferencePage.background"));
-    backgroundOptionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-    backgroundOptionsGroup.setLayout(layout);
-    backgroundOptionPage(backgroundOptionsGroup);
-
-    initialize();
-    
-   
-//    showLineNumber = new BooleanFieldEditor(PHPeclipsePlugin.LINE_NUMBER_RULER, 
-//    "Show line numbers", composite);
-//    showLineNumber.setPreferencePage(this);
-//    showLineNumber.setPreferenceStore(getPreferenceStore());
-//    showLineNumber.load();
-    
-//    formatterTabSize = new IntegerFieldEditor(PHPeclipsePlugin.FORMATTER_TAB_SIZE, 
-//    "Displayed tab width", composite, 3);
-//    formatterTabSize.setPreferencePage(this);
-//    formatterTabSize.setPreferenceStore(getPreferenceStore());
-//    formatterTabSize.load();
-//    
-//    spacesForTabs = new BooleanFieldEditor(PHPeclipsePlugin.SPACES_FOR_TABS, 
-//    "Spaces for Tabs", composite);
-//    spacesForTabs.setPreferencePage(this);
-//    spacesForTabs.setPreferenceStore(getPreferenceStore());
-//    spacesForTabs.load();
-    return composite;
-  }
-
-  private void initialize() {
-    initializeFields();
-    for (int i = 0; i < SyntaxColorListModel.length; i++)
-      SyntaxColorList.add(SyntaxColorListModel[i][0]);
-    SyntaxColorList.getDisplay().asyncExec(new Runnable() {
-      public void run() {
-        if (SyntaxColorList != null && !SyntaxColorList.isDisposed()) {
-          SyntaxColorList.select(0);
-          handleSyntaxColorListSelection();
-        }
-      }
-    });
-  }
-
-  private void initializeFields() {
-
-    Iterator e = ColorButtons.keySet().iterator();
-    while (e.hasNext()) {
-      ColorEditor c = (ColorEditor) e.next();
-      String key = (String) ColorButtons.get(c);
-      RGB rgb = PreferenceConverter.getColor(OverlayStore, key);
-      c.setColorValue(rgb);
-    }
-
-    e = CheckBoxes.keySet().iterator();
-    while (e.hasNext()) {
-      Button b = (Button) e.next();
-      String key = (String) CheckBoxes.get(b);
-      b.setSelection(OverlayStore.getBoolean(key));
-    }
-  }
-
-  public boolean performOk() {
-    OverlayStore.propagate();
-    IPreferenceStore store = getPreferenceStore();
-    PHPeclipsePlugin.getDefault().savePluginPreferences();
-    userdefPHPSyntaxFileFFE.store();
-   // showLineNumber.store();
-   // spacesForTabs.store();
-   // formatterTabSize.store();
-    return true;
-  }
-
-  protected void performDefaults() {
-    OverlayStore.loadDefaults();
-    initializeFields();
-    handleSyntaxColorListSelection();
-    userdefPHPSyntaxFileFFE.loadDefault();
-  //  showLineNumber.loadDefault();
-  //  spacesForTabs.loadDefault();
-  //  showLineNumber.loadDefault();
-  //  formatterTabSize.loadDefault();
-    super.performDefaults();
-  }
-
-  public void dispose() {
-    if (OverlayStore != null) {
-      OverlayStore.stop();
-      OverlayStore = null;
-    }
-    super.dispose();
-  }
-
-  private Control addColorButton(Composite composite, String label, String key, int indentation) {
-    Label labelControl = new Label(composite, SWT.NONE);
-    labelControl.setText(label);
-    GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-    gd.horizontalIndent = indentation;
-    labelControl.setLayoutData(gd);
-    ColorEditor editor = new ColorEditor(composite);
-    Button button = editor.getButton();
-    button.setData(editor);
-    gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-    button.setLayoutData(gd);
-    button.addSelectionListener(ColorButtonListener);
-    ColorButtons.put(editor, key);
-    return composite;
-  }
-
-  private Button addCheckBox(Composite parent, String label, String key, int indentation) {
-    Button checkBox = new Button(parent, SWT.CHECK);
-    checkBox.setText(label);
-    GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-    gd.horizontalIndent = indentation;
-    gd.horizontalSpan = 2;
-    checkBox.setLayoutData(gd);
-    checkBox.addSelectionListener(CheckBoxListener);
-    CheckBoxes.put(checkBox, key);
-    return checkBox;
-  }
-
-  private void updateStatus(IStatus status) {
-  }
-
-  /**
-   * @deprecated Inline to avoid reference to preference page
-   */
-  public static boolean indicateQuixFixableProblems() {
-    //         return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION);
-    return false;
-  }
-
-  /**
-   * @deprecated Inline to avoid reference to preference page
-   */
-  static public boolean synchronizeOutlineOnCursorMove() {
-    //         return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE);
-    return false;
-  }
-
-}
\ No newline at end of file
index 04d04fc..8cdd585 100644 (file)
@@ -12,9 +12,13 @@ Contributors:
 package net.sourceforge.phpeclipse;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
 
 import net.sourceforge.phpdt.externaltools.internal.model.ColorManager;
 import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
@@ -78,17 +82,17 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon
   /** 
    * id of builder - matches plugin.xml (concatenate pluginid.builderid) 
    */
-  public static final String BUILDER_INDEX_ID = PLUGIN_ID + ".indexbuilder";
   public static final String BUILDER_PARSER_ID = PLUGIN_ID + ".parserbuilder";
+//public static final String BUILDER_INDEX_ID = PLUGIN_ID + ".indexbuilder";
 
   /** General debug flag*/
   public static final boolean DEBUG = false;
 
-       /**
-        * The maximum number of allowed proposals by category
-        */
-       public final static int MAX_PROPOSALS = 200;
-       
+  /**
+   * The maximum number of allowed proposals by category
+   */
+  public final static int MAX_PROPOSALS = 200;
+
   private static ExternalToolsPlugin externalTools;
 
   /**
@@ -131,7 +135,7 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon
   /** Windows NT  */
   private static final int WINDOWS_NT = 5;
   private PHPDocumentProvider fCompilationUnitDocumentProvider;
+
   private ImageDescriptorRegistry fImageDescriptorRegistry;
   private HashMap fIndexManagerMap = new HashMap();
 
@@ -161,6 +165,34 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon
     return getActiveWorkbenchWindow().getShell();
   }
 
+  /**
+        * Returns an array of all editors that have an unsaved content. If the identical content is 
+        * presented in more than one editor, only one of those editor parts is part of the result.
+        * 
+        * @return an array of all dirty editor parts.
+        */
+  public static IEditorPart[] getDirtyEditors() {
+    Set inputs = new HashSet();
+    List result = new ArrayList(0);
+    IWorkbench workbench = getDefault().getWorkbench();
+    IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
+    for (int i = 0; i < windows.length; i++) {
+      IWorkbenchPage[] pages = windows[i].getPages();
+      for (int x = 0; x < pages.length; x++) {
+        IEditorPart[] editors = pages[x].getDirtyEditors();
+        for (int z = 0; z < editors.length; z++) {
+          IEditorPart ep = editors[z];
+          IEditorInput input = ep.getEditorInput();
+          if (!inputs.contains(input)) {
+            inputs.add(input);
+            result.add(ep);
+          }
+        }
+      }
+    }
+    return (IEditorPart[]) result.toArray(new IEditorPart[result.size()]);
+  }
+
   public static IWorkbenchWindow getActiveWorkbenchWindow() {
     return getDefault().getWorkbench().getActiveWorkbenchWindow();
   }
@@ -393,6 +425,7 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon
 
     PreferenceConverter.setDefault(store, PHP_MULTILINE_COMMENT, PHPColorProvider.MULTI_LINE_COMMENT);
     PreferenceConverter.setDefault(store, PHP_SINGLELINE_COMMENT, PHPColorProvider.SINGLE_LINE_COMMENT);
+               PreferenceConverter.setDefault(store, PHP_TAG, PHPColorProvider.TAG);
     PreferenceConverter.setDefault(store, PHP_KEYWORD, PHPColorProvider.KEYWORD);
     PreferenceConverter.setDefault(store, PHP_VARIABLE, PHPColorProvider.VARIABLE);
     PreferenceConverter.setDefault(store, PHP_FUNCTIONNAME, PHPColorProvider.FUNCTION_NAME);
@@ -400,12 +433,12 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon
     PreferenceConverter.setDefault(store, PHP_TYPE, PHPColorProvider.TYPE);
     PreferenceConverter.setDefault(store, PHP_STRING, PHPColorProvider.STRING);
     PreferenceConverter.setDefault(store, PHP_DEFAULT, PHPColorProvider.DEFAULT);
-    
-               PreferenceConverter.setDefault(store, PHPDOC_KEYWORD, PHPColorProvider.PHPDOC_KEYWORD);
-               PreferenceConverter.setDefault(store, PHPDOC_TAG, PHPColorProvider.PHPDOC_TAG);
-               PreferenceConverter.setDefault(store, PHPDOC_LINK, PHPColorProvider.PHPDOC_LINK);
-               PreferenceConverter.setDefault(store, PHPDOC_DEFAULT, PHPColorProvider.PHPDOC_DEFAULT);
-                       
+
+    PreferenceConverter.setDefault(store, PHPDOC_KEYWORD, PHPColorProvider.PHPDOC_KEYWORD);
+    PreferenceConverter.setDefault(store, PHPDOC_TAG, PHPColorProvider.PHPDOC_TAG);
+    PreferenceConverter.setDefault(store, PHPDOC_LINK, PHPColorProvider.PHPDOC_LINK);
+    PreferenceConverter.setDefault(store, PHPDOC_DEFAULT, PHPColorProvider.PHPDOC_DEFAULT);
+
     //    PreferenceConverter.setDefault(
     //      store,
     //      PHP_EDITOR_BACKGROUND,
index 3fbcb11..f12aa38 100644 (file)
@@ -22,7 +22,6 @@ import net.sourceforge.phpeclipse.views.PHPConsole;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IPath;
 import org.eclipse.help.IHelp;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -37,9 +36,8 @@ import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PartInitException;
-import org.eclipse.update.internal.ui.UpdatePerspective;
 import org.eclipse.ui.help.WorkbenchHelp;
-
+import org.eclipse.update.internal.ui.UpdatePerspective;
 import org.eclipse.update.internal.ui.views.IEmbeddedWebBrowser;
 //import org.eclipse.jdt.internal.ui.actions.OpenBrowserUtil;
 // import org.eclipse.help.ui.browser.LaunchURL;
index 36b568c..86f2b0a 100644 (file)
@@ -21,6 +21,7 @@ import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.ui.IObjectActionDelegate;
 import org.eclipse.ui.IWorkbenchPart;
+
 import test.PHPParserSuperclass;
 
 public class PHPExternalParserAction implements IObjectActionDelegate {
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPObfuscatorAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPObfuscatorAction.java
deleted file mode 100644 (file)
index 1a24c29..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/**********************************************************************
-Copyright (c) 2000, 2002 IBM Corp. and others.
-All rights reserved. This program and the accompanying materials
-are made available under the terms of the Common Public License v1.0
-which accompanies this distribution, and is available at
-http://www.eclipse.org/legal/cpl-v10.html
-
-    Klaus Hartlage - www.eclipseproject.de
-**********************************************************************/
-package net.sourceforge.phpeclipse.actions;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.mover.DefaultFilter;
-import net.sourceforge.phpeclipse.mover.DirectoryWalker;
-import net.sourceforge.phpeclipse.mover.IFilter;
-import net.sourceforge.phpeclipse.mover.IMover;
-import net.sourceforge.phpeclipse.mover.obfuscator.ObfuscatorIgnores;
-import net.sourceforge.phpeclipse.mover.obfuscator.PHPAnalyzer;
-import net.sourceforge.phpeclipse.mover.obfuscator.PHPObfuscatorMover;
-import net.sourceforge.phpeclipse.preferences.ProjectProperties;
-import net.sourceforge.phpeclipse.views.PHPConsole;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IObjectActionDelegate;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * 
- * @author khartlage
- *
- * Run the PHP Obfuscator 
- */
-public class PHPObfuscatorAction implements IObjectActionDelegate {
-
-  private IWorkbenchPart workbenchPart;
-  /**
-   * Constructor for PHPObfuscatorAction.
-   */
-  public PHPObfuscatorAction() {
-    super();
-  }
-
-  public void run(IAction action) {
-    ISelectionProvider selectionProvider = null;
-    selectionProvider = workbenchPart.getSite().getSelectionProvider();
-
-    StructuredSelection selection = null;
-    selection = (StructuredSelection) selectionProvider.getSelection();
-    PHPConsole console = PHPConsole.getInstance();
-
-    //   HashMap identifierMap = new HashMap(8096);
-    //   for (int i=0;i<PREDEFINED_PHP_VARIABLES.length;i++) {
-    //         identifierMap.put(PREDEFINED_PHP_VARIABLES[i], new PHPIdentifier(PREDEFINED_PHP_VARIABLES[i],PHPIdentifier.VARIABLE) );
-    //   }
-    HashMap identifierMap = null;
-
-    Shell shell = null;
-    Iterator iterator = null;
-    iterator = selection.iterator();
-    while (iterator.hasNext()) {
-      //  obj => selected object in the view
-      Object obj = iterator.next();
-
-      // is it a resource
-      if (obj instanceof IResource) {
-
-        IResource resource = (IResource) obj;
-        IProject proj = resource.getProject();
-        String sourcePath;
-
-        if (identifierMap == null) {
-          IPreferenceStore store =
-            PHPeclipsePlugin.getDefault().getPreferenceStore();
-          ObfuscatorIgnores ignore = new ObfuscatorIgnores(proj);
-          identifierMap = ignore.getIdentifierMap();
-        }
-
-        String publishPath;
-        try {
-          ProjectProperties properties = new ProjectProperties(proj);
-          publishPath = properties.getPublish();
-        } catch (CoreException e1) {
-          return;
-          //                                   e1.printStackTrace();
-        }
-        //        try {
-        //          publishPath = proj.getPersistentProperty(IObfuscatorPreferences.PUBLISH_PROPERTY_NAME);
-        //        } catch (CoreException e) {
-        //          return;
-        //        }
-
-        DefaultFilter[] filter =
-          { IFilter.PHP_FILTER, IFilter.DEFAULT_FILTER, };
-        IMover[] mover =
-          {
-            new PHPAnalyzer(
-              PHPConsole.getInstance(),
-              new Scanner(false, false),
-              identifierMap),
-            new PHPObfuscatorMover(
-              PHPConsole.getInstance(),
-              new Scanner(true, true),
-              identifierMap)};
-        DirectoryWalker walker = new DirectoryWalker(mover, filter);
-        switch (resource.getType()) {
-          case IResource.PROJECT :
-            IProject project = (IProject) resource;
-            sourcePath = project.getLocation().toOSString();
-            try {
-              walker.walk(sourcePath, publishPath);
-            } catch (IOException e) {
-            }
-            break;
-          case IResource.FOLDER :
-            IFolder folder = (IFolder) resource;
-            sourcePath = folder.getLocation().toOSString();
-            try {
-              walker.walk(sourcePath, publishPath);
-            } catch (IOException e) {
-            }
-            break;
-          case IResource.FILE :
-            // single file:
-            IFile file = (IFile) resource;
-            sourcePath = file.getLocation().toOSString();
-            try {
-              walker.walk(sourcePath, publishPath);
-            } catch (IOException e) {
-            }
-            break;
-        }
-      }
-    }
-  }
-  /**
-     * @see IActionDelegate#selectionChanged(IAction, ISelection)
-     */
-  public void selectionChanged(IAction action, ISelection selection) {
-  }
-
-  /**
-   * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
-   */
-  public void setActivePart(IAction action, IWorkbenchPart targetPart) {
-    workbenchPart = targetPart;
-  }
-
-}
index 0b08b11..b9e0232 100644 (file)
@@ -1,9 +1,3 @@
-/*
- * Created on 06.09.2003
- *
- * To change the template for this generated file go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
- */
 package net.sourceforge.phpeclipse.builder;
 
 import org.eclipse.core.resources.IStorage;
index 1080cd9..d4b5f6a 100644 (file)
@@ -1,9 +1,3 @@
-/*
- * Created on 06.09.2003
- *
- * To change the template for this generated file go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
- */
 package net.sourceforge.phpeclipse.builder;
 
 import java.io.File;
index 1047779..2e76596 100644 (file)
@@ -1,5 +1,6 @@
 package net.sourceforge.phpeclipse.builder;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
@@ -20,7 +21,8 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
-import net.sourceforge.phpeclipse.mover.obfuscator.PHPIdentifier;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpeclipse.obfuscator.PHPIdentifier;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.CoreException;
@@ -89,9 +91,9 @@ public class IdentifierIndexManager {
       fToken = TokenNameERROR;
     }
 
-    private void parseDeclarations(StringBuffer buf, boolean goBack) {
+    private void parseDeclarations(char[] parent, StringBuffer buf, boolean goBack) {
       char[] ident;
-                       char[] classVariable;
+      char[] classVariable;
       int counter = 0;
       int phpdocOffset = -1;
       int phpdocLength = -1;
@@ -111,8 +113,8 @@ public class IdentifierIndexManager {
             getNextToken();
             if (fToken == TokenNameVariable) {
               ident = fScanner.getCurrentIdentifierSource();
-                                                       classVariable = new char[ident.length-1];
-                                                       System.arraycopy(ident, 1, classVariable, 0, ident.length-1);
+              classVariable = new char[ident.length - 1];
+              System.arraycopy(ident, 1, classVariable, 0, ident.length - 1);
               addIdentifierInformation('v', classVariable, buf, phpdocOffset, phpdocLength);
               getNextToken();
             }
@@ -123,9 +125,20 @@ public class IdentifierIndexManager {
             }
             if (fToken == TokenNameIdentifier) {
               ident = fScanner.getCurrentIdentifierSource();
-              addIdentifierInformation('m', ident, buf, phpdocOffset, phpdocLength);
+              if (parent != null && equalCharArrays(parent, ident)) {
+                // constructor function
+                addIdentifierInformation('k', ident, buf, phpdocOffset, phpdocLength);
+              } else {
+                if (parent != null) {
+                  // class method function
+                  addIdentifierInformation('m', ident, buf, phpdocOffset, phpdocLength);
+                } else {
+                  // nested function ?!
+                  addIdentifierInformation('f', ident, buf, phpdocOffset, phpdocLength);
+                }
+              }
               getNextToken();
-              parseDeclarations(buf, true);
+              parseDeclarations(null, buf, true);
             }
           } else if (fToken == TokenNameclass) {
             getNextToken();
@@ -138,7 +151,7 @@ public class IdentifierIndexManager {
               while (fToken != TokenNameLBRACE && fToken != TokenNameEOF && fToken != TokenNameERROR) {
                 getNextToken();
               }
-              parseDeclarations(buf, true);
+              parseDeclarations(ident, buf, true);
             }
           } else if (fToken == TokenNamedefine) {
             getNextToken();
@@ -201,7 +214,7 @@ public class IdentifierIndexManager {
               ident = fScanner.getCurrentIdentifierSource();
               addIdentifierInformation('f', ident, buf, phpdocOffset, phpdocLength);
               getNextToken();
-              parseDeclarations(buf, true);
+              parseDeclarations(null, buf, true);
             }
           } else if (fToken == TokenNameclass) {
             getNextToken();
@@ -215,7 +228,7 @@ public class IdentifierIndexManager {
                 getNextToken();
               }
 
-              parseDeclarations(buf, true);
+              parseDeclarations(ident, buf, true);
 
             }
           } else if (fToken == TokenNamedefine) {
@@ -239,18 +252,18 @@ public class IdentifierIndexManager {
     }
   }
 
-       class StringComparator implements Comparator { 
-               public int compare(Object o1, Object o2) { 
-                       String s1 = (String)o1; 
-                       String s2 = (String)o2; 
-                       return s1.compareTo(s2); 
-               //      return s1.toUpperCase().compareTo(s2.toUpperCase()); 
-               }                                     
-               public boolean equals(Object o) { 
-                       String s = (String)o; 
-                       return compare(this, o)==0; 
-               } 
-       } 
+  class StringComparator implements Comparator {
+    public int compare(Object o1, Object o2) {
+      String s1 = (String) o1;
+      String s2 = (String) o2;
+      return s1.compareTo(s2);
+      //       return s1.toUpperCase().compareTo(s2.toUpperCase()); 
+    }
+    public boolean equals(Object o) {
+      String s = (String) o;
+      return compare(this, o) == 0;
+    }
+  }
 
   private HashMap fFileMap;
   private String fFilename;
@@ -263,32 +276,64 @@ public class IdentifierIndexManager {
   }
 
   /**
+   * Check if 2 char arrays are equal
+   * 
+   * @param a
+   * @param b
+   * @return
+   */
+  private static boolean equalCharArrays(char[] a, char[] b) {
+    if (a.length != b.length) {
+      return false;
+    }
+    for (int i = 0; i < b.length; i++) {
+      if (a[i] != b[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
    * Add the information for a given IFile resource
    *
    */
   public void addFile(IFile fileToParse) {
-    InputStream iStream;
+    //    InputStream iStream;
     LineCreator lineCreator = new LineCreator();
     try {
-      iStream = fileToParse.getContents();
-
-      StringBuffer buf = new StringBuffer();
-      int c0;
+      //      iStream = fileToParse.getContents();
+      //
+      //      StringBuffer buf = new StringBuffer();
+      //      int c0;
+      //      try {
+      //        while ((c0 = iStream.read()) != (-1)) {
+      //          buf.append((char) c0);
+      //        }
+      //      } catch (IOException e) {
+      //        return;
+      //      }
+      InputStream stream = null;
       try {
-        while ((c0 = iStream.read()) != (-1)) {
-          buf.append((char) c0);
+        stream = new BufferedInputStream(fileToParse.getContents());
+
+        StringBuffer lineBuffer = new StringBuffer();
+        lineBuffer.append(fileToParse.getFullPath().toString());
+        int lineLength = lineBuffer.length();
+        // lineCreator.parseIdentifiers(buf.toString().toCharArray(), lineBuffer);
+        lineCreator.parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1, null), lineBuffer);
+        if (lineLength != lineBuffer.length()) {
+          addLine(lineBuffer.toString());
         }
       } catch (IOException e) {
         return;
-      }
-
-      StringBuffer lineBuffer = new StringBuffer();
-      //      lineBuffer.append(fileToParse.getLocation().toString());
-      lineBuffer.append(fileToParse.getFullPath().toString());
-      int lineLength = lineBuffer.length();
-      lineCreator.parseIdentifiers(buf.toString().toCharArray(), lineBuffer);
-      if (lineLength != lineBuffer.length()) {
-        addLine(lineBuffer.toString());
+      } finally {
+        try {
+          if (stream != null) {
+            stream.close();
+          }
+        } catch (IOException e) {
+        }
       }
     } catch (CoreException e1) {
       // TODO Auto-generated catch block
@@ -337,6 +382,10 @@ public class IdentifierIndexManager {
           identifier = token.substring(1);
           phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
           break;
+        case 'k' : // constructor function name
+          identifier = token.substring(1);
+          phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CONSTRUCTOR, phpFileName);
+          break;
         case 'm' : //method inside a class
           identifier = token.substring(1);
           phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
@@ -504,6 +553,10 @@ public class IdentifierIndexManager {
           identifier = token.substring(1);
           phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.FUNCTION, phpFileName);
           break;
+        case 'k' : // constructor function name
+          identifier = token.substring(1);
+          phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.CONSTRUCTOR, phpFileName);
+          break;
         case 'm' : //method inside a class
           identifier = token.substring(1);
           phpIdentifier = new PHPIdentifierLocation(identifier, PHPIdentifier.METHOD, phpFileName, classname);
@@ -553,13 +606,13 @@ public class IdentifierIndexManager {
       }
       fileWriter.close();
     } catch (FileNotFoundException e) {
-       // ignore exception; project is deleted by user
+      // ignore exception; project is deleted by user
     } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
     }
   }
-  
+
   /**
    * @param fromKey
    * @param toKey
index 43006a0..2dfec02 100644 (file)
@@ -1,6 +1,6 @@
 package net.sourceforge.phpeclipse.builder;
 
-import net.sourceforge.phpeclipse.mover.obfuscator.PHPIdentifier;
+import net.sourceforge.phpeclipse.obfuscator.PHPIdentifier;
 
 /**
  * @author khartlage
@@ -12,6 +12,7 @@ public class PHPIdentifierLocation extends PHPIdentifier {
        private int fOffset;
        private int fPHPDocLength;
        private int fPHPDocOffset;
+       private String fUsage;
 
   public PHPIdentifierLocation(String identifier, int type, String filename) {
     this(identifier, type, filename, null);
@@ -24,6 +25,7 @@ public class PHPIdentifierLocation extends PHPIdentifier {
                fOffset = -1;
                fPHPDocLength = -1;
                fPHPDocOffset = -1;
+               fUsage = null;
        }
   /* (non-Javadoc)
    * @see java.lang.Object#equals(java.lang.Object)
@@ -71,6 +73,13 @@ public class PHPIdentifierLocation extends PHPIdentifier {
   }
 
   /**
+   * @return
+   */
+  public String getUsage() {
+    return fUsage;
+  }
+
+  /**
    * @param string
    */
   public void setClassname(String string) {
@@ -105,6 +114,13 @@ public class PHPIdentifierLocation extends PHPIdentifier {
     fPHPDocOffset = i;
   }
 
+  /**
+   * @param string
+   */
+  public void setUsage(String string) {
+    fUsage = string;
+  }
+
   /* (non-Javadoc)
    * @see java.lang.Object#toString()
    */
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/CopyMover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/CopyMover.java
deleted file mode 100644 (file)
index 3903545..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-/**
- * Copy the file from the source to the target directory.
- *
- */
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import net.sourceforge.phpeclipse.views.PHPConsole;
-
-public class CopyMover extends DefaultMover {
-  /**
-   * buffer, for obvious reasons access to this buffer must
-   * be synchronized
-   */
-  protected byte[] bytes = new byte[1024];
-
-  /**
-   * Return the name the file would have after moving. In this case,
-   * it's left unchanged.
-   * @param file file the mover would have to move
-   * @return the extension it would give the file in the target directory
-   */
-  public String getTargetName(File file) {
-    return file.getName();
-  }
-
-  /**
-   * Creates a CopyMover.
-   * @param console reports error to the PHPConsole
-   */
-  public CopyMover(PHPConsole console) {
-    super(console);
-  }
-
-  /**
-   * Move one file.
-   * @param sourceFile the file to move
-   * @param targetDir the directory to copy the result to
-   * @return file or null if the file was ignored
-   */
-  public File move(File sourceFile, File targetDir) {
-    try {
-      File targetFile = new File(targetDir, getTargetName(sourceFile));
-      if (targetFile.exists())
-        if (targetFile.lastModified() >= sourceFile.lastModified())
-          return null;
-      synchronized (bytes) {
-        FileInputStream in = new FileInputStream(sourceFile);
-        FileOutputStream out = new FileOutputStream(targetFile);
-        for (int len = in.read(bytes); len != -1; len = in.read(bytes)) {
-          out.write(bytes, 0, len);
-        }
-        in.close();
-        out.close();
-      }
-      return targetFile;
-    } catch (IOException e) {
-      fConsole.write(e.toString());
-    }
-    return null;
-  }
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DefaultFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DefaultFilter.java
deleted file mode 100644 (file)
index 0c2f4b9..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-import java.io.File;
-
-/**
- * 
- */
-public class DefaultFilter implements IFilter {
-  
-  public boolean isFileOk(File file) {
-    return true;
-  }
-  
-  public boolean isDirectoryOk(File file) {
-    return true;
-  }
-}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DefaultMover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DefaultMover.java
deleted file mode 100644 (file)
index b281529..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-
-import java.io.File;
-
-import net.sourceforge.phpeclipse.views.PHPConsole;
-
-/**
- * Provides default mover implementation 
- *
- */
-abstract public class DefaultMover
-   implements IMover
-{
-   /**
-    * Console for output 
-    * */
-   protected PHPConsole fConsole;
-
-   /**
-    * Creates a DefaultMover 
-    * @param console Console to report errors to
-    */
-   public DefaultMover(PHPConsole console)
-   {
-      this.fConsole = console;
-   }
-
-   /**
-    * compute a file extension
-    * @param file file to compute the extension from
-    * @return the file extension (excluding the .), "" if none
-    */
-   public static String getExtension(File file)
-   {
-      String filename = file.getName();
-      int index = filename.lastIndexOf('.');
-      return index != -1 ? filename.substring(index + 1) : "";
-   }
-
-   /**
-    * compute the filename without the extension
-    * @param file file to compute the extension from
-    * @return the file name without the extension (excluding the .)
-    */
-   public static String getDisplayName(File file)
-   {
-      String filename = file.getName();
-      int index = filename.lastIndexOf('.');
-      return index != -1 ? filename.substring(0,index) : filename;
-   }
-}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DirectoryWalker.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/DirectoryWalker.java
deleted file mode 100644 (file)
index 0746ad3..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-import java.io.File;
-import java.io.IOException;
-
-public class DirectoryWalker {
-
-  protected IMover[] fMover;
-  protected IFilter[] fFilter;
-  /**
-   * creates a new DirectoryWalker
-   * mover and filter array should have the same length !
-   */
-  public DirectoryWalker(IMover[] mover, IFilter[] filter) {
-    this.fMover = mover;
-    this.fFilter = filter;
-  }
-
-  /**
-   * creates a new DirectoryWalker with a IFilter.DEFAULT_FILTER
-   */
-  public DirectoryWalker(IMover[] mover) {
-    this.fMover = mover;
-    this.fFilter = new IFilter[mover.length];
-    for (int i = 0; i < mover.length; i++) {
-      this.fFilter[i] = IFilter.DEFAULT_FILTER;
-    }
-  }
-  /**
-   * walks through the source directory, processing files as it
-   * goes along to create the target directory
-   * @param source source directory
-   * @param target target directory
-   * @throws IOException error with the file system
-   * @throws XMException error caught by the application
-   */
-  public void walk(String source, String target) throws IOException {
-    try {
-
-      walk(new File(source), new File(target));
-    } finally {
-
-    }
-  }
-
-  /**
-   * actual implementation of the walking
-   * @param source source directory
-   * @param target target directory
-   * @throws IOException error with the file system
-   * @return true if walking should continue, false if the messenger
-   *    has asked for the end of the walking
-   */
-  protected boolean walk(File source, File target) throws IOException {
-
-    if (!(target.exists() && target.isDirectory()))
-      if (!target.mkdirs())
-        return false;
-
-    for (int j = 0; j < fMover.length; j++) {
-      File[] dirs;
-      File[] docs;
-      int idirs = 0, idocs = 0;
-      if (source.isDirectory()) {
-        File[] files = source.listFiles();
-        dirs = new File[files.length];
-        docs = new File[files.length];
-        String fileName;
-
-        for (int i = 0; i < files.length; i++) {
-          if (files[i].isDirectory()) {
-            if (fFilter[j].isDirectoryOk(files[i])) {
-              dirs[idirs++] = files[i];
-            }
-          } else if (files[i].isFile()) {
-            if (fFilter[j].isFileOk(files[i])) {
-              docs[idocs++] = files[i];
-            }
-          } else
-            return false;
-        }
-      } else {
-        dirs = new File[0];
-        docs = new File[1];
-        docs[0] = source;
-        idocs = 1;
-      }
-
-      for (int i = 0; i < idocs; i++) {
-        System.out.println(docs[i].getAbsolutePath());
-
-        File result = fMover[j].move(docs[i], target);
-      }
-
-      System.out.println("directories");
-      for (int i = 0; i < idirs; i++) {
-        System.out.println(dirs[i].getAbsolutePath());
-        if (!walk(dirs[i], new File(target, dirs[i].getName())))
-          return false;
-      }
-    }
-
-    return true;
-  }
-}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/IFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/IFilter.java
deleted file mode 100644 (file)
index 15cfc03..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-import java.io.File;
-
-/**
- * @author khartlage
- *
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>ObfuscatorIgnores.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
- */
-public interface IFilter {
-  final public static DefaultFilter DEFAULT_FILTER = new DefaultFilter();
-  final public static DefaultFilter PHP_FILTER = new PHPFilter();
-  
-  public boolean isFileOk(File file);
-  public boolean isDirectoryOk(File file);
-}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/IMover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/IMover.java
deleted file mode 100644 (file)
index 9bb72b3..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-/**
- * Specify how to move a file from the XML acquisition directory
- * to the publishing/HTML/other one. Implementations perform actual
- * styling/copying operations.
- *
- * @author <a href="http://www.marchal.com">Beno&#238;t Marchal</a>
- */
-
-// Copyright 2001, Benoît Marchal.
-//Changes 2003, Klaus Hartlage
-
-import java.io.*;
-
-public interface IMover
-{
-
-   /**
-    * Move one file.
-    * @param sourceFile the file to move
-    * @param targetDir the directory to copy the result to
-    * @return new file or null if the file was ignored
-    */
-   public File move(File sourceFile,File targetDir)
-      throws IOException;
-
-}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/PHPFilter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/PHPFilter.java
deleted file mode 100644 (file)
index eede4c9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.sourceforge.phpeclipse.mover;
-
-import java.io.File;
-
-/**
- * Allows only php files for the mover
- */
-public class PHPFilter extends DefaultFilter {
-  
-  public boolean isFileOk(File file) {
-    String fileName = file.getAbsolutePath().toLowerCase();
-    if (fileName.endsWith(".php")
-      || fileName.endsWith(".php3")
-      || fileName.endsWith(".php4")
-      || fileName.endsWith(".phtml")
-      || fileName.endsWith(".inc")) {
-      return true;
-    }
-    return false;
-  }
-  
-  public boolean isDirectoryOk(File file) {
-    return true;
-  }
-}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/default-obfuscator.xml b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/mover/obfuscator/default-obfuscator.xml
deleted file mode 100644 (file)
index 7800312..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<obfuscator>
-    <ignore>$this</ignore>
-    <ignore>$_SERVER</ignore>
-    <ignore>$AUTH_TYPE</ignore>
-    <ignore>$CONTENT_LENGTH</ignore>
-    <ignore>$CONTENT_TYPE</ignore>
-    <ignore>$GATEWAY_INTERFACE</ignore>
-    <ignore>$GLOBALS</ignore>
-    <ignore>$HTTP_ACCEPT</ignore>
-    <ignore>$HTTP_COOKIE</ignore>
-    <ignore>$HTTP_COOKIE_VARS</ignore>
-    <ignore>$HTTP_POST_VARS</ignore>
-    <ignore>$HTTP_REFERER</ignore>
-    <ignore>$HTTP_USER_AGENT</ignore>
-    <ignore>$PATH_INFO</ignore>
-    <ignore>$PATH_TRANSLATED</ignore>
-    <ignore>$PHP_AUTH_PW</ignore>
-    <ignore>$PHP_AUTH_USER</ignore>
-    <ignore>$PHP_ERRORMSG</ignore>
-    <ignore>$PHP_SELF</ignore>
-    <ignore>$QUERY_STRING</ignore>
-    <ignore>$REMOTE_ADDR</ignore>
-    <ignore>$REMOTE_HOST</ignore>
-    <ignore>$REMOTE_IDENT</ignore>
-    <ignore>$REMOTE_USER</ignore>
-    <ignore>$REQUEST_METHOD</ignore>
-    <ignore>$SCRIPT_NAME</ignore>
-    <ignore>$SERVER_NAME</ignore>
-    <ignore>$SERVER_PORT</ignore>
-    <ignore>$SERVER_PROTOCOL</ignore>
-    <ignore>$SERVER_SOFTWARE</ignore>
-</obfuscator>
\ No newline at end of file
index d522c65..c39c18d 100644 (file)
@@ -62,21 +62,22 @@ PHPEditorSyntaxPreferencePage.italic:Italic
 PHPEditorSyntaxPreferencePage.underline:Underline
 PHPEditorSyntaxPreferencePage.multiLineComment=Multi-line comment
 PHPEditorSyntaxPreferencePage.singleLineComment=Single-line comment
-PHPEditorSyntaxPreferencePage.keywords=Keywords
-PHPEditorSyntaxPreferencePage.variables=Variables
-PHPEditorSyntaxPreferencePage.types=Types
-PHPEditorSyntaxPreferencePage.functions=Functions
-PHPEditorSyntaxPreferencePage.constants=Constants
+PHPEditorSyntaxPreferencePage.keywords=Schlüsslworte
+PHPEditorSyntaxPreferencePage.tags=PHP Tags
+PHPEditorSyntaxPreferencePage.variables=Variablen
+PHPEditorSyntaxPreferencePage.types=Typen
+PHPEditorSyntaxPreferencePage.functions=Functionen
+PHPEditorSyntaxPreferencePage.constants=Konstanten
 PHPEditorSyntaxPreferencePage.strings=Strings
-PHPEditorSyntaxPreferencePage.others=Others
+PHPEditorSyntaxPreferencePage.others=Andere
 PHPEditorSyntaxPreferencePage.syntaxdialog=Custom PHP Syntax File:
 PHPEditorSyntaxPreferencePage.browse=Browse..
 PHPEditorSyntaxPreferencePage.textfont=Text font
 
-PHPLanguagePreferencePage.description=PHP Editor Language
-PHPLanguagePreferencePage.preflingo=PHP Language Preference
-PHPLanguagePreferencePage.choose=Choose Language
+PHPLanguagePreferencePage.description=PHP Editor Sprache
+PHPLanguagePreferencePage.preflingo=PHP Sprach Voreinstellungen
+PHPLanguagePreferencePage.choose=Wähle Sprache
 PHPLanguagePreferencePage.english=Englisch
 PHPLanguagePreferencePage.german=Deutsch
-PHPLanguagePreferencePage.french=Frensch
+PHPLanguagePreferencePage.french=Francais
 PHPLanguagePreferencePage.spanish=Spanish
index 9e03703..64b5314 100644 (file)
@@ -63,6 +63,7 @@ PHPEditorSyntaxPreferencePage.underline:Souslign
 PHPEditorSyntaxPreferencePage.multiLineComment=Commentaire Multi-ligne
 PHPEditorSyntaxPreferencePage.singleLineComment=Commenaire Mono-ligne
 PHPEditorSyntaxPreferencePage.keywords=Mots clef
+PHPEditorSyntaxPreferencePage.tags=PHP Tags
 PHPEditorSyntaxPreferencePage.variables=Variables
 PHPEditorSyntaxPreferencePage.types=Types
 PHPEditorSyntaxPreferencePage.functions=Fonctions
index c02902b..50d73e8 100644 (file)
@@ -61,6 +61,7 @@ PHPEditorSyntaxPreferencePage.italic:Italic
 PHPEditorSyntaxPreferencePage.underline:Underline
 PHPEditorSyntaxPreferencePage.multiLineComment=Multi-line comment
 PHPEditorSyntaxPreferencePage.singleLineComment=Single-line comment
+PHPEditorSyntaxPreferencePage.tags=PHP Tags
 PHPEditorSyntaxPreferencePage.keywords=Keywords
 PHPEditorSyntaxPreferencePage.variables=Variables
 PHPEditorSyntaxPreferencePage.types=Types
index a93dd07..8498138 100644 (file)
@@ -66,6 +66,7 @@ PHPEditorSyntaxPreferencePage.multiLineComment=Comentario varias l
 PHPEditorSyntaxPreferencePage.singleLineComment=Comentario una línia
 PHPEditorSyntaxPreferencePage.keywords=Palabras clave
 PHPEditorSyntaxPreferencePage.variables=Variables
+PHPEditorSyntaxPreferencePage.tags=PHP Tags
 PHPEditorSyntaxPreferencePage.types=Tipos
 PHPEditorSyntaxPreferencePage.functions=Funciones
 PHPEditorSyntaxPreferencePage.constants=Constantes
@@ -1,12 +1,18 @@
-package net.sourceforge.phpeclipse.mover.obfuscator;
-
-/**
- * Analyze the file with the PHP Scanner
- */
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator;
+
+import java.io.BufferedInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -14,37 +20,34 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.mover.DefaultMover;
-import net.sourceforge.phpeclipse.views.PHPConsole;
 
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.jface.preference.IPreferenceStore;
 
-public class PHPAnalyzer extends DefaultMover implements ITerminalSymbols {
+/**
+ * Analyzing php files in a first pass over all resources !
+ */
+public class ObfuscatorPass1Exporter implements ITerminalSymbols {
 
   protected Scanner fScanner;
   protected int fToken;
 
   protected HashMap fIdentifierMap;
 
-  /**
-   * buffer, for obvious reasons access to this buffer must
-   * be synchronized
-   */
-  protected byte[] bytes = new byte[1024];
-  
-  /**
-   * Creates a PHPAnalyzer
-   * @param console reports error to the PHPConsole
-   */
-  public PHPAnalyzer(PHPConsole console, Scanner scanner, HashMap identifierMap) {
-    super(console);
-    this.fScanner = scanner;
-    this.fIdentifierMap = identifierMap;
+  public ObfuscatorPass1Exporter(Scanner scanner, HashMap identifierMap) {
+    fScanner = scanner;
+    fIdentifierMap = identifierMap;
   }
 
   /**
-   * gets the next token from input
+   * Get the next token from input
    */
   private void getNextToken() {
 
@@ -156,35 +159,78 @@ public class PHPAnalyzer extends DefaultMover implements ITerminalSymbols {
       // do nothing 
     }
   }
+
   /**
-   * Move one file.
-   * @param sourceFile the file to move
-   * @param targetDir the directory to copy the result to
-   * @return file or null if the file was ignored
+   *  Do nothing in first pass
    */
-  public File move(File sourceFile, File targetDir) {
-
-    StringBuffer buf = new StringBuffer();
-
+  public void createFolder(IPath destinationPath) {
+    // do nothing here
+    //    new File(destinationPath.toOSString()).mkdir();
+  }
+  /**
+   *  Writes the passed resource to the specified location recursively
+   */
+  public void write(IResource resource, IPath destinationPath) throws CoreException, IOException {
+    if (resource.getType() == IResource.FILE)
+      writeFile((IFile) resource, destinationPath);
+    else
+      writeChildren((IContainer) resource, destinationPath);
+  }
+  /**
+   *  Exports the passed container's children
+   */
+  protected void writeChildren(IContainer folder, IPath destinationPath) throws CoreException, IOException {
+    if (folder.isAccessible()) {
+      IResource[] children = folder.members();
+      for (int i = 0; i < children.length; i++) {
+        IResource child = children[i];
+        writeResource(child, destinationPath.append(child.getName()));
+      }
+    }
+  }
+  /**
+   *  Analyzes the passed file resource for the PHP obfuscator
+   */
+  protected void writeFile(IFile file, IPath destinationPath) throws IOException, CoreException {
+               if (! PHPFileUtil.isPHPFile(file) ){
+                       return;
+               }
+    InputStream stream = null;
+    char[] charArray = null;
     try {
-      long filelen = sourceFile.length();
-      char[] charArray = new char[(int) filelen];
-
-      BufferedReader br = new BufferedReader(new FileReader(sourceFile.getAbsolutePath()));
-      br.read(charArray, 0, (int) filelen);
-      br.close();
-
-      //  String input = buf.toString();
-      /* fScanner initialization */
-      fScanner.setSource(charArray);
-      fScanner.setPHPMode(false);
-      fToken = TokenNameEOF;
-      getNextToken();
-      parseIdentifiers(false);
-      return null;
+      stream = new BufferedInputStream(file.getContents());
+      charArray = Util.getInputStreamAsCharArray(stream, -1, null);
     } catch (IOException e) {
-      fConsole.write(e.toString());
+      return;
+    } finally {
+      try {
+        if (stream != null) {
+          stream.close();
+        }
+      } catch (IOException e) {
+      }
+    }
+
+    if (charArray == null) {
+       // TODO show error message 
+      return;
+    }
+    /* fScanner initialization */
+    fScanner.setSource(charArray);
+    fScanner.setPHPMode(false);
+    fToken = TokenNameEOF;
+    getNextToken();
+    parseIdentifiers(false);
+  }
+  /**
+   *  Writes the passed resource to the specified location recursively
+   */
+  protected void writeResource(IResource resource, IPath destinationPath) throws CoreException, IOException {
+    if (resource.getType() == IResource.FILE)
+      writeFile((IFile) resource, destinationPath);
+    else {
+      createFolder(destinationPath);
+      writeChildren((IContainer) resource, destinationPath);
     }
-    return null;
   }
-}
\ No newline at end of file
+}
@@ -1,15 +1,23 @@
-package net.sourceforge.phpeclipse.mover.obfuscator;
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator;
 
-import java.io.BufferedReader;
+import java.io.BufferedInputStream;
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
-//import java.security.MessageDigest;
-//import java.security.NoSuchAlgorithmException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -17,58 +25,36 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.mover.DefaultMover;
-import net.sourceforge.phpeclipse.views.PHPConsole;
 
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.jface.preference.IPreferenceStore;
 
 /**
- * Obfuscate the file with the PHP Scanner
+ * Helper class for exporting resources to the file system.
  */
-public class PHPObfuscatorMover extends DefaultMover implements ITerminalSymbols {
-
+public class ObfuscatorPass2Exporter implements ITerminalSymbols {
   private Scanner fScanner;
   private int fToken;
- // private MessageDigest fAlgorithm;
   private int fCounter;
 
   protected HashMap fIdentifierMap;
 
-  /**
-   * buffer, for obvious reasons access to this buffer must
-   * be synchronized
-   */
-  protected byte[] bytes = new byte[1024];
-  /**
-   * Creates a PHPAnalyzer
-   * @param console reports error to the PHPConsole
-   */
-  public PHPObfuscatorMover(PHPConsole console, Scanner scanner, HashMap identifierMap) {
-    super(console);
-    this.fScanner = scanner;
-    this.fIdentifierMap = identifierMap;
-    this.fCounter = 0;
-//    try {
-//      this.fAlgorithm = MessageDigest.getInstance("MD5");
-//    } catch (NoSuchAlgorithmException e) {
-//      System.out.println(e.toString());
-//    }
+  public ObfuscatorPass2Exporter(Scanner scanner, HashMap identifierMap) {
+    fScanner = scanner;
+    fIdentifierMap = identifierMap;
+    fCounter = 0;
   }
-
+  
   /**
-   * Return the name the file would have after moving. In this case,
-   * it's left unchanged.
-   * @param file file the mover would have to move
-   * @return the extension it would give the file in the target directory
-   */
-  public String getTargetName(File file) {
-    return file.getName();
-  }
-
-  /**
-   * gets the next token from input
-   */
+       * gets the next token from input
+       */
   private void getNextToken() {
 
     try {
@@ -155,7 +141,7 @@ public class PHPObfuscatorMover extends DefaultMover implements ITerminalSymbols
 
           while (i < fScanner.currentPosition) {
             currentCharacter = fScanner.source[i++];
-            if (currentCharacter == '$' && fScanner.source[i-2]!='\\') {
+            if (currentCharacter == '$' && fScanner.source[i - 2] != '\\') {
               StringBuffer varName = new StringBuffer();
               varName.append("$");
               while (i < fScanner.currentPosition) {
@@ -192,9 +178,9 @@ public class PHPObfuscatorMover extends DefaultMover implements ITerminalSymbols
             }
             index = stringLiteral.indexOf(stringIdent);
             if (index >= 0) {
-              if (index > 0 && stringLiteral.charAt(index-1)!='\\') {
+              if (index > 0 && stringLiteral.charAt(index - 1) != '\\') {
                 stringLiteral.replace(index, index + stringIdent.length(), replacement);
-              } else if (index==0) {
+              } else if (index == 0) {
                 stringLiteral.replace(index, index + stringIdent.length(), replacement);
               }
             }
@@ -246,82 +232,113 @@ public class PHPObfuscatorMover extends DefaultMover implements ITerminalSymbols
 
     return false;
   }
-
-  public File copy(File sourceFile, File targetDir) {
-    try {
-      File targetFile = new File(targetDir, getTargetName(sourceFile));
-      //      if (targetFile.exists())
-      //        if (targetFile.lastModified() >= sourceFile.lastModified())
-      //          return null;
-      synchronized (bytes) {
-        FileInputStream in = new FileInputStream(sourceFile);
-        FileOutputStream out = new FileOutputStream(targetFile);
-        for (int len = in.read(bytes); len != -1; len = in.read(bytes)) {
-          out.write(bytes, 0, len);
-        }
-        in.close();
-        out.close();
+  /**
+   *  Creates the specified file system directory at <code>destinationPath</code>.
+   *  This creates a new file system directory.
+   */
+  public void createFolder(IPath destinationPath) {
+    new File(destinationPath.toOSString()).mkdir();
+  }
+  /**
+   *  Writes the passed resource to the specified location recursively
+   */
+  public void write(IResource resource, IPath destinationPath) throws CoreException, IOException {
+    if (resource.getType() == IResource.FILE)
+      writeFile((IFile) resource, destinationPath);
+    else
+      writeChildren((IContainer) resource, destinationPath);
+  }
+  /**
+   *  Exports the passed container's children
+   */
+  protected void writeChildren(IContainer folder, IPath destinationPath) throws CoreException, IOException {
+    if (folder.isAccessible()) {
+      IResource[] children = folder.members();
+      for (int i = 0; i < children.length; i++) {
+        IResource child = children[i];
+        writeResource(child, destinationPath.append(child.getName()));
       }
-      return targetFile;
-    } catch (IOException e) {
-      fConsole.write(e.toString());
     }
-    return null;
   }
-
   /**
-   * Move one file.
-   * @param sourceFile the file to move
-   * @param targetDir the directory to copy the result to
-   * @return file or null if the file was ignored
+   *  Writes the passed file resource to the specified destination on the local
+   *  file system
    */
-  public File move(File sourceFile, File targetDir) {
-
-    try {
-
-      String fileName = sourceFile.getAbsolutePath().toLowerCase();
-      if (fileName.endsWith(".php")
-        || fileName.endsWith(".php3")
-        || fileName.endsWith(".php4")
-        || fileName.endsWith(".phtml")
-        || fileName.endsWith(".inc")) {
-        StringBuffer buf = new StringBuffer();
-        long filelen = sourceFile.length();
-        char[] charArray = new char[(int) filelen];
+  protected void writeFile(IFile file, IPath destinationPath) throws IOException, CoreException {
+    if (PHPFileUtil.isPHPFile(file)) {
+      InputStream stream = null;
+      char[] charArray = null;
+      try {
+        stream = new BufferedInputStream(file.getContents());
+        charArray = Util.getInputStreamAsCharArray(stream, -1, null);
+      } catch (IOException e) {
+        return;
+      } finally {
+        try {
+          if (stream != null) {
+            stream.close();
+          }
+        } catch (IOException e) {
+        }
+      }
 
-        BufferedReader br = new BufferedReader(new FileReader(sourceFile.getAbsolutePath()));
-        br.read(charArray, 0, (int) filelen);
+      if (charArray == null) {
+        // TODO show error message 
+        return;
+      }
 
-        //        int offset = 0;
-        //        String line;
-        //        while ((line = br.readLine()) != null) {
-        //          System.arraycopy(line.toCharArray(), 0, charArray, offset, line.length());
-        //          offset += line.length();
-        //        }
-        br.close();
+      fScanner.setSource(charArray);
+      fScanner.setPHPMode(false);
+      fToken = TokenNameEOF;
+      getNextToken();
 
-        fScanner.setSource(charArray);
-        fScanner.setPHPMode(false);
-        fToken = TokenNameEOF;
-        getNextToken();
-        buf = new StringBuffer();
-        if (!obfuscate(buf)) {
-          return copy(sourceFile, targetDir);
-        } else {
-          File targetFile = new File(targetDir, getTargetName(sourceFile));
-          BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile));
-          bw.write(buf.toString());
-          bw.close();
-          return targetFile;
-        }
-        
+      StringBuffer buf = new StringBuffer();
+      if (!obfuscate(buf)) {
+        copyFile(file, destinationPath);
       } else {
-        return copy(sourceFile, targetDir);
+        //                             charArray = buf.toString().toCharArray();
+        //        File targetFile = new File(destinationPath.toOSString());
+        BufferedWriter bw = new BufferedWriter(new FileWriter(destinationPath.toOSString()));
+        bw.write(buf.toString());
+        bw.close();
       }
 
-    } catch (IOException e) {
-      fConsole.write(e.toString());
+    } else {
+      copyFile(file, destinationPath);
+    }
+  }
+
+  private void copyFile(IFile file, IPath destinationPath) throws FileNotFoundException, CoreException, IOException {
+    FileOutputStream output = null;
+    InputStream contentStream = null;
+
+    try {
+      output = new FileOutputStream(destinationPath.toOSString());
+      contentStream = file.getContents(false);
+      int chunkSize = contentStream.available();
+      byte[] readBuffer = new byte[chunkSize];
+      int n = contentStream.read(readBuffer);
+
+      while (n > 0) {
+        output.write(readBuffer);
+        n = contentStream.read(readBuffer);
+      }
+    } finally {
+      if (output != null)
+        output.close();
+      if (contentStream != null)
+        contentStream.close();
+    }
+  }
+  /**
+   *  Writes the passed resource to the specified location recursively
+   */
+  protected void writeResource(IResource resource, IPath destinationPath) throws CoreException, IOException {
+    if (resource.getType() == IResource.FILE)
+      writeFile((IFile) resource, destinationPath);
+    else {
+      createFolder(destinationPath);
+      writeChildren((IContainer) resource, destinationPath);
     }
-    return null;
   }
-}
\ No newline at end of file
+}
@@ -1,4 +1,4 @@
-package net.sourceforge.phpeclipse.mover.obfuscator;
+package net.sourceforge.phpeclipse.obfuscator;
 
 /**
  * @author khartlage
@@ -11,6 +11,7 @@ public class PHPIdentifier {
   public final static int METHOD = 4;
   public final static int VARIABLE = 3;
   public final static int DEFINE = 5;
+       public final static int CONSTRUCTOR = 6;
   private String fIdentifier;
 
   private int fType;
@@ -42,7 +43,7 @@ public class PHPIdentifier {
     return fType == CLASS;
   }
 
-  public boolean isFuncton() {
+  public boolean isFunction() {
     return fType == FUNCTION;
   }
 
@@ -58,6 +59,10 @@ public class PHPIdentifier {
     return fType == DEFINE;
   }
 
+       public boolean isConstructor() {
+               return fType == CONSTRUCTOR;
+       }
+       
   public void setIdentifier(String fIdentifier) {
     this.fIdentifier = fIdentifier;
   }
@@ -73,6 +78,8 @@ public class PHPIdentifier {
     switch (fType) {
       case CLASS :
         return "class - ";
+                       case CONSTRUCTOR :
+                               return "constructor - ";
       case DEFINE :
         return "define - ";
       case FUNCTION :
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/default-obfuscator.xml b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/default-obfuscator.xml
new file mode 100644 (file)
index 0000000..bd85d37
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<obfuscator>
+    <ignore>$this</ignore>
+    <ignore>$_COOKIE</ignore>
+    <ignore>$_ENV</ignore>
+    <ignore>$_FILES</ignore>
+    <ignore>$_GET</ignore>
+    <ignore>$_POST</ignore>
+    <ignore>$_REQUEST</ignore>
+    <ignore>$_SERVER</ignore>
+    <ignore>$_SESSION</ignore>
+    <ignore>$argc</ignore>
+    <ignore>$argv</ignore>
+    <ignore>$AUTH_TYPE</ignore>
+    <ignore>$CONTENT_LENGTH</ignore>
+    <ignore>$CONTENT_TYPE</ignore>
+    <ignore>$DOCUMENT_ROOT</ignore>
+    <ignore>$GATEWAY_INTERFACE</ignore>
+    <ignore>$GLOBALS</ignore>
+    <ignore>$HTTP_ACCEPT</ignore>   
+    <ignore>$HTTP_ACCEPT_ENCODING</ignore>
+    <ignore>$HTTP_ACCEPT_LANGUAGE</ignore>
+    <ignore>$HTTP_CACHE_CONTROL</ignore>
+    <ignore>$HTTP_CONNECTION</ignore>
+    <ignore>$HTTP_COOKIE</ignore>
+    <ignore>$HTTP_COOKIE_VARS</ignore>
+    <ignore>$HTTP_ENV_VARS</ignore>
+    <ignore>$HTTP_GET_VARS</ignore>
+    <ignore>$HTTP_HOST</ignore>
+    <ignore>$HTTP_HOST_FILES</ignore>
+    <ignore>$HTTP_POST_VARS</ignore>
+    <ignore>$HTTP_SERVER_VARS</ignore>
+    <ignore>$HTTP_SESSION_VARS</ignore>
+    <ignore>$HTTP_REFERER</ignore>
+    <ignore>$HTTP_USER_AGENT</ignore>
+    <ignore>$PATH</ignore>
+    <ignore>$PATH_INFO</ignore>
+    <ignore>$PATH_TRANSLATED</ignore>
+    <ignore>$PHP_AUTH_PW</ignore>
+    <ignore>$PHP_AUTH_USER</ignore>
+    <ignore>$PHP_ERRORMSG</ignore>
+    <ignore>$PHP_SELF</ignore>
+    <ignore>$QUERY_STRING</ignore>
+    <ignore>$REDIRECT_STATUS</ignore>
+    <ignore>$REDIRECT_URL</ignore>
+    <ignore>$REMOTE_ADDR</ignore>
+    <ignore>$REMOTE_HOST</ignore>
+    <ignore>$REMOTE_IDENT</ignore>
+    <ignore>$REMOTE_PORT</ignore>
+    <ignore>$REMOTE_USER</ignore>
+    <ignore>$REQUEST_METHOD</ignore>
+    <ignore>$REQUEST_URI</ignore>
+    <ignore>$SCRIPT_FILENAME</ignore>
+    <ignore>$SCRIPT_NAME</ignore>
+    <ignore>$SERVER_ADDR</ignore>
+    <ignore>$SERVER_ADMIN</ignore>
+    <ignore>$SERVER_NAME</ignore>
+    <ignore>$SERVER_PORT</ignore>
+    <ignore>$SERVER_PROTOCOL</ignore>
+    <ignore>$SERVER_SIGNATURE</ignore>
+    <ignore>$SERVER_SOFTWARE</ignore>
+</obfuscator>
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportMessages.java
new file mode 100644 (file)
index 0000000..655f7c8
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class which helps managing messages
+ */
+class ObfuscatorExportMessages {
+       private static final String RESOURCE_BUNDLE= "net.sourceforge.phpeclipse.obfuscator.export.messages";//$NON-NLS-1$
+       private static ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+private ObfuscatorExportMessages(){
+       // prevent instantiation of class
+}
+/**
+ * Returns the formatted message for the given key in
+ * the resource bundle. 
+ *
+ * @param key the resource name
+ * @param args the message arguments
+ * @return the string
+ */    
+public static String format(String key, Object[] args) {
+       return MessageFormat.format(getString(key),args);
+}
+/**
+ * Returns the resource object with the given key in
+ * the resource bundle. If there isn't any value under
+ * the given key, the key is returned.
+ *
+ * @param key the resource name
+ * @return the string
+ */    
+public static String getString(String key) {
+       try {
+               return bundle.getString(key);
+       } catch (MissingResourceException e) {
+               return key;
+       }
+}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportOperation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportOperation.java
new file mode 100644 (file)
index 0000000..f8e50dc
--- /dev/null
@@ -0,0 +1,640 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.obfuscator.ObfuscatorIgnores;
+import net.sourceforge.phpeclipse.obfuscator.ObfuscatorPass1Exporter;
+import net.sourceforge.phpeclipse.obfuscator.ObfuscatorPass2Exporter;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+
+/**
+ *     Operation for exporting the contents of a resource to the local file system.
+ */
+/*package*/
+class ObfuscatorExportOperation implements IRunnableWithProgress {
+  private IPath fPath;
+  private IProgressMonitor fMonitor;
+  private ObfuscatorPass1Exporter fExporter1 = null;
+  private ObfuscatorPass2Exporter fExporter2 = null;
+  private HashMap fCurrentIdentifierMap = null;
+  private HashMap fProjectMap = null;
+  private String fCurrentProjectName = "";
+
+  private List fResourcesToExport;
+  private IOverwriteQuery fOverwriteCallback;
+  private IResource fResource;
+  private List errorTable = new ArrayList(1);
+
+  //The constants for the overwrite 3 state
+  private static final int OVERWRITE_NOT_SET = 0;
+  private static final int OVERWRITE_NONE = 1;
+  private static final int OVERWRITE_ALL = 2;
+  private int overwriteState = OVERWRITE_NOT_SET;
+
+  //  private boolean createLeadupStructure = true;
+  private boolean createContainerDirectories = true;
+  /**
+   *  Create an instance of this class.  Use this constructor if you wish to
+   *  export specific resources without a common parent resource
+   */
+  //  public ObfuscatorExportOperation(List resources, String destinationPath, IOverwriteQuery overwriteImplementor) {
+  //    super();
+  //
+  //    exporter1 = new ObfuscatorPass1Exporter(new Scanner(false, false), identifierMap);
+  //           exporter2 = new ObfuscatorPass2Exporter(new Scanner(true, true), identifierMap);
+  //           identifierMap = null;
+  //           
+  //    // Eliminate redundancies in list of resources being exported
+  //    Iterator elementsEnum = resources.iterator();
+  //    while (elementsEnum.hasNext()) {
+  //      IResource currentResource = (IResource) elementsEnum.next();
+  //      if (isDescendent(resources, currentResource))
+  //        elementsEnum.remove(); //Remove currentResource
+  //    }
+  //
+  //    resourcesToExport = resources;
+  //    path = new Path(destinationPath);
+  //    overwriteCallback = overwriteImplementor;
+  //  }
+  /**
+   *  Create an instance of this class.  Use this constructor if you wish to
+   *  recursively export a single resource
+   */
+  public ObfuscatorExportOperation(IResource res, String destinationPath, IOverwriteQuery overwriteImplementor) {
+    super();
+
+    fResource = res;
+    fPath = new Path(destinationPath);
+    fOverwriteCallback = overwriteImplementor;
+  }
+  /**
+   *  Create an instance of this class.  Use this constructor if you wish to
+   *  export specific resources with a common parent resource (affects container
+   *  directory creation)
+   */
+  public ObfuscatorExportOperation(IResource res, List resources, String destinationPath, IOverwriteQuery overwriteImplementor) {
+    this(res, destinationPath, overwriteImplementor);
+    fResourcesToExport = resources;
+  }
+  /**
+   * Add a new entry to the error table with the passed information
+   */
+  protected void addError(String message, Throwable e) {
+    errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, e));
+  }
+  /**
+   *  Answer the total number of file resources that exist at or below self in the
+   *  resources hierarchy.
+   *
+   *  @return int
+   *  @param resource org.eclipse.core.resources.IResource
+   */
+  protected int countChildrenOf(IResource resource) throws CoreException {
+    if (resource.getType() == IResource.FILE)
+      return 1;
+
+    int count = 0;
+    if (resource.isAccessible()) {
+      IResource[] children = ((IContainer) resource).members();
+      for (int i = 0; i < children.length; i++)
+        count += countChildrenOf(children[i]);
+    }
+
+    return count;
+  }
+  /**
+   *   Answer a boolean indicating the number of file resources that were
+   *   specified for export
+   *
+   *   @return int
+   */
+  protected int countSelectedResources() throws CoreException {
+    int result = 0;
+    Iterator resources = fResourcesToExport.iterator();
+
+    while (resources.hasNext())
+      result += countChildrenOf((IResource) resources.next());
+
+    return result;
+  }
+  /**
+   *  Create the directories required for exporting the passed resource,
+   *  based upon its container hierarchy
+   *
+   *  @param resource org.eclipse.core.resources.IResource
+   */
+  protected void createLeadupDirectoriesFor(IResource resource) {
+    IPath resourcePath = resource.getFullPath().removeLastSegments(1);
+
+    for (int i = 0; i < resourcePath.segmentCount(); i++) {
+      fPath = fPath.append(resourcePath.segment(i));
+      fExporter2.createFolder(fPath);
+    }
+  }
+  /**
+   *   Recursively export the previously-specified resource
+   */
+  protected void exportAllResources1() throws InterruptedException {
+    if (fResource.getType() == IResource.FILE) {
+      exportFile1((IFile) fResource, fPath);
+    } else {
+      try {
+        setExporters(fResource);
+        exportChildren1(((IContainer) fResource).members(), fPath);
+      } catch (CoreException e) {
+        // not safe to show a dialog
+        // should never happen because the file system export wizard ensures that the
+        // single resource chosen for export is both existent and accessible
+        errorTable.add(e);
+      }
+    }
+  }
+  /**
+   *   Recursively export the previously-specified resource
+   */
+  protected void exportAllResources2() throws InterruptedException {
+    if (fResource.getType() == IResource.FILE) {
+      exportFile2((IFile) fResource, fPath);
+    } else {
+      try {
+        setExporters(fResource);
+        exportChildren2(((IContainer) fResource).members(), fPath);
+      } catch (CoreException e) {
+        // not safe to show a dialog
+        // should never happen because the file system export wizard ensures that the
+        // single resource chosen for export is both existent and accessible
+        errorTable.add(e);
+      }
+    }
+  }
+  /**
+   *   Export all of the resources contained in the passed collection
+   *
+   *   @param children java.util.Enumeration
+   *   @param currentPath IPath
+   */
+  protected void exportChildren1(IResource[] children, IPath currentPath) throws InterruptedException {
+    for (int i = 0; i < children.length; i++) {
+      IResource child = children[i];
+      if (!child.isAccessible())
+        continue;
+
+      if (child.getType() == IResource.FILE)
+        exportFile1((IFile) child, currentPath);
+      else {
+        IPath destination = currentPath.append(child.getName());
+        fExporter1.createFolder(destination);
+        try {
+          exportChildren1(((IContainer) child).members(), destination);
+        } catch (CoreException e) {
+          // not safe to show a dialog
+          // should never happen because:
+          // i. this method is called recursively iterating over the result of #members,
+          //           which only answers existing children
+          // ii. there is an #isAccessible check done before #members is invoked
+          errorTable.add(e.getStatus());
+        }
+      }
+    }
+  }
+
+  /**
+   *   Export all of the resources contained in the passed collection
+   *
+   *   @param children java.util.Enumeration
+   *   @param currentPath IPath
+   */
+  protected void exportChildren2(IResource[] children, IPath currentPath) throws InterruptedException {
+    for (int i = 0; i < children.length; i++) {
+      IResource child = children[i];
+      if (!child.isAccessible())
+        continue;
+
+      if (child.getType() == IResource.FILE)
+        exportFile2((IFile) child, currentPath);
+      else {
+        IPath destination = currentPath.append(child.getName());
+        fExporter2.createFolder(destination);
+        try {
+          exportChildren2(((IContainer) child).members(), destination);
+        } catch (CoreException e) {
+          // not safe to show a dialog
+          // should never happen because:
+          // i. this method is called recursively iterating over the result of #members,
+          //           which only answers existing children
+          // ii. there is an #isAccessible check done before #members is invoked
+          errorTable.add(e.getStatus());
+        }
+      }
+    }
+  }
+
+  protected void exportFile1(IFile file, IPath location) throws InterruptedException {
+    IPath fullPath = location.append(file.getName());
+    fMonitor.subTask(file.getFullPath().toString());
+    String properPathString = fullPath.toOSString();
+    File targetFile = new File(properPathString);
+
+    //    if (targetFile.exists()) {
+    //      if (!targetFile.canWrite()) {
+    //        errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, ObfuscatorExportMessages.format("ObfuscatorTransfer.cannotOverwrite", //$NON-NLS-1$
+    //        new Object[] { targetFile.getAbsolutePath()}), null));
+    //        monitor.worked(1);
+    //        return;
+    //      }
+    //
+    //      if (overwriteState == OVERWRITE_NONE)
+    //        return;
+    //
+    //      if (overwriteState != OVERWRITE_ALL) {
+    //        String overwriteAnswer = overwriteCallback.queryOverwrite(properPathString);
+    //
+    //        if (overwriteAnswer.equals(IOverwriteQuery.CANCEL))
+    //          throw new InterruptedException();
+    //
+    //        if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
+    //          monitor.worked(1);
+    //          return;
+    //        }
+    //
+    //        if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
+    //          monitor.worked(1);
+    //          overwriteState = OVERWRITE_NONE;
+    //          return;
+    //        }
+    //
+    //        if (overwriteAnswer.equals(IOverwriteQuery.ALL))
+    //          overwriteState = OVERWRITE_ALL;
+    //      }
+    //    }
+
+    try {
+      setExporters(file);
+      fExporter1.write(file, fullPath);
+    } catch (IOException e) {
+      errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, ObfuscatorExportMessages.format("ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+      new Object[] { fullPath, e.getMessage()}), e));
+    } catch (CoreException e) {
+      errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, ObfuscatorExportMessages.format("ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+      new Object[] { fullPath, e.getMessage()}), e));
+    }
+
+    fMonitor.worked(1);
+    ModalContext.checkCanceled(fMonitor);
+  }
+  /**
+   *  Export the passed file to the specified location
+   *
+   *  @param file org.eclipse.core.resources.IFile
+   *  @param location org.eclipse.core.runtime.IPath
+   */
+  protected void exportFile2(IFile file, IPath location) throws InterruptedException {
+    IPath fullPath = location.append(file.getName());
+    fMonitor.subTask(file.getFullPath().toString());
+    String properPathString = fullPath.toOSString();
+    File targetFile = new File(properPathString);
+
+    if (targetFile.exists()) {
+      if (!targetFile.canWrite()) {
+        errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, ObfuscatorExportMessages.format("ObfuscatorTransfer.cannotOverwrite", //$NON-NLS-1$
+        new Object[] { targetFile.getAbsolutePath()}), null));
+        fMonitor.worked(1);
+        return;
+      }
+
+      if (overwriteState == OVERWRITE_NONE)
+        return;
+
+      if (overwriteState != OVERWRITE_ALL) {
+        String overwriteAnswer = fOverwriteCallback.queryOverwrite(properPathString);
+
+        if (overwriteAnswer.equals(IOverwriteQuery.CANCEL))
+          throw new InterruptedException();
+
+        if (overwriteAnswer.equals(IOverwriteQuery.NO)) {
+          fMonitor.worked(1);
+          return;
+        }
+
+        if (overwriteAnswer.equals(IOverwriteQuery.NO_ALL)) {
+          fMonitor.worked(1);
+          overwriteState = OVERWRITE_NONE;
+          return;
+        }
+
+        if (overwriteAnswer.equals(IOverwriteQuery.ALL))
+          overwriteState = OVERWRITE_ALL;
+      }
+    }
+
+    try {
+      setExporters(file);
+      fExporter2.write(file, fullPath);
+    } catch (IOException e) {
+      errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, ObfuscatorExportMessages.format("ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+      new Object[] { fullPath, e.getMessage()}), e));
+    } catch (CoreException e) {
+      errorTable.add(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, ObfuscatorExportMessages.format("ObfuscatorTransfer.errorExporting", //$NON-NLS-1$
+      new Object[] { fullPath, e.getMessage()}), e));
+    }
+
+    fMonitor.worked(1);
+    ModalContext.checkCanceled(fMonitor);
+  }
+
+  protected void exportSpecifiedResources1() throws InterruptedException {
+    Iterator resources = fResourcesToExport.iterator();
+    IPath initPath = (IPath) fPath.clone();
+
+    while (resources.hasNext()) {
+      IResource currentResource = (IResource) resources.next();
+      if (!currentResource.isAccessible())
+        continue;
+      setExporters(currentResource);
+      fPath = initPath;
+
+      if (fResource == null) {
+        // No root resource specified and creation of containment directories
+        // is required.  Create containers from depth 2 onwards (ie.- project's
+        // child inclusive) for each resource being exported.
+        //        if (createLeadupStructure)
+        //          createLeadupDirectoriesFor(currentResource);
+
+      } else {
+        // Root resource specified.  Must create containment directories
+        // from this point onwards for each resource being exported
+        IPath containersToCreate =
+          currentResource.getFullPath().removeFirstSegments(fResource.getFullPath().segmentCount()).removeLastSegments(1);
+
+        for (int i = 0; i < containersToCreate.segmentCount(); i++) {
+          fPath = fPath.append(containersToCreate.segment(i));
+          fExporter1.createFolder(fPath);
+        }
+      }
+
+      if (currentResource.getType() == IResource.FILE)
+        exportFile1((IFile) currentResource, fPath);
+      else {
+        if (createContainerDirectories) {
+          fPath = fPath.append(currentResource.getName());
+          fExporter1.createFolder(fPath);
+        }
+
+        try {
+          exportChildren1(((IContainer) currentResource).members(), fPath);
+        } catch (CoreException e) {
+          // should never happen because #isAccessible is called before #members is invoked,
+          // which implicitly does an existence check
+          errorTable.add(e.getStatus());
+        }
+      }
+    }
+  }
+  /**
+   *   Export the resources contained in the previously-defined
+   *   resourcesToExport collection
+   */
+  protected void exportSpecifiedResources2() throws InterruptedException {
+    Iterator resources = fResourcesToExport.iterator();
+    IPath initPath = (IPath) fPath.clone();
+
+    while (resources.hasNext()) {
+      IResource currentResource = (IResource) resources.next();
+      if (!currentResource.isAccessible())
+        continue;
+      setExporters(currentResource);
+
+      fPath = initPath;
+
+      if (fResource == null) {
+        // No root resource specified and creation of containment directories
+        // is required.  Create containers from depth 2 onwards (ie.- project's
+        // child inclusive) for each resource being exported.
+        //        if (createLeadupStructure)
+        //          createLeadupDirectoriesFor(currentResource);
+
+      } else {
+        // Root resource specified.  Must create containment directories
+        // from this point onwards for each resource being exported
+        IPath containersToCreate =
+          currentResource.getFullPath().removeFirstSegments(fResource.getFullPath().segmentCount()).removeLastSegments(1);
+
+        for (int i = 0; i < containersToCreate.segmentCount(); i++) {
+          fPath = fPath.append(containersToCreate.segment(i));
+          fExporter2.createFolder(fPath);
+        }
+      }
+
+      if (currentResource.getType() == IResource.FILE)
+        exportFile2((IFile) currentResource, fPath);
+      else {
+        if (createContainerDirectories) {
+          fPath = fPath.append(currentResource.getName());
+          fExporter2.createFolder(fPath);
+        }
+
+        try {
+          exportChildren2(((IContainer) currentResource).members(), fPath);
+        } catch (CoreException e) {
+          // should never happen because #isAccessible is called before #members is invoked,
+          // which implicitly does an existence check
+          errorTable.add(e.getStatus());
+        }
+      }
+    }
+  }
+  /**
+   * Returns the status of the export operation.
+   * If there were any errors, the result is a status object containing
+   * individual status objects for each error.
+   * If there were no errors, the result is a status object with error code <code>OK</code>.
+   *
+   * @return the status
+   */
+  public IStatus getStatus() {
+    IStatus[] errors = new IStatus[errorTable.size()];
+    errorTable.toArray(errors);
+    return new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, errors, ObfuscatorExportMessages.getString("ObfuscatorExportOperation.problemsExporting"), //$NON-NLS-1$
+    null);
+  }
+  /**
+   *  Answer a boolean indicating whether the passed child is a descendent
+   *  of one or more members of the passed resources collection
+   *
+   *  @return boolean
+   *  @param resources java.util.List
+   *  @param child org.eclipse.core.resources.IResource
+   */
+  protected boolean isDescendent(List resources, IResource child) {
+    if (child.getType() == IResource.PROJECT)
+      return false;
+
+    IResource parent = child.getParent();
+    if (resources.contains(parent))
+      return true;
+
+    return isDescendent(resources, parent);
+  }
+
+  private void setExporters(IResource resource) {
+    if (fCurrentIdentifierMap == null) {
+      if (fProjectMap == null) {
+        fProjectMap = new HashMap();
+      }
+      createExporters(resource);
+    } else {
+      IProject project = resource.getProject();
+      if (!fCurrentProjectName.equals(project.getName())) {
+        HashMap temp = (HashMap) fProjectMap.get(project.getName());
+        if (temp != null) {
+          fCurrentProjectName = project.getName();
+          fCurrentIdentifierMap = temp;
+          fExporter1 = new ObfuscatorPass1Exporter(new Scanner(false, false), fCurrentIdentifierMap);
+          fExporter2 = new ObfuscatorPass2Exporter(new Scanner(true, true), fCurrentIdentifierMap);
+          return;
+        }
+        createExporters(resource);
+      }
+    }
+  }
+
+  private void createExporters(IResource resource) {
+    IProject project = resource.getProject();
+    IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
+    ObfuscatorIgnores ignore = new ObfuscatorIgnores(project);
+    fCurrentIdentifierMap = ignore.getIdentifierMap();
+    fCurrentProjectName = project.getName();
+    fProjectMap.put(fCurrentProjectName, fCurrentIdentifierMap);
+    fExporter1 = new ObfuscatorPass1Exporter(new Scanner(false, false), fCurrentIdentifierMap);
+    fExporter2 = new ObfuscatorPass2Exporter(new Scanner(true, true), fCurrentIdentifierMap);
+  }
+  /**
+   *   Export the resources that were previously specified for export
+   *   (or if a single resource was specified then export it recursively)
+   */
+  public void run(IProgressMonitor monitor) throws InterruptedException {
+    this.fMonitor = monitor;
+    final IPath tempPath = (IPath) fPath.clone();
+    if (fResource != null) {
+      setExporters(fResource);
+      //      if (createLeadupStructure)
+      //        createLeadupDirectoriesFor(resource);
+
+      if (createContainerDirectories && fResource.getType() != IResource.FILE) {
+        // ensure it's a container
+        fPath = fPath.append(fResource.getName());
+        fExporter2.createFolder(fPath);
+      }
+    }
+
+    try {
+       // reset variables for this run:
+       fCurrentIdentifierMap = null;
+       fProjectMap = null;
+       fCurrentProjectName = "";
+       
+       // count number of files
+      int totalWork = IProgressMonitor.UNKNOWN;
+      try {
+        if (fResourcesToExport == null) {
+          totalWork = countChildrenOf(fResource);
+        } else {
+          totalWork = countSelectedResources();
+        }
+      } catch (CoreException e) {
+        // Should not happen
+        errorTable.add(e.getStatus());
+      }
+      monitor.beginTask(ObfuscatorExportMessages.getString("ObfuscatorTransfer.exportingTitle1"), totalWork); //$NON-NLS-1$
+      if (fResourcesToExport == null) {
+        exportAllResources1();
+      } else {
+        exportSpecifiedResources1();
+      }
+
+      //      try {
+      //        if (resourcesToExport == null)
+      //          totalWork = countChildrenOf(resource);
+      //        else
+      //          totalWork = countSelectedResources();
+      //      } catch (CoreException e) {
+      //        // Should not happen
+      //        errorTable.add(e.getStatus());
+      //      }
+
+      // reset path:
+      fPath = tempPath;
+      monitor.beginTask(ObfuscatorExportMessages.getString("ObfuscatorTransfer.exportingTitle2"), totalWork); //$NON-NLS-1$
+      if (fResourcesToExport == null) {
+        exportAllResources2();
+      } else {
+        exportSpecifiedResources2();
+      }
+    } finally {
+      monitor.done();
+    }
+  }
+  /**
+   *   Set this boolean indicating whether a directory should be created for
+   *   Folder resources that are explicitly passed for export
+   *
+   *   @param value boolean
+   */
+  //  public void setCreateContainerDirectories(boolean value) {
+  //    createContainerDirectories = value;
+  //  }
+  /**
+   *   Set this boolean indicating whether each exported resource's complete path should
+   *   include containment hierarchies as dictated by its parents
+   *
+   *   @param value boolean
+   */
+  //  public void setCreateLeadupStructure(boolean value) {
+  //    createLeadupStructure = value;
+  //  }
+  /**
+   *   Set this boolean indicating whether exported resources should automatically
+   *   overwrite existing files when a conflict occurs. If not
+   *   query the user.
+   *
+   *   @param value boolean
+   */
+  public void setOverwriteFiles(boolean value) {
+    if (value)
+      overwriteState = OVERWRITE_ALL;
+  }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportWizard.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/ObfuscatorExportWizard.java
new file mode 100644 (file)
index 0000000..28eb3f8
--- /dev/null
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IExportWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+/**
+ * Standard workbench wizard for exporting resources from the workspace
+ * to the local file system.
+ * <p>
+ * This class may be instantiated and used without further configuration;
+ * this class is not intended to be subclassed.
+ * </p>
+ * <p>
+ * Example:
+ * <pre>
+ * IWizard wizard = new ObfuscatorExportWizard();
+ * wizard.init(workbench, selection);
+ * WizardDialog dialog = new WizardDialog(shell, wizard);
+ * dialog.open();
+ * </pre>
+ * During the call to <code>open</code>, the wizard dialog is presented to the
+ * user. When the user hits Finish, the user-selected workspace resources 
+ * are exported to the user-specified location in the local file system,
+ * the dialog closes, and the call to <code>open</code> returns.
+ * </p>
+ */
+public class ObfuscatorExportWizard extends Wizard implements IExportWizard {
+       private IWorkbench workbench;
+       private IStructuredSelection selection;
+       private WizardObfuscatorResourceExportPage1 mainPage;
+/**
+ * Creates a wizard for exporting workspace resources to the local file system.
+ */
+public ObfuscatorExportWizard() {
+       AbstractUIPlugin plugin = (AbstractUIPlugin) Platform.getPlugin(PlatformUI.PLUGIN_ID);
+       IDialogSettings workbenchSettings = plugin.getDialogSettings();
+       IDialogSettings section = workbenchSettings.getSection("ObfuscatorExportWizard");//$NON-NLS-1$
+       if(section == null)
+               section = workbenchSettings.addNewSection("ObfuscatorExportWizard");//$NON-NLS-1$
+       setDialogSettings(section);
+}
+/* (non-Javadoc)
+ * Method declared on IWizard.
+ */
+public void addPages() {
+       super.addPages();
+       mainPage = new WizardObfuscatorResourceExportPage1(selection);
+       addPage(mainPage);
+}
+/**
+ * Returns the image descriptor with the given relative path.
+ */
+private ImageDescriptor getImageDescriptor(String relativePath) {
+       String iconPath = "icons/full/";//$NON-NLS-1$   
+       try {
+               AbstractUIPlugin plugin = (AbstractUIPlugin) Platform.getPlugin(PlatformUI.PLUGIN_ID);
+               URL installURL = plugin.getDescriptor().getInstallURL();
+               URL url = new URL(installURL, iconPath + relativePath);
+               return ImageDescriptor.createFromURL(url);
+       }
+       catch (MalformedURLException e) {
+               // Should not happen
+               return null;
+       }
+}
+/* (non-Javadoc)
+ * Method declared on IWorkbenchWizard.
+ */
+public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
+       this.workbench = workbench;
+       
+       
+       //Make it the current selection by default but look it up otherwise
+       
+       selection = currentSelection;
+       
+       if(currentSelection.isEmpty() && workbench.getActiveWorkbenchWindow() != null){
+               IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage();
+               if(page != null){
+                       IEditorPart currentEditor = page.getActiveEditor();
+                       if(currentEditor != null){
+                               Object selectedResource = currentEditor.getEditorInput().getAdapter(IResource.class);
+                               if(selectedResource != null)
+                               selection = new StructuredSelection(selectedResource);
+                       }
+               }
+       }
+
+       setWindowTitle(ObfuscatorExportMessages.getString("ObfuscatorTransfer.export")); //$NON-NLS-1$
+       setDefaultPageImageDescriptor(getImageDescriptor("wizban/exportdir_wiz.gif"));//$NON-NLS-1$
+       setNeedsProgressMonitor(true);
+}
+/* (non-Javadoc)
+ * Method declared on IWizard.
+ */
+public boolean performFinish() {
+       return mainPage.finish();
+}
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/WizardObfuscatorResourceExportPage1.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/WizardObfuscatorResourceExportPage1.java
new file mode 100644 (file)
index 0000000..2b0c9e2
--- /dev/null
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.obfuscator.export;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.dialogs.WizardExportResourcesPage;
+
+/**
+ *     Page 1 of the base resource export-to-file-system Wizard
+ */
+/*package*/
+class WizardObfuscatorResourceExportPage1
+       extends WizardExportResourcesPage
+       implements Listener {
+
+       // widgets
+       private Combo destinationNameField;
+       private Button destinationBrowseButton;
+       protected Button overwriteExistingFilesCheckbox;
+//     protected Button createDirectoryStructureButton;
+//     protected Button createSelectionOnlyButton;
+
+       // constants
+       private static final int SIZING_TEXT_FIELD_WIDTH = 250;
+
+       // dialog store id constants
+       private static final String STORE_DESTINATION_NAMES_ID =
+               "WizardObfuscatorResourceExportPage1.STORE_DESTINATION_NAMES_ID";       //$NON-NLS-1$
+       private static final String STORE_OVERWRITE_EXISTING_FILES_ID =
+               "WizardObfuscatorResourceExportPage1.STORE_OVERWRITE_EXISTING_FILES_ID";        //$NON-NLS-1$
+//     private static final String STORE_CREATE_STRUCTURE_ID =
+//             "WizardObfuscatorResourceExportPage1.STORE_CREATE_STRUCTURE_ID";        //$NON-NLS-1$
+       //messages
+       private static final String SELECT_DESTINATION_MESSAGE = ObfuscatorExportMessages.getString("FileExport.selectDestinationMessage"); //$NON-NLS-1$
+       private static final String SELECT_DESTINATION_TITLE = ObfuscatorExportMessages.getString("FileExport.selectDestinationTitle"); //$NON-NLS-1$
+       /**
+        *      Create an instance of this class
+        */
+       protected WizardObfuscatorResourceExportPage1(
+               String name,
+               IStructuredSelection selection) {
+               super(name, selection);
+       }
+       /**
+        *      Create an instance of this class
+        */
+       public WizardObfuscatorResourceExportPage1(IStructuredSelection selection) {
+               this("fileSystemExportPage1", selection); //$NON-NLS-1$
+               setTitle(ObfuscatorExportMessages.getString("ObfuscatorTransfer.fileSystemTitle")); //$NON-NLS-1$
+               setDescription(ObfuscatorExportMessages.getString("FileExport.exportLocalFileSystem")); //$NON-NLS-1$
+       }
+       /**
+        *      Add the passed value to self's destination widget's history
+        *
+        *      @param value java.lang.String
+        */
+       protected void addDestinationItem(String value) {
+               destinationNameField.add(value);
+       }
+       /** (non-Javadoc)
+        * Method declared on IDialogPage.
+        */
+       public void createControl(Composite parent) {
+               super.createControl(parent);
+               giveFocusToDestination();
+//             WorkbenchHelp.setHelp(
+//                     getControl(),
+//                     IDataTransferHelpContextIds.FILE_SYSTEM_EXPORT_WIZARD_PAGE);
+       }
+       /**
+        *      Create the export destination specification widgets
+        *
+        *      @param parent org.eclipse.swt.widgets.Composite
+        */
+       protected void createDestinationGroup(Composite parent) {
+
+               Font font = parent.getFont();
+               // destination specification group
+               Composite destinationSelectionGroup = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout();
+               layout.numColumns = 3;
+               destinationSelectionGroup.setLayout(layout);
+               destinationSelectionGroup.setLayoutData(
+                       new GridData(
+                               GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+               destinationSelectionGroup.setFont(font);
+
+               Label destinationLabel = new Label(destinationSelectionGroup, SWT.NONE);
+               destinationLabel.setText(getDestinationLabel());
+               destinationLabel.setFont(font);
+
+               // destination name entry field
+               destinationNameField =
+                       new Combo(destinationSelectionGroup, SWT.SINGLE | SWT.BORDER);
+               destinationNameField.addListener(SWT.Modify, this);
+               destinationNameField.addListener(SWT.Selection, this);
+               GridData data =
+                       new GridData(
+                               GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
+               data.widthHint = SIZING_TEXT_FIELD_WIDTH;
+               destinationNameField.setLayoutData(data);
+               destinationNameField.setFont(font);
+
+               // destination browse button
+               destinationBrowseButton =
+                       new Button(destinationSelectionGroup, SWT.PUSH);
+               destinationBrowseButton.setText(ObfuscatorExportMessages.getString("ObfuscatorTransfer.browse")); //$NON-NLS-1$
+               destinationBrowseButton.addListener(SWT.Selection, this);
+               destinationBrowseButton.setFont(font);
+               setButtonLayoutData(destinationBrowseButton);
+
+               new Label(parent, SWT.NONE); // vertical spacer
+       }
+
+       /**
+        * Create the buttons in the options group.
+        */
+
+       protected void createOptionsGroupButtons(Group optionsGroup) {
+
+               Font font = optionsGroup.getFont();
+               createOverwriteExisting(optionsGroup, font);
+
+//             createDirectoryStructureOptions(optionsGroup, font);
+       }
+
+       /**
+        * Create the buttons for the group that determine if the entire or
+        * selected directory structure should be created.
+        * @param optionsGroup
+        * @param font
+        */
+//     protected void createDirectoryStructureOptions(
+//             Group optionsGroup,
+//             Font font) {
+//             // create directory structure radios
+//             createDirectoryStructureButton =
+//                     new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
+//             createDirectoryStructureButton.setText(ObfuscatorExportMessages.getString("FileExport.createDirectoryStructure")); //$NON-NLS-1$
+//             createDirectoryStructureButton.setSelection(false);
+//             createDirectoryStructureButton.setFont(font);
+//
+//             // create directory structure radios
+//             createSelectionOnlyButton =
+//                     new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
+//             createSelectionOnlyButton.setText(
+//                     ObfuscatorExportMessages.getString(
+//                             "FileExport.createSelectedDirectories"));//$NON-NLS-1$
+//             createSelectionOnlyButton.setSelection(true);
+//             createSelectionOnlyButton.setFont(font);
+//     }
+
+       /**
+        * Create the button for checking if we should ask if we are going to
+        * overwrite existing files.
+        * @param optionsGroup
+        * @param font
+        */
+       protected void createOverwriteExisting(Group optionsGroup, Font font) {
+               // overwrite... checkbox
+               overwriteExistingFilesCheckbox =
+                       new Button(optionsGroup, SWT.CHECK | SWT.LEFT);
+               overwriteExistingFilesCheckbox.setText(ObfuscatorExportMessages.getString("ExportFile.overwriteExisting")); //$NON-NLS-1$
+               overwriteExistingFilesCheckbox.setFont(font);
+       }
+
+       /**
+        * Attempts to ensure that the specified directory exists on the local file system.
+        * Answers a boolean indicating success.
+        *
+        * @return boolean
+        * @param directory java.io.File
+        */
+       protected boolean ensureDirectoryExists(File directory) {
+               if (!directory.exists()) {
+                       if (!queryYesNoQuestion(ObfuscatorExportMessages.getString("ObfuscatorTransfer.createTargetDirectory"))) //$NON-NLS-1$
+                               return false;
+
+                       if (!directory.mkdirs()) {
+                               displayErrorDialog(ObfuscatorExportMessages.getString("ObfuscatorTransfer.directoryCreationError")); //$NON-NLS-1$
+                               giveFocusToDestination();
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+       /**
+        *      If the target for export does not exist then attempt to create it.
+        *      Answer a boolean indicating whether the target exists (ie.- if it
+        *      either pre-existed or this method was able to create it)
+        *
+        *      @return boolean
+        */
+       protected boolean ensureTargetIsValid(File targetDirectory) {
+               if (targetDirectory.exists() && !targetDirectory.isDirectory()) {
+                       displayErrorDialog(ObfuscatorExportMessages.getString("FileExport.directoryExists")); //$NON-NLS-1$
+                       giveFocusToDestination();
+                       return false;
+               }
+
+               return ensureDirectoryExists(targetDirectory);
+       }
+       /**
+        *  Set up and execute the passed Operation.  Answer a boolean indicating success.
+        *
+        *  @return boolean
+        */
+       protected boolean executeExportOperation(ObfuscatorExportOperation op) {
+//             op.setCreateLeadupStructure(
+//                     createDirectoryStructureButton.getSelection());
+               op.setOverwriteFiles(overwriteExistingFilesCheckbox.getSelection());
+
+               try {
+                       getContainer().run(true, true, op);
+               } catch (InterruptedException e) {
+                       return false;
+               } catch (InvocationTargetException e) {
+                       displayErrorDialog(e.getTargetException());
+                       return false;
+               }
+
+               IStatus status = op.getStatus();
+               if (!status.isOK()) {
+                       ErrorDialog.openError(getContainer().getShell(), ObfuscatorExportMessages.getString("ObfuscatorTransfer.exportProblems"), //$NON-NLS-1$
+                       null, // no special message
+                       status);
+                       return false;
+               }
+
+               return true;
+       }
+       /**
+        *      The Finish button was pressed.  Try to do the required work now and answer
+        *      a boolean indicating success.  If false is returned then the wizard will
+        *      not close.
+        *
+        *      @return boolean
+        */
+       public boolean finish() {
+               if (!ensureTargetIsValid(new File(getDestinationValue())))
+                       return false;
+
+               List resourcesToExport = getWhiteCheckedResources();
+
+               //Save dirty editors if possible but do not stop if not all are saved
+               saveDirtyEditors();
+               // about to invoke the operation so save our state
+               saveWidgetValues();
+
+               if (resourcesToExport.size() > 0)
+                       return executeExportOperation(
+                               new ObfuscatorExportOperation(
+                                       null,
+                                       resourcesToExport,
+                                       getDestinationValue(),
+                                       this));
+
+               MessageDialog.openInformation(getContainer().getShell(), ObfuscatorExportMessages.getString("ObfuscatorTransfer.information"), //$NON-NLS-1$
+               ObfuscatorExportMessages.getString("FileExport.noneSelected")); //$NON-NLS-1$
+
+               return false;
+       }
+       /**
+        *      Answer the string to display in self as the destination type
+        *
+        *      @return java.lang.String
+        */
+       protected String getDestinationLabel() {
+               return ObfuscatorExportMessages.getString("FileExport.toDirectory"); //$NON-NLS-1$
+       }
+       /**
+        *      Answer the contents of self's destination specification widget
+        *
+        *      @return java.lang.String
+        */
+       protected String getDestinationValue() {
+               return destinationNameField.getText().trim();
+       }
+       /**
+        *      Set the current input focus to self's destination entry field
+        */
+       protected void giveFocusToDestination() {
+               destinationNameField.setFocus();
+       }
+       /**
+        *      Open an appropriate destination browser so that the user can specify a source
+        *      to import from
+        */
+       protected void handleDestinationBrowseButtonPressed() {
+               DirectoryDialog dialog =
+                       new DirectoryDialog(getContainer().getShell(), SWT.SAVE);
+               dialog.setMessage(SELECT_DESTINATION_MESSAGE);
+               dialog.setText(SELECT_DESTINATION_TITLE);
+               dialog.setFilterPath(getDestinationValue());
+               String selectedDirectoryName = dialog.open();
+
+               if (selectedDirectoryName != null) {
+                       setErrorMessage(null);
+                       setDestinationValue(selectedDirectoryName);
+               }
+       }
+       /**
+        * Handle all events and enablements for widgets in this page
+        * @param e Event
+        */
+       public void handleEvent(Event e) {
+               Widget source = e.widget;
+
+               if (source == destinationBrowseButton)
+                       handleDestinationBrowseButtonPressed();
+
+               updatePageCompletion();
+       }
+       /**
+        *      Hook method for saving widget values for restoration by the next instance
+        *      of this class.
+        */
+       protected void internalSaveWidgetValues() {
+               // update directory names history
+               IDialogSettings settings = getDialogSettings();
+               if (settings != null) {
+                       String[] directoryNames =
+                               settings.getArray(STORE_DESTINATION_NAMES_ID);
+                       if (directoryNames == null)
+                               directoryNames = new String[0];
+
+                       directoryNames =
+                               addToHistory(directoryNames, getDestinationValue());
+                       settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
+
+                       // options
+                       settings.put(
+                               STORE_OVERWRITE_EXISTING_FILES_ID,
+                               overwriteExistingFilesCheckbox.getSelection());
+
+//                     settings.put(
+//                             STORE_CREATE_STRUCTURE_ID,
+//                             createDirectoryStructureButton.getSelection());
+
+               }
+       }
+       /**
+        *      Hook method for restoring widget values to the values that they held
+        *      last time this wizard was used to completion.
+        */
+       protected void restoreWidgetValues() {
+               IDialogSettings settings = getDialogSettings();
+               if (settings != null) {
+                       String[] directoryNames =
+                               settings.getArray(STORE_DESTINATION_NAMES_ID);
+                       if (directoryNames == null)
+                               return; // ie.- no settings stored
+
+                       // destination
+                       setDestinationValue(directoryNames[0]);
+                       for (int i = 0; i < directoryNames.length; i++)
+                               addDestinationItem(directoryNames[i]);
+
+                       // options
+                       overwriteExistingFilesCheckbox.setSelection(
+                               settings.getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID));
+
+//                     boolean createDirectories =
+//                             settings.getBoolean(STORE_CREATE_STRUCTURE_ID);
+//                     createDirectoryStructureButton.setSelection(createDirectories);
+//                     createSelectionOnlyButton.setSelection(!createDirectories);
+               }
+       }
+       /**
+        *      Set the contents of the receivers destination specification widget to
+        *      the passed value
+        *
+        */
+       protected void setDestinationValue(String value) {
+               destinationNameField.setText(value);
+       }
+       /**
+        *      Answer a boolean indicating whether the receivers destination specification
+        *      widgets currently all contain valid values.
+        */
+       protected boolean validateDestinationGroup() {
+               String destinationValue = getDestinationValue();
+               if (destinationValue.length() == 0) {
+                       setMessage(destinationEmptyMessage());
+                       return false;
+               }
+
+               String conflictingContainer =
+                       getConflictingContainerNameFor(destinationValue);
+               if (conflictingContainer == null)
+                       setErrorMessage(""); //$NON-NLS-1$
+               else {
+                       setErrorMessage(ObfuscatorExportMessages.format("FileExport.conflictingContainer", //$NON-NLS-1$
+                       new Object[] { conflictingContainer }));
+                       giveFocusToDestination();
+                       return false;
+               }
+
+               return true;
+       }
+       
+       /**
+        * Get the message used to denote an empty destination.
+        */
+       protected String destinationEmptyMessage(){
+               return ObfuscatorExportMessages.getString("FileExport.destinationEmpty"); //$NON-NLS-1$
+       }
+
+       /**
+        * Returns the name of a container with a location that encompasses targetDirectory.
+        * Returns null if there is no conflict.
+        * 
+        * @param targetDirectory the path of the directory to check.
+        * @return the conflicting container name or <code>null</code>
+        */
+       protected String getConflictingContainerNameFor(String targetDirectory) {
+
+               IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+               IPath testPath = new Path(targetDirectory);
+
+               if (root.getLocation().isPrefixOf(testPath))
+                       return ObfuscatorExportMessages.getString("FileExport.rootName"); //$NON-NLS-1$
+
+               IProject[] projects = root.getProjects();
+
+               for (int i = 0; i < projects.length; i++) {
+                       if (projects[i].getLocation().isPrefixOf(testPath))
+                               return projects[i].getName();
+               }
+
+               return null;
+
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/obfuscator/export/messages.properties
new file mode 100644 (file)
index 0000000..baaf49d
--- /dev/null
@@ -0,0 +1,64 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# package: org.eclipse.ui.wizards.ObfuscatorTransfer
+
+# ==============================================================================
+# Data Transfer Wizards
+# ==============================================================================
+ObfuscatorTransfer.fileSystemTitle = File system
+
+ObfuscatorTransfer.browse = B&rowse...
+ObfuscatorTransfer.selectTypes = Filter &Types...
+ObfuscatorTransfer.selectAll = &Select All
+ObfuscatorTransfer.deselectAll = &Deselect All
+
+ObfuscatorTransfer.typeDelimiter = ,
+ObfuscatorTransfer.allFiles = All files matching this criteria
+ObfuscatorTransfer.oneSelected = 1 file selected
+ObfuscatorTransfer.details = Details...
+ObfuscatorTransfer.allTypes = All types
+
+ObfuscatorTransfer.cannotOverwrite = Cannot overwrite file: {0}
+ObfuscatorTransfer.emptyString = 
+ObfuscatorTransfer.scanningChildren = Scanning for children...
+ObfuscatorTransfer.scanningMatching = Scanning for matching files...
+ObfuscatorTransfer.information = Information
+
+# --- Export Wizards ---
+ObfuscatorTransfer.export = Obfuscator Export
+
+ObfuscatorTransfer.exportingTitle1 = Obfuscating Pass 1:
+ObfuscatorTransfer.exportingTitle2 = Obfuscating Pass 2:
+ObfuscatorTransfer.selectDestination = Select the destination directory.
+ObfuscatorTransfer.directory = Director&y:
+ObfuscatorTransfer.createTargetDirectory = Target directory does not exist.  Would you like to create it?
+ObfuscatorTransfer.directoryCreationError = Target directory could not be created.
+ObfuscatorTransfer.errorExporting = Error exporting {0}: {1}
+ObfuscatorTransfer.exportProblems = Export Problems
+
+ExportFile.overwriteExisting = &Overwrite existing files without warning
+ExportFile.createDirectoriesForSelected = Create directories for selected folders
+ExportFile.createDirectoryStructure = &Create directory structure
+
+FileExport.selectDestinationTitle= Export To Directory
+FileExport.selectDestinationMessage=Select a directory to export to.
+FileExport.exportLocalFileSystem = Export obfuscated PHP resources to the local file system.
+FileExport.destinationEmpty = Please enter a destination directory.
+FileExport.createDirectoryStructure = &Create directory structure for files
+FileExport.createSelectedDirectories = Create on&ly selected directories
+FileExport.noneSelected = There are no resources currently selected for export.
+FileExport.directoryExists = Target directory already exists as a file.
+FileExport.conflictingContainer = Destination directory conflicts with location of {0}.
+FileExport.rootName = workspace root
+ObfuscatorExportOperation.problemsExporting = Problems were encountered during export:
+FileExport.toDirectory = To director&y:
index c6ed4c2..a9e0ebc 100644 (file)
@@ -10,16 +10,44 @@ Contributors:
 **********************************************************************/
 package net.sourceforge.phpeclipse.phpeditor;
 
+import org.eclipse.jface.text.Assert;
+
 public final class AnnotationType {
        
-       public final static AnnotationType ALL= new AnnotationType();
-       public final static AnnotationType UNKNOWN= new AnnotationType();
-       public final static AnnotationType BOOKMARK= new AnnotationType();
-       public final static AnnotationType TASK= new AnnotationType();
-       public final static AnnotationType ERROR= new AnnotationType();
-       public final static AnnotationType WARNING= new AnnotationType();
-       public final static AnnotationType SEARCH_RESULT= new AnnotationType();
+       public static final AnnotationType ALL= new AnnotationType();
+       public static final AnnotationType UNKNOWN= new AnnotationType();
+       public static final AnnotationType BOOKMARK= new AnnotationType();
+       public static final AnnotationType TASK= new AnnotationType();
+       public static final AnnotationType ERROR= new AnnotationType();
+       public static final AnnotationType WARNING= new AnnotationType();
+       public static final AnnotationType SEARCH= new AnnotationType();
        
        private AnnotationType() {
        }
-}
+
+       public String toString() {
+               if (this == ALL)
+                       return "AnnotationType.ALL"; //$NON-NLS-1$
+               
+               if (this == UNKNOWN)
+                       return "AnnotationType.UNKNOWN"; //$NON-NLS-1$
+
+               if (this == BOOKMARK)
+                       return "AnnotationType.BOOKMARK"; //$NON-NLS-1$
+
+               if (this == TASK)
+                       return "AnnotationType.TASK"; //$NON-NLS-1$
+               
+               if (this == ERROR)
+                       return "AnnotationType.ERROR"; //$NON-NLS-1$
+
+               if (this == WARNING)
+                       return "AnnotationType.WARNING"; //$NON-NLS-1$
+
+               if (this == SEARCH)
+                       return "AnnotationType.SEARCH"; //$NON-NLS-1$
+
+               Assert.isLegal(false);
+               return ""; //$NON-NLS-1$
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/EditorUtility.java
new file mode 100644 (file)
index 0000000..2cff713
--- /dev/null
@@ -0,0 +1,362 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+/**
+ * A number of routines for working with JavaElements in editors
+ *
+ * Use 'isOpenInEditor' to test if an element is already open in a editor  
+ * Use 'openInEditor' to force opening an element in a editor
+ * With 'getWorkingCopy' you get the working copy (element in the editor) of an element
+ */
+public class EditorUtility {
+       
+       
+       public static boolean isEditorInput(Object element, IEditorPart editor) {
+               if (editor != null) {
+//                     try {
+                               return editor.getEditorInput().equals(getEditorInput(element));
+//                     } catch (JavaModelException x) {
+//                             JavaPlugin.log(x.getStatus());
+//                     }
+               }
+               return false;
+       }
+       
+       /** 
+        * Tests if a cu is currently shown in an editor
+        * @return the IEditorPart if shown, null if element is not open in an editor
+        */     
+       public static IEditorPart isOpenInEditor(Object inputElement) {
+               IEditorInput input= null;
+               
+//             try {
+                       input= getEditorInput(inputElement);
+//             } catch (JavaModelException x) {
+//                     JavaPlugin.log(x.getStatus());
+//             }
+               
+               if (input != null) {
+                       IWorkbenchPage p= PHPeclipsePlugin.getActivePage();
+                       if (p != null) {
+                               return p.findEditor(input);
+                       }
+               }
+               
+               return null;
+       }
+       
+       /**
+        * Opens a Java editor for an element such as <code>IJavaElement</code>, <code>IFile</code>, or <code>IStorage</code>.
+        * The editor is activated by default.
+        * @return the IEditorPart or null if wrong element type or opening failed
+        */
+       public static IEditorPart openInEditor(Object inputElement) throws JavaModelException, PartInitException {
+               return openInEditor(inputElement, true);
+       }
+               
+       /**
+        * Opens a Java editor for an element (IJavaElement, IFile, IStorage...)
+        * @return the IEditorPart or null if wrong element type or opening failed
+        */
+       public static IEditorPart openInEditor(Object inputElement, boolean activate) throws JavaModelException, PartInitException {
+               
+               if (inputElement instanceof IFile)
+                       return openInEditor((IFile) inputElement, activate);
+               
+               IEditorInput input= getEditorInput(inputElement);
+               if (input instanceof IFileEditorInput) {
+                       IFileEditorInput fileInput= (IFileEditorInput) input;
+                       return openInEditor(fileInput.getFile(), activate);
+               }
+               
+               if (input != null)
+                       return openInEditor(input, getEditorID(input, inputElement), activate);
+                       
+               return null;
+       }
+       
+       /** 
+        * Selects a Java Element in an editor
+        */     
+//     public static void revealInEditor(IEditorPart part, IJavaElement element) {
+//             if (element != null && part instanceof PHPEditor) {
+//                     ((PHPEditor) part).setSelection(element);
+//             }
+//     }
+       
+       private static IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException {
+               if (file != null) {
+                       IWorkbenchPage p= PHPeclipsePlugin.getActivePage();
+                       if (p != null) {
+                               IEditorPart editorPart= p.openEditor(file, null, activate);
+                               initializeHighlightRange(editorPart);
+                               return editorPart;
+                       }
+               }
+               return null;
+       }
+
+       private static IEditorPart openInEditor(IEditorInput input, String editorID, boolean activate) throws PartInitException {
+               if (input != null) {
+                       IWorkbenchPage p= PHPeclipsePlugin.getActivePage();
+                       if (p != null) {
+                               IEditorPart editorPart= p.openEditor(input, editorID, activate);
+                               initializeHighlightRange(editorPart);
+                               return editorPart;
+                       }
+               }
+               return null;
+       }
+
+       private static void initializeHighlightRange(IEditorPart editorPart) {
+               if (editorPart instanceof ITextEditor) {
+                       TogglePresentationAction toggleAction= new TogglePresentationAction();
+                       // Initialize editor
+                       toggleAction.setEditor((ITextEditor)editorPart);
+                       // Reset action
+                       toggleAction.setEditor(null);
+               }
+       }
+       
+       /**
+        *@deprecated   Made it public again for java debugger UI.
+        */
+       public static String getEditorID(IEditorInput input, Object inputObject) {
+               IEditorRegistry registry= PlatformUI.getWorkbench().getEditorRegistry();
+               IEditorDescriptor descriptor= registry.getDefaultEditor(input.getName());
+               if (descriptor != null)
+                       return descriptor.getId();
+               return null;
+       }
+       
+//     private static IEditorInput getEditorInput(IJavaElement element) throws JavaModelException {
+//             while (element != null) {
+//                     if (element instanceof IWorkingCopy && ((IWorkingCopy) element).isWorkingCopy()) 
+//                             element= ((IWorkingCopy) element).getOriginalElement();
+//                             
+//                     if (element instanceof ICompilationUnit) {
+//                             ICompilationUnit unit= (ICompilationUnit) element;
+//                                     IResource resource= unit.getResource();
+//                                     if (resource instanceof IFile)
+//                                             return new FileEditorInput((IFile) resource);
+//                     }
+//                     
+//                     if (element instanceof IClassFile)
+//                             return new InternalClassFileEditorInput((IClassFile) element);
+//                     
+//                     element= element.getParent();
+//             }
+//             
+//             return null;
+//     }       
+
+       public static IEditorInput getEditorInput(Object input) {
+//             throws JavaModelException {
+       
+               if (input instanceof IJavaElement)
+                       return getEditorInput((IJavaElement) input);
+                       
+               if (input instanceof IFile) 
+                       return new FileEditorInput((IFile) input);
+               
+//             if (input instanceof IStorage) 
+//                     return new JarEntryEditorInput((IStorage)input);
+       
+               return null;
+       }
+       
+       /**
+        * If the current active editor edits a java element return it, else
+        * return null
+        */
+       public static IJavaElement getActiveEditorJavaInput() {
+               IWorkbenchPage page= PHPeclipsePlugin.getActivePage();
+               if (page != null) {
+                       IEditorPart part= page.getActiveEditor();
+                       if (part != null) {
+                               IEditorInput editorInput= part.getEditorInput();
+                               if (editorInput != null) {
+                                       return (IJavaElement)editorInput.getAdapter(IJavaElement.class);
+                               }
+                       }
+               }
+               return null;    
+       }
+       
+       /** 
+        * Gets the working copy of an compilation unit opened in an editor
+        * @param part the editor part
+        * @param cu the original compilation unit (or another working copy)
+        * @return the working copy of the compilation unit, or null if not found
+        */     
+//     public static ICompilationUnit getWorkingCopy(ICompilationUnit cu) {
+//             if (cu == null)
+//                     return null;
+//             if (cu.isWorkingCopy())
+//                     return cu;
+//                     
+//             return (ICompilationUnit)cu.findSharedWorkingCopy(JavaUI.getBufferFactory());
+//     }
+       
+       /** 
+        * Gets the working copy of an member opened in an editor
+        *
+        * @param member the original member or a member in a working copy
+        * @return the corresponding member in the shared working copy or <code>null</code> if not found
+        */     
+//     public static IMember getWorkingCopy(IMember member) throws JavaModelException {
+//             ICompilationUnit cu= member.getCompilationUnit();
+//             if (cu != null) {
+//                     ICompilationUnit workingCopy= getWorkingCopy(cu);
+//                     if (workingCopy != null) {
+//                             return JavaModelUtil.findMemberInCompilationUnit(workingCopy, member);
+//                     }
+//             }
+//             return null;
+//     }
+       
+       /**
+        * Returns the compilation unit for the given java element.
+        * @param element the java element whose compilation unit is searched for
+        * @return the compilation unit of the given java element
+        */
+//     private static ICompilationUnit getCompilationUnit(IJavaElement element) {
+//             
+//             if (element == null)
+//                     return null;
+//                     
+//             if (element instanceof IMember)
+//                     return ((IMember) element).getCompilationUnit();
+//             
+//             int type= element.getElementType();
+//             if (IJavaElement.COMPILATION_UNIT == type)
+//                     return (ICompilationUnit) element;
+//             if (IJavaElement.CLASS_FILE == type)
+//                     return null;
+//                     
+//             return getCompilationUnit(element.getParent());
+//     }
+       
+       /** 
+        * Returns the working copy of the given java element.
+        * @param javaElement the javaElement for which the working copyshould be found
+        * @param reconcile indicates whether the working copy must be reconcile prior to searching it
+        * @return the working copy of the given element or <code>null</code> if none
+        */     
+//     public static IJavaElement getWorkingCopy(IJavaElement element, boolean reconcile) throws JavaModelException {
+//             ICompilationUnit unit= getCompilationUnit(element);
+//             if (unit == null)
+//                     return null;
+//                     
+//             if (unit.isWorkingCopy())
+//                     return element;
+//                     
+//             ICompilationUnit workingCopy= getWorkingCopy(unit);
+//             if (workingCopy != null) {
+//                     if (reconcile) {
+//                             synchronized (workingCopy) {
+//                                     workingCopy.reconcile();
+//                                     return JavaModelUtil.findInCompilationUnit(workingCopy, element);
+//                             }
+//                     } else {
+//                                     return JavaModelUtil.findInCompilationUnit(workingCopy, element);
+//                     }
+//             }
+//             
+//             return null;
+//     }
+
+       /**
+        * Maps the localized modifier name to a code in the same
+        * manner as #findModifier.
+        * 
+        * @return the SWT modifier bit, or <code>0</code> if no match was found
+        * @see findModifier
+        * @since 2.1.1
+        */
+       public static int findLocalizedModifier(String token) {
+               if (token == null)
+                       return 0;
+               
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.CTRL)))
+                       return SWT.CTRL;
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT)))
+                       return SWT.SHIFT;
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.ALT)))
+                       return SWT.ALT;
+               if (token.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND)))
+                       return SWT.COMMAND;
+
+               return 0;
+       }
+
+       /**
+        * Returns the modifier string for the given SWT modifier
+        * modifier bits.
+        * 
+        * @param stateMask     the SWT modifier bits
+        * @return the modifier string
+        * @since 2.1.1
+        */
+       public static String getModifierString(int stateMask) {
+               String modifierString= ""; //$NON-NLS-1$
+               if ((stateMask & SWT.CTRL) == SWT.CTRL)
+                       modifierString= appendModifierString(modifierString, SWT.CTRL);
+               if ((stateMask & SWT.ALT) == SWT.ALT)
+                       modifierString= appendModifierString(modifierString, SWT.ALT);
+               if ((stateMask & SWT.SHIFT) == SWT.SHIFT)
+                       modifierString= appendModifierString(modifierString, SWT.SHIFT);
+               if ((stateMask & SWT.COMMAND) == SWT.COMMAND)
+                       modifierString= appendModifierString(modifierString,  SWT.COMMAND);
+               
+               return modifierString;
+       }
+
+       /**
+        * Appends to modifier string of the given SWT modifier bit
+        * to the given modifierString.
+        * 
+        * @param modifierString        the modifier string
+        * @param modifier                      an int with SWT modifier bit
+        * @return the concatenated modifier string
+        * @since 2.1.1
+        */
+       private static String appendModifierString(String modifierString, int modifier) {
+               if (modifierString == null)
+                       modifierString= ""; //$NON-NLS-1$
+               String newModifierString= Action.findModifierString(modifier);
+               if (modifierString.length() == 0)
+                       return newModifierString;
+               return PHPEditorMessages.getFormattedString("EditorUtility.concatModifierStrings", new String[] {modifierString, newModifierString}); //$NON-NLS-1$
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/IJavaAnnotation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/IJavaAnnotation.java
new file mode 100644 (file)
index 0000000..266d368
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Iterator;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Interface of annotations representing markers
+ * and problems.
+ * 
+ * @see org.eclipse.core.resources.IMarker
+ * @see org.eclipse.jdt.core.compiler.IProblem
+ */
+public interface IJavaAnnotation {
+       
+       AnnotationType getAnnotationType();
+       
+       boolean isTemporary();
+       
+       String getMessage();
+       
+       String[] getArguments();
+       
+       int getId();
+       
+       
+       Image getImage(Display display);
+       
+       /**
+        * Returns whether this annotation is relavant.
+        * <p>
+        * If the annotation is overlaid then it is not
+        * relevant. After all overlays have been removed
+        * the annotation might either become relevant again
+        * or stay irrelevant.
+        * </p>
+        * 
+        * @return <code>true</code> if relevant
+        * @see #hasOverlay()
+        */
+       boolean isRelevant();
+       
+       /**
+        * Returns whether this annotation is overlaid.
+        * 
+        * @return <code>true</code> if overlaid
+        */
+       boolean hasOverlay();
+       
+       /**
+        * Returns an iterator for iterating over the
+        * annotation which are overlaid by this annotation.
+        * 
+        * @return an iterator over the overlaid annotaions
+        */
+       Iterator getOverlaidIterator();
+       
+       /**
+        * Adds the given annotation to the list of
+        * annotations which are overlaid by this annotations.
+        *  
+        * @param annotation    the problem annoation
+        */
+       void addOverlaid(IJavaAnnotation annotation);
+       
+       /**
+        * Removes the given annotation from the list of
+        * annotations which are overlaid by this annotation.
+        *  
+        * @param annotation    the problem annoation
+        */
+       void removeOverlaid(IJavaAnnotation annotation);
+       
+       /**
+        * Tells whether this annotation is a problem
+        * annotation.
+        * 
+        * @return <code>true</code> if it is a problem annotation
+        */
+       boolean isProblem();
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationIterator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaAnnotationIterator.java
new file mode 100644 (file)
index 0000000..66b9669
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+
+/**
+ * Filters problems based on their types.
+ */
+public class JavaAnnotationIterator implements Iterator {
+                       
+       private Iterator fIterator;
+       private IJavaAnnotation fNext;
+       private boolean fSkipIrrelevants;
+       
+       public JavaAnnotationIterator(IAnnotationModel model, boolean skipIrrelevants) {
+               fIterator= model.getAnnotationIterator();
+               fSkipIrrelevants= skipIrrelevants;
+               skip();
+       }
+       
+       private void skip() {
+               while (fIterator.hasNext()) {
+                       Object next= fIterator.next();
+                       if (next instanceof IJavaAnnotation) {
+                               IJavaAnnotation a= (IJavaAnnotation) next;
+                               if (fSkipIrrelevants) {
+                                       if (a.isRelevant()) {
+                                               fNext= a;
+                                               return;
+                                       }
+                               } else {
+                                       fNext= a;
+                                       return;
+                               }
+                       }
+               }
+               fNext= null;
+       }
+       
+       /*
+        * @see Iterator#hasNext()
+        */
+       public boolean hasNext() {
+               return fNext != null;
+       }
+
+       /*
+        * @see Iterator#next()
+        */
+       public Object next() {
+               try {
+                       return fNext;
+               } finally {
+                       skip();
+               }
+       }
+
+       /*
+        * @see Iterator#remove()
+        */
+       public void remove() {
+               throw new UnsupportedOperationException();
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaMarkerAnnotation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaMarkerAnnotation.java
new file mode 100644 (file)
index 0000000..64905c4
--- /dev/null
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpeclipse.phpeditor;
+
+
+import java.util.Iterator;
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.text.Assert;
+import org.eclipse.search.ui.SearchUI;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+
+
+
+public class JavaMarkerAnnotation extends MarkerAnnotation implements IJavaAnnotation {
+       
+       private static final int NO_IMAGE= 0;
+       private static final int ORIGINAL_MARKER_IMAGE= 1;
+       private static final int QUICKFIX_IMAGE= 2;
+       private static final int QUICKFIX_ERROR_IMAGE= 3;
+       private static final int OVERLAY_IMAGE= 4;
+       private static final int GRAY_IMAGE= 5;
+       private static final int BREAKPOINT_IMAGE= 6;
+
+       private static Image fgQuickFixImage;
+       private static Image fgQuickFixErrorImage;
+       private static ImageRegistry fgGrayMarkersImageRegistry;
+       
+       private IDebugModelPresentation fPresentation;
+       private IJavaAnnotation fOverlay;
+       private boolean fNotRelevant= false;
+       private AnnotationType fType;
+       private int fImageType;
+       private boolean fQuickFixIconEnabled;
+       
+       
+       public JavaMarkerAnnotation(IMarker marker) {
+               super(marker);
+       }
+       
+       /*
+        * @see MarkerAnnotation#getUnknownImageName(IMarker)
+        */
+       protected String getUnknownImageName(IMarker marker) {
+               return PHPUiImages.IMG_OBJS_GHOST;
+       }
+       
+       /**
+        * Initializes the annotation's icon representation and its drawing layer
+        * based upon the properties of the underlying marker.
+        */
+       protected void initialize() {
+               fQuickFixIconEnabled= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+               fImageType= NO_IMAGE;
+               IMarker marker= getMarker();
+               
+               if (MarkerUtilities.isMarkerType(marker, IBreakpoint.BREAKPOINT_MARKER)) {
+                       
+                       if (fPresentation == null) 
+                               fPresentation= DebugUITools.newDebugModelPresentation();
+
+                       setImage(null); // see bug 32469
+                       setLayer(4);
+                       fImageType= BREAKPOINT_IMAGE;                                   
+                       
+                       fType= AnnotationType.UNKNOWN;
+                       
+               } else {
+                       
+                       fType= AnnotationType.UNKNOWN;
+                       if (marker.exists()) {
+                               try {
+                                       
+                                       if (marker.isSubtypeOf(IMarker.PROBLEM)) {
+                                               int severity= marker.getAttribute(IMarker.SEVERITY, -1);
+                                               switch (severity) {
+                                                       case IMarker.SEVERITY_ERROR:
+                                                               fType= AnnotationType.ERROR;
+                                                               break;
+                                                       case IMarker.SEVERITY_WARNING:
+                                                               fType= AnnotationType.WARNING;
+                                                               break;
+                                               }
+                                       } else if (marker.isSubtypeOf(IMarker.TASK))
+                                               fType= AnnotationType.TASK; 
+                                       else if (marker.isSubtypeOf(SearchUI.SEARCH_MARKER)) 
+                                               fType= AnnotationType.SEARCH;
+                                       else if (marker.isSubtypeOf(IMarker.BOOKMARK))
+                                               fType= AnnotationType.BOOKMARK;
+                                               
+                               } catch(CoreException e) {
+                                       PHPeclipsePlugin.log(e);
+                               }
+                       }
+                       super.initialize();
+               }
+       }
+       
+//     private boolean mustShowQuickFixIcon() {
+//             return fQuickFixIconEnabled && JavaCorrectionProcessor.hasCorrections(getMarker());
+//     }
+//     
+//     private Image getQuickFixImage() {
+//             if (fgQuickFixImage == null)
+//                     fgQuickFixImage= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_FIXABLE_PROBLEM);
+//             return fgQuickFixImage;
+//     }
+//
+//     private Image getQuickFixErrorImage() {
+//             if (fgQuickFixErrorImage == null)
+//                     fgQuickFixErrorImage= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_FIXABLE_ERROR);
+//             return fgQuickFixErrorImage;
+//     }
+
+       /*
+        * @see IJavaAnnotation#getMessage()
+        */
+       public String getMessage() {
+               IMarker marker= getMarker();
+               if (marker == null || !marker.exists())
+                       return ""; //$NON-NLS-1$
+               else
+                       return marker.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
+       }
+
+       /*
+        * @see IJavaAnnotation#isTemporary()
+        */
+       public boolean isTemporary() {
+               return false;
+       }
+       
+       /*
+        * @see IJavaAnnotation#getArguments()
+        */
+       public String[] getArguments() {
+               IMarker marker= getMarker();
+//             if (marker != null && marker.exists() && isProblem())
+//                     return Util.getProblemArgumentsFromMarker(marker.getAttribute(IJavaModelMarker.ARGUMENTS, "")); //$NON-NLS-1$
+               return null;
+       }
+
+       /*
+        * @see IJavaAnnotation#getId()
+        */
+       public int getId() {
+               IMarker marker= getMarker();
+//             if (marker != null  && marker.exists() && isProblem())
+//                     return marker.getAttribute(IJavaModelMarker.ID, -1);
+               return -1;
+       }
+       
+       /*
+        * @see IJavaAnnotation#isProblem()
+        */
+       public boolean isProblem() {
+               return fType == AnnotationType.WARNING || fType == AnnotationType.ERROR;
+       }
+       
+       /*
+        * @see IJavaAnnotation#isRelevant()
+        */
+       public boolean isRelevant() {
+               return !fNotRelevant;
+       }
+
+       /**
+        * Overlays this annotation with the given javaAnnotation.
+        * 
+        * @param javaAnnotation annotation that is overlaid by this annotation
+        */
+       public void setOverlay(IJavaAnnotation javaAnnotation) {
+               if (fOverlay != null)
+                       fOverlay.removeOverlaid(this);
+                       
+               fOverlay= javaAnnotation;
+               fNotRelevant= (fNotRelevant || fOverlay != null);
+               
+               if (javaAnnotation != null)
+                       javaAnnotation.addOverlaid(this);
+       }
+       
+       /*
+        * @see IJavaAnnotation#hasOverlay()
+        */
+       public boolean hasOverlay() {
+               return fOverlay != null;
+       }
+       
+       /*
+        * @see MarkerAnnotation#getImage(Display)
+        */
+       public Image getImage(Display display) {
+               if (fImageType == BREAKPOINT_IMAGE) {
+                       Image result= super.getImage(display);
+                       if (result == null) {
+                               IMarker marker= getMarker();
+                               if (marker != null && marker.exists()) {
+                                       result= fPresentation.getImage(getMarker());
+                                       setImage(result);
+                               }
+                       }                                       
+                       return result;
+               }
+
+               int newImageType= NO_IMAGE;
+
+               if (hasOverlay())
+                       newImageType= OVERLAY_IMAGE;
+               else if (isRelevant()) {
+//                     if (mustShowQuickFixIcon()) {
+//                             if (fType == AnnotationType.ERROR)
+//                                     newImageType= QUICKFIX_ERROR_IMAGE;
+//                             else
+//                                     newImageType= QUICKFIX_IMAGE; 
+//                     } else
+                               newImageType= ORIGINAL_MARKER_IMAGE; 
+               } else
+                       newImageType= GRAY_IMAGE;
+
+               if (fImageType == newImageType && newImageType != OVERLAY_IMAGE)
+                       // Nothing changed - simply return the current image
+                       return super.getImage(display);
+
+               Image newImage= null;
+               switch (newImageType) {
+                       case ORIGINAL_MARKER_IMAGE:
+                               newImage= null;
+                               break;
+                       case OVERLAY_IMAGE:
+                               newImage= fOverlay.getImage(display);
+                               break;
+//                     case QUICKFIX_IMAGE:
+//                             newImage= getQuickFixImage();
+//                             break;
+//                     case QUICKFIX_ERROR_IMAGE:
+//                             newImage= getQuickFixErrorImage();
+//                             break;
+                       case GRAY_IMAGE:
+                               if (fImageType != ORIGINAL_MARKER_IMAGE)
+                                       setImage(null);
+                               Image originalImage= super.getImage(display);
+                               if (originalImage != null) {
+                                       ImageRegistry imageRegistry= getGrayMarkerImageRegistry(display);
+                                       if (imageRegistry != null) {
+                                               String key= Integer.toString(originalImage.hashCode());
+                                               Image grayImage= imageRegistry.get(key);
+                                               if (grayImage == null) {
+                                                       grayImage= new Image(display, originalImage, SWT.IMAGE_GRAY);
+                                                       imageRegistry.put(key, grayImage);
+                                               }
+                                               newImage= grayImage;
+                                       }
+                               }
+                               break;
+                       default:
+                               Assert.isLegal(false);
+               }
+
+               fImageType= newImageType;
+               setImage(newImage);
+               return super.getImage(display);
+       }
+       
+       private ImageRegistry getGrayMarkerImageRegistry(Display display) {
+               if (fgGrayMarkersImageRegistry == null)
+                       fgGrayMarkersImageRegistry= new ImageRegistry(display);
+               return fgGrayMarkersImageRegistry;
+       }
+       
+       /*
+        * @see IJavaAnnotation#addOverlaid(IJavaAnnotation)
+        */
+       public void addOverlaid(IJavaAnnotation annotation) {
+               // not supported
+       }
+
+       /*
+        * @see IJavaAnnotation#removeOverlaid(IJavaAnnotation)
+        */
+       public void removeOverlaid(IJavaAnnotation annotation) {
+               // not supported
+       }
+       
+       /*
+        * @see IJavaAnnotation#getOverlaidIterator()
+        */
+       public Iterator getOverlaidIterator() {
+               // not supported
+               return null;
+       }
+       
+       /*
+        * @see org.eclipse.jdt.internal.ui.javaeditor.IJavaAnnotation#getAnnotationType()
+        */
+       public AnnotationType getAnnotationType() {
+               return fType;
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRuler.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRuler.java
deleted file mode 100644 (file)
index e59e385..0000000
+++ /dev/null
@@ -1,760 +0,0 @@
-/**********************************************************************
-Copyright (c) 2000, 2002 IBM Corp. and others.
-All rights reserved. This program and the accompanying materials
-are made available under the terms of the Common Public License v1.0
-which accompanies this distribution, and is available at
-http://www.eclipse.org/legal/cpl-v10.html
-
-Contributors:
-    IBM Corporation - Initial implementation
-**********************************************************************/
-
-package net.sourceforge.phpeclipse.phpeditor;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import net.sourceforge.phpdt.ui.text.JavaTextTools;
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextListener;
-import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.ITextViewerExtension3;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.Region;
-import org.eclipse.jface.text.TextEvent;
-import org.eclipse.jface.text.source.Annotation;
-import org.eclipse.jface.text.source.IAnnotationModel;
-import org.eclipse.jface.text.source.IAnnotationModelListener;
-import org.eclipse.jface.text.source.IVerticalRulerInfo;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * 
- */
-public class OverviewRuler implements IVerticalRulerInfo {
-
-  /**
-   * Internal listener class.
-   */
-  class InternalListener implements ITextListener, IAnnotationModelListener {
-
-    /*
-     * @see ITextListener#textChanged
-     */
-    public void textChanged(TextEvent e) {
-      if (fTextViewer != null && e.getDocumentEvent() == null && e.getViewerRedrawState()) {
-        // handle only changes of visible document
-        redraw();
-      }
-    }
-
-    /*
-     * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
-     */
-    public void modelChanged(IAnnotationModel model) {
-      update();
-    }
-  }
-
-  /**
-   * Filters problems based on their types.
-   */
-  class FilterIterator implements Iterator {
-
-    private final static int IGNORE = 0;
-    private final static int TEMPORARY = 1;
-    private final static int PERSISTENT = 2;
-
-    private Iterator fIterator;
-    private AnnotationType fType;
-    private IProblemAnnotation fNext;
-    private int fTemporary;
-
-    public FilterIterator(AnnotationType type) {
-      this(type, IGNORE);
-    }
-
-    public FilterIterator(AnnotationType type, boolean temporary) {
-      this(type, temporary ? TEMPORARY : PERSISTENT);
-    }
-
-    private FilterIterator(AnnotationType type, int temporary) {
-      fType = type;
-      fTemporary = temporary;
-      if (fModel != null) {
-        fIterator = fModel.getAnnotationIterator();
-        skip();
-      }
-    }
-
-    private void skip() {
-      while (fIterator.hasNext()) {
-        Object next = fIterator.next();
-        if (next instanceof IProblemAnnotation) {
-          fNext = (IProblemAnnotation) next;
-          AnnotationType type = fNext.getAnnotationType();
-          if (fType == AnnotationType.ALL || fType == type) {
-            if (fTemporary == IGNORE)
-              return;
-            if (fTemporary == TEMPORARY && fNext.isTemporary())
-              return;
-            if (fTemporary == PERSISTENT && !fNext.isTemporary())
-              return;
-          }
-        }
-      }
-      fNext = null;
-    }
-
-    /*
-     * @see Iterator#hasNext()
-     */
-    public boolean hasNext() {
-      return fNext != null;
-    }
-    /*
-     * @see Iterator#next()
-     */
-    public Object next() {
-      try {
-        return fNext;
-      } finally {
-        if (fModel != null)
-          skip();
-      }
-    }
-    /*
-     * @see Iterator#remove()
-     */
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-  };
-
-  private static final int INSET = 2;
-  private static final int PROBLEM_HEIGHT_MIN = 4;
-  private static boolean PROBLEM_HEIGHT_SCALABLE = false;
-
-  /** The model of the overview ruler */
-  private IAnnotationModel fModel;
-  /** The view to which this ruler is connected */
-  private ITextViewer fTextViewer;
-  /** The ruler's canvas */
-  private Canvas fCanvas;
-  /** The drawable for double buffering */
-  private Image fBuffer;
-  /** The internal listener */
-  private InternalListener fInternalListener = new InternalListener();
-  /** The width of this vertical ruler */
-  private int fWidth;
-  /** The hit detection cursor */
-  private Cursor fHitDetectionCursor;
-  /** The last cursor */
-  private Cursor fLastCursor;
-  /** Cache for the actual scroll position in pixels */
-  private int fScrollPos;
-  /** The line of the last mouse button activity */
-  private int fLastMouseButtonActivityLine = -1;
-  /** The actual problem height */
-  private int fProblemHeight = -1;
-
-  private Set fAnnotationSet = new HashSet();
-  private Map fLayers = new HashMap();
-  private Map fColorTable = new HashMap();
-
-  /**
-   * Constructs a vertical ruler with the given width.
-   *
-   * @param width the width of the vertical ruler
-   */
-  public OverviewRuler(int width) {
-    fWidth = width;
-  }
-
-  public Control getControl() {
-    return fCanvas;
-  }
-
-  public int getWidth() {
-    return fWidth;
-  }
-
-  public void setModel(IAnnotationModel model) {
-    if (model != fModel || model != null) {
-
-      if (fModel != null)
-        fModel.removeAnnotationModelListener(fInternalListener);
-
-      fModel = model;
-
-      if (fModel != null)
-        fModel.addAnnotationModelListener(fInternalListener);
-
-      update();
-    }
-  }
-
-  public Control createControl(Composite parent, ITextViewer textViewer) {
-
-    fTextViewer = textViewer;
-
-    fHitDetectionCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
-    fCanvas = new Canvas(parent, SWT.NO_BACKGROUND);
-
-    fCanvas.addPaintListener(new PaintListener() {
-      public void paintControl(PaintEvent event) {
-        if (fTextViewer != null)
-          doubleBufferPaint(event.gc);
-      }
-    });
-
-    fCanvas.addDisposeListener(new DisposeListener() {
-      public void widgetDisposed(DisposeEvent event) {
-        handleDispose();
-        fTextViewer = null;
-      }
-    });
-
-    fCanvas.addMouseListener(new MouseAdapter() {
-      public void mouseDown(MouseEvent event) {
-        handleMouseDown(event);
-      }
-    });
-
-    fCanvas.addMouseMoveListener(new MouseMoveListener() {
-      public void mouseMove(MouseEvent event) {
-        handleMouseMove(event);
-      }
-    });
-
-    if (fTextViewer != null)
-      fTextViewer.addTextListener(fInternalListener);
-
-    return fCanvas;
-  }
-
-  /**
-   * Disposes the ruler's resources.
-   */
-  private void handleDispose() {
-
-    if (fTextViewer != null) {
-      fTextViewer.removeTextListener(fInternalListener);
-      fTextViewer = null;
-    }
-
-    if (fModel != null)
-      fModel.removeAnnotationModelListener(fInternalListener);
-
-    if (fBuffer != null) {
-      fBuffer.dispose();
-      fBuffer = null;
-    }
-
-    if (fHitDetectionCursor != null) {
-      fHitDetectionCursor.dispose();
-      fHitDetectionCursor = null;
-    }
-
-    fAnnotationSet.clear();
-    fLayers.clear();
-    fColorTable.clear();
-  }
-
-  /**
-   * Double buffer drawing.
-   */
-  private void doubleBufferPaint(GC dest) {
-
-    Point size = fCanvas.getSize();
-
-    if (size.x <= 0 || size.y <= 0)
-      return;
-
-    if (fBuffer != null) {
-      Rectangle r = fBuffer.getBounds();
-      if (r.width != size.x || r.height != size.y) {
-        fBuffer.dispose();
-        fBuffer = null;
-      }
-    }
-    if (fBuffer == null)
-      fBuffer = new Image(fCanvas.getDisplay(), size.x, size.y);
-
-    GC gc = new GC(fBuffer);
-    try {
-      gc.setBackground(fCanvas.getBackground());
-      gc.fillRectangle(0, 0, size.x, size.y);
-
-      if (fTextViewer instanceof ITextViewerExtension3)
-        doPaint1(gc);
-      else
-        doPaint(gc);
-
-    } finally {
-      gc.dispose();
-    }
-
-    dest.drawImage(fBuffer, 0, 0);
-  }
-
-  private void doPaint(GC gc) {
-
-    if (fTextViewer == null)
-      return;
-
-    Rectangle r = new Rectangle(0, 0, 0, 0);
-    int yy, hh = PROBLEM_HEIGHT_MIN;
-
-    IDocument document = fTextViewer.getDocument();
-    IRegion visible = fTextViewer.getVisibleRegion();
-
-    StyledText textWidget = fTextViewer.getTextWidget();
-    int maxLines = textWidget.getLineCount();
-    fScrollPos = textWidget.getTopPixel();
-
-    Point size = fCanvas.getSize();
-    int writable = maxLines * textWidget.getLineHeight();
-    if (size.y > writable)
-      size.y = writable;
-
-    List indices = new ArrayList(fLayers.keySet());
-    Collections.sort(indices);
-
-    for (Iterator iterator = indices.iterator(); iterator.hasNext();) {
-      Object layer = iterator.next();
-      AnnotationType annotationType = (AnnotationType) fLayers.get(layer);
-
-      if (skip(annotationType))
-        continue;
-
-      boolean[] temporary = new boolean[] { false, true };
-      for (int t = 0; t < temporary.length; t++) {
-
-        Iterator e = new FilterIterator(annotationType, temporary[t]);
-        Color fill = getFillColor(annotationType, temporary[t]);
-        Color stroke = getStrokeColor(annotationType, temporary[t]);
-
-        for (int i = 0; e.hasNext(); i++) {
-
-          Annotation a = (Annotation) e.next();
-          Position p = fModel.getPosition(a);
-
-          if (p == null || !p.overlapsWith(visible.getOffset(), visible.getLength()))
-            continue;
-
-          int problemOffset = Math.max(p.getOffset(), visible.getOffset());
-          int problemEnd = Math.min(p.getOffset() + p.getLength(), visible.getOffset() + visible.getLength());
-          int problemLength = problemEnd - problemOffset;
-
-          try {
-            if (PROBLEM_HEIGHT_SCALABLE) {
-              int numbersOfLines = document.getNumberOfLines(problemOffset, problemLength);
-              hh = (numbersOfLines * size.y) / maxLines;
-              if (hh < PROBLEM_HEIGHT_MIN)
-                hh = PROBLEM_HEIGHT_MIN;
-            }
-            fProblemHeight = hh;
-
-            int startLine = textWidget.getLineAtOffset(problemOffset - visible.getOffset());
-            yy = Math.min((startLine * size.y) / maxLines, size.y - hh);
-
-            if (fill != null) {
-              gc.setBackground(fill);
-              gc.fillRectangle(INSET, yy, size.x - (2 * INSET), hh);
-            }
-
-            if (stroke != null) {
-              gc.setForeground(stroke);
-              r.x = INSET;
-              r.y = yy;
-              r.width = size.x - (2 * INSET) - 1;
-              r.height = hh;
-              gc.setLineWidth(1);
-              gc.drawRectangle(r);
-            }
-          } catch (BadLocationException x) {
-          }
-        }
-      }
-    }
-  }
-
-  private void doPaint1(GC gc) {
-
-    if (fTextViewer == null)
-      return;
-
-    Rectangle r = new Rectangle(0, 0, 0, 0);
-    int yy, hh = PROBLEM_HEIGHT_MIN;
-
-    ITextViewerExtension3 extension = (ITextViewerExtension3) fTextViewer;
-    IDocument document = fTextViewer.getDocument();
-    StyledText textWidget = fTextViewer.getTextWidget();
-    fScrollPos = textWidget.getTopPixel();
-
-    int maxLines = textWidget.getLineCount();
-    Point size = fCanvas.getSize();
-    int writable = maxLines * textWidget.getLineHeight();
-    if (size.y > writable)
-      size.y = writable;
-
-    List indices = new ArrayList(fLayers.keySet());
-    Collections.sort(indices);
-
-    for (Iterator iterator = indices.iterator(); iterator.hasNext();) {
-      Object layer = iterator.next();
-      AnnotationType annotationType = (AnnotationType) fLayers.get(layer);
-
-      if (skip(annotationType))
-        continue;
-
-      boolean[] temporary = new boolean[] { false, true };
-      for (int t = 0; t < temporary.length; t++) {
-
-        Iterator e = new FilterIterator(annotationType, temporary[t]);
-        Color fill = getFillColor(annotationType, temporary[t]);
-        Color stroke = getStrokeColor(annotationType, temporary[t]);
-
-        for (int i = 0; e.hasNext(); i++) {
-
-          Annotation a = (Annotation) e.next();
-          Position p = fModel.getPosition(a);
-
-          if (p == null)
-            continue;
-
-          IRegion widgetRegion = extension.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength()));
-          if (widgetRegion == null)
-            continue;
-
-          try {
-            if (PROBLEM_HEIGHT_SCALABLE) {
-              int numbersOfLines = document.getNumberOfLines(p.getOffset(), p.getLength());
-              hh = (numbersOfLines * size.y) / maxLines;
-              if (hh < PROBLEM_HEIGHT_MIN)
-                hh = PROBLEM_HEIGHT_MIN;
-            }
-            fProblemHeight = hh;
-
-            int startLine = textWidget.getLineAtOffset(widgetRegion.getOffset());
-            yy = Math.min((startLine * size.y) / maxLines, size.y - hh);
-
-            if (fill != null) {
-              gc.setBackground(fill);
-              gc.fillRectangle(INSET, yy, size.x - (2 * INSET), hh);
-            }
-
-            if (stroke != null) {
-              gc.setForeground(stroke);
-              r.x = INSET;
-              r.y = yy;
-              r.width = size.x - (2 * INSET) - 1;
-              r.height = hh;
-              gc.setLineWidth(1);
-              gc.drawRectangle(r);
-            }
-          } catch (BadLocationException x) {
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Thread-safe implementation.
-   * Can be called from any thread.
-   */
-  public void update() {
-    if (fCanvas != null && !fCanvas.isDisposed()) {
-      Display d = fCanvas.getDisplay();
-      if (d != null) {
-        d.asyncExec(new Runnable() {
-          public void run() {
-            redraw();
-          }
-        });
-      }
-    }
-  }
-
-  /**
-   * Redraws the overview ruler.
-   */
-  private void redraw() {
-    if (fCanvas != null && !fCanvas.isDisposed()) {
-      GC gc = new GC(fCanvas);
-      doubleBufferPaint(gc);
-      gc.dispose();
-    }
-  }
-
-  private int[] toLineNumbers(int y_coordinate) {
-
-    StyledText textWidget = fTextViewer.getTextWidget();
-    int maxLines = textWidget.getContent().getLineCount();
-
-    int rulerLength = fCanvas.getSize().y;
-    int writable = maxLines * textWidget.getLineHeight();
-
-    if (rulerLength > writable)
-      rulerLength = writable;
-
-    if (y_coordinate >= writable)
-      return new int[] { -1, -1 };
-
-    int[] lines = new int[2];
-
-    int pixel = Math.max(y_coordinate - 1, 0);
-    lines[0] = (pixel * maxLines) / rulerLength;
-
-    pixel = Math.min(rulerLength, y_coordinate + 1);
-    lines[1] = (pixel * maxLines) / rulerLength;
-
-    if (fTextViewer instanceof ITextViewerExtension3) {
-      ITextViewerExtension3 extension = (ITextViewerExtension3) fTextViewer;
-      lines[0] = extension.widgetlLine2ModelLine(lines[0]);
-      lines[1] = extension.widgetlLine2ModelLine(lines[1]);
-    } else {
-      try {
-        IRegion visible = fTextViewer.getVisibleRegion();
-        int lineNumber = fTextViewer.getDocument().getLineOfOffset(visible.getOffset());
-        lines[0] += lineNumber;
-        lines[1] += lineNumber;
-      } catch (BadLocationException x) {
-      }
-    }
-
-    return lines;
-  }
-
-  boolean hasAnnotationAt(int y_coordinate) {
-    return findBestMatchingLineNumber(toLineNumbers(y_coordinate)) != -1;
-  }
-
-  private Position getProblemPositionAt(int[] lineNumbers) {
-    if (lineNumbers[0] == -1)
-      return null;
-
-    Position found = null;
-
-    try {
-      IDocument d = fTextViewer.getDocument();
-      IRegion line = d.getLineInformation(lineNumbers[0]);
-
-      int start = line.getOffset();
-
-      line = d.getLineInformation(lineNumbers[lineNumbers.length - 1]);
-      int end = line.getOffset() + line.getLength();
-
-      Iterator e = new FilterIterator(AnnotationType.ALL);
-      while (e.hasNext()) {
-        Annotation a = (Annotation) e.next();
-        Position p = fModel.getPosition(a);
-        if (start <= p.getOffset() && p.getOffset() < end) {
-          if (found == null || p.getOffset() < found.getOffset())
-            found = p;
-        }
-      }
-
-    } catch (BadLocationException x) {
-    }
-
-    return found;
-  }
-
-  /**
-   * Returns the line which best corresponds to one of
-   * the underlying problem annotations at the given
-   * y ruler coordinate.
-   * 
-   * @return the best matching line or <code>-1</code> if no such line can be found
-   * @since 2.1
-   */
-  private int findBestMatchingLineNumber(int[] lineNumbers) {
-    if (lineNumbers == null || lineNumbers.length < 1)
-      return -1;
-
-    try {
-      Position pos = getProblemPositionAt(lineNumbers);
-      if (pos == null)
-        return -1;
-      return fTextViewer.getDocument().getLineOfOffset(pos.getOffset());
-    } catch (BadLocationException ex) {
-      return -1;
-    }
-  }
-
-  private void handleMouseDown(MouseEvent event) {
-    if (fTextViewer != null) {
-      int[] lines = toLineNumbers(event.y);
-      Position p = getProblemPositionAt(lines);
-      if (p != null) {
-        fTextViewer.revealRange(p.getOffset(), p.getLength());
-        fTextViewer.setSelectedRange(p.getOffset(), p.getLength());
-      }
-      fTextViewer.getTextWidget().setFocus();
-    }
-    fLastMouseButtonActivityLine = toDocumentLineNumber(event.y);
-  }
-
-  private void handleMouseMove(MouseEvent event) {
-    if (fTextViewer != null) {
-      int[] lines = toLineNumbers(event.y);
-      Position p = getProblemPositionAt(lines);
-      Cursor cursor = (p != null ? fHitDetectionCursor : null);
-      if (cursor != fLastCursor) {
-        fCanvas.setCursor(cursor);
-        fLastCursor = cursor;
-      }
-    }
-  }
-
-  private void handleMouseDoubleClick(MouseEvent event) {
-    fLastMouseButtonActivityLine = toDocumentLineNumber(event.y);
-  }
-
-  public void showAnnotation(AnnotationType annotationType, boolean show) {
-    if (show)
-      fAnnotationSet.add(annotationType);
-    else
-      fAnnotationSet.remove(annotationType);
-  }
-
-  public void setLayer(AnnotationType annotationType, int layer) {
-    if (layer >= 0)
-      fLayers.put(new Integer(layer), annotationType);
-    else {
-      Iterator e = fLayers.keySet().iterator();
-      while (e.hasNext()) {
-        Object key = e.next();
-        if (annotationType.equals(fLayers.get(key))) {
-          fLayers.remove(key);
-          return;
-        }
-      }
-    }
-  }
-
-  public void setColor(AnnotationType annotationType, Color color) {
-    if (color != null)
-      fColorTable.put(annotationType, color);
-    else
-      fColorTable.remove(annotationType);
-  }
-
-  private boolean skip(AnnotationType annotationType) {
-    return !fAnnotationSet.contains(annotationType);
-  }
-
-  private static RGB interpolate(RGB fg, RGB bg, double scale) {
-    return new RGB(
-      (int) ((1.0 - scale) * fg.red + scale * bg.red),
-      (int) ((1.0 - scale) * fg.green + scale * bg.green),
-      (int) ((1.0 - scale) * fg.blue + scale * bg.blue));
-  }
-
-  private static double greyLevel(RGB rgb) {
-    if (rgb.red == rgb.green && rgb.green == rgb.blue)
-      return rgb.red;
-    return (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue + 0.5);
-  }
-
-  private static boolean isDark(RGB rgb) {
-    return greyLevel(rgb) > 128;
-  }
-
-  private static Color getColor(RGB rgb) {
-    JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
-    return textTools.getColorManager().getColor(rgb);
-  }
-
-  private Color getColor(AnnotationType annotationType, double scale) {
-    Color base = (Color) fColorTable.get(annotationType);
-    if (base == null)
-      return null;
-
-    RGB baseRGB = base.getRGB();
-    RGB background = fCanvas.getBackground().getRGB();
-
-    boolean darkBase = isDark(baseRGB);
-    boolean darkBackground = isDark(background);
-    if (darkBase && darkBackground)
-      background = new RGB(255, 255, 255);
-    else if (!darkBase && !darkBackground)
-      background = new RGB(0, 0, 0);
-
-    return getColor(interpolate(baseRGB, background, scale));
-  }
-
-  private Color getStrokeColor(AnnotationType annotationType, boolean temporary) {
-    return getColor(annotationType, temporary ? 0.5 : 0.2);
-  }
-
-  private Color getFillColor(AnnotationType annotationType, boolean temporary) {
-    return getColor(annotationType, temporary ? 0.9 : 0.6);
-  }
-
-  /**
-   * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
-   * @since 2.1
-   */
-  public int getLineOfLastMouseButtonActivity() {
-    return fLastMouseButtonActivityLine;
-  }
-
-  /**
-   * @see IVerticalRulerInfo#toDocumentLineNumber(int)
-   * @since 2.1
-   */
-  public int toDocumentLineNumber(int y_coordinate) {
-
-    if (fTextViewer == null || y_coordinate == -1)
-      return -1;
-
-    int[] lineNumbers = toLineNumbers(y_coordinate);
-    int bestLine = findBestMatchingLineNumber(lineNumbers);
-    if (bestLine == -1 && lineNumbers.length > 0)
-      return lineNumbers[0];
-    return bestLine;
-  }
-
-  /**
-   * Returns the height of the problem rectangle.
-   * 
-   * @return the height of the problem rectangle
-   * @since 2.1
-   */
-  int getAnnotationHeight() {
-    return fProblemHeight;
-  }
-}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRulerHoverManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/OverviewRulerHoverManager.java
deleted file mode 100644 (file)
index b63d26d..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2000, 2002 IBM Corp. and others..
- * All rights reserved. Â  This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- */
-package net.sourceforge.phpeclipse.phpeditor;
-
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-
-import org.eclipse.jface.text.IInformationControlCreator;
-import org.eclipse.jface.text.source.AnnotationBarHoverManager;
-import org.eclipse.jface.text.source.IAnnotationHover;
-import org.eclipse.jface.text.source.ISourceViewer;
-
-/**
- * This manager controls the layout, content, and visibility of an information
- * control in reaction to mouse hover events issued by the overview ruler of a
- * source viewer.
- * 
- * @since 2.1
- */
-class OverviewRulerHoverManager extends AnnotationBarHoverManager {
-
-       /**
-        * Creates an overview hover manager with the given parameters. In addition,
-        * the hovers anchor is RIGHT and the margin is 5 points to the right.
-        *
-        * @param ruler the overview ruler this manager connects to
-        * @param sourceViewer the source viewer this manager connects to
-        * @param annotationHover the annotation hover providing the information to be displayed
-        * @param creator the information control creator
-        */
-       public OverviewRulerHoverManager(OverviewRuler ruler, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) {
-               super(ruler, sourceViewer, annotationHover, creator);
-       }
-       
-       /*
-        * @see AbstractHoverInformationControlManager#computeInformation()
-        */
-       protected void computeInformation() {
-               Point location= getHoverEventLocation();
-               int line= getVerticalRulerInfo().toDocumentLineNumber(location.y);
-               setInformation(getAnnotationHover().getHoverInfo(getSourceViewer(), line), computeArea(location.y));
-       }
-
-       /**
-        * Determines graphical area covered for which the hover is valid.
-        *
-        * @param y-coordinate in the vertical ruler
-        * @return the graphical extend where the hover is valid
-        */
-       private Rectangle computeArea(int y) {
-               // This is ok (see constructor)
-               OverviewRuler overviewRuler= (OverviewRuler)getVerticalRulerInfo();
-
-               int hover_height= overviewRuler.getAnnotationHeight();
-               int hover_width= getVerticalRulerInfo().getControl().getSize().x;
-
-               // Calculate y-coordinate for hover
-               int hover_y= y;
-               boolean hasAnnotation= true;
-               while (hasAnnotation && hover_y > y - hover_height) {
-                       hover_y--;
-                       hasAnnotation= overviewRuler.hasAnnotationAt(hover_y);
-               }
-               hover_y++;
-                       
-               return new Rectangle(0, hover_y, hover_width, hover_height);
-       }
-}
index 10e9170..f97f1dd 100644 (file)
@@ -37,11 +37,11 @@ import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.actions.RetargetAction;
+import org.eclipse.ui.editors.text.EncodingActionGroup;
 import org.eclipse.ui.texteditor.AbstractTextEditor;
 import org.eclipse.ui.texteditor.BasicTextEditorActionContributor;
 import org.eclipse.ui.texteditor.ITextEditor;
 import org.eclipse.ui.texteditor.RetargetTextEditorAction;
-
 /**
  * Contributes interesting PHP actions to the desktop's Edit menu and the toolbar.
  */
@@ -59,6 +59,7 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
   protected PHPParserAction fParserAction;
   protected ShowExternalPreviewAction fShowExternalPreviewAction;
 
+  private EncodingActionGroup fEncodingActionGroup;
   /**
    * Default constructor.
    */
@@ -68,17 +69,14 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
     ResourceBundle b = PHPEditorMessages.getResourceBundle();
 
     fRetargetContentAssist = new RetargetAction(PHPdtActionConstants.CONTENT_ASSIST, PHPEditorMessages.getString("ContentAssistProposal.label")); //$NON-NLS-1$
-    fRetargetContentAssist.setActionDefinitionId(
-      PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+    fRetargetContentAssist.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
     markAsPartListener(fRetargetContentAssist);
 
     fContentAssist = new RetargetTextEditorAction(b, "ContentAssistProposal."); //$NON-NLS-1$
-    fContentAssist.setActionDefinitionId(
-      PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+    fContentAssist.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
 
     fGotoMatchingBracket = new RetargetTextEditorAction(b, "GotoMatchingBracket."); //$NON-NLS-1$
-    fGotoMatchingBracket.setActionDefinitionId(
-      PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+    fGotoMatchingBracket.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
 
     // fContentAssist.setImageDescriptor(JavaPluginImages.DESC_CLCL_CODE_ASSIST);
     // fContentAssist.setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_CODE_ASSIST);
@@ -87,6 +85,9 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
     fContentAssistTip = new RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(), "ContentAssistTip."); //$NON-NLS-1$
     //  fTogglePresentation = new PresentationAction();
 
+    // character encoding
+    fEncodingActionGroup = new EncodingActionGroup();
+
     fParserAction = PHPParserAction.getInstance();
 
     if (SWT.getPlatform().equals("win32")) {
@@ -142,16 +143,15 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
 
     super.contributeToMenu(menu);
 
-    IMenuManager editMenu =
-      menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+    IMenuManager editMenu = menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
     if (editMenu != null) {
       editMenu.add(new Separator(IContextMenuConstants.GROUP_OPEN));
       editMenu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
       editMenu.add(new Separator(IContextMenuConstants.GROUP_ADDITIONS));
 
-//      editMenu.appendToGroup(
-//        IContextMenuConstants.GROUP_GENERATE,
-//        fRetargetContentAssist);
+      //      editMenu.appendToGroup(
+      //        IContextMenuConstants.GROUP_GENERATE,
+      //        fRetargetContentAssist);
 
       //                               MenuManager structureSelection= new MenuManager(JavaEditorMessages.getString("ExpandSelectionMenu.label"), "expandSelection"); //$NON-NLS-1$ //$NON-NLS-2$ 
       //                               structureSelection.add(fStructureSelectEnclosingAction);
@@ -193,7 +193,8 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
     Iterator e = fPartListeners.iterator();
     while (e.hasNext())
       page.addPartListener((RetargetAction) e.next());
-
+    // character encoding
+    fEncodingActionGroup.fillActionBars(bars);
     super.init(bars, page);
   }
   /*
@@ -203,8 +204,7 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
     super.init(bars);
 
     IMenuManager menuManager = bars.getMenuManager();
-    IMenuManager editMenu =
-      menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+    IMenuManager editMenu = menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
     if (editMenu != null) {
       editMenu.add(new Separator());
       editMenu.add(fContentAssist);
@@ -212,9 +212,7 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
       //   editMenu.add(fContentAssistTip);
     }
 
-    bars.setGlobalActionHandler(
-      PHPdtActionConstants.CONTENT_ASSIST,
-      fContentAssist);
+    bars.setGlobalActionHandler(PHPdtActionConstants.CONTENT_ASSIST, fContentAssist);
     //    IToolBarManager toolBarManager = bars.getToolBarManager();
     //    if (toolBarManager != null) {
     //      toolBarManager.add(new Separator());
@@ -222,7 +220,10 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
     //    }
   }
 
-  private void doSetActiveEditor(IEditorPart part) {
+  /*
+   * @see IEditorActionBarContributor#setActiveEditor(IEditorPart)
+   */
+  public void setActiveEditor(IEditorPart part) {
     super.setActiveEditor(part);
 
     IActionBars bars = getActionBars();
@@ -236,21 +237,16 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
 
     fContentAssist.setAction(getAction(textEditor, "ContentAssistProposal")); //$NON-NLS-1$
     fContentAssistTip.setAction(getAction(textEditor, "ContentAssistTip")); //$NON-NLS-1$
-    fGotoMatchingBracket.setAction(
-      getAction(textEditor, GotoMatchingBracketAction.GOTO_MATCHING_BRACKET));
+    fGotoMatchingBracket.setAction(getAction(textEditor, GotoMatchingBracketAction.GOTO_MATCHING_BRACKET));
 
     bars.setGlobalActionHandler(PHPdtActionConstants.SHIFT_RIGHT, getAction(textEditor, "ShiftRight")); //$NON-NLS-1$
     bars.setGlobalActionHandler(PHPdtActionConstants.SHIFT_LEFT, getAction(textEditor, "ShiftLeft")); //$NON-NLS-1$
+    // character encoding
+    fEncodingActionGroup.retarget(textEditor);
 
-    bars.setGlobalActionHandler(
-      PHPdtActionConstants.COMMENT,
-      getAction(textEditor, "Comment"));
-    bars.setGlobalActionHandler(
-      PHPdtActionConstants.UNCOMMENT,
-      getAction(textEditor, "Uncomment"));
-    bars.setGlobalActionHandler(
-      PHPdtActionConstants.FORMAT,
-      getAction(textEditor, "Format"));
+    bars.setGlobalActionHandler(PHPdtActionConstants.COMMENT, getAction(textEditor, "Comment"));
+    bars.setGlobalActionHandler(PHPdtActionConstants.UNCOMMENT, getAction(textEditor, "Uncomment"));
+    bars.setGlobalActionHandler(PHPdtActionConstants.FORMAT, getAction(textEditor, "Format"));
 
     if (part instanceof PHPEditor) {
       PHPEditor phpEditor = (PHPEditor) part;
@@ -277,12 +273,10 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
       PHPeclipsePlugin.getDefault().setLastEditorFile(file);
       fParserAction.setEditor(textEditor);
       fParserAction.update();
-      if (SWT.getPlatform().equals("win32")
-        && textEditor instanceof AbstractTextEditor) {
+      if (SWT.getPlatform().equals("win32") && textEditor instanceof AbstractTextEditor) {
         fShowExternalPreviewAction.setEditor(textEditor);
         fShowExternalPreviewAction.update();
-        IPreferenceStore store =
-          PHPeclipsePlugin.getDefault().getPreferenceStore();
+        IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
         if (store.getBoolean(PHPeclipsePlugin.SHOW_EXTERNAL_PREVIEW_PREF)) {
           IAction a = ShowExternalPreviewAction.getInstance();
           if (a != null)
@@ -290,14 +284,6 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
         }
       }
     }
-
-  }
-
-  /*
-   * @see IEditorActionBarContributor#setActiveEditor(IEditorPart)
-   */
-  public void setActiveEditor(IEditorPart part) {
-    doSetActiveEditor(part);
   }
 
   /*
@@ -309,7 +295,7 @@ public class PHPActionContributor extends BasicTextEditorActionContributor {
       getPage().removePartListener((RetargetAction) e.next());
     fPartListeners.clear();
 
-    doSetActiveEditor(null);
+    setActiveEditor(null);
     super.dispose();
   }
 }
index 2fa0115..891f7f2 100644 (file)
@@ -12,18 +12,38 @@ Contributors:
     Klaus Hartlage - www.eclipseproject.de
 **********************************************************************/
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.sourceforge.phpdt.core.IProblemRequestor;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.ui.text.java.IProblemRequestorExtension;
 import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants;
 import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner;
 
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jface.text.DefaultLineTracker;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IDocumentPartitioner;
 import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.Position;
 import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
+import org.eclipse.jface.util.ListenerList;
+import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.editors.text.FileDocumentProvider;
 import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
 
 /** 
  * The PHPDocumentProvider provides the IDocuments used by java editors.
@@ -39,12 +59,421 @@ public class PHPDocumentProvider extends FileDocumentProvider {
       IPHPPartitionScannerConstants.HTML,
       IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT,
       IPHPPartitionScannerConstants.JAVASCRIPT,
-      IPHPPartitionScannerConstants.CSS };
+      IPHPPartitionScannerConstants.CSS,
+                       IPHPPartitionScannerConstants.SMARTY,
+                       IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT };
+
+  private static PHPPartitionScanner PHP_PARTITION_SCANNER = null;
+  private static PHPPartitionScanner HTML_PARTITION_SCANNER = null;
+  private static PHPPartitionScanner XML_PARTITION_SCANNER = null;
+  private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null;
+
+  /** annotation model listener added to all created CU annotation models */
+  //           private GlobalAnnotationModelListener fGlobalAnnotationModelListener;   
+
+  /**
+                * Internal structure for mapping positions to some value. 
+                * The reason for this specific structure is that positions can
+                * change over time. Thus a lookup is based on value and not
+                * on hash value.
+                */
+  protected static class ReverseMap {
+
+    static class Entry {
+      Position fPosition;
+      Object fValue;
+    };
+
+    private List fList = new ArrayList(2);
+    private int fAnchor = 0;
+
+    public ReverseMap() {
+    }
+
+    public Object get(Position position) {
+
+      Entry entry;
+
+      // behind anchor
+      int length = fList.size();
+      for (int i = fAnchor; i < length; i++) {
+        entry = (Entry) fList.get(i);
+        if (entry.fPosition.equals(position)) {
+          fAnchor = i;
+          return entry.fValue;
+        }
+      }
+
+      // before anchor
+      for (int i = 0; i < fAnchor; i++) {
+        entry = (Entry) fList.get(i);
+        if (entry.fPosition.equals(position)) {
+          fAnchor = i;
+          return entry.fValue;
+        }
+      }
 
-  private static PHPPartitionScanner fgScanner = null;
+      return null;
+    }
+
+    private int getIndex(Position position) {
+      Entry entry;
+      int length = fList.size();
+      for (int i = 0; i < length; i++) {
+        entry = (Entry) fList.get(i);
+        if (entry.fPosition.equals(position))
+          return i;
+      }
+      return -1;
+    }
+
+    public void put(Position position, Object value) {
+      int index = getIndex(position);
+      if (index == -1) {
+        Entry entry = new Entry();
+        entry.fPosition = position;
+        entry.fValue = value;
+        fList.add(entry);
+      } else {
+        Entry entry = (Entry) fList.get(index);
+        entry.fValue = value;
+      }
+    }
+
+    public void remove(Position position) {
+      int index = getIndex(position);
+      if (index > -1)
+        fList.remove(index);
+    }
+
+    public void clear() {
+      fList.clear();
+    }
+  };
+
+  /**
+                * Annotation model dealing with java marker annotations and temporary problems.
+                * Also acts as problem requestor for its compilation unit. Initialiy inactive. Must explicitly be
+                * activated.
+                */
+  protected class CompilationUnitAnnotationModel
+    extends ResourceMarkerAnnotationModel
+    implements IProblemRequestor, IProblemRequestorExtension {
+
+    private IFileEditorInput fInput;
+    private List fCollectedProblems;
+    private List fGeneratedAnnotations;
+    private IProgressMonitor fProgressMonitor;
+    private boolean fIsActive = false;
+
+    private ReverseMap fReverseMap = new ReverseMap();
+    private List fPreviouslyOverlaid = null;
+    private List fCurrentlyOverlaid = new ArrayList();
+
+    public CompilationUnitAnnotationModel(IFileEditorInput input) {
+      super(input.getFile());
+      fInput = input;
+    }
+
+    protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
+      return new JavaMarkerAnnotation(marker);
+    }
+
+    protected Position createPositionFromProblem(IProblem problem) {
+      int start = problem.getSourceStart();
+      if (start < 0)
+        return null;
+
+      int length = problem.getSourceEnd() - problem.getSourceStart() + 1;
+      if (length < 0)
+        return null;
+
+      return new Position(start, length);
+    }
+
+    protected void update(IMarkerDelta[] markerDeltas) {
+
+      super.update(markerDeltas);
+
+      //                                       if (markerDeltas != null && markerDeltas.length > 0) {
+      //                                               try {
+      //                                                       ICompilationUnit workingCopy = getWorkingCopy(fInput);
+      //                                                       if (workingCopy != null)
+      //                                                               workingCopy.reconcile(true, null);
+      //                                               } catch (JavaModelException ex) {
+      //                                                       handleCoreException(ex, ex.getMessage());
+      //                                               }
+      //                                       }
+    }
+
+    /*
+     * @see IProblemRequestor#beginReporting()
+     */
+    public void beginReporting() {
+      //                                       ICompilationUnit unit= getWorkingCopy(fInput);
+      //                                       if (unit != null && unit.getJavaProject().isOnClasspath(unit))
+      //                                               fCollectedProblems= new ArrayList();
+      //                                       else
+      fCollectedProblems = null;
+    }
+
+    /*
+     * @see IProblemRequestor#acceptProblem(IProblem)
+     */
+    public void acceptProblem(IProblem problem) {
+      if (isActive())
+        fCollectedProblems.add(problem);
+    }
+
+    /*
+     * @see IProblemRequestor#endReporting()
+     */
+    public void endReporting() {
+      if (!isActive())
+        return;
+
+      if (fProgressMonitor != null && fProgressMonitor.isCanceled())
+        return;
+
+      boolean isCanceled = false;
+      boolean temporaryProblemsChanged = false;
+      fPreviouslyOverlaid = fCurrentlyOverlaid;
+      fCurrentlyOverlaid = new ArrayList();
+
+      synchronized (fAnnotations) {
+
+        if (fGeneratedAnnotations.size() > 0) {
+          temporaryProblemsChanged = true;
+          removeAnnotations(fGeneratedAnnotations, false, true);
+          fGeneratedAnnotations.clear();
+        }
+
+        if (fCollectedProblems != null && fCollectedProblems.size() > 0) {
+
+          Iterator e = fCollectedProblems.iterator();
+          while (e.hasNext()) {
+
+            IProblem problem = (IProblem) e.next();
+
+            if (fProgressMonitor != null && fProgressMonitor.isCanceled()) {
+              isCanceled = true;
+              break;
+            }
+
+            Position position = createPositionFromProblem(problem);
+            if (position != null) {
+
+              //                                                                       ProblemAnnotation annotation= new ProblemAnnotation(problem);
+              //                                                                       overlayMarkers(position, annotation);                                                           
+              //                                                                       fGeneratedAnnotations.add(annotation);
+              //                                                                       addAnnotation(annotation, position, false);
+
+              temporaryProblemsChanged = true;
+            }
+          }
+
+          fCollectedProblems.clear();
+        }
+
+        removeMarkerOverlays(isCanceled);
+        fPreviouslyOverlaid.clear();
+        fPreviouslyOverlaid = null;
+      }
+
+      //                                       if (temporaryProblemsChanged)
+      //                                               fireModelChanged(new CompilationUnitAnnotationModelEvent(this, getResource(), false));
+    }
+
+    private void removeMarkerOverlays(boolean isCanceled) {
+      if (isCanceled) {
+        fCurrentlyOverlaid.addAll(fPreviouslyOverlaid);
+      } else if (fPreviouslyOverlaid != null) {
+        Iterator e = fPreviouslyOverlaid.iterator();
+        while (e.hasNext()) {
+          JavaMarkerAnnotation annotation = (JavaMarkerAnnotation) e.next();
+          annotation.setOverlay(null);
+        }
+      }
+    }
+
+    /**
+     * Overlays value with problem annotation.
+     * @param problemAnnotation
+     */
+    //                         private void setOverlay(Object value, ProblemAnnotation problemAnnotation) {
+    //                                 if (value instanceof  JavaMarkerAnnotation) {
+    //                                         JavaMarkerAnnotation annotation= (JavaMarkerAnnotation) value;
+    //                                         if (annotation.isProblem()) {
+    //                                                 annotation.setOverlay(problemAnnotation);
+    //                                                 fPreviouslyOverlaid.remove(annotation);
+    //                                                 fCurrentlyOverlaid.add(annotation);
+    //                                         }
+    //                                 }
+    //                         }
+
+    //                         private void  overlayMarkers(Position position, ProblemAnnotation problemAnnotation) {
+    //                                 Object value= getAnnotations(position);
+    //                                 if (value instanceof List) {
+    //                                         List list= (List) value;
+    //                                         for (Iterator e = list.iterator(); e.hasNext();)
+    //                                                 setOverlay(e.next(), problemAnnotation);
+    //                                 } else {
+    //                                         setOverlay(value, problemAnnotation);
+    //                                 }
+    //                         }
+
+    /**
+     * Tells this annotation model to collect temporary problems from now on.
+     */
+    private void startCollectingProblems() {
+      fCollectedProblems = new ArrayList();
+      fGeneratedAnnotations = new ArrayList();
+    }
+
+    /**
+     * Tells this annotation model to no longer collect temporary problems.
+     */
+    private void stopCollectingProblems() {
+      if (fGeneratedAnnotations != null) {
+        removeAnnotations(fGeneratedAnnotations, true, true);
+        fGeneratedAnnotations.clear();
+      }
+      fCollectedProblems = null;
+      fGeneratedAnnotations = null;
+    }
+
+    /*
+     * @see AnnotationModel#fireModelChanged()
+     */
+    //                         protected void fireModelChanged() {
+    //                                 fireModelChanged(new CompilationUnitAnnotationModelEvent(this, getResource(), true));
+    //                         }
+
+    /*
+     * @see IProblemRequestor#isActive()
+     */
+    public boolean isActive() {
+      return fIsActive && (fCollectedProblems != null);
+    }
+
+    /*
+     * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor)
+     */
+    public void setProgressMonitor(IProgressMonitor monitor) {
+      fProgressMonitor = monitor;
+    }
+
+    /*
+     * @see IProblemRequestorExtension#setIsActive(boolean)
+     */
+    public void setIsActive(boolean isActive) {
+      if (fIsActive != isActive) {
+        fIsActive = isActive;
+        if (fIsActive)
+          startCollectingProblems();
+        else
+          stopCollectingProblems();
+      }
+    }
+
+    private Object getAnnotations(Position position) {
+      return fReverseMap.get(position);
+    }
+
+    /*
+     * @see AnnotationModel#addAnnotation(Annotation, Position, boolean)
+     */
+    protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged) {
+      super.addAnnotation(annotation, position, fireModelChanged);
+
+      Object cached = fReverseMap.get(position);
+      if (cached == null)
+        fReverseMap.put(position, annotation);
+      else if (cached instanceof List) {
+        List list = (List) cached;
+        list.add(annotation);
+      } else if (cached instanceof Annotation) {
+        List list = new ArrayList(2);
+        list.add(cached);
+        list.add(annotation);
+        fReverseMap.put(position, list);
+      }
+    }
+
+    /*
+     * @see AnnotationModel#removeAllAnnotations(boolean)
+     */
+    protected void removeAllAnnotations(boolean fireModelChanged) {
+      super.removeAllAnnotations(fireModelChanged);
+      fReverseMap.clear();
+    }
+
+    /*
+     * @see AnnotationModel#removeAnnotation(Annotation, boolean)
+     */
+    protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) {
+      Position position = getPosition(annotation);
+      Object cached = fReverseMap.get(position);
+      if (cached instanceof List) {
+        List list = (List) cached;
+        list.remove(annotation);
+        if (list.size() == 1) {
+          fReverseMap.put(position, list.get(0));
+          list.clear();
+        }
+      } else if (cached instanceof Annotation) {
+        fReverseMap.remove(position);
+      }
+
+      super.removeAnnotation(annotation, fireModelChanged);
+    }
+  };
+
+  protected static class GlobalAnnotationModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+    private ListenerList fListenerList;
+
+    public GlobalAnnotationModelListener() {
+      fListenerList = new ListenerList();
+    }
+
+    /**
+     * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+     */
+    public void modelChanged(IAnnotationModel model) {
+      Object[] listeners = fListenerList.getListeners();
+      for (int i = 0; i < listeners.length; i++) {
+        ((IAnnotationModelListener) listeners[i]).modelChanged(model);
+      }
+    }
+
+    /**
+     * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)
+     */
+    public void modelChanged(AnnotationModelEvent event) {
+      Object[] listeners = fListenerList.getListeners();
+      for (int i = 0; i < listeners.length; i++) {
+        Object curr = listeners[i];
+        if (curr instanceof IAnnotationModelListenerExtension) {
+          ((IAnnotationModelListenerExtension) curr).modelChanged(event);
+        }
+      }
+    }
+
+    public void addListener(IAnnotationModelListener listener) {
+      fListenerList.add(listener);
+    }
+
+    public void removeListener(IAnnotationModelListener listener) {
+      fListenerList.remove(listener);
+    }
+  };
 
   public PHPDocumentProvider() {
     super();
+
+    //         fGlobalAnnotationModelListener= new GlobalAnnotationModelListener();
+
   }
 
   /* (non-Javadoc)
@@ -59,7 +488,7 @@ public class PHPDocumentProvider extends FileDocumentProvider {
         IFile file = (IFile) ((FileEditorInput) element).getAdapter(IFile.class);
         String filename = file.getLocation().toString();
         String extension = filename.substring(filename.lastIndexOf("."), filename.length());
-     //   System.out.println(extension);
+        //   System.out.println(extension);
         if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) {
           // html
           partitioner = createHTMLPartitioner();
@@ -101,23 +530,23 @@ public class PHPDocumentProvider extends FileDocumentProvider {
    * Return a partitioner for .html files.
    */
   private IDocumentPartitioner createHTMLPartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
   }
 
   private IDocumentPartitioner createXMLPartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+    return new DefaultPartitioner(getXMLPartitionScanner(), TYPES);
   }
 
   private IDocumentPartitioner createJavaScriptPartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
   }
 
   private IDocumentPartitioner createCSSPartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
   }
 
   private IDocumentPartitioner createSmartyPartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+    return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES);
   }
 
   private IDocumentPartitioner createIncludePartitioner() {
@@ -127,9 +556,36 @@ public class PHPDocumentProvider extends FileDocumentProvider {
    * Return a scanner for creating php partitions.
    */
   private PHPPartitionScanner getPHPPartitionScanner() {
-    if (fgScanner == null)
-      fgScanner = new PHPPartitionScanner();
-    return fgScanner;
+    if (PHP_PARTITION_SCANNER == null)
+      PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.PHP_FILE);
+    return PHP_PARTITION_SCANNER;
+  }
+
+  /**
+   * Return a scanner for creating html partitions.
+   */
+  private PHPPartitionScanner getHTMLPartitionScanner() {
+    if (HTML_PARTITION_SCANNER == null)
+      HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.HTML_FILE);
+    return HTML_PARTITION_SCANNER;
+  }
+
+  /**
+   * Return a scanner for creating xml partitions.
+   */
+  private PHPPartitionScanner getXMLPartitionScanner() {
+    if (XML_PARTITION_SCANNER == null)
+      XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.XML_FILE);
+    return XML_PARTITION_SCANNER;
+  }
+
+  /**
+   * Return a scanner for creating smarty partitions.
+   */
+  private PHPPartitionScanner getSmartyPartitionScanner() {
+    if (SMARTY_PARTITION_SCANNER == null)
+      SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitionScannerConstants.SMARTY_FILE);
+    return SMARTY_PARTITION_SCANNER;
   }
 
   /**
index 16072a2..29f1f20 100644 (file)
@@ -13,6 +13,8 @@ Contributors:
 **********************************************************************/
 import java.util.ArrayList;
 import java.util.List;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
 
 import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
 import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
@@ -30,69 +32,934 @@ import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Preferences;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.DocumentEvent;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
 import org.eclipse.jface.text.IInformationControl;
 import org.eclipse.jface.text.IInformationControlCreator;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextInputListener;
 import org.eclipse.jface.text.ITextOperationTarget;
 import org.eclipse.jface.text.ITextViewer;
 import org.eclipse.jface.text.ITextViewerExtension2;
 import org.eclipse.jface.text.ITextViewerExtension3;
 import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
 import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.information.IInformationProvider;
 import org.eclipse.jface.text.information.InformationPresenter;
+import org.eclipse.jface.text.source.Annotation;
 import org.eclipse.jface.text.source.AnnotationRulerColumn;
 import org.eclipse.jface.text.source.CompositeRuler;
+import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.ISharedTextColors;
 import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ISourceViewerExtension;
 import org.eclipse.jface.text.source.IVerticalRuler;
 import org.eclipse.jface.text.source.IVerticalRulerColumn;
 import org.eclipse.jface.text.source.LineNumberRulerColumn;
+import org.eclipse.jface.text.source.OverviewRuler;
+import org.eclipse.jface.text.source.SourceViewer;
 import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BidiSegmentEvent;
 import org.eclipse.swt.custom.BidiSegmentListener;
+import org.eclipse.swt.custom.StyleRange;
 import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.actions.ActionContext;
 import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.editors.text.DefaultEncodingSupport;
+import org.eclipse.ui.editors.text.IEncodingSupport;
+import org.eclipse.ui.texteditor.AddTaskAction;
 import org.eclipse.ui.texteditor.ContentAssistAction;
 import org.eclipse.ui.texteditor.DefaultRangeIndicator;
+import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
 import org.eclipse.ui.texteditor.IDocumentProvider;
 import org.eclipse.ui.texteditor.IEditorStatusLine;
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.ResourceAction;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
 import org.eclipse.ui.texteditor.StatusTextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
 import org.eclipse.ui.texteditor.TextOperationAction;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
 /**
  * PHP specific text editor.
  */
-public class PHPEditor
-  extends StatusTextEditor
-  implements IViewPartInputProvider { // extends TextEditor {
+public abstract class PHPEditor extends StatusTextEditor implements IViewPartInputProvider { // extends TextEditor {
+  class SelectionChangedListener implements ISelectionChangedListener {
+    public void selectionChanged(SelectionChangedEvent event) {
+      doSelectionChanged(event);
+    }
+  };
+
+  /*
+  * Link mode.  
+  */
+  class MouseClickListener
+    implements
+      KeyListener,
+      MouseListener,
+      MouseMoveListener,
+      FocusListener,
+      PaintListener,
+      IPropertyChangeListener,
+      IDocumentListener,
+      ITextInputListener {
+
+    /** The session is active. */
+    private boolean fActive;
+
+    /** The currently active style range. */
+    private IRegion fActiveRegion;
+    /** The currently active style range as position. */
+    private Position fRememberedPosition;
+    /** The hand cursor. */
+    private Cursor fCursor;
+
+    /** The link color. */
+    private Color fColor;
+    /** The key modifier mask. */
+    private int fKeyModifierMask;
+
+    public void deactivate() {
+      deactivate(false);
+    }
+
+    public void deactivate(boolean redrawAll) {
+      if (!fActive)
+        return;
+
+      repairRepresentation(redrawAll);
+      fActive = false;
+    }
+
+    public void install() {
+
+      ISourceViewer sourceViewer = getSourceViewer();
+      if (sourceViewer == null)
+        return;
+
+      StyledText text = sourceViewer.getTextWidget();
+      if (text == null || text.isDisposed())
+        return;
+
+      updateColor(sourceViewer);
+
+      sourceViewer.addTextInputListener(this);
+
+      IDocument document = sourceViewer.getDocument();
+      if (document != null)
+        document.addDocumentListener(this);
+
+      text.addKeyListener(this);
+      text.addMouseListener(this);
+      text.addMouseMoveListener(this);
+      text.addFocusListener(this);
+      text.addPaintListener(this);
+
+      updateKeyModifierMask();
+
+      IPreferenceStore preferenceStore = getPreferenceStore();
+      preferenceStore.addPropertyChangeListener(this);
+    }
+
+    private void updateKeyModifierMask() {
+      String modifiers = getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER);
+      fKeyModifierMask = computeStateMask(modifiers);
+      if (fKeyModifierMask == -1) {
+        // Fallback to stored state mask
+        fKeyModifierMask = getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
+      };
+    }
+
+    private int computeStateMask(String modifiers) {
+      if (modifiers == null)
+        return -1;
+
+      if (modifiers.length() == 0)
+        return SWT.NONE;
+
+      int stateMask = 0;
+      StringTokenizer modifierTokenizer = new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
+      while (modifierTokenizer.hasMoreTokens()) {
+        int modifier = EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
+        if (modifier == 0 || (stateMask & modifier) == modifier)
+          return -1;
+        stateMask = stateMask | modifier;
+      }
+      return stateMask;
+    }
+
+    public void uninstall() {
+
+      if (fColor != null) {
+        fColor.dispose();
+        fColor = null;
+      }
+
+      if (fCursor != null) {
+        fCursor.dispose();
+        fCursor = null;
+      }
+
+      ISourceViewer sourceViewer = getSourceViewer();
+      if (sourceViewer == null)
+        return;
+
+      sourceViewer.removeTextInputListener(this);
+
+      IDocument document = sourceViewer.getDocument();
+      if (document != null)
+        document.removeDocumentListener(this);
+
+      IPreferenceStore preferenceStore = getPreferenceStore();
+      if (preferenceStore != null)
+        preferenceStore.removePropertyChangeListener(this);
+
+      StyledText text = sourceViewer.getTextWidget();
+      if (text == null || text.isDisposed())
+        return;
+
+      text.removeKeyListener(this);
+      text.removeMouseListener(this);
+      text.removeMouseMoveListener(this);
+      text.removeFocusListener(this);
+      text.removePaintListener(this);
+    }
+
+    /*
+     * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+     */
+    public void propertyChange(PropertyChangeEvent event) {
+      if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
+        ISourceViewer viewer = getSourceViewer();
+        if (viewer != null)
+          updateColor(viewer);
+      } else if (event.getProperty().equals(BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
+        updateKeyModifierMask();
+      }
+    }
+
+    private void updateColor(ISourceViewer viewer) {
+      if (fColor != null)
+        fColor.dispose();
 
+      StyledText text = viewer.getTextWidget();
+      if (text == null || text.isDisposed())
+        return;
+
+      Display display = text.getDisplay();
+      fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR, display);
+    }
+
+    /**
+     * Creates a color from the information stored in the given preference store.
+     * Returns <code>null</code> if there is no such information available.
+     */
+    private Color createColor(IPreferenceStore store, String key, Display display) {
+
+      RGB rgb = null;
+
+      if (store.contains(key)) {
+
+        if (store.isDefault(key))
+          rgb = PreferenceConverter.getDefaultColor(store, key);
+        else
+          rgb = PreferenceConverter.getColor(store, key);
+
+        if (rgb != null)
+          return new Color(display, rgb);
+      }
+
+      return null;
+    }
+
+    private void repairRepresentation() {
+      repairRepresentation(false);
+    }
+
+    private void repairRepresentation(boolean redrawAll) {
+
+      if (fActiveRegion == null)
+        return;
+
+      ISourceViewer viewer = getSourceViewer();
+      if (viewer != null) {
+        resetCursor(viewer);
+
+        int offset = fActiveRegion.getOffset();
+        int length = fActiveRegion.getLength();
+
+        // remove style
+        if (!redrawAll && viewer instanceof ITextViewerExtension2)
+           ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length);
+        else
+          viewer.invalidateTextPresentation();
+
+        // remove underline                            
+        if (viewer instanceof ITextViewerExtension3) {
+          ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+          offset = extension.modelOffset2WidgetOffset(offset);
+        } else {
+          offset -= viewer.getVisibleRegion().getOffset();
+        }
+
+        StyledText text = viewer.getTextWidget();
+        try {
+          text.redrawRange(offset, length, true);
+        } catch (IllegalArgumentException x) {
+          PHPeclipsePlugin.log(x);
+        }
+      }
+
+      fActiveRegion = null;
+    }
+
+    // will eventually be replaced by a method provided by jdt.core            
+    private IRegion selectWord(IDocument document, int anchor) {
+
+      try {
+        int offset = anchor;
+        char c;
+
+        while (offset >= 0) {
+          c = document.getChar(offset);
+          if (!Character.isJavaIdentifierPart(c))
+            break;
+          --offset;
+        }
+
+        int start = offset;
+
+        offset = anchor;
+        int length = document.getLength();
+
+        while (offset < length) {
+          c = document.getChar(offset);
+          if (!Character.isJavaIdentifierPart(c))
+            break;
+          ++offset;
+        }
+
+        int end = offset;
+
+        if (start == end)
+          return new Region(start, 0);
+        else
+          return new Region(start + 1, end - start - 1);
+
+      } catch (BadLocationException x) {
+        return null;
+      }
+    }
+
+    IRegion getCurrentTextRegion(ISourceViewer viewer) {
+
+      int offset = getCurrentTextOffset(viewer);
+      if (offset == -1)
+        return null;
+
+      return null;
+      //                               IJavaElement input= SelectionConverter.getInput(PHPEditor.this);
+      //                               if (input == null)
+      //                                       return null;
+      //
+      //                               try {
+      //                               
+      //                                       IJavaElement[] elements= null;
+      //                                       synchronized (input) {
+      //                                               elements= ((ICodeAssist) input).codeSelect(offset, 0);
+      //                                       }
+      //                               
+      //                                       if (elements == null || elements.length == 0)
+      //                                               return null;
+      //                                       
+      //                                       return selectWord(viewer.getDocument(), offset);
+      //                                       
+      //                               } catch (JavaModelException e) {
+      //                                       return null;    
+      //                               }
+    }
+
+    private int getCurrentTextOffset(ISourceViewer viewer) {
+
+      try {
+        StyledText text = viewer.getTextWidget();
+        if (text == null || text.isDisposed())
+          return -1;
+
+        Display display = text.getDisplay();
+        Point absolutePosition = display.getCursorLocation();
+        Point relativePosition = text.toControl(absolutePosition);
+
+        int widgetOffset = text.getOffsetAtLocation(relativePosition);
+        if (viewer instanceof ITextViewerExtension3) {
+          ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+          return extension.widgetOffset2ModelOffset(widgetOffset);
+        } else {
+          return widgetOffset + viewer.getVisibleRegion().getOffset();
+        }
+
+      } catch (IllegalArgumentException e) {
+        return -1;
+      }
+    }
+
+    private void highlightRegion(ISourceViewer viewer, IRegion region) {
+
+      if (region.equals(fActiveRegion))
+        return;
+
+      repairRepresentation();
+
+      StyledText text = viewer.getTextWidget();
+      if (text == null || text.isDisposed())
+        return;
+
+      // highlight region
+      int offset = 0;
+      int length = 0;
+
+      if (viewer instanceof ITextViewerExtension3) {
+        ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+        IRegion widgetRange = extension.modelRange2WidgetRange(region);
+        if (widgetRange == null)
+          return;
+
+        offset = widgetRange.getOffset();
+        length = widgetRange.getLength();
+
+      } else {
+        offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
+        length = region.getLength();
+      }
+
+      StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset);
+      Color foregroundColor = fColor;
+      Color backgroundColor = oldStyleRange == null ? text.getBackground() : oldStyleRange.background;
+      StyleRange styleRange = new StyleRange(offset, length, foregroundColor, backgroundColor);
+      text.setStyleRange(styleRange);
+
+      // underline
+      text.redrawRange(offset, length, true);
+
+      fActiveRegion = region;
+    }
+
+    private void activateCursor(ISourceViewer viewer) {
+      StyledText text = viewer.getTextWidget();
+      if (text == null || text.isDisposed())
+        return;
+      Display display = text.getDisplay();
+      if (fCursor == null)
+        fCursor = new Cursor(display, SWT.CURSOR_HAND);
+      text.setCursor(fCursor);
+    }
+
+    private void resetCursor(ISourceViewer viewer) {
+      StyledText text = viewer.getTextWidget();
+      if (text != null && !text.isDisposed())
+        text.setCursor(null);
+
+      if (fCursor != null) {
+        fCursor.dispose();
+        fCursor = null;
+      }
+    }
+
+    /*
+     * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+     */
+    public void keyPressed(KeyEvent event) {
+
+      if (fActive) {
+        deactivate();
+        return;
+      }
+
+      if (event.keyCode != fKeyModifierMask) {
+        deactivate();
+        return;
+      }
+
+      fActive = true;
+
+      //                               removed for #25871                      
+      //
+      //                               ISourceViewer viewer= getSourceViewer();
+      //                               if (viewer == null)
+      //                                       return;
+      //                       
+      //                               IRegion region= getCurrentTextRegion(viewer);
+      //                               if (region == null)
+      //                                       return;
+      //                       
+      //                               highlightRegion(viewer, region);
+      //                               activateCursor(viewer);                                                                                         
+    }
+
+    /*
+     * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+     */
+    public void keyReleased(KeyEvent event) {
+
+      if (!fActive)
+        return;
+
+      deactivate();
+    }
+
+    /*
+     * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+     */
+    public void mouseDoubleClick(MouseEvent e) {
+    }
+    /*
+     * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+     */
+    public void mouseDown(MouseEvent event) {
+
+      if (!fActive)
+        return;
+
+      if (event.stateMask != fKeyModifierMask) {
+        deactivate();
+        return;
+      }
+
+      if (event.button != 1) {
+        deactivate();
+        return;
+      }
+    }
+
+    /*
+     * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+     */
+    public void mouseUp(MouseEvent e) {
+
+      if (!fActive)
+        return;
+
+      if (e.button != 1) {
+        deactivate();
+        return;
+      }
+
+      boolean wasActive = fCursor != null;
+
+      deactivate();
+
+      if (wasActive) {
+        IAction action = getAction("OpenEditor"); //$NON-NLS-1$
+        if (action != null)
+          action.run();
+      }
+    }
+
+    /*
+     * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+     */
+    public void mouseMove(MouseEvent event) {
+
+      if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) {
+        deactivate();
+        return;
+      }
+
+      if (!fActive) {
+        if (event.stateMask != fKeyModifierMask)
+          return;
+        // modifier was already pressed
+        fActive = true;
+      }
+
+      ISourceViewer viewer = getSourceViewer();
+      if (viewer == null) {
+        deactivate();
+        return;
+      }
+
+      StyledText text = viewer.getTextWidget();
+      if (text == null || text.isDisposed()) {
+        deactivate();
+        return;
+      }
+
+      if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) {
+        deactivate();
+        return;
+      }
+
+      IRegion region = getCurrentTextRegion(viewer);
+      if (region == null || region.getLength() == 0) {
+        repairRepresentation();
+        return;
+      }
+
+      highlightRegion(viewer, region);
+      activateCursor(viewer);
+    }
+
+    /*
+     * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+     */
+    public void focusGained(FocusEvent e) {
+    }
+
+    /*
+     * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+     */
+    public void focusLost(FocusEvent event) {
+      deactivate();
+    }
+
+    /*
+     * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+     */
+    public void documentAboutToBeChanged(DocumentEvent event) {
+      if (fActive && fActiveRegion != null) {
+        fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength());
+        try {
+          event.getDocument().addPosition(fRememberedPosition);
+        } catch (BadLocationException x) {
+          fRememberedPosition = null;
+        }
+      }
+    }
+
+    /*
+     * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+     */
+    public void documentChanged(DocumentEvent event) {
+      if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) {
+        event.getDocument().removePosition(fRememberedPosition);
+        fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength());
+      }
+      fRememberedPosition = null;
+
+      ISourceViewer viewer = getSourceViewer();
+      if (viewer != null) {
+        StyledText widget = viewer.getTextWidget();
+        if (widget != null && !widget.isDisposed()) {
+          widget.getDisplay().asyncExec(new Runnable() {
+            public void run() {
+              deactivate();
+            }
+          });
+        }
+      }
+    }
+
+    /*
+     * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
+     */
+    public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+      if (oldInput == null)
+        return;
+      deactivate();
+      oldInput.removeDocumentListener(this);
+    }
+
+    /*
+     * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
+     */
+    public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+      if (newInput == null)
+        return;
+      newInput.addDocumentListener(this);
+    }
+
+    /*
+     * @see PaintListener#paintControl(PaintEvent)
+     */
+    public void paintControl(PaintEvent event) {
+      if (fActiveRegion == null)
+        return;
+
+      ISourceViewer viewer = getSourceViewer();
+      if (viewer == null)
+        return;
+
+      StyledText text = viewer.getTextWidget();
+      if (text == null || text.isDisposed())
+        return;
+
+      int offset = 0;
+      int length = 0;
+
+      if (viewer instanceof ITextViewerExtension3) {
+
+        ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
+        IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset, length));
+        if (widgetRange == null)
+          return;
+
+        offset = widgetRange.getOffset();
+        length = widgetRange.getLength();
+
+      } else {
+
+        IRegion region = viewer.getVisibleRegion();
+        if (!includes(region, fActiveRegion))
+          return;
+
+        offset = fActiveRegion.getOffset() - region.getOffset();
+        length = fActiveRegion.getLength();
+      }
+
+      // support for bidi
+      Point minLocation = getMinimumLocation(text, offset, length);
+      Point maxLocation = getMaximumLocation(text, offset, length);
+
+      int x1 = minLocation.x;
+      int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+      int y = minLocation.y + text.getLineHeight() - 1;
+
+      GC gc = event.gc;
+      if (fColor != null && !fColor.isDisposed())
+        gc.setForeground(fColor);
+      gc.drawLine(x1, y, x2, y);
+    }
+
+    private boolean includes(IRegion region, IRegion position) {
+      return position.getOffset() >= region.getOffset()
+        && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
+    }
+
+    private Point getMinimumLocation(StyledText text, int offset, int length) {
+      Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+      for (int i = 0; i <= length; i++) {
+        Point location = text.getLocationAtOffset(offset + i);
+
+        if (location.x < minLocation.x)
+          minLocation.x = location.x;
+        if (location.y < minLocation.y)
+          minLocation.y = location.y;
+      }
+
+      return minLocation;
+    }
+
+    private Point getMaximumLocation(StyledText text, int offset, int length) {
+      Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+
+      for (int i = 0; i <= length; i++) {
+        Point location = text.getLocationAtOffset(offset + i);
+
+        if (location.x > maxLocation.x)
+          maxLocation.x = location.x;
+        if (location.y > maxLocation.y)
+          maxLocation.y = location.y;
+      }
+
+      return maxLocation;
+    }
+  };
+
+  /**
+   * This action dispatches into two behaviours: If there is no current text
+   * hover, the javadoc is displayed using information presenter. If there is
+   * a current text hover, it is converted into a information presenter in
+   * order to make it sticky.
+   */
+  class InformationDispatchAction extends TextEditorAction {
+
+    /** The wrapped text operation action. */
+    private final TextOperationAction fTextOperationAction;
+
+    /**
+     * Creates a dispatch action.
+     */
+    public InformationDispatchAction(ResourceBundle resourceBundle, String prefix, final TextOperationAction textOperationAction) {
+      super(resourceBundle, prefix, PHPEditor.this);
+      if (textOperationAction == null)
+        throw new IllegalArgumentException();
+      fTextOperationAction = textOperationAction;
+    }
+
+    /*
+     * @see org.eclipse.jface.action.IAction#run()
+     */
+    public void run() {
+
+      ISourceViewer sourceViewer = getSourceViewer();
+      if (sourceViewer == null) {
+        fTextOperationAction.run();
+        return;
+      }
+
+      if (!(sourceViewer instanceof ITextViewerExtension2)) {
+        fTextOperationAction.run();
+        return;
+      }
+
+      ITextViewerExtension2 textViewerExtension2 = (ITextViewerExtension2) sourceViewer;
+
+      // does a text hover exist?
+      ITextHover textHover = textViewerExtension2.getCurrentTextHover();
+      if (textHover == null) {
+        fTextOperationAction.run();
+        return;
+      }
+
+      Point hoverEventLocation = textViewerExtension2.getHoverEventLocation();
+      int offset = computeOffsetAtLocation(sourceViewer, hoverEventLocation.x, hoverEventLocation.y);
+      if (offset == -1) {
+        fTextOperationAction.run();
+        return;
+      }
+
+      try {
+        // get the text hover content
+        IDocument document = sourceViewer.getDocument();
+        String contentType = document.getContentType(offset);
+
+        final IRegion hoverRegion = textHover.getHoverRegion(sourceViewer, offset);
+        if (hoverRegion == null)
+          return;
+
+        final String hoverInfo = textHover.getHoverInfo(sourceViewer, hoverRegion);
+
+        // with information provider
+        IInformationProvider informationProvider = new IInformationProvider() {
+          /*
+           * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int)
+           */
+          public IRegion getSubject(ITextViewer textViewer, int offset) {
+            return hoverRegion;
+          }
+          /*
+           * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
+           */
+          public String getInformation(ITextViewer textViewer, IRegion subject) {
+            return hoverInfo;
+          }
+        };
+
+        fInformationPresenter.setOffset(offset);
+        fInformationPresenter.setInformationProvider(informationProvider, contentType);
+        fInformationPresenter.showInformation();
+
+      } catch (BadLocationException e) {
+      }
+    }
+
+    // modified version from TextViewer
+    private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {
+
+      StyledText styledText = textViewer.getTextWidget();
+      IDocument document = textViewer.getDocument();
+
+      if (document == null)
+        return -1;
+
+      try {
+        int widgetLocation = styledText.getOffsetAtLocation(new Point(x, y));
+        if (textViewer instanceof ITextViewerExtension3) {
+          ITextViewerExtension3 extension = (ITextViewerExtension3) textViewer;
+          return extension.widgetOffset2ModelOffset(widgetLocation);
+        } else {
+          IRegion visibleRegion = textViewer.getVisibleRegion();
+          return widgetLocation + visibleRegion.getOffset();
+        }
+      } catch (IllegalArgumentException e) {
+        return -1;
+      }
+
+    }
+  };
+
+  static protected class AnnotationAccess implements IAnnotationAccess {
+    /*
+     * @see org.eclipse.jface.text.source.IAnnotationAccess#getType(org.eclipse.jface.text.source.Annotation)
+     */
+    public Object getType(Annotation annotation) {
+      if (annotation instanceof IJavaAnnotation) {
+        IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+        if (javaAnnotation.isRelevant())
+          return javaAnnotation.getAnnotationType();
+      }
+      return null;
+    }
+
+    /*
+     * @see org.eclipse.jface.text.source.IAnnotationAccess#isMultiLine(org.eclipse.jface.text.source.Annotation)
+     */
+    public boolean isMultiLine(Annotation annotation) {
+      return true;
+    }
+
+    /*
+     * @see org.eclipse.jface.text.source.IAnnotationAccess#isTemporary(org.eclipse.jface.text.source.Annotation)
+     */
+    public boolean isTemporary(Annotation annotation) {
+      if (annotation instanceof IJavaAnnotation) {
+        IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
+        if (javaAnnotation.isRelevant())
+          return javaAnnotation.isTemporary();
+      }
+      return false;
+    }
+  };
+
+  private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener {
+    /*
+     * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+     */
+    public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+      handlePreferencePropertyChanged(event);
+    }
+  };
   /** Preference key for showing the line number ruler */
-  private final static String LINE_NUMBER_RULER =
-    PreferenceConstants.EDITOR_LINE_NUMBER_RULER;
+  private final static String LINE_NUMBER_RULER = PreferenceConstants.EDITOR_LINE_NUMBER_RULER;
   /** Preference key for the foreground color of the line numbers */
-  private final static String LINE_NUMBER_COLOR =
-    PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR;
+  private final static String LINE_NUMBER_COLOR = PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR;
   /** Preference key for the link color */
-  private final static String LINK_COLOR =
-    PreferenceConstants.EDITOR_LINK_COLOR;
+  private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR;
 
   // protected PHPActionGroup fActionGroups;
   /** The outline page */
@@ -101,11 +968,17 @@ public class PHPEditor
   //  protected PHPSyntaxParserThread fValidationThread = null;
 
   // private IPreferenceStore fPHPPrefStore;
+  /** The selection changed listener */
+  protected ISelectionChangedListener fSelectionChangedListener = new SelectionChangedListener();
 
   /** The editor's bracket matcher */
-  private PHPPairMatcher fBracketMatcher;
+  private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS);
   /** The line number ruler column */
   private LineNumberRulerColumn fLineNumberRulerColumn;
+  /** This editor's encoding support */
+  private DefaultEncodingSupport fEncodingSupport;
+  /** The mouse listener */
+  private MouseClickListener fMouseListener;
 
   protected CompositeActionGroup fActionGroups;
   /** The standard action groups added to the menu */
@@ -114,6 +987,17 @@ public class PHPEditor
 
   /** The information presenter. */
   private InformationPresenter fInformationPresenter;
+  /** The annotation access */
+  protected IAnnotationAccess fAnnotationAccess = new AnnotationAccess();
+  /** The overview ruler */
+  protected OverviewRuler isOverviewRulerVisible;
+  /** The source viewer decoration support */
+  protected SourceViewerDecorationSupport fSourceViewerDecorationSupport;
+  /** The overview ruler */
+  protected OverviewRuler fOverviewRuler;
+
+  /** The preference property change listener for java core. */
+  private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
 
   /**
    * Default constructor.
@@ -121,15 +1005,15 @@ public class PHPEditor
   public PHPEditor() {
     super();
     JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
-    setSourceViewerConfiguration(
-      new PHPSourceViewerConfiguration(textTools, this));
+    setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this));
     setRangeIndicator(new DefaultRangeIndicator());
     setPreferenceStore(PHPeclipsePlugin.getDefault().getPreferenceStore());
 
+    // don't activate this scope without synchronizing plugin.xml !!!
+    //    setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$
+
     //    if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
     //      fUpdater= new OutlinePageSelectionUpdater();
-
-    initializeEditor();
   }
   //
   //   /**
@@ -146,7 +1030,15 @@ public class PHPEditor
   //   
   //           return doc.get().toCharArray();
   //   }
-
+  /*
+   * @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions()
+   */
+  protected void updatePropertyDependentActions() {
+    super.updatePropertyDependentActions();
+    if (fEncodingSupport != null)
+      fEncodingSupport.reset();
+  }
+  
   /*
    * Update the hovering behavior depending on the preferences.
    */
@@ -158,32 +1050,22 @@ public class PHPEditor
 
       String t = types[i];
 
-      int[] stateMasks =
-        configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t);
+      int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t);
 
       ISourceViewer sourceViewer = getSourceViewer();
       if (sourceViewer instanceof ITextViewerExtension2) {
         if (stateMasks != null) {
           for (int j = 0; j < stateMasks.length; j++) {
             int stateMask = stateMasks[j];
-            ITextHover textHover =
-              configuration.getTextHover(sourceViewer, t, stateMask);
-            ((ITextViewerExtension2) sourceViewer).setTextHover(
-              textHover,
-              t,
-              stateMask);
+            ITextHover textHover = configuration.getTextHover(sourceViewer, t, stateMask);
+            ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, stateMask);
           }
         } else {
           ITextHover textHover = configuration.getTextHover(sourceViewer, t);
-          ((ITextViewerExtension2) sourceViewer).setTextHover(
-            textHover,
-            t,
-            ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+          ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
         }
       } else
-        sourceViewer.setTextHover(
-          configuration.getTextHover(sourceViewer, t),
-          t);
+        sourceViewer.setTextHover(configuration.getTextHover(sourceViewer, t), t);
     }
   }
 
@@ -201,16 +1083,16 @@ public class PHPEditor
   public void createPartControl(Composite parent) {
     super.createPartControl(parent);
 
-    IInformationControlCreator informationControlCreator =
-      new IInformationControlCreator() {
+    fSourceViewerDecorationSupport.install(getPreferenceStore());
+
+    Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
+    preferences.addPropertyChangeListener(fPropertyChangeListener);
+
+    IInformationControlCreator informationControlCreator = new IInformationControlCreator() {
       public IInformationControl createInformationControl(Shell parent) {
         boolean cutDown = false;
         int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
-        return new DefaultInformationControl(
-          parent,
-          SWT.RESIZE,
-          style,
-          new HTMLTextPresenter(cutDown));
+        return new DefaultInformationControl(parent, SWT.RESIZE, style, new HTMLTextPresenter(cutDown));
       }
     };
 
@@ -225,8 +1107,7 @@ public class PHPEditor
    * @return the document's complete text
    */
   public String get() {
-    IDocument doc =
-      this.getDocumentProvider().getDocument(this.getEditorInput());
+    IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
     return doc.get();
   }
 
@@ -248,6 +1129,17 @@ public class PHPEditor
   protected void createActions() {
     super.createActions();
 
+    ResourceAction resAction = new AddTaskAction(PHPEditorMessages.getResourceBundle(), "AddTask.", this); //$NON-NLS-1$
+    resAction.setHelpContextId(IAbstractTextEditorHelpContextIds.ADD_TASK_ACTION);
+    resAction.setActionDefinitionId(ITextEditorActionDefinitionIds.ADD_TASK);
+    setAction(ITextEditorActionConstants.ADD_TASK, resAction);
+
+    resAction = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "ShowJavaDoc.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$
+    resAction = new InformationDispatchAction(PHPEditorMessages.getResourceBundle(), "ShowJavaDoc.", (TextOperationAction) resAction); //$NON-NLS-1$
+    resAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_JAVADOC);
+    setAction("ShowJavaDoc", resAction); //$NON-NLS-1$
+    //                                         WorkbenchHelp.setHelp(resAction, IJavaHelpContextIds.SHOW_JAVADOC_ACTION);
+
     Action action;
 
     setAction(
@@ -259,12 +1151,14 @@ public class PHPEditor
         ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION));
 
     action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$
-    action.setActionDefinitionId(
-      PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+    action.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
     setAction("ContentAssistProposal", action); //$NON-NLS-1$
     markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
     // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.CONTENT_ASSIST_ACTION);
 
+    fEncodingSupport = new DefaultEncodingSupport();
+    fEncodingSupport.initialize(this);
+
     action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Comment.", this, ITextOperationTarget.PREFIX); //$NON-NLS-1$
     action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT);
     setAction("Comment", action); //$NON-NLS-1$
@@ -285,19 +1179,15 @@ public class PHPEditor
     // WorkbenchHelp.setHelp(action, IJavaHelpContextIds.FORMAT_ACTION);
 
     action = new GotoMatchingBracketAction(this);
-    action.setActionDefinitionId(
-      PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+    action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
     setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
 
-    fGenerateActionGroup =
-      new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
+    fGenerateActionGroup = new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
 
-    fActionGroups =
-      new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup });
+    fActionGroups = new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup });
 
     // We have to keep the context menu group separate to have better control over positioning
-    fContextMenuGroup =
-      new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup });
+    fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup });
     //      rg, 
     //      new LocalHistoryActionGroup(this, ITextEditorActionConstants.GROUP_EDIT)});
 
@@ -324,6 +1214,29 @@ public class PHPEditor
     if (fActionGroups != null)
       fActionGroups.dispose();
 
+    if (isBrowserLikeLinks())
+      disableBrowserLikeLinks();
+
+    if (fEncodingSupport != null) {
+      fEncodingSupport.dispose();
+      fEncodingSupport = null;
+    }
+
+    if (fPropertyChangeListener != null) {
+      Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
+      preferences.removePropertyChangeListener(fPropertyChangeListener);
+      fPropertyChangeListener = null;
+    }
+
+    if (fSourceViewerDecorationSupport != null) {
+      fSourceViewerDecorationSupport.dispose();
+      fSourceViewerDecorationSupport = null;
+    }
+
+    if (fBracketMatcher != null) {
+      fBracketMatcher.dispose();
+      fBracketMatcher = null;
+    }
     super.dispose();
   }
 
@@ -344,7 +1257,7 @@ public class PHPEditor
   public void doSave(IProgressMonitor monitor) {
     super.doSave(monitor);
     // compile or not, according to the user preferences
-    IPreferenceStore store = getPreferenceStore(); // fPHPPrefStore;
+    // IPreferenceStore store = getPreferenceStore(); 
 
     // the parse on save was changed to the eclipse "builders" concept
     //    if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
@@ -371,15 +1284,53 @@ public class PHPEditor
     if (fOutlinePage != null)
       fOutlinePage.update();
   }
+  /*
+        * @see StatusTextEditor#getStatusHeader(IStatus)
+        */
+  protected String getStatusHeader(IStatus status) {
+    if (fEncodingSupport != null) {
+      String message = fEncodingSupport.getStatusHeader(status);
+      if (message != null)
+        return message;
+    }
+    return super.getStatusHeader(status);
+  }
+
+  /*
+   * @see StatusTextEditor#getStatusBanner(IStatus)
+   */
+  protected String getStatusBanner(IStatus status) {
+    if (fEncodingSupport != null) {
+      String message = fEncodingSupport.getStatusBanner(status);
+      if (message != null)
+        return message;
+    }
+    return super.getStatusBanner(status);
+  }
 
+  /*
+   * @see StatusTextEditor#getStatusMessage(IStatus)
+   */
+  protected String getStatusMessage(IStatus status) {
+    if (fEncodingSupport != null) {
+      String message = fEncodingSupport.getStatusMessage(status);
+      if (message != null)
+        return message;
+    }
+    return super.getStatusMessage(status);
+  }
   /** The <code>PHPEditor</code> implementation of this 
    * <code>AbstractTextEditor</code> method performs sets the 
    * input of the outline page after AbstractTextEditor has set input.
    */
   protected void doSetInput(IEditorInput input) throws CoreException {
     super.doSetInput(input);
+
+    if (fEncodingSupport != null)
+      fEncodingSupport.reset();
     if (fOutlinePage != null)
       fOutlinePage.setInput(input);
+    //         setOutlinePageInput(fOutlinePage, input);
   }
 
   /*
@@ -395,15 +1346,10 @@ public class PHPEditor
    */
   public void editorContextMenuAboutToShow(MenuManager menu) {
     super.editorContextMenuAboutToShow(menu);
-    menu.appendToGroup(
-      ITextEditorActionConstants.GROUP_UNDO,
-      new Separator(IContextMenuConstants.GROUP_OPEN));
-    menu.insertAfter(
-      IContextMenuConstants.GROUP_OPEN,
-      new GroupMarker(IContextMenuConstants.GROUP_SHOW));
-
-    ActionContext context =
-      new ActionContext(getSelectionProvider().getSelection());
+    menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, new Separator(IContextMenuConstants.GROUP_OPEN));
+    menu.insertAfter(IContextMenuConstants.GROUP_OPEN, new GroupMarker(IContextMenuConstants.GROUP_SHOW));
+
+    ActionContext context = new ActionContext(getSelectionProvider().getSelection());
     fContextMenuGroup.setContext(context);
     fContextMenuGroup.fillContextMenu(menu);
     fContextMenuGroup.setContext(null);
@@ -416,6 +1362,31 @@ public class PHPEditor
     //    fContextMenuGroup.setContext(null);
   }
 
+  /**
+   * Creates the outline page used with this editor.
+   */
+  protected AbstractContentOutlinePage createOutlinePage() {
+
+    AbstractContentOutlinePage page = new PHPContentOutlinePage(getDocumentProvider(), this);
+
+    page.addSelectionChangedListener(fSelectionChangedListener);
+    //    setOutlinePageInput(page, getEditorInput());
+    if (getEditorInput() != null)
+      fOutlinePage.setInput(getEditorInput());
+
+    return page;
+  }
+
+  /**
+   * Informs the editor that its outliner has been closed.
+   */
+  public void outlinePageClosed() {
+    if (fOutlinePage != null) {
+      fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
+      fOutlinePage = null;
+      resetHighlightRange();
+    }
+  }
   protected void updateStateDependentActions() {
     super.updateStateDependentActions();
     fGenerateActionGroup.editorStateChanged();
@@ -435,9 +1406,45 @@ public class PHPEditor
       }
       return fOutlinePage;
     }
+
+    if (IEncodingSupport.class.equals(required))
+      return fEncodingSupport;
+
     return super.getAdapter(required);
   }
 
+  protected void doSelectionChanged(SelectionChangedEvent event) {
+
+    //                 ISourceReference reference= null;
+    //         
+    //                 ISelection selection= event.getSelection();
+    //                 Iterator iter= ((IStructuredSelection) selection).iterator();
+    //                 while (iter.hasNext()) {
+    //                         Object o= iter.next();
+    //                         if (o instanceof ISourceReference) {
+    //                                 reference= (ISourceReference) o;
+    //                                 break;
+    //                         }
+    //                 }
+    if (!isActivePart() && PHPeclipsePlugin.getActivePage() != null)
+      PHPeclipsePlugin.getActivePage().bringToTop(this);
+
+    //                 try {
+    //                         editingScriptStarted();
+    //                         setSelection(reference, !isActivePart());
+    //                 } finally {
+    //                         editingScriptEnded();
+    //                 }
+  }
+
+  protected boolean isActivePart() {
+    IWorkbenchWindow window = getSite().getWorkbenchWindow();
+    IPartService service = window.getPartService();
+    IWorkbenchPart part = service.getActivePart();
+    return part != null && part.equals(this);
+  }
+
+               
   //  public void openContextHelp() {
   //    IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
   //    ITextSelection selection = (ITextSelection) this.getSelectionProvider().getSelection();
@@ -489,12 +1496,19 @@ public class PHPEditor
         if (value instanceof Integer) {
           sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
         } else if (value instanceof String) {
-          sourceViewer.getTextWidget().setTabs(
-            Integer.parseInt((String) value));
+          sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value));
         }
         return;
       }
 
+      if (OVERVIEW_RULER.equals(property)) {
+        if (isOverviewRulerVisible())
+          showOverviewRuler();
+        else
+          hideOverviewRuler();
+        return;
+      }
+
       if (LINE_NUMBER_RULER.equals(property)) {
         if (isLineNumberRulerVisible())
           showLineNumberRuler();
@@ -585,6 +1599,49 @@ public class PHPEditor
       c.addDecorator(1, createLineNumberRulerColumn());
     }
   }
+  /**
+        * Return whether the browser like links should be enabled
+        * according to the preference store settings.
+        * @return <code>true</code> if the browser like links should be enabled
+        */
+  private boolean isBrowserLikeLinks() {
+    IPreferenceStore store = getPreferenceStore();
+    return store.getBoolean(BROWSER_LIKE_LINKS);
+  }
+
+  /**
+   * Enables browser like links.
+   */
+  private void enableBrowserLikeLinks() {
+    if (fMouseListener == null) {
+      fMouseListener = new MouseClickListener();
+      fMouseListener.install();
+    }
+  }
+
+  /**
+   * Disables browser like links.
+   */
+  private void disableBrowserLikeLinks() {
+    if (fMouseListener != null) {
+      fMouseListener.uninstall();
+      fMouseListener = null;
+    }
+  }
+  /**
+   * Handles a property change event describing a change
+   * of the java core's preferences and updates the preference
+   * related editor properties.
+   * 
+   * @param event the property change event
+   */
+  protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+    //         if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
+    //                 ISourceViewer sourceViewer= getSourceViewer();
+    //                 if (sourceViewer != null && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue())))
+    //                         sourceViewer.invalidateTextPresentation();
+    //         }
+  }
 
   /**
    * Return whether the line number ruler column should be 
@@ -635,13 +1692,9 @@ public class PHPEditor
       if (!store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
         if (store.contains(PREFERENCE_COLOR_BACKGROUND)) {
           if (store.isDefault(PREFERENCE_COLOR_BACKGROUND))
-            rgb =
-              PreferenceConverter.getDefaultColor(
-                store,
-                PREFERENCE_COLOR_BACKGROUND);
+            rgb = PreferenceConverter.getDefaultColor(store, PREFERENCE_COLOR_BACKGROUND);
           else
-            rgb =
-              PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND);
+            rgb = PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND);
         }
       }
       rulerColumn.setBackground(manager.getColor(rgb));
@@ -668,35 +1721,6 @@ public class PHPEditor
     return ruler;
   }
 
-  /* (non-Javadoc)
-   * Method declared on TextEditor
-   */
-  protected void initializeEditor() {
-    IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
-    //   PHPEditorEnvironment.connect(this);
-
-    //    store.addPropertyChangeListener(new IPropertyChangeListener() {
-    //      public void propertyChange(PropertyChangeEvent event) {
-    //        PHPCodeScanner scanner = PHPEditorEnvironment.getPHPCodeScanner();
-    //        if (scanner != null) {
-    //          scanner.updateToken(PHPEditorEnvironment.getPHPColorProvider());
-    //        }
-    //        if (getSourceViewer() != null) {
-    //          getSourceViewer().invalidateTextPresentation();
-    //        }
-    //
-    //        String property = event.getProperty();
-    //        if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
-    //          if (isLineNumberRulerVisible())
-    //            showLineNumberRuler();
-    //          else
-    //            hideLineNumberRuler();
-    //          return;
-    //        }
-    //      }
-    //    });
-  }
-
   private static IRegion getSignedSelection(ITextViewer viewer) {
 
     StyledText text = viewer.getTextWidget();
@@ -718,6 +1742,78 @@ public class PHPEditor
     return new Region(offset, length);
   }
 
+  /** Preference key for matching brackets */
+  protected final static String MATCHING_BRACKETS = PreferenceConstants.EDITOR_MATCHING_BRACKETS;
+  /** Preference key for matching brackets color */
+  protected final static String MATCHING_BRACKETS_COLOR = PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
+  /** Preference key for highlighting current line */
+  protected final static String CURRENT_LINE = PreferenceConstants.EDITOR_CURRENT_LINE;
+  /** Preference key for highlight color of current line */
+  protected final static String CURRENT_LINE_COLOR = PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
+  /** Preference key for showing print marging ruler */
+  protected final static String PRINT_MARGIN = PreferenceConstants.EDITOR_PRINT_MARGIN;
+  /** Preference key for print margin ruler color */
+  protected final static String PRINT_MARGIN_COLOR = PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
+  /** Preference key for print margin ruler column */
+  protected final static String PRINT_MARGIN_COLUMN = PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
+  /** Preference key for error indication */
+  protected final static String ERROR_INDICATION = PreferenceConstants.EDITOR_PROBLEM_INDICATION;
+  /** Preference key for error color */
+  protected final static String ERROR_INDICATION_COLOR = PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
+  /** Preference key for warning indication */
+  protected final static String WARNING_INDICATION = PreferenceConstants.EDITOR_WARNING_INDICATION;
+  /** Preference key for warning color */
+  protected final static String WARNING_INDICATION_COLOR = PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
+  /** Preference key for task indication */
+  protected final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION;
+  /** Preference key for task color */
+  protected final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
+  /** Preference key for bookmark indication */
+  protected final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
+  /** Preference key for bookmark color */
+  protected final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
+  /** Preference key for search result indication */
+  protected final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
+  /** Preference key for search result color */
+  protected final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
+  /** Preference key for unknown annotation indication */
+  protected final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
+  /** Preference key for unknown annotation color */
+  protected final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
+  /** Preference key for shwoing the overview ruler */
+  protected final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER;
+  /** Preference key for error indication in overview ruler */
+  protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
+  /** Preference key for warning indication in overview ruler */
+  protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER =
+    PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
+  /** Preference key for task indication in overview ruler */
+  protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
+  /** Preference key for bookmark indication in overview ruler */
+  protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER =
+    PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+  /** Preference key for search result indication in overview ruler */
+  protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER =
+    PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+  /** Preference key for unknown annotation indication in overview ruler */
+  protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER =
+    PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+  //           /** Preference key for compiler task tags */
+  //           private final static String COMPILER_TASK_TAGS= JavaCore.COMPILER_TASK_TAGS;
+  /** Preference key for browser like links */
+  private final static String BROWSER_LIKE_LINKS = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS;
+  /** Preference key for key modifier of browser like links */
+  private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER;
+  /**
+   * Preference key for key modifier mask of browser like links.
+   * The value is only used if the value of <code>EDITOR_BROWSER_LIKE_LINKS</code>
+   * cannot be resolved to valid SWT modifier bits.
+   * 
+   * @since 2.1.1
+   */
+  private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK =
+    PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
+
   private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
 
   private static boolean isBracket(char character) {
@@ -727,28 +1823,70 @@ public class PHPEditor
     return false;
   }
 
-  private static boolean isSurroundedByBrackets(
-    IDocument document,
-    int offset) {
+  private static boolean isSurroundedByBrackets(IDocument document, int offset) {
     if (offset == 0 || offset == document.getLength())
       return false;
 
     try {
-      return isBracket(document.getChar(offset - 1))
-        && isBracket(document.getChar(offset));
+      return isBracket(document.getChar(offset - 1)) && isBracket(document.getChar(offset));
 
     } catch (BadLocationException e) {
       return false;
     }
   }
+
+  protected void configureSourceViewerDecorationSupport() {
+
+    fSourceViewerDecorationSupport.setCharacterPairMatcher(fBracketMatcher);
+
+    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+      AnnotationType.UNKNOWN,
+      UNKNOWN_INDICATION_COLOR,
+      UNKNOWN_INDICATION,
+      UNKNOWN_INDICATION_IN_OVERVIEW_RULER,
+      0);
+    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+      AnnotationType.BOOKMARK,
+      BOOKMARK_INDICATION_COLOR,
+      BOOKMARK_INDICATION,
+      BOOKMARK_INDICATION_IN_OVERVIEW_RULER,
+      1);
+    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+      AnnotationType.TASK,
+      TASK_INDICATION_COLOR,
+      TASK_INDICATION,
+      TASK_INDICATION_IN_OVERVIEW_RULER,
+      2);
+    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+      AnnotationType.SEARCH,
+      SEARCH_RESULT_INDICATION_COLOR,
+      SEARCH_RESULT_INDICATION,
+      SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER,
+      3);
+    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+      AnnotationType.WARNING,
+      WARNING_INDICATION_COLOR,
+      WARNING_INDICATION,
+      WARNING_INDICATION_IN_OVERVIEW_RULER,
+      4);
+    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
+      AnnotationType.ERROR,
+      ERROR_INDICATION_COLOR,
+      ERROR_INDICATION,
+      ERROR_INDICATION_IN_OVERVIEW_RULER,
+      5);
+
+    fSourceViewerDecorationSupport.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR);
+    fSourceViewerDecorationSupport.setMarginPainterPreferenceKeys(PRINT_MARGIN, PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN);
+    fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
+
+    fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey());
+  }
   /**
     * Jumps to the matching bracket.
     */
   public void gotoMatchingBracket() {
 
-    if (fBracketMatcher == null)
-      fBracketMatcher = new PHPPairMatcher(BRACKETS);
-
     ISourceViewer sourceViewer = getSourceViewer();
     IDocument document = sourceViewer.getDocument();
     if (document == null)
@@ -782,8 +1920,7 @@ public class PHPEditor
       return;
 
     int anchor = fBracketMatcher.getAnchor();
-    int targetOffset =
-      (PHPPairMatcher.RIGHT == anchor) ? offset : offset + length - 1;
+    int targetOffset = (PHPPairMatcher.RIGHT == anchor) ? offset : offset + length - 1;
 
     boolean visible = false;
     if (sourceViewer instanceof ITextViewerExtension3) {
@@ -791,9 +1928,7 @@ public class PHPEditor
       visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
     } else {
       IRegion visibleRegion = sourceViewer.getVisibleRegion();
-      visible =
-        (targetOffset >= visibleRegion.getOffset()
-          && targetOffset < visibleRegion.getOffset() + visibleRegion.getLength());
+      visible = (targetOffset >= visibleRegion.getOffset() && targetOffset < visibleRegion.getOffset() + visibleRegion.getLength());
     }
 
     if (!visible) {
@@ -813,8 +1948,7 @@ public class PHPEditor
      * @param msg message to be set
      */
   protected void setStatusLineErrorMessage(String msg) {
-    IEditorStatusLine statusLine =
-      (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
+    IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
     if (statusLine != null)
       statusLine.setMessage(true, msg, null);
   }
@@ -828,18 +1962,14 @@ public class PHPEditor
      * @return the line's bidi segmentation
      * @throws BadLocationException in case lineOffset is not valid in document
      */
-  public static int[] getBidiLineSegments(IDocument document, int lineOffset)
-    throws BadLocationException {
+  public static int[] getBidiLineSegments(IDocument document, int lineOffset) throws BadLocationException {
 
     IRegion line = document.getLineInformationOfOffset(lineOffset);
-    ITypedRegion[] linePartitioning =
-      document.computePartitioning(lineOffset, line.getLength());
+    ITypedRegion[] linePartitioning = document.computePartitioning(lineOffset, line.getLength());
 
     List segmentation = new ArrayList();
     for (int i = 0; i < linePartitioning.length; i++) {
-      if (IPHPPartitionScannerConstants
-        .PHP_STRING
-        .equals(linePartitioning[i].getType()))
+      if (IPHPPartitionScannerConstants.PHP_STRING.equals(linePartitioning[i].getType()))
         segmentation.add(linePartitioning[i]);
     }
 
@@ -899,29 +2029,76 @@ public class PHPEditor
   /*
    * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
    */
-  protected final ISourceViewer createSourceViewer(
-    Composite parent,
-    IVerticalRuler ruler,
-    int styles) {
-    ISourceViewer viewer = createJavaSourceViewer(parent, ruler, styles);
+  //  protected final ISourceViewer createSourceViewer(
+  //    Composite parent,
+  //    IVerticalRuler ruler,
+  //    int styles) {
+  //    ISourceViewer viewer = createJavaSourceViewer(parent, ruler, styles);
+  //    StyledText text = viewer.getTextWidget();
+  //    text.addBidiSegmentListener(new BidiSegmentListener() {
+  //      public void lineGetSegments(BidiSegmentEvent event) {
+  //        event.segments = getBidiLineSegments(event.lineOffset, event.lineText);
+  //      }
+  //    });
+  //    //   JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+  //    return viewer;
+  //  }
+  protected final ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
+
+    ISharedTextColors sharedColors = PHPeclipsePlugin.getDefault().getJavaTextTools().getColorManager();
+
+    fOverviewRuler = new OverviewRuler(fAnnotationAccess, VERTICAL_RULER_WIDTH, sharedColors);
+    fOverviewRuler.addHeaderAnnotationType(AnnotationType.WARNING);
+    fOverviewRuler.addHeaderAnnotationType(AnnotationType.ERROR);
+
+    ISourceViewer viewer = createJavaSourceViewer(parent, verticalRuler, fOverviewRuler, isOverviewRulerVisible(), styles);
+
     StyledText text = viewer.getTextWidget();
     text.addBidiSegmentListener(new BidiSegmentListener() {
       public void lineGetSegments(BidiSegmentEvent event) {
         event.segments = getBidiLineSegments(event.lineOffset, event.lineText);
       }
     });
-    //   JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+
+    //         JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
+
+    fSourceViewerDecorationSupport = new SourceViewerDecorationSupport(viewer, fOverviewRuler, fAnnotationAccess, sharedColors);
+    configureSourceViewerDecorationSupport();
+
     return viewer;
   }
 
+  protected void showOverviewRuler() {
+    if (fOverviewRuler != null) {
+      if (getSourceViewer() instanceof ISourceViewerExtension) {
+        ((ISourceViewerExtension) getSourceViewer()).showAnnotationsOverview(true);
+        fSourceViewerDecorationSupport.updateOverviewDecorations();
+      }
+    }
+  }
+
+  protected void hideOverviewRuler() {
+    if (getSourceViewer() instanceof ISourceViewerExtension) {
+      fSourceViewerDecorationSupport.hideAnnotationOverview();
+      ((ISourceViewerExtension) getSourceViewer()).showAnnotationsOverview(false);
+    }
+  }
+
+  protected boolean isOverviewRulerVisible() {
+    IPreferenceStore store = getPreferenceStore();
+    return store.getBoolean(OVERVIEW_RULER);
+  }
   /*
    * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
    */
   protected ISourceViewer createJavaSourceViewer(
     Composite parent,
     IVerticalRuler ruler,
+    IOverviewRuler overviewRuler,
+    boolean isOverviewRulerVisible,
     int styles) {
-    return super.createSourceViewer(parent, ruler, styles);
+    return new SourceViewer(parent, ruler, overviewRuler, isOverviewRulerVisible(), styles);
+    //    return super.createSourceViewer(parent, ruler, styles);
   }
 
   /*
@@ -931,4 +2108,5 @@ public class PHPEditor
     JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
     return textTools.affectsBehavior(event);
   }
+
 }
index fb97a56..e18c5da 100644 (file)
@@ -7,31 +7,34 @@ public interface PHPEditorActionDefinitionIds {
    *
    * @since 2.1
    */
-  public static final String GOTO_MATCHING_BRACKET= "net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket"; //$NON-NLS-1$
+  public static final String GOTO_MATCHING_BRACKET = "net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket"; //$NON-NLS-1$
 
-       /**
-        * Value: net.sourceforge.phpeclipse.phpeditor.comment
-        */
-       public static final String COMMENT =
-               "net.sourceforge.phpeclipse.phpeditor.comment";
+  /**
+   * Value: net.sourceforge.phpeclipse.phpeditor.comment
+   */
+  public static final String COMMENT = "net.sourceforge.phpeclipse.phpeditor.comment";
+
+  /**
+   * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
+   */
+  public static final String UNCOMMENT = "net.sourceforge.phpeclipse.phpeditor.uncomment";
 
-       /**
-        * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
-        */
-       public static final String UNCOMMENT =
-               "net.sourceforge.phpeclipse.phpeditor.uncomment";
-       
   /**
    * Action definition ID of the source -> format action 
    */
-  public static final String FORMAT= "net.sourceforge.phpeclipse.phpeditor.format"; //$NON-NLS-1$
+  public static final String FORMAT = "net.sourceforge.phpeclipse.phpeditor.format"; //$NON-NLS-1$
+
+  /**
+  * Action definition ID of the edit -> content assist proposal action (value
+  * <code>"org.phpeclipse.phpdt.ui.edit.text.php.content.assist. proposals"
+  * </code>).
+        */
+  public static final String CONTENT_ASSIST_PROPOSALS = "net.sourceforge.phpeclipse.ui.edit.text.php.content.assist.proposals"; //$NON-NLS-1$
+  
+  /**
+        * Action definition ID of the edit -> show Javadoc action
+        * (value <code>"org.eclipse.jdt.ui.edit.text.java.show.javadoc"</code>).
+        */
+  public static final String SHOW_JAVADOC = "net.sourceforge.phpeclipse.ui.edit.text.java.show.javadoc"; //$NON-NLS-1$
 
-       /**
-       * Action definition ID of the edit -> content assist proposal action (value
-       * <code>"org.phpeclipse.phpdt.ui.edit.text.php.content.assist. proposals"
-       * </code>).
-                */
-       public static final String CONTENT_ASSIST_PROPOSALS = 
-        "net.sourceforge.phpeclipse.ui.edit.text.php.content.assist.proposals"; //$NON-NLS-1$
-       
 }
index c82eccb..4641ae5 100644 (file)
@@ -11,6 +11,7 @@ Contributors:
 **********************************************************************/
 package net.sourceforge.phpeclipse.phpeditor;
 
+import java.text.MessageFormat;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
@@ -31,6 +32,13 @@ public class PHPEditorMessages {
                }
        }
        
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */     
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+       
        public static ResourceBundle getResourceBundle() {
                return fgResourceBundle;
        }
index 3bbf088..5d40c35 100644 (file)
@@ -47,10 +47,37 @@ ParserAction.tooltip=Parse the current PHP file
 ParserAction.image=java.gif
 ParserAction.description=Parse the current PHP file
 
-
 GotoMatchingBracket.label=Go to Matching &Bracket
 GotoMatchingBracket.tooltip=Go to Matching Bracket
 GotoMatchingBracket.description=Go to Matching Bracket
 GotoMatchingBracket.error.invalidSelection=No bracket selected
 GotoMatchingBracket.error.noMatchingBracket=No matching bracket found
 GotoMatchingBracket.error.bracketOutsideSelectedElement=Matching bracket is outside of selected element
+
+AddTask.label=&Task...
+AddTask.tooltip=Add Task
+AddTask.image=
+AddTask.description=Add Task
+AddTask.dialog.title=Add Task
+AddTask.dialog.message=Enter Task description
+AddTask.error.dialog.title=Add Task
+AddTask.error.dialog.message=Problems adding new task
+
+ShowJavaDoc.label=Show &Tooltip Description
+ShowJavaDoc.tooltip=Shows Tooltip Description for Element at Cursor
+ShowJavaDoc.description=Shows the tooltip description for the element at the cursor
+
+EditorUtility.concatModifierStrings= {0} + {1}
+
+
+PHPUnitEditor.error.saving.message1=File has been deleted.
+PHPUnitEditor.error.saving.message2=Could not save file.
+PHPUnitEditor.error.saving.message3=Could not save file. 
+PHPUnitEditor.error.saving.title1=Cannot Save
+PHPUnitEditor.error.saving.title2=Save Problems
+PHPUnitEditor.error.saving.title3=Save Problems
+PHPUnitEditor.warning.save.delete=The original file ''{0}'' has been deleted.
+
+PHPUnitEditor.warning.save.nonWorkbenchEncoding.title= Save Resource In Non-Workbench Encoding
+PHPUnitEditor.warning.save.nonWorkbenchEncoding.message1= {0} will be saved in \" {1} \" encoding which is not the current workbench encoding. This can result in conflicts with other tools. Continue anyway?
+PHPUnitEditor.warning.save.nonWorkbenchEncoding.message2= The resource will be saved in \" {0} \" encoding which is not the current platform encoding. This can result in conflicts with other tools. Continue anyway?
index f5cbca0..3d78be7 100644 (file)
@@ -12,11 +12,13 @@ Contributors:
     Klaus Hartlage - www.eclipseproject.de
 **********************************************************************/
 
+import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
+import net.sourceforge.phpdt.internal.compiler.util.Util;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
 import org.eclipse.core.resources.IFile;
@@ -27,8 +29,9 @@ import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.texteditor.ITextEditor;
 import org.eclipse.ui.texteditor.TextEditorAction;
-import test.PHPParserSuperclass;
+
 import test.PHPParserManager;
+import test.PHPParserSuperclass;
 
 /**
  * ClassDeclaration that defines the action for parsing the current PHP file
@@ -69,11 +72,12 @@ public class PHPParserAction extends TextEditorAction {
     try {
 
       if (fileToParse == null) {
-        // should never happen
+        // TODO should never happen => should throw an exception
         System.err.println("Error : no file in the editor");
-        // should throw an exception
+
         return;
       }
+      // TODO use isPHPFile()
       String name = fileToParse.getName().toLowerCase();
       for (int i = 0; i < EXTENSIONS.length; i++) {
         if (name.endsWith(EXTENSIONS[i])) {
@@ -90,13 +94,12 @@ public class PHPParserAction extends TextEditorAction {
           //the tasks are removed here
           fileToParse.deleteMarkers(IMarker.TASK, false, 0);
 
-          try {
-            InputStream iStream = fileToParse.getContents();
-            //        int c = iStream.read();
-            parse(fileToParse, iStream);
-            iStream.close();
-          } catch (IOException e) {
-          }
+          //                    try {
+          //                      InputStream iStream = fileToParse.getContents();
+          parse(fileToParse); //, iStream);
+          //                      iStream.close();
+          //                    } catch (IOException e) {
+          //                    }
         } else {
           PHPParserSuperclass.phpExternalParse(fileToParse);
         }
@@ -162,23 +165,35 @@ public class PHPParserAction extends TextEditorAction {
   //    return identifier.toString();
   //  }
 
-  protected static void parse(IFile fileToParse, InputStream iStream) {
-
-    StringBuffer buf = new StringBuffer();
-    int c0;
-    try {
-      while ((c0 = iStream.read()) != (-1)) {
-        buf.append((char) c0);
-      }
-    } catch (IOException e) {
-      return;
-    }
-    String input = buf.toString();
-
-    PHPParserSuperclass parser = PHPParserManager.getParser(fileToParse);
+  protected static void parse(IFile fileToParse) {
+
+    //    StringBuffer buf = new StringBuffer();
+    //    int c0;
+    //    try {
+    //      while ((c0 = iStream.read()) != (-1)) {
+    //        buf.append((char) c0);
+    //      }
+    //    } catch (IOException e) {
+    //      return;
+    //    }
+    //    String input = buf.toString();
+
+    InputStream stream = null;
+    char[] charArray;
     try {
-      parser.parse(input);
+      stream = new BufferedInputStream(fileToParse.getContents());
+      charArray = Util.getInputStreamAsCharArray(stream, -1, null);
+      PHPParserSuperclass parser = PHPParserManager.getParser(fileToParse);
+      parser.parse(new String(charArray));
     } catch (CoreException e) {
+    } catch (IOException e) {
+    } finally {
+      try {
+       if (stream!=null) {
+          stream.close();
+       }
+      } catch (IOException e) {
+      }
     }
   }
 }
\ No newline at end of file
index ab128ff..360da1e 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Vector;
 
 import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
 import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
+import net.sourceforge.phpdt.internal.ui.text.PHPAnnotationHover;
 import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy;
 import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
@@ -169,8 +170,14 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
     return PHPeclipsePlugin.getDefault().getPreferenceStore();
   }
 
-  /* (non-Javadoc)
-   * Method declared on SourceViewerConfiguration
+  //  /* (non-Javadoc)
+  //   * Method declared on SourceViewerConfiguration
+  //   */
+  //  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+  //    return new PHPAnnotationHover();
+  //  }
+  /*
+   * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
    */
   public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
     return new PHPAnnotationHover();
@@ -201,6 +208,25 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
     return fJavaTextTools.getHTMLScanner();
   }
 
+       /**
+        * Returns the Smarty source code scanner for this configuration.
+        *
+        * @return the Smarty source code scanner
+        */
+       protected RuleBasedScanner getSmartyScanner() {
+               return fJavaTextTools.getSmartyScanner();
+       }
+       
+       /**
+        * Returns the SmartyDoc source code scanner for this configuration.
+        *
+        * @return the SmartyDoc source code scanner
+        */
+       protected RuleBasedScanner getSmartyDocScanner() {
+               return fJavaTextTools.getSmartyDocScanner();
+       }
+       
+               
   /**
    * Returns the PHPDoc source code scanner for this configuration.
    *
@@ -223,6 +249,8 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
       IPHPPartitionScannerConstants.CSS_MULTILINE_COMMENT,
       IPHPPartitionScannerConstants.JAVASCRIPT,
       IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT,
+      IPHPPartitionScannerConstants.SMARTY,
+                       IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT,
       IDocument.DEFAULT_CONTENT_TYPE };
   }
 
@@ -240,6 +268,9 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
     assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.CSS_MULTILINE_COMMENT);
     assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.JAVASCRIPT);
     assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT);
+    // TODO define special smarty partition content assist
+    assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.SMARTY);
+               assistant.setContentAssistProcessor(processor, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT);
 
     assistant.setContentAssistProcessor(new PHPCompletionProcessor(), IPHPPartitionScannerConstants.PHP);
 
@@ -349,6 +380,15 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
     dr = new DefaultDamagerRepairer(getHTMLScanner());
     reconciler.setDamager(dr, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT);
     reconciler.setRepairer(dr, IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT);
+    
+               dr = new DefaultDamagerRepairer(getSmartyScanner());
+                               reconciler.setDamager(dr, IPHPPartitionScannerConstants.SMARTY);
+                               reconciler.setRepairer(dr, IPHPPartitionScannerConstants.SMARTY);
+                               
+               dr = new DefaultDamagerRepairer(getSmartyDocScanner());
+                               reconciler.setDamager(dr, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT);
+                               reconciler.setRepairer(dr, IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT);
+                               
     dr =
       new DefaultDamagerRepairer(
         new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(PHPColorProvider.MULTI_LINE_COMMENT))));
@@ -381,21 +421,54 @@ public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
       IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile();
       return new PHPTextHover(f.getProject());
     } catch (NullPointerException e) {
-       // this exception occurs, if getTextHover is called by preference pages !
+      // this exception occurs, if getTextHover is called by preference pages !
     }
     return new PHPTextHover(null);
   }
-  
-       /*
-        * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer)
-        * @since 2.0
-        */
-       public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
-               return new IInformationControlCreator() {
-                       public IInformationControl createInformationControl(Shell parent) {
-                               return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true));
-                               // return new HoverBrowserControl(parent);
-                       }
-               };
-       }
+
+  /*
+   * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer)
+   * @since 2.0
+   */
+  public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
+    return new IInformationControlCreator() {
+      public IInformationControl createInformationControl(Shell parent) {
+        return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true));
+        // return new HoverBrowserControl(parent);
+      }
+    };
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
+   * @since 2.0
+   */
+  //   public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
+  //           InformationPresenter presenter= new InformationPresenter(getInformationPresenterControlCreator(sourceViewer));
+  //           IInformationProvider provider= new JavaInformationProvider(getEditor());
+  //           presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
+  //           presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
+  //           presenter.setSizeConstraints(60, 10, true, true);               
+  //           return presenter;
+  //   }
+
+  /**
+   * Returns the information presenter control creator. The creator is a factory creating the
+   * presenter controls for the given source viewer. This implementation always returns a creator
+   * for <code>DefaultInformationControl</code> instances.
+   * 
+   * @param sourceViewer the source viewer to be configured by this configuration
+   * @return an information control creator
+   * @since 2.1
+   */
+  private IInformationControlCreator getInformationPresenterControlCreator(ISourceViewer sourceViewer) {
+    return new IInformationControlCreator() {
+      public IInformationControl createInformationControl(Shell parent) {
+        int shellStyle = SWT.RESIZE;
+        int style = SWT.V_SCROLL | SWT.H_SCROLL;
+        return new DefaultInformationControl(parent, shellStyle, style, new HTMLTextPresenter(false));
+        // return new HoverBrowserControl(parent);
+      }
+    };
+  }
 }
index 571cc66..591542c 100644 (file)
@@ -9,7 +9,6 @@ import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 
-
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
index 5271e47..02a3c70 100644 (file)
@@ -83,7 +83,6 @@ public class PHPTextHover implements ITextHover {
                 PHPIdentifierLocation location;
                 String filename;
                 FileReader phpdocFileReader;
-        //        PHPDocCharArrayCommentReader phpdocConverter;
                 StringBuffer hoverInfoBuffer = new StringBuffer();
                 String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
                 //                boolean foundPHPdoc = false;
@@ -91,23 +90,8 @@ public class PHPTextHover implements ITextHover {
                   location = (PHPIdentifierLocation) list.get(i);
                                                                        filename = workspaceLocation + location.getFilename();
                   PHPDocUtil.appendPHPDoc(hoverInfoBuffer, filename, location);
-//                                                                     
-//                                                                     hoverInfoBuffer.append(location.toString());
-//                                                                     hoverInfoBuffer.append('\n');
-//                  if (location.getPHPDocOffset() >= 0) {
-//                    //                    foundPHPdoc = true;
-//                    phpdocFileReader = new FileReader(filename);
-//                    char[] charArray = new char[location.getPHPDocLength()];
-//                    phpdocFileReader.skip(location.getPHPDocOffset());
-//                    phpdocFileReader.read(charArray, 0, location.getPHPDocLength());
-//                    phpdocConverter = new PHPDocCharArrayCommentReader(charArray);
-//                    hoverInfoBuffer.append(phpdocConverter.getString());
-//                    hoverInfoBuffer.append('\n');
-//                  }
                 }
-                //                if (foundPHPdoc) {
                 hoverInfo = hoverInfoBuffer.toString();
-                //                }
               } catch (Throwable e) {
                 // ignore exceptions
                 // e.printStackTrace();
index 37f9bbe..63c79a4 100644 (file)
@@ -1,10 +1,9 @@
 package net.sourceforge.phpeclipse.phpeditor;
 
+import java.text.MessageFormat;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
@@ -20,12 +19,12 @@ import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Preferences;
-import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
 import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
-import org.eclipse.jface.text.AbstractHoverInformationControlManager;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.DocumentCommand;
 import org.eclipse.jface.text.IDocument;
@@ -37,27 +36,24 @@ import org.eclipse.jface.text.ITypedRegion;
 import org.eclipse.jface.text.IWidgetTokenKeeper;
 import org.eclipse.jface.text.contentassist.ContentAssistant;
 import org.eclipse.jface.text.contentassist.IContentAssistant;
-import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IOverviewRuler;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.text.source.IVerticalRuler;
 import org.eclipse.jface.text.source.SourceViewer;
 import org.eclipse.jface.text.source.SourceViewerConfiguration;
 import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.custom.VerifyKeyListener;
 import org.eclipse.swt.events.VerifyEvent;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.editors.text.IStorageDocumentProvider;
 import org.eclipse.ui.help.WorkbenchHelp;
 import org.eclipse.ui.texteditor.IDocumentProvider;
 
@@ -76,87 +72,281 @@ Contributors:
  * PHP specific text editor.
  */
 public class PHPUnitEditor extends PHPEditor {
-       
+
   interface ITextConverter {
     void customizeDocumentCommand(IDocument document, DocumentCommand command);
   };
 
-  class AdaptedRulerLayout extends Layout {
-
-    protected int fGap;
-    protected AdaptedSourceViewer fAdaptedSourceViewer;
-
-    protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
-      fGap = gap;
-      fAdaptedSourceViewer = asv;
-    }
-
-    protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
-      Control[] children = composite.getChildren();
-      Point s = children[children.length - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
-      if (fAdaptedSourceViewer.isVerticalRulerVisible())
-        s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
-      return s;
-    }
-
-    protected void layout(Composite composite, boolean flushCache) {
-      Rectangle clArea = composite.getClientArea();
-      if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
-
-        StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
-        Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
-        int scrollbarHeight = trim.height;
-
-        IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
-        int vrWidth = vr.getWidth();
-
-        int orWidth = 0;
-        if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
-          OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
-          orWidth = or.getWidth();
-          or.getControl().setBounds(clArea.width - orWidth, scrollbarHeight, orWidth, clArea.height - 3 * scrollbarHeight);
-        }
-
-        textWidget.setBounds(vrWidth + fGap, 0, clArea.width - vrWidth - orWidth - 2 * fGap, clArea.height);
-        vr.getControl().setBounds(0, 0, vrWidth, clArea.height - scrollbarHeight);
-
-      } else {
-        StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
-        textWidget.setBounds(0, 0, clArea.width, clArea.height);
-      }
-    }
-  };
-
-  class AdaptedSourceViewer extends SourceViewer { // extends JavaCorrectionSourceViewer  {
+  //  class AdaptedRulerLayout extends Layout {
+  //
+  //    protected int fGap;
+  //    protected AdaptedSourceViewer fAdaptedSourceViewer;
+  //
+  //    protected AdaptedRulerLayout(int gap, AdaptedSourceViewer asv) {
+  //      fGap = gap;
+  //      fAdaptedSourceViewer = asv;
+  //    }
+  //
+  //    protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
+  //      Control[] children = composite.getChildren();
+  //      Point s = children[children.length - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
+  //      if (fAdaptedSourceViewer.isVerticalRulerVisible())
+  //        s.x += fAdaptedSourceViewer.getVerticalRuler().getWidth() + fGap;
+  //      return s;
+  //    }
+  //
+  //    protected void layout(Composite composite, boolean flushCache) {
+  //      Rectangle clArea = composite.getClientArea();
+  //      if (fAdaptedSourceViewer.isVerticalRulerVisible()) {
+  //
+  //        StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
+  //        Rectangle trim = textWidget.computeTrim(0, 0, 0, 0);
+  //        int scrollbarHeight = trim.height;
+  //
+  //        IVerticalRuler vr = fAdaptedSourceViewer.getVerticalRuler();
+  //        int vrWidth = vr.getWidth();
+  //
+  //        int orWidth = 0;
+  //        if (fAdaptedSourceViewer.isOverviewRulerVisible()) {
+  //          OverviewRuler or = fAdaptedSourceViewer.getOverviewRuler();
+  //          orWidth = or.getWidth();
+  //          or.getControl().setBounds(clArea.width - orWidth, scrollbarHeight, orWidth, clArea.height - 3 * scrollbarHeight);
+  //        }
+  //
+  //        textWidget.setBounds(vrWidth + fGap, 0, clArea.width - vrWidth - orWidth - 2 * fGap, clArea.height);
+  //        vr.getControl().setBounds(0, 0, vrWidth, clArea.height - scrollbarHeight);
+  //
+  //      } else {
+  //        StyledText textWidget = fAdaptedSourceViewer.getTextWidget();
+  //        textWidget.setBounds(0, 0, clArea.width, clArea.height);
+  //      }
+  //    }
+  //  };
+  //
+  //  class AdaptedSourceViewer extends SourceViewer { // extends JavaCorrectionSourceViewer  {
+  //
+  //    private List fTextConverters;
+  //
+  //    private OverviewRuler fOverviewRuler;
+  //    private boolean fIsOverviewRulerVisible;
+  //    /** The viewer's overview ruler hovering controller */
+  //    private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
+  //
+  //    private boolean fIgnoreTextConverters = false;
+  //
+  //    private IVerticalRuler fCachedVerticalRuler;
+  //    private boolean fCachedIsVerticalRulerVisible;
+  //
+  //    public AdaptedSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+  //      super(parent, ruler, styles); //, CompilationUnitEditor.this);
+  //
+  //      fCachedVerticalRuler = ruler;
+  //      fCachedIsVerticalRulerVisible = (ruler != null);
+  //      fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
+  //
+  //      delayedCreateControl(parent, styles);
+  //    }
+  //
+  //    /*
+  //     * @see ISourceViewer#showAnnotations(boolean)
+  //     */
+  //    public void showAnnotations(boolean show) {
+  //      fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
+  //      //   super.showAnnotations(show);
+  //    }
+  //
+  //    public IContentAssistant getContentAssistant() {
+  //      return fContentAssistant;
+  //    }
+  //
+  //    /*
+  //     * @see ITextOperationTarget#doOperation(int)
+  //     */
+  //    public void doOperation(int operation) {
+  //
+  //      if (getTextWidget() == null)
+  //        return;
+  //
+  //      switch (operation) {
+  //        case CONTENTASSIST_PROPOSALS :
+  //          String msg = fContentAssistant.showPossibleCompletions();
+  //          setStatusLineErrorMessage(msg);
+  //          return;
+  //        case UNDO :
+  //          fIgnoreTextConverters = true;
+  //          break;
+  //        case REDO :
+  //          fIgnoreTextConverters = true;
+  //          break;
+  //      }
+  //
+  //      super.doOperation(operation);
+  //    }
+  //
+  //    public void insertTextConverter(ITextConverter textConverter, int index) {
+  //      throw new UnsupportedOperationException();
+  //    }
+  //
+  //    public void addTextConverter(ITextConverter textConverter) {
+  //      if (fTextConverters == null) {
+  //        fTextConverters = new ArrayList(1);
+  //        fTextConverters.add(textConverter);
+  //      } else if (!fTextConverters.contains(textConverter))
+  //        fTextConverters.add(textConverter);
+  //    }
+  //
+  //    public void removeTextConverter(ITextConverter textConverter) {
+  //      if (fTextConverters != null) {
+  //        fTextConverters.remove(textConverter);
+  //        if (fTextConverters.size() == 0)
+  //          fTextConverters = null;
+  //      }
+  //    }
+  //
+  //    /*
+  //     * @see TextViewer#customizeDocumentCommand(DocumentCommand)
+  //     */
+  //    protected void customizeDocumentCommand(DocumentCommand command) {
+  //      super.customizeDocumentCommand(command);
+  //      if (!fIgnoreTextConverters && fTextConverters != null) {
+  //        for (Iterator e = fTextConverters.iterator(); e.hasNext();)
+  //           ((ITextConverter) e.next()).customizeDocumentCommand(getDocument(), command);
+  //      }
+  //      fIgnoreTextConverters = false;
+  //    }
+  //
+  //    public IVerticalRuler getVerticalRuler() {
+  //      return fCachedVerticalRuler;
+  //    }
+  //
+  //    public boolean isVerticalRulerVisible() {
+  //      return fCachedIsVerticalRulerVisible;
+  //    }
+  //
+  //    public OverviewRuler getOverviewRuler() {
+  //      return fOverviewRuler;
+  //    }
+  //
+  //    /*
+  //     * @see TextViewer#createControl(Composite, int)
+  //     */
+  //    protected void createControl(Composite parent, int styles) {
+  //      // do nothing here
+  //    }
+  //
+  //    protected void delayedCreateControl(Composite parent, int styles) {
+  //      //create the viewer
+  //      super.createControl(parent, styles);
+  //
+  //      Control control = getControl();
+  //      if (control instanceof Composite) {
+  //        Composite composite = (Composite) control;
+  //        composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
+  //        fOverviewRuler.createControl(composite, this);
+  //      }
+  //    }
+
+  //    protected void ensureOverviewHoverManagerInstalled() {
+  //      if (fOverviewRulerHoveringController == null && fAnnotationHover != null && fHoverControlCreator != null) {
+  //        fOverviewRulerHoveringController =
+  //          new OverviewRulerHoverManager(fOverviewRuler, this, fAnnotationHover, fHoverControlCreator);
+  //        fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
+  //      }
+  //    }
+  //
+  //    public void hideOverviewRuler() {
+  //      fIsOverviewRulerVisible = false;
+  //      Control control = getControl();
+  //      if (control instanceof Composite) {
+  //        Composite composite = (Composite) control;
+  //        composite.layout();
+  //      }
+  //      if (fOverviewRulerHoveringController != null) {
+  //        fOverviewRulerHoveringController.dispose();
+  //        fOverviewRulerHoveringController = null;
+  //      }
+  //    }
+  //
+  //    public void showOverviewRuler() {
+  //      fIsOverviewRulerVisible = true;
+  //      Control control = getControl();
+  //      if (control instanceof Composite) {
+  //        Composite composite = (Composite) control;
+  //        composite.layout();
+  //      }
+  //      ensureOverviewHoverManagerInstalled();
+  //    }
+  //
+  //    public boolean isOverviewRulerVisible() {
+  //      return fIsOverviewRulerVisible;
+  //    }
+  //
+  //    /*
+  //     * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
+  //     */
+  //    public void setDocument(
+  //      IDocument document,
+  //      IAnnotationModel annotationModel,
+  //      int visibleRegionOffset,
+  //      int visibleRegionLength) {
+  //      super.setDocument(document, annotationModel, visibleRegionOffset, visibleRegionLength);
+  //      fOverviewRuler.setModel(annotationModel);
+  //    }
+  //
+  //    // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
+  //    public void updateIndentationPrefixes() {
+  //      SourceViewerConfiguration configuration = getSourceViewerConfiguration();
+  //      String[] types = configuration.getConfiguredContentTypes(this);
+  //      for (int i = 0; i < types.length; i++) {
+  //        String[] prefixes = configuration.getIndentPrefixes(this, types[i]);
+  //        if (prefixes != null && prefixes.length > 0)
+  //          setIndentPrefixes(prefixes, types[i]);
+  //      }
+  //    }
+  //
+  //    /*
+  //     * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
+  //     */
+  //    public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
+  //      if (WorkbenchHelp.isContextHelpDisplayed())
+  //        return false;
+  //      return super.requestWidgetToken(requester);
+  //    }
+  //
+  //    /*
+  //     * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
+  //     */
+  //    public void configure(SourceViewerConfiguration configuration) {
+  //      super.configure(configuration);
+  //      //      prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
+  //    }
+  //
+  //    protected void handleDispose() {
+  //      fOverviewRuler = null;
+  //
+  //      if (fOverviewRulerHoveringController != null) {
+  //        fOverviewRulerHoveringController.dispose();
+  //        fOverviewRulerHoveringController = null;
+  //      }
+  //
+  //      super.handleDispose();
+  //    }
+  //
+  //  };
+
+  class AdaptedSourceViewer extends SourceViewer {
 
     private List fTextConverters;
-
-    private OverviewRuler fOverviewRuler;
-    private boolean fIsOverviewRulerVisible;
-    /** The viewer's overview ruler hovering controller */
-    private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
-
     private boolean fIgnoreTextConverters = false;
+    //                 private JavaCorrectionAssistant fCorrectionAssistant;
 
-    private IVerticalRuler fCachedVerticalRuler;
-    private boolean fCachedIsVerticalRulerVisible;
-
-    public AdaptedSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
-      super(parent, ruler, styles); //, CompilationUnitEditor.this);
-
-      fCachedVerticalRuler = ruler;
-      fCachedIsVerticalRulerVisible = (ruler != null);
-      fOverviewRuler = new OverviewRuler(VERTICAL_RULER_WIDTH);
-
-      delayedCreateControl(parent, styles);
-    }
-
-    /*
-     * @see ISourceViewer#showAnnotations(boolean)
-     */
-    public void showAnnotations(boolean show) {
-      fCachedIsVerticalRulerVisible = (show && fCachedVerticalRuler != null);
-      //   super.showAnnotations(show);
+    public AdaptedSourceViewer(
+      Composite parent,
+      IVerticalRuler verticalRuler,
+      IOverviewRuler overviewRuler,
+      boolean showAnnotationsOverview,
+      int styles) {
+      super(parent, verticalRuler, overviewRuler, showAnnotationsOverview, styles);
     }
 
     public IContentAssistant getContentAssistant() {
@@ -176,6 +366,9 @@ public class PHPUnitEditor extends PHPEditor {
           String msg = fContentAssistant.showPossibleCompletions();
           setStatusLineErrorMessage(msg);
           return;
+          //                                   case CORRECTIONASSIST_PROPOSALS:
+          //                                           fCorrectionAssistant.showPossibleCompletions();
+          //                                           return;
         case UNDO :
           fIgnoreTextConverters = true;
           break;
@@ -187,6 +380,26 @@ public class PHPUnitEditor extends PHPEditor {
       super.doOperation(operation);
     }
 
+    /*
+     * @see ITextOperationTarget#canDoOperation(int)
+     */
+    public boolean canDoOperation(int operation) {
+      //                               if (operation == CORRECTIONASSIST_PROPOSALS)
+      //                                       return isEditable();
+      return super.canDoOperation(operation);
+    }
+
+    /*
+     * @see TextViewer#handleDispose()
+     */
+    protected void handleDispose() {
+      //                               if (fCorrectionAssistant != null) {
+      //                                       fCorrectionAssistant.uninstall();
+      //                                       fCorrectionAssistant= null;
+      //                               }
+      super.handleDispose();
+    }
+
     public void insertTextConverter(ITextConverter textConverter, int index) {
       throw new UnsupportedOperationException();
     }
@@ -219,84 +432,6 @@ public class PHPUnitEditor extends PHPEditor {
       fIgnoreTextConverters = false;
     }
 
-    public IVerticalRuler getVerticalRuler() {
-      return fCachedVerticalRuler;
-    }
-
-    public boolean isVerticalRulerVisible() {
-      return fCachedIsVerticalRulerVisible;
-    }
-
-    public OverviewRuler getOverviewRuler() {
-      return fOverviewRuler;
-    }
-
-    /*
-     * @see TextViewer#createControl(Composite, int)
-     */
-    protected void createControl(Composite parent, int styles) {
-      // do nothing here
-    }
-
-    protected void delayedCreateControl(Composite parent, int styles) {
-      //create the viewer
-      super.createControl(parent, styles);
-
-      Control control = getControl();
-      if (control instanceof Composite) {
-        Composite composite = (Composite) control;
-        composite.setLayout(new AdaptedRulerLayout(GAP_SIZE, this));
-        fOverviewRuler.createControl(composite, this);
-      }
-    }
-
-    protected void ensureOverviewHoverManagerInstalled() {
-      if (fOverviewRulerHoveringController == null && fAnnotationHover != null && fHoverControlCreator != null) {
-        fOverviewRulerHoveringController =
-          new OverviewRulerHoverManager(fOverviewRuler, this, fAnnotationHover, fHoverControlCreator);
-        fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
-      }
-    }
-
-    public void hideOverviewRuler() {
-      fIsOverviewRulerVisible = false;
-      Control control = getControl();
-      if (control instanceof Composite) {
-        Composite composite = (Composite) control;
-        composite.layout();
-      }
-      if (fOverviewRulerHoveringController != null) {
-        fOverviewRulerHoveringController.dispose();
-        fOverviewRulerHoveringController = null;
-      }
-    }
-
-    public void showOverviewRuler() {
-      fIsOverviewRulerVisible = true;
-      Control control = getControl();
-      if (control instanceof Composite) {
-        Composite composite = (Composite) control;
-        composite.layout();
-      }
-      ensureOverviewHoverManagerInstalled();
-    }
-
-    public boolean isOverviewRulerVisible() {
-      return fIsOverviewRulerVisible;
-    }
-
-    /*
-     * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
-     */
-    public void setDocument(
-      IDocument document,
-      IAnnotationModel annotationModel,
-      int visibleRegionOffset,
-      int visibleRegionLength) {
-      super.setDocument(document, annotationModel, visibleRegionOffset, visibleRegionLength);
-      fOverviewRuler.setModel(annotationModel);
-    }
-
     // http://dev.eclipse.org/bugs/show_bug.cgi?id=19270
     public void updateIndentationPrefixes() {
       SourceViewerConfiguration configuration = getSourceViewerConfiguration();
@@ -322,22 +457,12 @@ public class PHPUnitEditor extends PHPEditor {
      */
     public void configure(SourceViewerConfiguration configuration) {
       super.configure(configuration);
-      //      prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
-    }
-
-    protected void handleDispose() {
-      fOverviewRuler = null;
-
-      if (fOverviewRulerHoveringController != null) {
-        fOverviewRulerHoveringController.dispose();
-        fOverviewRulerHoveringController = null;
-      }
-
-      super.handleDispose();
+      //                               fCorrectionAssistant= new JavaCorrectionAssistant(CompilationUnitEditor.this);
+      //                               fCorrectionAssistant.install(this);
+      //TODO install SmartBracesAutoEditStrategy
+      //                               prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this), IDocument.DEFAULT_CONTENT_TYPE);
     }
-
   };
-
   static class TabConverter implements ITextConverter {
 
     private int fTabRatio;
@@ -451,6 +576,14 @@ public class PHPUnitEditor extends PHPEditor {
     }
 
   }
+
+  //  private static class BracketLevel {
+  //    int fOffset;
+  //    int fLength;
+  //    LinkedPositionManager fManager;
+  //    LinkedPositionUI fEditor;
+  //  };
+
   private class BracketInserter implements VerifyKeyListener, LinkedPositionUI.ExitListener {
 
     private boolean fCloseBracketsPHP = true;
@@ -675,7 +808,7 @@ public class PHPUnitEditor extends PHPEditor {
 
   }
   /** The editor's paint manager */
-  private PaintManager fPaintManager;
+  //  private PaintManager fPaintManager;
   /** The editor's bracket painter */
   private BracketPainter fBracketPainter;
   /** The editor's bracket matcher */
@@ -685,14 +818,14 @@ public class PHPUnitEditor extends PHPEditor {
   /** The editor's print margin ruler painter */
   private PrintMarginPainter fPrintMarginPainter;
   /** The editor's problem painter */
-  private ProblemPainter fProblemPainter;
+  //  private ProblemPainter fProblemPainter;
   /** The editor's tab converter */
   private TabConverter fTabConverter;
   /** History for structure select action */
   //private SelectionHistory fSelectionHistory;
 
   /** The preference property change listener for php core. */
-  private IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
+  //  private IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
   /** The remembered selection */
   private ITextSelection fRememberedSelection;
   /** The remembered php element offset */
@@ -700,14 +833,14 @@ public class PHPUnitEditor extends PHPEditor {
   /** The bracket inserter. */
   private BracketInserter fBracketInserter = new BracketInserter();
 
-  private class PropertyChangeListener implements IPropertyChangeListener {
-    /*
-     * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
-     */
-    public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
-      handlePreferencePropertyChanged(event);
-    }
-  }
+  //  private class PropertyChangeListener implements IPropertyChangeListener {
+  //    /*
+  //     * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+  //     */
+  //    public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+  //      handlePreferencePropertyChanged(event);
+  //    }
+  //  }
   /* Preference key for code formatter tab size */
   private final static String CODE_FORMATTER_TAB_SIZE = PHPCore.FORMATTER_TAB_SIZE;
   /** Preference key for matching brackets */
@@ -790,63 +923,63 @@ public class PHPUnitEditor extends PHPEditor {
 
   /** Preference key for smart paste */
   private final static String SMART_PASTE = PreferenceConstants.EDITOR_SMART_PASTE;
-  private final static class AnnotationInfo {
-    public String fColorPreference;
-    public String fOverviewRulerPreference;
-    public String fEditorPreference;
-  };
-
-  private final static Map ANNOTATION_MAP;
-  static {
-
-    AnnotationInfo info;
-    ANNOTATION_MAP = new HashMap();
-
-    info = new AnnotationInfo();
-    info.fColorPreference = TASK_INDICATION_COLOR;
-    info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
-    info.fEditorPreference = TASK_INDICATION;
-    ANNOTATION_MAP.put(AnnotationType.TASK, info);
-
-    info = new AnnotationInfo();
-    info.fColorPreference = ERROR_INDICATION_COLOR;
-    info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
-    info.fEditorPreference = ERROR_INDICATION;
-    ANNOTATION_MAP.put(AnnotationType.ERROR, info);
-
-    info = new AnnotationInfo();
-    info.fColorPreference = WARNING_INDICATION_COLOR;
-    info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
-    info.fEditorPreference = WARNING_INDICATION;
-    ANNOTATION_MAP.put(AnnotationType.WARNING, info);
-
-    info = new AnnotationInfo();
-    info.fColorPreference = BOOKMARK_INDICATION_COLOR;
-    info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
-    info.fEditorPreference = BOOKMARK_INDICATION;
-    ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
-
-    info = new AnnotationInfo();
-    info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
-    info.fOverviewRulerPreference = SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
-    info.fEditorPreference = SEARCH_RESULT_INDICATION;
-    ANNOTATION_MAP.put(AnnotationType.SEARCH_RESULT, info);
-
-    info = new AnnotationInfo();
-    info.fColorPreference = UNKNOWN_INDICATION_COLOR;
-    info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
-    info.fEditorPreference = UNKNOWN_INDICATION;
-    ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
-  };
-
-  private final static AnnotationType[] ANNOTATION_LAYERS =
-    new AnnotationType[] {
-      AnnotationType.UNKNOWN,
-      AnnotationType.BOOKMARK,
-      AnnotationType.TASK,
-      AnnotationType.SEARCH_RESULT,
-      AnnotationType.WARNING,
-      AnnotationType.ERROR };
+  //  private final static class AnnotationInfo {
+  //    public String fColorPreference;
+  //    public String fOverviewRulerPreference;
+  //    public String fEditorPreference;
+  //  };
+
+  //  private final static Map ANNOTATION_MAP;
+  //  static {
+  //
+  //    AnnotationInfo info;
+  //    ANNOTATION_MAP = new HashMap();
+  //
+  //    info = new AnnotationInfo();
+  //    info.fColorPreference = TASK_INDICATION_COLOR;
+  //    info.fOverviewRulerPreference = TASK_INDICATION_IN_OVERVIEW_RULER;
+  //    info.fEditorPreference = TASK_INDICATION;
+  //    ANNOTATION_MAP.put(AnnotationType.TASK, info);
+  //
+  //    info = new AnnotationInfo();
+  //    info.fColorPreference = ERROR_INDICATION_COLOR;
+  //    info.fOverviewRulerPreference = ERROR_INDICATION_IN_OVERVIEW_RULER;
+  //    info.fEditorPreference = ERROR_INDICATION;
+  //    ANNOTATION_MAP.put(AnnotationType.ERROR, info);
+  //
+  //    info = new AnnotationInfo();
+  //    info.fColorPreference = WARNING_INDICATION_COLOR;
+  //    info.fOverviewRulerPreference = WARNING_INDICATION_IN_OVERVIEW_RULER;
+  //    info.fEditorPreference = WARNING_INDICATION;
+  //    ANNOTATION_MAP.put(AnnotationType.WARNING, info);
+  //
+  //    info = new AnnotationInfo();
+  //    info.fColorPreference = BOOKMARK_INDICATION_COLOR;
+  //    info.fOverviewRulerPreference = BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+  //    info.fEditorPreference = BOOKMARK_INDICATION;
+  //    ANNOTATION_MAP.put(AnnotationType.BOOKMARK, info);
+  //
+  //    info = new AnnotationInfo();
+  //    info.fColorPreference = SEARCH_RESULT_INDICATION_COLOR;
+  //    info.fOverviewRulerPreference = SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+  //    info.fEditorPreference = SEARCH_RESULT_INDICATION;
+  //    ANNOTATION_MAP.put(AnnotationType.SEARCH, info);
+  //
+  //    info = new AnnotationInfo();
+  //    info.fColorPreference = UNKNOWN_INDICATION_COLOR;
+  //    info.fOverviewRulerPreference = UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+  //    info.fEditorPreference = UNKNOWN_INDICATION;
+  //    ANNOTATION_MAP.put(AnnotationType.UNKNOWN, info);
+  //  };
+  //
+  //  private final static AnnotationType[] ANNOTATION_LAYERS =
+  //    new AnnotationType[] {
+  //      AnnotationType.UNKNOWN,
+  //      AnnotationType.BOOKMARK,
+  //      AnnotationType.TASK,
+  //      AnnotationType.SEARCH,
+  //      AnnotationType.WARNING,
+  //      AnnotationType.ERROR };
   /**
    * Creates a new php unit editor.
    */
@@ -861,14 +994,14 @@ public class PHPUnitEditor extends PHPEditor {
   public void createPartControl(Composite parent) {
     super.createPartControl(parent);
 
-    fPaintManager = new PaintManager(getSourceViewer());
+    //    fPaintManager = new PaintManager(getSourceViewer());
 
     LinePainter linePainter;
     linePainter = new LinePainter(getSourceViewer());
 
     linePainter.setHighlightColor(new Color(Display.getCurrent(), 225, 235, 224));
 
-    fPaintManager.addPainter(linePainter);
+    //    fPaintManager.addPainter(linePainter);
 
     if (isBracketHighlightingEnabled())
       startBracketHighlighting();
@@ -877,21 +1010,21 @@ public class PHPUnitEditor extends PHPEditor {
     if (isPrintMarginVisible())
       showPrintMargin();
 
-    Iterator e = ANNOTATION_MAP.keySet().iterator();
-    while (e.hasNext()) {
-      AnnotationType type = (AnnotationType) e.next();
-      if (isAnnotationIndicationEnabled(type))
-        startAnnotationIndication(type);
-    }
+    //    Iterator e = ANNOTATION_MAP.keySet().iterator();
+    //    while (e.hasNext()) {
+    //      AnnotationType type = (AnnotationType) e.next();
+    //      if (isAnnotationIndicationEnabled(type))
+    //        startAnnotationIndication(type);
+    //    }
 
     if (isTabConversionEnabled())
       startTabConversion();
 
-    if (isOverviewRulerVisible())
-      showOverviewRuler();
-
-    Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
-    preferences.addPropertyChangeListener(fPropertyChangeListener);
+    //    if (isOverviewRulerVisible())
+    //      showOverviewRuler();
+    //
+    //    Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
+    //    preferences.addPropertyChangeListener(fPropertyChangeListener);
 
     IPreferenceStore preferenceStore = getPreferenceStore();
     boolean closeBracketsPHP = preferenceStore.getBoolean(CLOSE_BRACKETS_PHP);
@@ -945,13 +1078,13 @@ public class PHPUnitEditor extends PHPEditor {
       ISourceViewer sourceViewer = getSourceViewer();
       fBracketPainter = new BracketPainter(sourceViewer);
       fBracketPainter.setHighlightColor(getColor(MATCHING_BRACKETS_COLOR));
-      fPaintManager.addPainter(fBracketPainter);
+      //      fPaintManager.addPainter(fBracketPainter);
     }
   }
 
   private void stopBracketHighlighting() {
     if (fBracketPainter != null) {
-      fPaintManager.removePainter(fBracketPainter);
+      //      fPaintManager.removePainter(fBracketPainter);
       fBracketPainter.deactivate(true);
       fBracketPainter.dispose();
       fBracketPainter = null;
@@ -968,13 +1101,13 @@ public class PHPUnitEditor extends PHPEditor {
       ISourceViewer sourceViewer = getSourceViewer();
       fLinePainter = new LinePainter(sourceViewer);
       fLinePainter.setHighlightColor(getColor(CURRENT_LINE_COLOR));
-      fPaintManager.addPainter(fLinePainter);
+      //      fPaintManager.addPainter(fLinePainter);
     }
   }
 
   private void stopLineHighlighting() {
     if (fLinePainter != null) {
-      fPaintManager.removePainter(fLinePainter);
+      //      fPaintManager.removePainter(fLinePainter);
       fLinePainter.deactivate(true);
       fLinePainter.dispose();
       fLinePainter = null;
@@ -991,13 +1124,13 @@ public class PHPUnitEditor extends PHPEditor {
       fPrintMarginPainter = new PrintMarginPainter(getSourceViewer());
       fPrintMarginPainter.setMarginRulerColor(getColor(PRINT_MARGIN_COLOR));
       fPrintMarginPainter.setMarginRulerColumn(getPreferenceStore().getInt(PRINT_MARGIN_COLUMN));
-      fPaintManager.addPainter(fPrintMarginPainter);
+      //      fPaintManager.addPainter(fPrintMarginPainter);
     }
   }
 
   private void hidePrintMargin() {
     if (fPrintMarginPainter != null) {
-      fPaintManager.removePainter(fPrintMarginPainter);
+      //      fPaintManager.removePainter(fPrintMarginPainter);
       fPrintMarginPainter.deactivate(true);
       fPrintMarginPainter.dispose();
       fPrintMarginPainter = null;
@@ -1009,71 +1142,71 @@ public class PHPUnitEditor extends PHPEditor {
     return store.getBoolean(PRINT_MARGIN);
   }
 
-  private void startAnnotationIndication(AnnotationType annotationType) {
-    if (fProblemPainter == null) {
-      fProblemPainter = new ProblemPainter(this, getSourceViewer());
-      fPaintManager.addPainter(fProblemPainter);
-    }
-    fProblemPainter.setColor(annotationType, getColor(annotationType));
-    fProblemPainter.paintAnnotations(annotationType, true);
-    fProblemPainter.paint(IPainter.CONFIGURATION);
-  }
-
-  private void shutdownAnnotationIndication() {
-    if (fProblemPainter != null) {
-
-      if (!fProblemPainter.isPaintingAnnotations()) {
-        fPaintManager.removePainter(fProblemPainter);
-        fProblemPainter.deactivate(true);
-        fProblemPainter.dispose();
-        fProblemPainter = null;
-      } else {
-        fProblemPainter.paint(IPainter.CONFIGURATION);
-      }
-    }
-  }
-
-  private void stopAnnotationIndication(AnnotationType annotationType) {
-    if (fProblemPainter != null) {
-      fProblemPainter.paintAnnotations(annotationType, false);
-      shutdownAnnotationIndication();
-    }
-  }
-
-  private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
-    IPreferenceStore store = getPreferenceStore();
-    AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
-    if (info != null)
-      return store.getBoolean(info.fEditorPreference);
-    return false;
-  }
-
-  private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
-    IPreferenceStore store = getPreferenceStore();
-    AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
-    if (info != null)
-      return store.getBoolean(info.fOverviewRulerPreference);
-    return false;
-  }
-
-  private void showAnnotationIndicationInOverviewRuler(AnnotationType annotationType, boolean show) {
-    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
-    OverviewRuler ruler = asv.getOverviewRuler();
-    if (ruler != null) {
-      ruler.setColor(annotationType, getColor(annotationType));
-      ruler.showAnnotation(annotationType, show);
-      ruler.update();
-    }
-  }
-
-  private void setColorInOverviewRuler(AnnotationType annotationType, Color color) {
-    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
-    OverviewRuler ruler = asv.getOverviewRuler();
-    if (ruler != null) {
-      ruler.setColor(annotationType, color);
-      ruler.update();
-    }
-  }
+  //  private void startAnnotationIndication(AnnotationType annotationType) {
+  //    if (fProblemPainter == null) {
+  //      fProblemPainter = new ProblemPainter(this, getSourceViewer());
+  ////      fPaintManager.addPainter(fProblemPainter);
+  //    }
+  //    fProblemPainter.setColor(annotationType, getColor(annotationType));
+  //    fProblemPainter.paintAnnotations(annotationType, true);
+  //    fProblemPainter.paint(IPainter.CONFIGURATION);
+  //  }
+  //
+  //  private void shutdownAnnotationIndication() {
+  //    if (fProblemPainter != null) {
+  //
+  //      if (!fProblemPainter.isPaintingAnnotations()) {
+  ////        fPaintManager.removePainter(fProblemPainter);
+  //        fProblemPainter.deactivate(true);
+  //        fProblemPainter.dispose();
+  //        fProblemPainter = null;
+  //      } else {
+  //        fProblemPainter.paint(IPainter.CONFIGURATION);
+  //      }
+  //    }
+  //  }
+  //
+  //  private void stopAnnotationIndication(AnnotationType annotationType) {
+  //    if (fProblemPainter != null) {
+  //      fProblemPainter.paintAnnotations(annotationType, false);
+  //      shutdownAnnotationIndication();
+  //    }
+  //  }
+  //
+  //  private boolean isAnnotationIndicationEnabled(AnnotationType annotationType) {
+  //    IPreferenceStore store = getPreferenceStore();
+  //    AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
+  //    if (info != null)
+  //      return store.getBoolean(info.fEditorPreference);
+  //    return false;
+  //  }
+  //
+  //  private boolean isAnnotationIndicationInOverviewRulerEnabled(AnnotationType annotationType) {
+  //    IPreferenceStore store = getPreferenceStore();
+  //    AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
+  //    if (info != null)
+  //      return store.getBoolean(info.fOverviewRulerPreference);
+  //    return false;
+  //  }
+  //
+  //  private void showAnnotationIndicationInOverviewRuler(AnnotationType annotationType, boolean show) {
+  //    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+  //    OverviewRuler ruler = asv.getOverviewRuler();
+  //    if (ruler != null) {
+  //      ruler.setColor(annotationType, getColor(annotationType));
+  //      ruler.showAnnotation(annotationType, show);
+  //      ruler.update();
+  //    }
+  //  }
+  //
+  //  private void setColorInOverviewRuler(AnnotationType annotationType, Color color) {
+  //    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+  //    OverviewRuler ruler = asv.getOverviewRuler();
+  //    if (ruler != null) {
+  //      ruler.setColor(annotationType, color);
+  //      ruler.update();
+  //    }
+  //  }
 
   private void configureTabConverter() {
     if (fTabConverter != null) {
@@ -1117,30 +1250,30 @@ public class PHPUnitEditor extends PHPEditor {
     return store.getBoolean(SPACES_FOR_TABS);
   }
 
-  private void showOverviewRuler() {
-    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
-    asv.showOverviewRuler();
-
-    OverviewRuler overviewRuler = asv.getOverviewRuler();
-    if (overviewRuler != null) {
-      for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
-        AnnotationType type = ANNOTATION_LAYERS[i];
-        overviewRuler.setLayer(type, i);
-        if (isAnnotationIndicationInOverviewRulerEnabled(type))
-          showAnnotationIndicationInOverviewRuler(type, true);
-      }
-    }
-  }
-
-  private void hideOverviewRuler() {
-    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
-    asv.hideOverviewRuler();
-  }
-
-  private boolean isOverviewRulerVisible() {
-    IPreferenceStore store = getPreferenceStore();
-    return store.getBoolean(OVERVIEW_RULER);
-  }
+  //  private void showOverviewRuler() {
+  //    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+  //    asv.showOverviewRuler();
+  //
+  //    OverviewRuler overviewRuler = asv.getOverviewRuler();
+  //    if (overviewRuler != null) {
+  //      for (int i = 0; i < ANNOTATION_LAYERS.length; i++) {
+  //        AnnotationType type = ANNOTATION_LAYERS[i];
+  //        overviewRuler.setLayer(type, i);
+  //        if (isAnnotationIndicationInOverviewRulerEnabled(type))
+  //          showAnnotationIndicationInOverviewRuler(type, true);
+  //      }
+  //    }
+  //  }
+  //
+  //  private void hideOverviewRuler() {
+  //    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+  //    asv.hideOverviewRuler();
+  //  }
+  //
+  //  private boolean isOverviewRulerVisible() {
+  //    IPreferenceStore store = getPreferenceStore();
+  //    return store.getBoolean(OVERVIEW_RULER);
+  //  }
 
   private Color getColor(String key) {
     RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key);
@@ -1152,23 +1285,23 @@ public class PHPUnitEditor extends PHPEditor {
     return textTools.getColorManager().getColor(rgb);
   }
 
-  private Color getColor(AnnotationType annotationType) {
-    AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
-    if (info != null)
-      return getColor(info.fColorPreference);
-    return null;
-  }
+  //  private Color getColor(AnnotationType annotationType) {
+  //    AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(annotationType);
+  //    if (info != null)
+  //      return getColor(info.fColorPreference);
+  //    return null;
+  //  }
 
   public void dispose() {
     ISourceViewer sourceViewer = getSourceViewer();
     if (sourceViewer instanceof ITextViewerExtension)
        ((ITextViewerExtension) sourceViewer).removeVerifyKeyListener(fBracketInserter);
 
-    if (fPropertyChangeListener != null) {
-      Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
-      preferences.removePropertyChangeListener(fPropertyChangeListener);
-      fPropertyChangeListener = null;
-    }
+    //    if (fPropertyChangeListener != null) {
+    //      Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
+    //      preferences.removePropertyChangeListener(fPropertyChangeListener);
+    //      fPropertyChangeListener = null;
+    //    }
 
     //    if (fJavaEditorErrorTickUpdater != null) {
     //      fJavaEditorErrorTickUpdater.dispose();
@@ -1178,31 +1311,33 @@ public class PHPUnitEditor extends PHPEditor {
     //    if (fSelectionHistory != null)
     //      fSelectionHistory.dispose();
 
-    if (fPaintManager != null) {
-      fPaintManager.dispose();
-      fPaintManager = null;
-    }
+    //    if (fPaintManager != null) {
+    //      fPaintManager.dispose();
+    //      fPaintManager = null;
+    //    }
 
-    if (fActionGroups != null)
+    if (fActionGroups != null) {
       fActionGroups.dispose();
+      fActionGroups = null;
+    }
 
     super.dispose();
   }
 
-  protected AnnotationType getAnnotationType(String preferenceKey) {
-    Iterator e = ANNOTATION_MAP.keySet().iterator();
-    while (e.hasNext()) {
-      AnnotationType type = (AnnotationType) e.next();
-      AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(type);
-      if (info != null) {
-        if (preferenceKey.equals(info.fColorPreference)
-          || preferenceKey.equals(info.fEditorPreference)
-          || preferenceKey.equals(info.fOverviewRulerPreference))
-          return type;
-      }
-    }
-    return null;
-  }
+  //  protected AnnotationType getAnnotationType(String preferenceKey) {
+  //    Iterator e = ANNOTATION_MAP.keySet().iterator();
+  //    while (e.hasNext()) {
+  //      AnnotationType type = (AnnotationType) e.next();
+  //      AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(type);
+  //      if (info != null) {
+  //        if (preferenceKey.equals(info.fColorPreference)
+  //          || preferenceKey.equals(info.fEditorPreference)
+  //          || preferenceKey.equals(info.fOverviewRulerPreference))
+  //          return type;
+  //      }
+  //    }
+  //    return null;
+  //  }
 
   /*
    * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
@@ -1302,36 +1437,36 @@ public class PHPUnitEditor extends PHPEditor {
           return;
         }
 
-        AnnotationType type = getAnnotationType(p);
-        if (type != null) {
-
-          AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(type);
-          if (info.fColorPreference.equals(p)) {
-            Color color = getColor(type);
-            if (fProblemPainter != null) {
-              fProblemPainter.setColor(type, color);
-              fProblemPainter.paint(IPainter.CONFIGURATION);
-            }
-            setColorInOverviewRuler(type, color);
-            return;
-          }
-
-          if (info.fEditorPreference.equals(p)) {
-            if (isAnnotationIndicationEnabled(type))
-              startAnnotationIndication(type);
-            else
-              stopAnnotationIndication(type);
-            return;
-          }
-
-          if (info.fOverviewRulerPreference.equals(p)) {
-            if (isAnnotationIndicationInOverviewRulerEnabled(type))
-              showAnnotationIndicationInOverviewRuler(type, true);
-            else
-              showAnnotationIndicationInOverviewRuler(type, false);
-            return;
-          }
-        }
+        //        AnnotationType type = getAnnotationType(p);
+        //        if (type != null) {
+        //
+        //          AnnotationInfo info = (AnnotationInfo) ANNOTATION_MAP.get(type);
+        //          if (info.fColorPreference.equals(p)) {
+        //            Color color = getColor(type);
+        //            if (fProblemPainter != null) {
+        //              fProblemPainter.setColor(type, color);
+        //              fProblemPainter.paint(IPainter.CONFIGURATION);
+        //            }
+        //            setColorInOverviewRuler(type, color);
+        //            return;
+        //          }
+        //
+        //          if (info.fEditorPreference.equals(p)) {
+        //            if (isAnnotationIndicationEnabled(type))
+        //              startAnnotationIndication(type);
+        //            else
+        //              stopAnnotationIndication(type);
+        //            return;
+        //          }
+        //
+        //          if (info.fOverviewRulerPreference.equals(p)) {
+        //            if (isAnnotationIndicationInOverviewRulerEnabled(type))
+        //              showAnnotationIndicationInOverviewRuler(type, true);
+        //            else
+        //              showAnnotationIndicationInOverviewRuler(type, false);
+        //            return;
+        //          }
+        //        }
 
         IContentAssistant c = asv.getContentAssistant();
         if (c instanceof ContentAssistant)
@@ -1343,13 +1478,9 @@ public class PHPUnitEditor extends PHPEditor {
     }
   }
 
-  /**
-   * Handles a property change event describing a change
-   * of the php core's preferences and updates the preference
-   * related editor properties.
-   * 
-   * @param event the property change event
-   */
+  /*
+        * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
+        */
   protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
     AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
     if (asv != null) {
@@ -1360,14 +1491,42 @@ public class PHPUnitEditor extends PHPEditor {
           fTabConverter.setNumberOfSpacesPerTab(getTabSize());
       }
     }
+    super.handlePreferencePropertyChanged(event);
   }
 
+  /**
+   * Handles a property change event describing a change
+   * of the php core's preferences and updates the preference
+   * related editor properties.
+   * 
+   * @param event the property change event
+   */
+  //  protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
+  //    AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer();
+  //    if (asv != null) {
+  //      String p = event.getProperty();
+  //      if (CODE_FORMATTER_TAB_SIZE.equals(p)) {
+  //        asv.updateIndentationPrefixes();
+  //        if (fTabConverter != null)
+  //          fTabConverter.setNumberOfSpacesPerTab(getTabSize());
+  //      }
+  //    }
+  //  }
+
   /*
    * @see PHPEditor#createJavaSourceViewer(Composite, IVerticalRuler, int)
    */
-  protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
-    return new AdaptedSourceViewer(parent, ruler, styles);
+  protected ISourceViewer createJavaSourceViewer(
+    Composite parent,
+    IVerticalRuler verticalRuler,
+    IOverviewRuler overviewRuler,
+    boolean isOverviewRulerVisible,
+    int styles) {
+    return new AdaptedSourceViewer(parent, verticalRuler, overviewRuler, isOverviewRulerVisible, styles);
   }
+  //  protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+  //    return new AdaptedSourceViewer(parent, ruler, styles);
+  //  }
 
   private boolean isValidSelection(int offset, int length) {
     IDocumentProvider provider = getDocumentProvider();
@@ -1406,16 +1565,103 @@ public class PHPUnitEditor extends PHPEditor {
 
     return oldExtension.equals(newExtension);
   }
-  
-       /*
-        * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager)
-        */
-       public void editorContextMenuAboutToShow(IMenuManager menu) {
-               super.editorContextMenuAboutToShow(menu);               
-                               
-               ActionContext context= new ActionContext(getSelectionProvider().getSelection());
-               fContextMenuGroup.setContext(context);
-               fContextMenuGroup.fillContextMenu(menu);
-               fContextMenuGroup.setContext(null);
-       }
+
+  /*
+   * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager)
+   */
+  public void editorContextMenuAboutToShow(IMenuManager menu) {
+    super.editorContextMenuAboutToShow(menu);
+
+    ActionContext context = new ActionContext(getSelectionProvider().getSelection());
+    fContextMenuGroup.setContext(context);
+    fContextMenuGroup.fillContextMenu(menu);
+    fContextMenuGroup.setContext(null);
+  }
+
+  /*
+   * @see AbstractTextEditor#doSaveAs
+   */
+  public void doSaveAs() {
+    if (askIfNonWorkbenchEncodingIsOk()) {
+      super.doSaveAs();
+    }
+  }
+
+  /*
+        * @see AbstractTextEditor#doSave(IProgressMonitor)
+        */
+  public void doSave(IProgressMonitor progressMonitor) {
+
+    IDocumentProvider p = getDocumentProvider();
+    if (p == null) {
+      // editor has been closed
+      return;
+    }
+
+    if (!askIfNonWorkbenchEncodingIsOk()) {
+      progressMonitor.setCanceled(true);
+      return;
+    }
+
+    if (p.isDeleted(getEditorInput())) {
+
+      if (isSaveAsAllowed()) {
+
+        /*
+         * 1GEUSSR: ITPUI:ALL - User should never loose changes made in the editors.
+         * Changed Behavior to make sure that if called inside a regular save (because
+         * of deletion of input element) there is a way to report back to the caller.
+         */
+        //                                      performSaveAs(progressMonitor);
+        super.doSave(progressMonitor);
+      } else {
+
+        /* 
+         * 1GF5YOX: ITPJUI:ALL - Save of delete file claims it's still there
+         * Missing resources.
+         */
+        Shell shell = getSite().getShell();
+        MessageDialog.openError(shell, PHPEditorMessages.getString("PHPUnitEditor.error.saving.title1"), PHPEditorMessages.getString("PHPUnitEditor.error.saving.message1")); //$NON-NLS-1$ //$NON-NLS-2$
+      }
+
+    } else {
+
+      setStatusLineErrorMessage(null);
+      super.doSave(progressMonitor);
+
+      //                               IWorkingCopyManager manager= JavaPlugin.getDefault().getWorkingCopyManager();
+      //                               ICompilationUnit unit= manager.getWorkingCopy(getEditorInput());
+      //                       
+      //                               if (unit != null) {
+      //                                       synchronized (unit) { 
+      //                                               performSaveOperation(createSaveOperation(false), progressMonitor); 
+      //                                       }
+      //                               } else 
+      //                                       performSaveOperation(createSaveOperation(false), progressMonitor);
+    }
+  }
+  /**
+   * Asks the user if it is ok to store in non-workbench encoding.
+   * @return <true> if the user wants to continue
+   */
+  private boolean askIfNonWorkbenchEncodingIsOk() {
+    IDocumentProvider provider = getDocumentProvider();
+    if (provider instanceof IStorageDocumentProvider) {
+      IEditorInput input = getEditorInput();
+      IStorageDocumentProvider storageProvider = (IStorageDocumentProvider) provider;
+      String encoding = storageProvider.getEncoding(input);
+      String defaultEncoding = storageProvider.getDefaultEncoding();
+      if (encoding != null && !encoding.equals(defaultEncoding)) {
+        Shell shell = getSite().getShell();
+        String title = PHPEditorMessages.getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.title"); //$NON-NLS-1$
+        String msg;
+        if (input != null)
+          msg = MessageFormat.format(PHPEditorMessages.getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.message1"), new String[] { input.getName(), encoding }); //$NON-NLS-1$
+        else
+          msg = MessageFormat.format(PHPEditorMessages.getString("PHPUnitEditor.warning.save.nonWorkbenchEncoding.message2"), new String[] { encoding }); //$NON-NLS-1$
+        return MessageDialog.openQuestion(shell, title, msg);
+      }
+    }
+    return true;
+  }
 }
index 7f06294..03b6594 100644 (file)
@@ -10,13 +10,6 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.widgets.Control;
-
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.BadPositionCategoryException;
 import org.eclipse.jface.text.DefaultPositionUpdater;
@@ -30,6 +23,12 @@ import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.widgets.Control;
 
 
 public final class PaintManager implements KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener {          
index ad9fd45..f722bbc 100644 (file)
@@ -5,6 +5,7 @@ package net.sourceforge.phpeclipse.phpeditor;
  * All Rights Reserved.
  */
 
+import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.events.PaintEvent;
@@ -13,8 +14,6 @@ import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Rectangle;
 
-import org.eclipse.jface.text.source.ISourceViewer;
-
 
 
 public class PrintMarginPainter  implements IPainter, PaintListener {
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/TogglePresentationAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/TogglePresentationAction.java
new file mode 100644 (file)
index 0000000..1a59a91
--- /dev/null
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor;
+
+
+import net.sourceforge.phpdt.internal.ui.PHPUiImages;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+
+/**
+ * A toolbar action which toggles the presentation model of the
+ * connected text editor. The editor shows either the highlight range
+ * only or always the whole document.
+ */
+public class TogglePresentationAction extends TextEditorAction implements IPropertyChangeListener {
+               
+       private IPreferenceStore fStore;
+
+       /**
+        * Constructs and updates the action.
+        */
+       public TogglePresentationAction() {
+               super(PHPEditorMessages.getResourceBundle(), "TogglePresentation.", null); //$NON-NLS-1$
+               PHPUiImages.setToolImageDescriptors(this, "segment_edit.gif"); //$NON-NLS-1$
+               setToolTipText(PHPEditorMessages.getString("TogglePresentation.tooltip")); //$NON-NLS-1$
+               setActionDefinitionId(PHPEditorActionDefinitionIds.TOGGLE_PRESENTATION);
+//             WorkbenchHelp.setHelp(this,     IJavaHelpContextIds.TOGGLE_PRESENTATION_ACTION);                
+               update();
+       }
+       
+       /*
+        * @see IAction#actionPerformed
+        */
+       public void run() {
+               
+               ITextEditor editor= getTextEditor();
+               if (editor == null)
+                       return;
+               
+               IRegion remembered= editor.getHighlightRange();
+               editor.resetHighlightRange();
+               
+               boolean showAll= !editor.showsHighlightRangeOnly();
+               setChecked(showAll);
+               
+               editor.showHighlightRangeOnly(showAll);
+               if (remembered != null)
+                       editor.setHighlightRange(remembered.getOffset(), remembered.getLength(), true);
+               
+               fStore.removePropertyChangeListener(this);
+               fStore.setValue(PreferenceConstants.EDITOR_SHOW_SEGMENTS, showAll);
+               fStore.addPropertyChangeListener(this);
+       }
+       
+       /*
+        * @see TextEditorAction#update
+        */
+       public void update() {
+               ITextEditor editor= getTextEditor();
+               boolean checked= (editor != null && editor.showsHighlightRangeOnly());
+               setChecked(checked);
+               setEnabled(editor != null);
+       }
+       
+       /*
+        * @see TextEditorAction#setEditor(ITextEditor)
+        */
+       public void setEditor(ITextEditor editor) {
+               
+               super.setEditor(editor);
+               
+               if (editor != null) {
+                       
+                       if (fStore == null) {
+                               fStore= PHPeclipsePlugin.getDefault().getPreferenceStore();
+                               fStore.addPropertyChangeListener(this);
+                       }
+                       synchronizeWithPreference(editor);
+                       
+               } else if (fStore != null) {
+                       fStore.removePropertyChangeListener(this);
+                       fStore= null;
+               }
+               
+               update();
+       }
+       
+       /**
+        * Synchronizes the appearance of the editor with what the preference store tells him.
+        */
+       private void synchronizeWithPreference(ITextEditor editor) {
+               
+               if (editor == null)
+                       return;
+               
+               boolean showSegments= fStore.getBoolean(PreferenceConstants.EDITOR_SHOW_SEGMENTS);                      
+               setChecked(showSegments);
+               
+               if (editor.showsHighlightRangeOnly() != showSegments) {
+                       IRegion remembered= editor.getHighlightRange();
+                       editor.resetHighlightRange();
+                       editor.showHighlightRangeOnly(showSegments);
+                       if (remembered != null)
+                               editor.setHighlightRange(remembered.getOffset(), remembered.getLength(), true);
+               }
+       }
+
+       /*
+        * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+        */
+       public void propertyChange(PropertyChangeEvent event) {
+               if (event.getProperty().equals(PreferenceConstants.EDITOR_SHOW_SEGMENTS))
+                       synchronizeWithPreference(getTextEditor());
+       }
+}
index fcdb34a..30ed71c 100644 (file)
@@ -1,7 +1,5 @@
  package net.sourceforge.phpeclipse.phpeditor.html;
 
-import java.io.PrintWriter;
-import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.HashSet;
 import java.util.Set;
index 17d4095..e3d00d4 100644 (file)
@@ -70,7 +70,6 @@ public class HTMLFormattingStrategy implements IFormattingStrategy, IHTMLConstan
        }
 
        public static String getLineDelimiterFor(IDocument doc) {
-               // new for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in java editor inserts lines in wrong format
                String lineDelim = null;
                try {
                        lineDelim = doc.getLineDelimiter(0);
index 1f712a3..95360b8 100644 (file)
@@ -123,6 +123,7 @@ public class HTMLCompletionProcessor implements IContentAssistProcessor {
 
     fComparator = new PHPCompletionProposalComparator();
   }
+  
   /* (non-Javadoc)
    * Method declared on IContentAssistProcessor
    */
index 9d9c023..2613a37 100644 (file)
@@ -19,4 +19,11 @@ public interface IPHPPartitionScannerConstants
        public final static String CSS_MULTILINE_COMMENT = "__css_multiline_comment"; //$NON-NLS-1$
        public final static String HTML = "__html"; //$NON-NLS-1$
        public final static String HTML_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$
+       public final static String SMARTY = "__smarty"; //$NON-NLS-1$
+       public final static String SMARTY_MULTILINE_COMMENT = "__smarty_multiline_comment"; //$NON-NLS-1$
+       
+       public final static int PHP_FILE = 1; 
+       public final static int HTML_FILE = 2; 
+       public final static int XML_FILE = 3; 
+       public final static int SMARTY_FILE = 4; 
 }
index 1fd27c1..09d6734 100644 (file)
@@ -34,18 +34,7 @@ import org.eclipse.jface.text.rules.WordRule;
 /**
  * PHP Code Scanner
  */
-public class PHPCodeScanner
-  extends AbstractJavaScanner {
-
-//  private static Token variable;
-//  private static Token keyword;
-//  private static Token type;
-//  private static Token constant;
-//  private static Token functionName;
-//  private static Token string;
-//  private static Token comment;
-//  private static Token multi_comment;
-//  private static Token other;
+public class PHPCodeScanner extends AbstractJavaScanner {
 
   private class PHPWordRule extends WordRule {
     private StringBuffer fBuffer = new StringBuffer();
@@ -61,6 +50,37 @@ public class PHPCodeScanner
     public IToken evaluate(ICharacterScanner scanner) {
       int c = scanner.read();
       boolean isVariable = false;
+      if (c == '<') {
+        c = scanner.read();
+        if (c != '?') {
+          scanner.unread();
+        } else {
+          c = scanner.read();
+          if (c != 'p') {
+            scanner.unread();
+          } else {
+            c = scanner.read();
+            if (c != 'h') {
+              scanner.unread();
+            } else {
+              c = scanner.read();
+              if (c != 'p') {
+                scanner.unread();
+              } else {
+                return getToken(IPreferenceConstants.PHP_TAG);
+              }
+            }
+          }
+        }
+
+      }
+      if (c == '?') {
+                               c = scanner.read();
+        if (c == '>') {
+          return getToken(IPreferenceConstants.PHP_TAG);
+        }
+        scanner.unread();
+      }
       if (fDetector.isWordStart((char) c)) {
         if (c == '$') {
           isVariable = true;
@@ -71,8 +91,7 @@ public class PHPCodeScanner
           do {
             fBuffer.append((char) c);
             c = scanner.read();
-          } while (
-            c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+          } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
           scanner.unread();
 
           if (isVariable) {
@@ -96,16 +115,18 @@ public class PHPCodeScanner
 
   //private PHPColorProvider fColorProvider;
 
-  private static String[] fgTokenProperties = {
-               IPreferenceConstants.PHP_MULTILINE_COMMENT,
-               IPreferenceConstants.PHP_SINGLELINE_COMMENT,
-               IPreferenceConstants.PHP_KEYWORD,
-               IPreferenceConstants.PHP_FUNCTIONNAME,
-               IPreferenceConstants.PHP_VARIABLE,
-               IPreferenceConstants.PHP_STRING,
-               IPreferenceConstants.PHP_TYPE,
-               IPreferenceConstants.PHP_CONSTANT,
-               IPreferenceConstants.PHP_DEFAULT };
+  private static String[] fgTokenProperties =
+    {
+      IPreferenceConstants.PHP_MULTILINE_COMMENT,
+      IPreferenceConstants.PHP_SINGLELINE_COMMENT,
+                       IPreferenceConstants.PHP_TAG,
+      IPreferenceConstants.PHP_KEYWORD,
+      IPreferenceConstants.PHP_FUNCTIONNAME,
+      IPreferenceConstants.PHP_VARIABLE,
+      IPreferenceConstants.PHP_STRING,
+      IPreferenceConstants.PHP_TYPE,
+      IPreferenceConstants.PHP_CONSTANT,
+      IPreferenceConstants.PHP_DEFAULT };
   /**
        * Creates a PHP code scanner
        */
@@ -248,12 +269,12 @@ public class PHPCodeScanner
    */
   protected List createRules() {
     List rules = new ArrayList();
-    Token token= getToken(IPreferenceConstants.PHP_SINGLELINE_COMMENT);
+    Token token = getToken(IPreferenceConstants.PHP_SINGLELINE_COMMENT);
     // Add rule for single line comments.
     rules.add(new EndOfLineRule("//", token)); //$NON-NLS-1$
     rules.add(new EndOfLineRule("#", token)); //$NON-NLS-1$
     // Add rule for strings and character constants.
-    token= getToken(IPreferenceConstants.PHP_STRING);
+    token = getToken(IPreferenceConstants.PHP_STRING);
     rules.add(new MultiLineRule("\"", "\"", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
     rules.add(new MultiLineRule("`", "`", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
     rules.add(new MultiLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
@@ -261,28 +282,27 @@ public class PHPCodeScanner
     //previous version
     //rules.add(new SingleLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
 
-       
-    token= getToken(IPreferenceConstants.PHP_MULTILINE_COMMENT);
+    token = getToken(IPreferenceConstants.PHP_MULTILINE_COMMENT);
     rules.add(new MultiLineRule("/*", "*/", token)); //$NON-NLS-2$ //$NON-NLS-1$
     // Add generic whitespace rule.
     rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
     // Add word rule for keywords, types, and constants.
-    token= getToken(IPreferenceConstants.PHP_DEFAULT);
+    token = getToken(IPreferenceConstants.PHP_DEFAULT);
     PHPWordRule wordRule = new PHPWordRule(new PHPWordDetector(), token);
 
-    Token keyword= getToken(IPreferenceConstants.PHP_KEYWORD);
-    Token functionName= getToken(IPreferenceConstants.PHP_FUNCTIONNAME);
-    Token type= getToken(IPreferenceConstants.PHP_TYPE);
-    Token constant= getToken(IPreferenceConstants.PHP_CONSTANT);
-    
+    Token keyword = getToken(IPreferenceConstants.PHP_KEYWORD);
+    Token functionName = getToken(IPreferenceConstants.PHP_FUNCTIONNAME);
+    Token type = getToken(IPreferenceConstants.PHP_TYPE);
+    Token constant = getToken(IPreferenceConstants.PHP_CONSTANT);
+
     ArrayList buffer = PHPSyntaxRdr.getSyntaxData();
-  //  String strbuffer = null;  unused
+    //  String strbuffer = null;  unused
     PHPElement elbuffer = null;
-    for (int i=0;i<buffer.size();i++) {
-//    while ((buffer != null)
-//      && (!buffer.isEmpty()
-//        && ((elbuffer = (PHPElement) buffer.remove(0)) != null))) {
-                       elbuffer = (PHPElement) buffer.get(i);
+    for (int i = 0; i < buffer.size(); i++) {
+      //    while ((buffer != null)
+      //      && (!buffer.isEmpty()
+      //        && ((elbuffer = (PHPElement) buffer.remove(0)) != null))) {
+      elbuffer = (PHPElement) buffer.get(i);
       if (elbuffer instanceof PHPKeyword)
         wordRule.addWord(((PHPKeyword) elbuffer).getName(), keyword);
       if (elbuffer instanceof PHPFunction)
@@ -293,7 +313,7 @@ public class PHPCodeScanner
         wordRule.addWord(elbuffer.getName(), constant);
     }
     rules.add(wordRule);
-   // IRule[] result = new IRule[rules.size()];unused
+    // IRule[] result = new IRule[rules.size()];unused
     //    rules.toArray(result);
     //    setRules(result);
     return rules;
index 976f385..4d4acc5 100644 (file)
@@ -41,9 +41,7 @@ import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
-import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.TextPresentation;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
@@ -132,126 +130,6 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     }
   };
 
-  //  public final class VariablesCompletionProposal implements IJavaCompletionProposal {
-  //    private String fDisplayString;
-  //    private String fReplacementString;
-  //    private int fReplacementOffset;
-  //    private int fReplacementLength;
-  //    private int fCursorPosition;
-  //    private Image fImage;
-  //    private IContextInformation fContextInformation;
-  //    private String fAdditionalProposalInfo;
-  //
-  //    /**
-  //     * Creates a new completion proposal based on the provided information.  The replacement string is
-  //     * considered being the display string too. All remaining fields are set to <code>null</code>.
-  //     *
-  //     * @param replacementString the actual string to be inserted into the document
-  //     * @param replacementOffset the offset of the text to be replaced
-  //     * @param replacementLength the length of the text to be replaced
-  //     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
-  //     */
-  //    public VariablesCompletionProposal(
-  //      String replacementString,
-  //      int replacementOffset,
-  //      int replacementLength,
-  //      int cursorPosition) {
-  //      this(replacementString, replacementOffset, replacementLength, cursorPosition, null, null, null, null);
-  //    }
-  //
-  //    /**
-  //     * Creates a new completion proposal. All fields are initialized based on the provided information.
-  //     *
-  //     * @param replacementString the actual string to be inserted into the document
-  //     * @param replacementOffset the offset of the text to be replaced
-  //     * @param replacementLength the length of the text to be replaced
-  //     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
-  //     * @param image the image to display for this proposal
-  //     * @param displayString the string to be displayed for the proposal
-  //     * @param contentInformation the context information associated with this proposal
-  //     * @param additionalProposalInfo the additional information associated with this proposal
-  //     */
-  //    public VariablesCompletionProposal(
-  //      String replacementString,
-  //      int replacementOffset,
-  //      int replacementLength,
-  //      int cursorPosition,
-  //      Image image,
-  //      String displayString,
-  //      IContextInformation contextInformation,
-  //      String additionalProposalInfo) {
-  //      //      Assert.isNotNull(replacementString);
-  //      //      Assert.isTrue(replacementOffset >= 0);
-  //      //      Assert.isTrue(replacementLength >= 0);
-  //      //      Assert.isTrue(cursorPosition >= 0);
-  //
-  //      fReplacementString = replacementString;
-  //      fReplacementOffset = replacementOffset;
-  //      fReplacementLength = replacementLength;
-  //      fCursorPosition = cursorPosition;
-  //      fImage = image;
-  //      fDisplayString = displayString;
-  //      fContextInformation = contextInformation;
-  //      fAdditionalProposalInfo = additionalProposalInfo;
-  //    }
-  //
-  //    /*
-  //     * @see ICompletionProposal#apply
-  //     */
-  //    public void apply(IDocument document) {
-  //      try {
-  //        document.replace(fReplacementOffset, fReplacementLength, fReplacementString);
-  //      } catch (BadLocationException x) {
-  //        // ignore
-  //      }
-  //    }
-  //
-  //    /*
-  //     * @see ICompletionProposal#getSelection
-  //     */
-  //    public Point getSelection(IDocument document) {
-  //      return new Point(fReplacementOffset + fCursorPosition, 0);
-  //    }
-  //
-  //    /*
-  //     * @see ICompletionProposal#getContextInformation()
-  //     */
-  //    public IContextInformation getContextInformation() {
-  //      return fContextInformation;
-  //    }
-  //
-  //    /*
-  //     * @see ICompletionProposal#getImage()
-  //     */
-  //    public Image getImage() {
-  //      return fImage;
-  //    }
-  //
-  //    /*
-  //     * @see ICompletionProposal#getDisplayString()
-  //     */
-  //    public String getDisplayString() {
-  //      if (fDisplayString != null)
-  //        return fDisplayString;
-  //      return fReplacementString;
-  //    }
-  //
-  //    /*
-  //     * @see ICompletionProposal#getAdditionalProposalInfo()
-  //     */
-  //    public String getAdditionalProposalInfo() {
-  //      return fAdditionalProposalInfo;
-  //    }
-  //    /**
-  //    * Returns the relevance of the proposal.
-  //    */
-  //    public int getRelevance() {
-  //      return 0;
-  //    }
-  //  }
-
-//  protected final static String[] fgProposals = PHPFunctionNames.FUNCTION_NAMES;
-
   private char[] fProposalAutoActivationSet;
   protected IContextInformationValidator fValidator = new Validator();
   private TemplateEngine fTemplateEngine;
@@ -285,55 +163,25 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
   public void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
     fProposalAutoActivationSet = activationSet;
   }
+
   /* (non-Javadoc)
    * Method declared on IContentAssistProcessor
    */
   public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
-    //    IDocument document = viewer.getDocument();
-    //    if (documentOffset > 0) {
-    //      try {
-    //        ICompletionProposal[] result;
-    //        char character = document.getChar(documentOffset - 1);
-    //        if (character == '$') {
-    ////viewer.  .getActivePage().getActiveEditor();
-    //          result = new ICompletionProposal[fgProposals.length];
-    //          for (int i = 0; i < fgProposals.length; i++) {
-    //            IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-    //            result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-    //          }
-    //          return result;
-    //        }
-    //      } catch (BadLocationException e) {
-    //        return new ICompletionProposal[0];
-    //      }
-    //    }
-    //
-    //    ICompletionProposal[] result = new ICompletionProposal[fgProposals.length];
-    //    for (int i = 0; i < fgProposals.length; i++) {
-    //      IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-    //      result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-    //    }
-    //    return result;
     int contextInformationPosition = guessContextInformationPosition(viewer, documentOffset);
     return internalComputeCompletionProposals(viewer, documentOffset, contextInformationPosition);
-
   }
 
-  private boolean isReference(ITextViewer viewer, int completionPosition) {
+  private int getLastToken(ITextViewer viewer, int completionPosition, PHPUnitContext context) {
     IDocument document = viewer.getDocument();
-    ContextType contextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
-    ((CompilationUnitContextType) contextType).setContextParameters(document, completionPosition, 0);
-
-    PHPUnitContext context = (PHPUnitContext) contextType.createContext();
     int start = context.getStart();
     int end = context.getEnd();
-    String prefix = context.getKey();
-    IRegion region = new Region(start, end - start);
 
     String startText;
-    boolean useClassEntries = false;
+    int lastSignificantToken = ITerminalSymbols.TokenNameEOF;
+
     try {
-      // search begin of 2 lines behind this
+      // begin search 2 lines behind of this
       int j = start;
       if (j != 0) {
         char ch;
@@ -358,32 +206,42 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
         scanner.setSource(startText.toCharArray());
         scanner.setPHPMode(true);
         int token = ITerminalSymbols.TokenNameEOF;
+        int beforeLastToken = ITerminalSymbols.TokenNameEOF;
         int lastToken = ITerminalSymbols.TokenNameEOF;
 
         try {
           token = scanner.getNextToken();
           lastToken = token;
           while (token != ITerminalSymbols.TokenNameERROR && token != ITerminalSymbols.TokenNameEOF) {
+            beforeLastToken = lastToken;
             lastToken = token;
             //                                                         System.out.println(scanner.toStringAction(lastToken));
             token = scanner.getNextToken();
           }
         } catch (InvalidInputException e1) {
         }
-        if (lastToken == ITerminalSymbols.TokenNameMINUS_GREATER) {
-          // dereferencing operator '->' found
-          useClassEntries = true;
-          //                                                   System.out.println("useClassEntries = true");
+        switch (lastToken) {
+          case ITerminalSymbols.TokenNameMINUS_GREATER :
+            // dereferencing operator '->' found
+            lastSignificantToken = ITerminalSymbols.TokenNameMINUS_GREATER;
+            if (beforeLastToken == ITerminalSymbols.TokenNamethis) {
+              lastSignificantToken = ITerminalSymbols.TokenNamethis;
+            }
+            break;
+          case ITerminalSymbols.TokenNamenew :
+            lastSignificantToken = ITerminalSymbols.TokenNamenew;
+            break;
         }
       }
     } catch (BadLocationException e) {
     }
-    return useClassEntries;
+    return lastSignificantToken;
   }
-  
+
   private ICompletionProposal[] internalComputeCompletionProposals(ITextViewer viewer, int offset, int contextOffset) {
     IDocument document = viewer.getDocument();
     Object[] identifiers = null;
+    IFile file = null;
     IProject project = null;
     if (offset > 0) {
 
@@ -393,8 +251,8 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
       IEditorPart targetEditor = PHPeclipsePlugin.getActiveWorkbenchWindow().getActivePage().getActiveEditor();
       if (targetEditor != null && (targetEditor instanceof PHPEditor)) {
         editor = (PHPEditor) targetEditor;
-        IFile f = ((IFileEditorInput) editor.getEditorInput()).getFile();
-        project = f.getProject();
+        file = ((IFileEditorInput) editor.getEditorInput()).getFile();
+        project = file.getProject();
         outlinePage = editor.getfOutlinePage();
         if (outlinePage instanceof PHPContentOutlinePage) {
           identifiers = ((PHPContentOutlinePage) outlinePage).getVariables();
@@ -402,28 +260,32 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
       }
     }
 
+    ContextType phpContextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
+     ((CompilationUnitContextType) phpContextType).setContextParameters(document, offset, 0);
+
+    PHPUnitContext context = (PHPUnitContext) phpContextType.createContext();
+    String prefix = context.getKey();
+
+    int lastSignificantToken = getLastToken(viewer, offset, context);
+    boolean useClassMembers =
+      (lastSignificantToken == ITerminalSymbols.TokenNameMINUS_GREATER) || 
+      (lastSignificantToken == ITerminalSymbols.TokenNamethis) ||
+                 (lastSignificantToken == ITerminalSymbols.TokenNamenew);
+    boolean emptyPrefix = prefix == null || prefix.equals("");
+
     if (fTemplateEngine != null) {
-      ICompletionProposal[] results;
-      //      try {
-      fTemplateEngine.reset();
-      fTemplateEngine.complete(viewer, offset); //, unit);
-      //      } catch (JavaModelException x) {
-      //        Shell shell= viewer.getTextWidget().getShell();
-      //        ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
-      //      }       
+      IPHPCompletionProposal[] templateResults = new IPHPCompletionProposal[0];
 
-      IPHPCompletionProposal[] templateResults = fTemplateEngine.getResults();
+      ICompletionProposal[] results;
+      if (!emptyPrefix) {
+        fTemplateEngine.reset();
+        fTemplateEngine.complete(viewer, offset); //, unit);
+        templateResults = fTemplateEngine.getResults();
+      }
 
       IPHPCompletionProposal[] identifierResults = new IPHPCompletionProposal[0];
-      if (identifiers != null) {
+      if ((!useClassMembers) && identifiers != null) {
         IdentifierEngine identifierEngine;
-        String proposal;
-        // int j = 0;
-        //        for (int i = templateResults.length; i < templateResults.length + variables.length; i++) {
-        //          proposal = (String) variables[j++];
-        //          IContextInformation info = new ContextInformation(proposal, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { proposal })); //$NON-NLS-1$
-        //          results[i] = new VariablesCompletionProposal(proposal, offset, 0, proposal.length(), null, proposal, info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { proposal })); //$NON-NLS-1$
-        //        }
 
         ContextType contextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
         if (contextType != null) {
@@ -433,27 +295,26 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
         }
       }
 
-      boolean useClassEntries = isReference(viewer, offset);
+      // declarations stored in file project.index on project level
       IPHPCompletionProposal[] declarationResults = new IPHPCompletionProposal[0];
       if (project != null) {
-        DeclarationEngine identifierEngine;
-        String proposal;
+        DeclarationEngine declarationEngine;
 
         ContextType contextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
         if (contextType != null) {
           IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(project);
           SortedMap sortedMap = indexManager.getIdentifierMap();
 
-          identifierEngine = new DeclarationEngine(contextType, useClassEntries);
-          identifierEngine.complete(viewer, offset, sortedMap);
-          identifierResults = identifierEngine.getResults();
+          declarationEngine = new DeclarationEngine(contextType, lastSignificantToken, file);
+          declarationEngine.complete(viewer, offset, sortedMap);
+          declarationResults = declarationEngine.getResults();
         }
       }
 
       // built in function names from phpsyntax.xml
-                       ArrayList syntaxbuffer = PHPSyntaxRdr.getSyntaxData();
+      ArrayList syntaxbuffer = PHPSyntaxRdr.getSyntaxData();
       IPHPCompletionProposal[] builtinResults = new IPHPCompletionProposal[0];
-      if ((!useClassEntries)&&syntaxbuffer != null) {
+      if ((!useClassMembers) && syntaxbuffer != null) {
         BuiltInEngine builtinEngine;
         String proposal;
 
@@ -465,7 +326,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
         }
       }
 
-      // concatenate arrays
+      // concatenate the result arrays
       IPHPCompletionProposal[] total;
       total =
         new IPHPCompletionProposal[templateResults.length
index 522df96..e9e7998 100644 (file)
@@ -4,11 +4,11 @@
  */
 package net.sourceforge.phpeclipse.phpeditor.php;
 
-import org.eclipse.jface.text.*;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * @author slanger
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
  */
 public class PHPPartition extends Partition
 {
index 52f8def..eb31667 100644 (file)
@@ -6,11 +6,10 @@
  * Created on 05.03.2003
  *
  * @author Stefan Langer (musk)
- * @version $Revision: 1.19 $
+ * @version $Revision: 1.20 $
  */
 package net.sourceforge.phpeclipse.phpeditor.php;
 
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -27,509 +26,470 @@ import org.eclipse.jface.text.rules.Token;
 /**
  * 
  */
-public class PHPPartitionScanner implements IPartitionTokenScanner
-{
-    private static final boolean DEBUG = false;
-    private boolean fInString = false;
-    private boolean fInDoubString = false;
-    private IDocument fDocument = null;
-    private int fOffset = -1;
-    private String fContentType = IPHPPartitionScannerConstants.HTML;
-    private String fPrevContentType = IPHPPartitionScannerConstants.HTML;
-    private boolean partitionBorder = false;
-    private int fTokenOffset;
-    private int fEnd = -1;
-    private int fLength;
-    private int fCurrentLength;
-    private Map tokens = new HashMap();
-
-    public PHPPartitionScanner()
-    {
-        this.tokens.put(
-            IPHPPartitionScannerConstants.PHP,
-            new Token(IPHPPartitionScannerConstants.PHP));
-        this.tokens.put(
-            IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT,
-            new Token(IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT));
-        this.tokens.put(
-            IPHPPartitionScannerConstants.HTML,
-            new Token(IPHPPartitionScannerConstants.HTML));
-        this.tokens.put(
-            IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT,
-            new Token(IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT));
-        this.tokens.put(
-            IDocument.DEFAULT_CONTENT_TYPE,
-            new Token(IDocument.DEFAULT_CONTENT_TYPE));
-    }
+public class PHPPartitionScanner implements IPartitionTokenScanner {
+  private static final boolean DEBUG = false;
 
-    private IToken getToken(String type)
-    {
-        fLength = fCurrentLength;
-        if (DEBUG)
-        {
-
-            try
-            {
-                if (fLength <= 0)
-                {
-                    int line = fDocument.getLineOfOffset(fOffset);
-                    System.err.println(
-                        "Error at "
-                            + line
-                            + " offset:"
-                            + String.valueOf(
-                                fOffset - fDocument.getLineOffset(line)));
-                }
-            }
-            catch (BadLocationException e)
-            {  // should never happen
-                // TODO Write stacktrace to log
-                e.printStackTrace();
-            }
-        }
-        Assert.isTrue(fLength > 0, "Partition length <= 0!");
-        fCurrentLength = 0;
-        // String can never cross partition borders so reset string detection
-        fInString = false;
-        fInDoubString = false;
-        IToken token = (IToken) this.tokens.get(type);
-        Assert.isNotNull(token, "Token for type \"" + type + "\" not found!");
-        if (DEBUG)
-        {
-            System.out.println(
-                "Partition: fTokenOffset="
-                    + fTokenOffset
-                    + " fContentType="
-                    + type
-                    + " fLength="
-                    + fLength);
-        }
-        return token;
-    }
+  private boolean fInString = false;
+  private boolean fInDoubString = false;
+  private IDocument fDocument = null;
+  private int fOffset = -1;
+  private String fContentType = IPHPPartitionScannerConstants.HTML;
+  private String fPrevContentType = IPHPPartitionScannerConstants.HTML;
+  private boolean partitionBorder = false;
+  private int fTokenOffset;
+  private int fEnd = -1;
+  private int fLength;
+  private int fCurrentLength;
+  private int fFileType;
+  private Map tokens = new HashMap();
 
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int)
-     */
-    public void setPartialRange(
-        IDocument document,
-        int offset,
-        int length,
-        String contentType,
-        int partitionOffset)
-    {
-        if (DEBUG)
-        {
-            System.out.println(
-                "PartialRange: contentType="
-                    + contentType
-                    + " partitionOffset="
-                    + partitionOffset);
-        }
+  public PHPPartitionScanner(int fileType) {
+    this.tokens.put(IPHPPartitionScannerConstants.PHP, new Token(IPHPPartitionScannerConstants.PHP));
+    this.tokens.put(
+      IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT,
+      new Token(IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT));
+    this.tokens.put(IPHPPartitionScannerConstants.HTML, new Token(IPHPPartitionScannerConstants.HTML));
+    this.tokens.put(
+      IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT,
+      new Token(IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT));
 
-        try
-        {
-            if (partitionOffset > -1)
-            {
-                partitionBorder = false;
-                // because of strings we have to parse the whole partition
-                this.setRange(
-                    document,
-                    partitionOffset,
-                    offset - partitionOffset + length);
-                // sometimes we get a wrong partition so we retrieve the partition
-                // directly from the document
-                fContentType = fDocument.getContentType(partitionOffset);
-            }
-            else
-                this.setRange(document, offset, length);
+    this.tokens.put(IPHPPartitionScannerConstants.SMARTY, new Token(IPHPPartitionScannerConstants.SMARTY));
+    this.tokens.put(
+      IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT,
+      new Token(IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT));
 
-        }
-        catch (BadLocationException e)
-        {
-            // should never happen
-            // TODO print stack trace to log
-            // fall back just scan the whole document again
-            this.setRange(document, 0, fDocument.getLength());
-        }
+    this.tokens.put(IDocument.DEFAULT_CONTENT_TYPE, new Token(IDocument.DEFAULT_CONTENT_TYPE));
+    fFileType = fileType;
+  }
 
+  private IToken getToken(String type) {
+    fLength = fCurrentLength;
+    if (DEBUG) {
+
+      try {
+        if (fLength <= 0) {
+          int line = fDocument.getLineOfOffset(fOffset);
+          System.err.println("Error at " + line + " offset:" + String.valueOf(fOffset - fDocument.getLineOffset(line)));
+        }
+      } catch (BadLocationException e) { // should never happen
+        // TODO Write stacktrace to log
+        e.printStackTrace();
+      }
     }
+    Assert.isTrue(fLength > 0, "Partition length <= 0!");
+    fCurrentLength = 0;
+    // String can never cross partition borders so reset string detection
+    fInString = false;
+    fInDoubString = false;
+    IToken token = (IToken) this.tokens.get(type);
+    Assert.isNotNull(token, "Token for type \"" + type + "\" not found!");
+    if (DEBUG) {
+      System.out.println("Partition: fTokenOffset=" + fTokenOffset + " fContentType=" + type + " fLength=" + fLength);
+    }
+    return token;
+  }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
-     */
-    public int getTokenLength()
-    {
-        return fLength;
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int)
+   */
+  public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+    if (DEBUG) {
+      System.out.println("*****");
+      System.out.println("PartialRange: contentType=" + contentType + " partitionOffset=" + partitionOffset);
     }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
-     */
-    public int getTokenOffset()
-    {
-        return fTokenOffset;
+    try {
+      if (partitionOffset > -1) {
+        partitionBorder = false;
+        // because of strings we have to parse the whole partition
+        this.setRange(document, partitionOffset, offset - partitionOffset + length);
+        // sometimes we get a wrong partition so we retrieve the partition
+        // directly from the document
+        fContentType = fDocument.getContentType(partitionOffset);
+      } else
+        this.setRange(document, offset, length);
+
+    } catch (BadLocationException e) {
+      // should never happen
+      // TODO print stack trace to log
+      // fall back just scan the whole document again
+      this.setRange(document, 0, fDocument.getLength());
     }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
-     */
-    public IToken nextToken()
-    {
-        int c;
-
-        // check if we are not allready at the end of the
-        // file
-        if ((c = read()) == ICharacterScanner.EOF)
-        {
-            partitionBorder = false;
-            return Token.EOF;
-        }
-        else
-            unread();
+  }
 
-        if (partitionBorder)
-        {
-            fTokenOffset = fOffset;
-            partitionBorder = false;
-        }
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+   */
+  public int getTokenLength() {
+    return fLength;
+  }
 
-        while ((c = read()) != ICharacterScanner.EOF)
-        {
-            switch (c)
-            {
-                case '<' :
-                    if (!isInString(IPHPPartitionScannerConstants.PHP)
-                        && fContentType
-                            != IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT
-                        && checkPattern(new char[] { '?', 'p', 'h', 'p' }, true))
-                    {
-                        if (fContentType != IPHPPartitionScannerConstants.PHP
-                            && fCurrentLength > 5)
-                        {
-                            unread(5);
-                            IToken token = getToken(fContentType);
-                            // save previouse contenttype
-                            //TODO build stack for previouse contenttype 
-                            fPrevContentType = fContentType;
-
-                            fContentType = IPHPPartitionScannerConstants.PHP;
-
-                            return token;
-                        }
-                        else
-                            fContentType = IPHPPartitionScannerConstants.PHP;
-
-                        // remember offset of this partition
-                        fTokenOffset = fOffset - 5;
-                        fCurrentLength = 5;
-                    }
-                    else if (
-                        !isInString(IPHPPartitionScannerConstants.PHP)
-                            && fContentType
-                                != IPHPPartitionScannerConstants
-                                    .PHP_MULTILINE_COMMENT
-                            && checkPattern(new char[] { '?' }, false))
-                    {
-                        if (fContentType != IPHPPartitionScannerConstants.PHP
-                            && fCurrentLength > 2)
-                        {
-                            unread(2);
-                            IToken token = getToken(fContentType);
-                            // save previouse contenttype
-                            fPrevContentType = fContentType;
-                            fContentType = IPHPPartitionScannerConstants.PHP;
-                            return token;
-                        }
-                        else
-                            fContentType = IPHPPartitionScannerConstants.PHP;
-                        // remember offset of this partition
-                        fTokenOffset = fOffset - 2;
-                        fCurrentLength = 2;
-                    }
-                    else if (
-                        !isInString(IPHPPartitionScannerConstants.PHP)
-                            && checkPattern(new char[] { '!', '-', '-' }))
-                    { // return previouse partition
-                        if (fContentType
-                            != IPHPPartitionScannerConstants
-                                .HTML_MULTILINE_COMMENT
-                            && fCurrentLength > 4)
-                        {
-                            unread(4);
-                            IToken token = getToken(fContentType);
-                            fContentType =
-                                IPHPPartitionScannerConstants
-                                    .HTML_MULTILINE_COMMENT;
-                            return token;
-                        }
-                        else
-                            fContentType =
-                                IPHPPartitionScannerConstants
-                                    .HTML_MULTILINE_COMMENT;
-                                    
-                        fTokenOffset = fOffset - 4;
-                        fCurrentLength = 4;
-                    }
-                    break;
-                case '?' :
-                    if (!isInString(IPHPPartitionScannerConstants.PHP)
-                        && fContentType == IPHPPartitionScannerConstants.PHP)
-                    {
-                        if ((c = read()) == '>')
-                        { 
-                            if (fPrevContentType != null)
-                                fContentType = fPrevContentType;
-                            else
-                                fContentType =
-                                    IPHPPartitionScannerConstants.HTML;
-                            partitionBorder = true;
-                            return getToken(IPHPPartitionScannerConstants.PHP);
-                        }
-                        else if (c != ICharacterScanner.EOF)
-                            unread();
-                    }
-                    break;
-                case '-' :
-                    if (!isInString(IPHPPartitionScannerConstants.PHP)
-                        && fContentType
-                            == IPHPPartitionScannerConstants
-                                .HTML_MULTILINE_COMMENT
-                        && checkPattern(new char[] { '-', '>' }))
-                    {
-                        fContentType = IPHPPartitionScannerConstants.HTML;
-                        partitionBorder = true;
-                        return getToken(
-                            IPHPPartitionScannerConstants
-                                .HTML_MULTILINE_COMMENT);
-                    }
-                    break;
-                case '/' :
-                    if (!isInString(IPHPPartitionScannerConstants.PHP) && (c = read()) == '*')
-                    { // MULTINE COMMENT JAVASCRIPT, CSS, PHP
-                        if (fContentType == IPHPPartitionScannerConstants.PHP
-                            && fCurrentLength > 2)
-                        {
-                            unread(2);
-                            IToken token = getToken(fContentType);
-                            fContentType =
-                                IPHPPartitionScannerConstants
-                                    .PHP_MULTILINE_COMMENT;
-                            return token;
-                        }
-                        else if (
-                            fContentType
-                                == IPHPPartitionScannerConstants
-                                    .PHP_MULTILINE_COMMENT)
-                        {
-
-                            fTokenOffset = fOffset - 2;
-                            fCurrentLength = 2;
-                        }
-
-                    }
-                    else if (!isInString(IPHPPartitionScannerConstants.PHP) && c != ICharacterScanner.EOF)
-                        unread();
-                    break;
-                case '*' :
-                    if (!isInString(IPHPPartitionScannerConstants.PHP) && (c = read()) == '/')
-                    {
-                        if (fContentType
-                            == IPHPPartitionScannerConstants
-                                .PHP_MULTILINE_COMMENT)
-                        {
-                            fContentType = IPHPPartitionScannerConstants.PHP;
-                            partitionBorder = true;
-                            return getToken(
-                                IPHPPartitionScannerConstants
-                                    .PHP_MULTILINE_COMMENT);
-                        }
-                        else if (
-                            fContentType
-                                == IPHPPartitionScannerConstants
-                                    .CSS_MULTILINE_COMMENT)
-                        {
-                        }
-                        else if (
-                            fContentType
-                                == IPHPPartitionScannerConstants
-                                    .JS_MULTILINE_COMMENT)
-                        {
-                        }
-                    }
-                    else if (!isInString(IPHPPartitionScannerConstants.PHP) && c != ICharacterScanner.EOF)
-                        unread();
-                    break;
-                case '\'' :
-                    if (!fInDoubString)
-                        fInString = !fInString;
-                    break;
-                case '"' :
-                    // toggle String mode
-                    if (!fInString)
-                        fInDoubString = !fInDoubString;
-                    break;
-            }
-        } // end of file reached but we have to return the
-        // last partition.
-        return getToken(fContentType);
-    }
-    /* (non-Javadoc)
-     * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int)
-     */
-    public void setRange(IDocument document, int offset, int length)
-    {
-        if (DEBUG)
-        {
-            System.out.println(
-                "SET RANGE: offset=" + offset + " length=" + length);
-        }
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+   */
+  public int getTokenOffset() {
+    return fTokenOffset;
+  }
 
-        fDocument = document;
-        fOffset = offset;
-        fTokenOffset = offset;
-        fCurrentLength = 0;
-        fLength = 0;
-        fEnd = fOffset + length;
-        fInString = false;
-        fInDoubString = false;
-        fContentType = IPHPPartitionScannerConstants.HTML;
-//        String[] prev = getPartitionStack(offset);
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+   */
+  public IToken nextToken() {
+    int c;
+
+    // check if we are not allready at the end of the
+    // file
+    if ((c = read()) == ICharacterScanner.EOF) {
+      partitionBorder = false;
+      return Token.EOF;
+    } else
+      unread();
+
+    if (partitionBorder) {
+      fTokenOffset = fOffset;
+      partitionBorder = false;
     }
 
-    private int read()
-    {
-        try
-        {
-            if (fOffset < fEnd)
-            {
-               fCurrentLength++;
-                return fDocument.getChar(fOffset++);
+    while ((c = read()) != ICharacterScanner.EOF) {
+      switch (c) {
+        case '<' :
+          if (!isInString(IPHPPartitionScannerConstants.PHP)
+            && fContentType != IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT
+            && checkPattern(new char[] { '?', 'p', 'h', 'p' }, true)) {
+            if (fContentType != IPHPPartitionScannerConstants.PHP && fCurrentLength > 5) {
+              unread(5);
+              IToken token = getToken(fContentType);
+              // save previouse contenttype
+              //TODO build stack for previouse contenttype 
+              fPrevContentType = fContentType;
+
+              fContentType = IPHPPartitionScannerConstants.PHP;
+
+              return token;
+            } else
+              fContentType = IPHPPartitionScannerConstants.PHP;
+
+            // remember offset of this partition
+            fTokenOffset = fOffset - 5;
+            fCurrentLength = 5;
+          } else if (
+            !isInString(IPHPPartitionScannerConstants.PHP)
+              && fContentType != IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT
+              && checkPattern(new char[] { '?' }, false)) {
+            if (fContentType != IPHPPartitionScannerConstants.PHP && fCurrentLength > 2) {
+              unread(2);
+              IToken token = getToken(fContentType);
+              // save previouse contenttype
+              fPrevContentType = fContentType;
+              fContentType = IPHPPartitionScannerConstants.PHP;
+              return token;
+            } else
+              fContentType = IPHPPartitionScannerConstants.PHP;
+            // remember offset of this partition
+            fTokenOffset = fOffset - 2;
+            fCurrentLength = 2;
+          } else if (
+            !isInString(IPHPPartitionScannerConstants.PHP)
+              && (fContentType != IPHPPartitionScannerConstants.PHP) // BUG #769044
+              && (fContentType != IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT) // BUG #769044
+              && checkPattern(new char[] { '!', '-', '-' })) { // return previouse partition
+            if (fContentType != IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT && fCurrentLength > 4) {
+              unread(4);
+              IToken token = getToken(fContentType);
+              fContentType = IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT;
+              return token;
+            } else
+              fContentType = IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT;
+
+            fTokenOffset = fOffset - 4;
+            fCurrentLength = 4;
+          }
+          break;
+        case '?' :
+          if (!isInString(IPHPPartitionScannerConstants.PHP) && fContentType == IPHPPartitionScannerConstants.PHP) {
+            if ((c = read()) == '>') {
+              if (fPrevContentType != null)
+                fContentType = fPrevContentType;
+              else
+                fContentType = IPHPPartitionScannerConstants.HTML;
+              partitionBorder = true;
+              return getToken(IPHPPartitionScannerConstants.PHP);
+            } else if (c != ICharacterScanner.EOF)
+              unread();
+          }
+          break;
+        case '-' :
+          if (!isInString(IPHPPartitionScannerConstants.PHP)
+            && fContentType == IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT
+            && checkPattern(new char[] { '-', '>' })) {
+            fContentType = IPHPPartitionScannerConstants.HTML;
+            partitionBorder = true;
+            return getToken(IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT);
+          }
+          break;
+        case '{' : // SMARTY code starts here ?
+          if (fFileType == IPHPPartitionScannerConstants.SMARTY_FILE) {
+            if ((c = read()) == '*') {
+              if (DEBUG) {
+                System.out.println(
+                  "SMARTYDOC_TOKEN start "
+                    + fTokenOffset
+                    + " fContentType="
+                    + fContentType
+                    + " fLength="
+                    + fLength
+                    + " fOffset="
+                    + fOffset
+                    + " fCurrentLength="
+                    + fCurrentLength);
+              }
+              if (fContentType != IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT && fCurrentLength > 2) {
+                // SMARTY doc code starts here 
+                unread(2);
+                IToken token = getToken(fContentType);
+                fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT;
+                return token;
+                //              } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset == 2) {
+                //                fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT;
+              } else { // if (fContentType == IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT) {
+                fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT;
+                fTokenOffset = fOffset - 2;
+                fCurrentLength = 2;
+              }
+              break;
+            }
+            if (DEBUG) {
+              System.out.println(
+                "SMARTY_TOKEN start "
+                  + fTokenOffset
+                  + " fContentType="
+                  + fContentType
+                  + " fLength="
+                  + fLength
+                  + " fOffset="
+                  + fOffset);
+            }
+            unread();
+            if (fContentType != IPHPPartitionScannerConstants.SMARTY && fCurrentLength > 1) {
+              unread(1);
+              IToken token = getToken(fContentType);
+              fContentType = IPHPPartitionScannerConstants.SMARTY;
+              return token;
+              //            } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset==1) {
+              //              fContentType = IPHPPartitionScannerConstants.SMARTY;
+            } else {
+              fContentType = IPHPPartitionScannerConstants.SMARTY;
+              fTokenOffset = fOffset - 1;
+              fCurrentLength = 1;
+            }
+          }
+          break;
+        case '}' : // SMARTY code ends here ?
+          if (fFileType == IPHPPartitionScannerConstants.SMARTY_FILE && fContentType == IPHPPartitionScannerConstants.SMARTY) {
+            if (DEBUG) {
+              System.out.println(
+                "SMARTY_TOKEN end "
+                  + fTokenOffset
+                  + " fContentType="
+                  + fContentType
+                  + " fLength="
+                  + fLength
+                  + " fOffset="
+                  + fOffset);
+            }
+            fContentType = IPHPPartitionScannerConstants.HTML;
+            partitionBorder = true;
+            return getToken(IPHPPartitionScannerConstants.SMARTY);
+          }
+          break;
+        case '/' :
+          if (!isInString(IPHPPartitionScannerConstants.PHP) && (c = read()) == '*') { // MULTINE COMMENT JAVASCRIPT, CSS, PHP
+            if (fContentType == IPHPPartitionScannerConstants.PHP && fCurrentLength > 2) {
+              unread(2);
+              IToken token = getToken(fContentType);
+              fContentType = IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT;
+              return token;
+            } else if (fContentType == IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT) {
+              fTokenOffset = fOffset - 2;
+              fCurrentLength = 2;
+            }
+
+          } else if (!isInString(IPHPPartitionScannerConstants.PHP) && c != ICharacterScanner.EOF)
+            unread();
+          break;
+        case '*' :
+          if (!isInString(IPHPPartitionScannerConstants.PHP) && (c = read()) == '/') {
+            if (fContentType == IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT) {
+              fContentType = IPHPPartitionScannerConstants.PHP;
+              partitionBorder = true;
+              return getToken(IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT);
+            } else if (fContentType == IPHPPartitionScannerConstants.CSS_MULTILINE_COMMENT) {
+            } else if (fContentType == IPHPPartitionScannerConstants.JS_MULTILINE_COMMENT) {
             }
-            return ICharacterScanner.EOF;
-        }
-        catch (BadLocationException e)
-        {
-            // should never happen
-            // TODO write stacktrace to log
-            fOffset = fEnd;
-            return ICharacterScanner.EOF;
-        }
+          } else if (fFileType == IPHPPartitionScannerConstants.SMARTY_FILE && (c = read()) == '}') {
+            if (DEBUG) {
+              System.out.println(
+                "SMARTYDOC_TOKEN end "
+                  + fTokenOffset
+                  + " fContentType="
+                  + fContentType
+                  + " fLength="
+                  + fLength
+                  + " fOffset="
+                  + fOffset);
+            }
+            if (fContentType == IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT) {
+              fContentType = IPHPPartitionScannerConstants.HTML;
+              partitionBorder = true;
+              return getToken(IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT);
+            }
+          } else if (!isInString(IPHPPartitionScannerConstants.PHP) && c != ICharacterScanner.EOF) {
+            unread();
+          }
+          break;
+        case '\'' :
+          if (!fInDoubString)
+            fInString = !fInString;
+          break;
+        case '"' :
+          // toggle String mode
+          if (!fInString)
+            fInDoubString = !fInDoubString;
+          break;
+      }
+    } // end of file reached but we have to return the
+    // last partition.
+    return getToken(fContentType);
+  }
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int)
+   */
+  public void setRange(IDocument document, int offset, int length) {
+    if (DEBUG) {
+      System.out.println("SET RANGE: offset=" + offset + " length=" + length);
     }
 
-    private void unread()
-    {
-        --fOffset;
-        --fCurrentLength;
-    }
-    
-    private void unread(int num)
-    {
-       fOffset -= num;
-       fCurrentLength -= num;
-    }
+    fDocument = document;
+    fOffset = offset;
+    fTokenOffset = offset;
+    fCurrentLength = 0;
+    fLength = 0;
+    fEnd = fOffset + length;
+    fInString = false;
+    fInDoubString = false;
+    fContentType = IPHPPartitionScannerConstants.HTML;
+    //        String[] prev = getPartitionStack(offset);
+  }
 
-    private boolean checkPattern(char[] pattern)
-    {
-        return checkPattern(pattern, false);
+  private int read() {
+    try {
+      if (fOffset < fEnd) {
+        fCurrentLength++;
+        return fDocument.getChar(fOffset++);
+      }
+      return ICharacterScanner.EOF;
+    } catch (BadLocationException e) {
+      // should never happen
+      // TODO write stacktrace to log
+      fOffset = fEnd;
+      return ICharacterScanner.EOF;
     }
+  }
 
-    /**
-     * Check if next character sequence read from document is equals to 
-     * the provided pattern. Pattern is read from left to right until the 
-     * first character read doesn't match. If this happens all read characters are
-     * unread.
-     * @param pattern The pattern to check.
-     * @return <code>true</code> if pattern is equals else returns <code>false</code>.
-     */
-    private boolean checkPattern(char[] pattern, boolean ignoreCase)
-    {
-        int prevOffset = fOffset;
-        int prevLength = fCurrentLength;
-        for (int i = 0; i < pattern.length; i++)
-        {
-            int c = read();
-
-            if (c == ICharacterScanner.EOF
-                || !letterEquals(c, pattern[i], ignoreCase))
-            {
-                fOffset = prevOffset;
-                fCurrentLength = prevLength;
-                return false;
-            }
-        }
+  private void unread() {
+    --fOffset;
+    --fCurrentLength;
+  }
 
-        return true;
-    }
+  private void unread(int num) {
+    fOffset -= num;
+    fCurrentLength -= num;
+  }
+
+  private boolean checkPattern(char[] pattern) {
+    return checkPattern(pattern, false);
+  }
 
-    private boolean letterEquals(int test, char letter, boolean ignoreCase)
-    {
-        if (test == letter)
-            return true;
-        else if (
-            ignoreCase
-                && Character.isLowerCase(letter)
-                && test == Character.toUpperCase(letter))
-            return true;
-        else if (
-            ignoreCase
-                && Character.isUpperCase(letter)
-                && test == Character.toLowerCase(letter))
-            return true;
+  /**
+   * Check if next character sequence read from document is equals to 
+   * the provided pattern. Pattern is read from left to right until the 
+   * first character read doesn't match. If this happens all read characters are
+   * unread.
+   * @param pattern The pattern to check.
+   * @return <code>true</code> if pattern is equals else returns <code>false</code>.
+   */
+  private boolean checkPattern(char[] pattern, boolean ignoreCase) {
+    int prevOffset = fOffset;
+    int prevLength = fCurrentLength;
+    for (int i = 0; i < pattern.length; i++) {
+      int c = read();
 
+      if (c == ICharacterScanner.EOF || !letterEquals(c, pattern[i], ignoreCase)) {
+        fOffset = prevOffset;
+        fCurrentLength = prevLength;
         return false;
+      }
     }
-    
-    /**
-     * Checks wether the offset is in a <code>String</code> and the specified 
-     * contenttype is the current content type.
-     * Strings are delimited, mutual exclusive, by a " or by a '.
-     * 
-     * @param contentType The contenttype to check.
-     * @return <code>true</code> if the current offset is in a string else 
-     *                         returns false.
-     */
-    private  boolean isInString(String contentType)
-    {
-       if(fContentType == contentType)
-               return (fInString || fInDoubString);
-       else
-               return false;           
-    }
-    
-    /**
-     * Returns the previouse partition stack for the given offset.
-     * 
-     * @param offset The offset to return the previouse partitionstack for.
-     * 
-     * @return The stack as a string array.
-     */
-    private String[] getPartitionStack(int offset)
-    {
-       ArrayList types = new ArrayList();
-       int tmpOffset = 0;
-       try
-        {
-            ITypedRegion region = fDocument.getPartition(offset);
-            tmpOffset = region.getOffset();
-            while(tmpOffset-1 > 0)
-            {
-               region = fDocument.getPartition(tmpOffset-1);
-               tmpOffset = region.getOffset();
-               types.add(0, region.getType());
-            }
-        }
-        catch (BadLocationException e)
-        {
-           if(DEBUG)
-           {
-                       e.printStackTrace();
-           }
-        }
-       
-               String[] retVal = new String[types.size()];
-       
-       retVal = (String[])types.toArray(retVal);
-       return retVal;
+
+    return true;
+  }
+
+  private boolean letterEquals(int test, char letter, boolean ignoreCase) {
+    if (test == letter)
+      return true;
+    else if (ignoreCase && Character.isLowerCase(letter) && test == Character.toUpperCase(letter))
+      return true;
+    else if (ignoreCase && Character.isUpperCase(letter) && test == Character.toLowerCase(letter))
+      return true;
+
+    return false;
+  }
+
+  /**
+   * Checks wether the offset is in a <code>String</code> and the specified 
+   * contenttype is the current content type.
+   * Strings are delimited, mutual exclusive, by a " or by a '.
+   * 
+   * @param contentType The contenttype to check.
+   * @return <code>true</code> if the current offset is in a string else 
+   *                   returns false.
+   */
+  private boolean isInString(String contentType) {
+    if (fContentType == contentType)
+      return (fInString || fInDoubString);
+    else
+      return false;
+  }
+
+  /**
+   * Returns the previouse partition stack for the given offset.
+   * 
+   * @param offset The offset to return the previouse partitionstack for.
+   * 
+   * @return The stack as a string array.
+   */
+  private String[] getPartitionStack(int offset) {
+    ArrayList types = new ArrayList();
+    int tmpOffset = 0;
+    try {
+      ITypedRegion region = fDocument.getPartition(offset);
+      tmpOffset = region.getOffset();
+      while (tmpOffset - 1 > 0) {
+        region = fDocument.getPartition(tmpOffset - 1);
+        tmpOffset = region.getOffset();
+        types.add(0, region.getType());
+      }
+    } catch (BadLocationException e) {
+      if (DEBUG) {
+        e.printStackTrace();
+      }
     }
-    
+
+    String[] retVal = new String[types.size()];
+
+    retVal = (String[]) types.toArray(retVal);
+    return retVal;
+  }
+
 }
index bf83815..8f9dbe5 100644 (file)
@@ -4,8 +4,11 @@
  */
 package net.sourceforge.phpeclipse.phpeditor.php;
 
-import org.eclipse.jface.text.*;
-import org.eclipse.jface.text.rules.*;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
 
 
 /**
@@ -13,7 +16,7 @@ import org.eclipse.jface.text.rules.*;
  * partitions contained within other partitions.
  * 
  * @author Stefan Langer
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
  */
 public abstract class Partition
 {
index 380b4cf..de24d80 100644 (file)
@@ -4,16 +4,16 @@
  */
 package net.sourceforge.phpeclipse.phpeditor.php;
 
-import java.util.*;
+import java.util.ArrayList;
 
-import org.eclipse.jface.text.*;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * A stack for keeping track of the contenttypes for partitions that 
  * contain other partitions.
  * 
  * @author Stefan Langer
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
  */
 public class PartitionStack
 {
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java
new file mode 100644 (file)
index 0000000..278e954
--- /dev/null
@@ -0,0 +1,204 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+    IBM Corporation - Initial implementation
+    Klaus Hartlage - www.eclipseproject.de
+**********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+/**
+ * PHP Code Scanner
+ */
+public class SmartyCodeScanner extends AbstractJavaScanner {
+  public static String[] SMARTY_KEYWORDS =
+    {
+      "capture",
+      "config_load",
+      "else",
+      "elseif",
+      "foreach",
+      "foreachelse",
+      "if",
+      "include",
+      "insert",
+      "ldelim",
+      "literal",
+      "php",
+      "rdelim",
+      "section",
+      "sectionelse",
+      "strip" };
+  public static String[] SMARTY_FUNCTION_NAMES =
+    {
+      "assign",
+      "counter",
+      "cycle",
+      "debug",
+      "eval",
+      "fetch",
+      "html_checkboxes",
+      "html_image",
+      "html_options",
+      "html_radios",
+      "html_select_date",
+      "html_select_time",
+      "html_table",
+      "math",
+      "popup",
+      "popup_init",
+      "textformat" };
+  private class SmartyWordRule extends WordRule {
+    private StringBuffer fBuffer = new StringBuffer();
+
+    public SmartyWordRule(IWordDetector detector) {
+      super(detector, Token.UNDEFINED);
+    }
+
+    public SmartyWordRule(IWordDetector detector, IToken defaultToken) {
+      super(detector, defaultToken);
+    }
+
+    public IToken evaluate(ICharacterScanner scanner) {
+      int c = scanner.read();
+      boolean isVariable = false;
+      if (c == '{') {
+        c = scanner.read();
+        if (c != '/') {
+          scanner.unread();
+        }
+        return getToken(IPreferenceConstants.PHP_TAG);
+      }
+      if (c == '}') {
+        return getToken(IPreferenceConstants.PHP_TAG);
+      }
+      if (fDetector.isWordStart((char) c)) {
+        if (c == '$') {
+          isVariable = true;
+        }
+        if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+          fBuffer.setLength(0);
+          do {
+            fBuffer.append((char) c);
+            c = scanner.read();
+          } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+          scanner.unread();
+
+          if (isVariable) {
+            return getToken(IPreferenceConstants.PHP_VARIABLE);
+          }
+          IToken token = (IToken) fWords.get(fBuffer.toString());
+          if (token != null)
+            return token;
+
+          if (fDefaultToken.isUndefined())
+            unreadBuffer(scanner);
+
+          return fDefaultToken;
+        }
+      }
+
+      scanner.unread();
+      return Token.UNDEFINED;
+    }
+  }
+
+  private static String[] fgTokenProperties =
+    {
+      IPreferenceConstants.PHP_MULTILINE_COMMENT,
+      IPreferenceConstants.PHP_SINGLELINE_COMMENT,
+                       IPreferenceConstants.PHP_TAG,
+      IPreferenceConstants.PHP_KEYWORD,
+      IPreferenceConstants.PHP_FUNCTIONNAME,
+      IPreferenceConstants.PHP_VARIABLE,
+      IPreferenceConstants.PHP_STRING,
+      IPreferenceConstants.PHP_TYPE,
+      IPreferenceConstants.PHP_CONSTANT,
+      IPreferenceConstants.PHP_DEFAULT };
+  /**
+       * Creates a PHP code scanner
+       */
+  // public PHPCodeScanner(JavaColorManager provider, IPreferenceStore store) {
+  public SmartyCodeScanner(IColorManager manager, IPreferenceStore store) {
+    super(manager, store);
+    initialize();
+  }
+
+  /*
+   * @see AbstractJavaScanner#getTokenProperties()
+   */
+  protected String[] getTokenProperties() {
+    return fgTokenProperties;
+  }
+  /*
+   * @see AbstractJavaScanner#createRules()
+   */
+  protected List createRules() {
+    List rules = new ArrayList();
+    // Add rule for strings and character constants.
+    Token token = getToken(IPreferenceConstants.PHP_STRING);
+    rules.add(new MultiLineRule("\"", "\"", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+
+    // Add generic whitespace rule.
+    rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+    // Add word rule for keywords, types, and constants.
+    token = getToken(IPreferenceConstants.PHP_DEFAULT);
+
+    SmartyWordRule wordRule = new SmartyWordRule(new PHPWordDetector(), token);
+
+    Token keyword = getToken(IPreferenceConstants.PHP_KEYWORD);
+    Token functionName = getToken(IPreferenceConstants.PHP_FUNCTIONNAME);
+//    Token type = getToken(IPreferenceConstants.PHP_TYPE);
+//    Token constant = getToken(IPreferenceConstants.PHP_CONSTANT);
+
+    
+    for (int i = 0; i < SMARTY_KEYWORDS.length; i++) {
+      wordRule.addWord(SMARTY_KEYWORDS[i], keyword);
+    }
+
+    for (int i = 0; i < SMARTY_FUNCTION_NAMES.length; i++) {
+      wordRule.addWord(SMARTY_FUNCTION_NAMES[i], functionName);
+    }
+    
+//     ArrayList buffer = PHPSyntaxRdr.getSyntaxData();
+//    PHPElement elbuffer = null;
+//    for (int i = 0; i < buffer.size(); i++) {
+//
+//      elbuffer = (PHPElement) buffer.get(i);
+//      if (elbuffer instanceof PHPKeyword)
+//        wordRule.addWord(((PHPKeyword) elbuffer).getName(), keyword);
+//      //      if (elbuffer instanceof PHPFunction)
+//      //        wordRule.addWord(((PHPFunction) elbuffer).getName(), functionName);
+//      if (elbuffer instanceof PHPType)
+//        wordRule.addWord(elbuffer.getName(), type);
+//      if (elbuffer instanceof PHPConstant)
+//        wordRule.addWord(elbuffer.getName(), constant);
+//    }
+    rules.add(wordRule);
+
+    return rules;
+  }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyDocCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyDocCodeScanner.java
new file mode 100644 (file)
index 0000000..a0e42ea
--- /dev/null
@@ -0,0 +1,193 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+    IBM Corporation - Initial implementation
+**********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
+import net.sourceforge.phpdt.ui.text.IColorManager;
+import net.sourceforge.phpeclipse.IPreferenceConstants;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.SingleLineRule;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
+import org.eclipse.jface.text.rules.WordRule;
+
+
+
+
+/**
+ * A rule based SmartyDoc scanner.
+ */
+public final class SmartyDocCodeScanner extends AbstractJavaScanner {
+               
+               
+  /**
+   * A key word detector.
+   */
+  static class JavaDocKeywordDetector implements IWordDetector {
+
+    /**
+     * @see IWordDetector#isWordStart
+     */
+    public boolean isWordStart(char c) {
+      return (c == '@');
+    }
+
+    /**
+     * @see IWordDetector#isWordPart
+     */
+    public boolean isWordPart(char c) {
+      return Character.isLetter(c);
+    }
+  };
+       
+       
+  /**
+   * Detector for HTML comment delimiters.
+   */
+  static class HTMLCommentDetector implements IWordDetector {
+
+    /**
+     * @see IWordDetector#isWordStart
+     */
+    public boolean isWordStart(char c) {
+      return (c == '<' || c == '-');
+    }
+
+    /**
+     * @see IWordDetector#isWordPart
+     */
+    public boolean isWordPart(char c) {
+      return (c == '-' || c == '!' || c == '>');
+    }
+  };
+       
+  class TagRule extends SingleLineRule {
+               
+    /*
+     * @see SingleLineRule
+     */
+    public TagRule(IToken token) {
+      super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
+    }
+               
+    /*
+     * @see SingleLineRule 
+     */
+    public TagRule(IToken token, char escapeCharacter) {
+      super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
+    }
+               
+    private IToken checkForWhitespace(ICharacterScanner scanner) {
+                       
+      try {
+                               
+        char c= getDocument().getChar(getTokenOffset() + 1);
+        if (!Character.isWhitespace(c)) 
+          return fToken;
+                                       
+      } catch (BadLocationException x) {
+      }
+                       
+      return Token.UNDEFINED;
+    }
+                               
+    /*
+     * @see PatternRule#evaluate(ICharacterScanner)
+     */
+    public IToken evaluate(ICharacterScanner scanner) {
+      IToken result= super.evaluate(scanner);
+      if (result == fToken)
+        return checkForWhitespace(scanner);
+      return result;
+    }
+  };
+       
+       
+  private static String[] fgKeywords= {"@author", "@deprecated", "@exception", "@param", "@return", "@see", "@serial", "@serialData", "@serialField", "@since", "@throws", "@version"}; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+       
+  private static String[] fgTokenProperties= {
+               IPreferenceConstants.PHPDOC_KEYWORD,
+               IPreferenceConstants.PHPDOC_TAG,
+               IPreferenceConstants.PHPDOC_LINK,
+               IPreferenceConstants.PHPDOC_DEFAULT
+  };                   
+       
+       
+  public SmartyDocCodeScanner(IColorManager manager, IPreferenceStore store) {
+    super(manager, store);
+    initialize();
+  }
+       
+  public IDocument getDocument() {
+    return fDocument;
+  }
+       
+  /*
+   * @see AbstractJavaScanner#getTokenProperties()
+   */
+  protected String[] getTokenProperties() {
+    return fgTokenProperties;
+  }
+
+  /*
+   * @see AbstractJavaScanner#createRules()
+   */
+  protected List createRules() {
+               
+    List list= new ArrayList();
+               
+    // Add rule for tags.
+    Token token= getToken(IPreferenceConstants.PHPDOC_TAG);
+    list.add(new TagRule(token));
+               
+               
+    // Add rule for HTML comments
+    WordRule wordRule= new WordRule(new HTMLCommentDetector(), token);
+    wordRule.addWord("<!--", token); //$NON-NLS-1$
+    wordRule.addWord("--!>", token); //$NON-NLS-1$
+    list.add(wordRule);
+               
+               
+    // Add rule for links.
+    token= getToken(IPreferenceConstants.PHPDOC_LINK);
+    list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
+               
+               
+    // Add generic whitespace rule.
+    list.add(new WhitespaceRule(new PHPWhitespaceDetector()));
+               
+               
+    // Add word rule for keywords.
+    token= getToken(IPreferenceConstants.PHPDOC_DEFAULT);
+    wordRule= new WordRule(new JavaDocKeywordDetector(), token);
+               
+    token= getToken(IPreferenceConstants.PHPDOC_KEYWORD);
+    for (int i= 0; i < fgKeywords.length; i++)
+      wordRule.addWord(fgKeywords[i], token);
+    list.add(wordRule);
+               
+    setDefaultReturnToken(getToken(IPreferenceConstants.PHPDOC_DEFAULT));
+    return list;
+  }
+}
+
+
index daeab8c..cf7f67b 100644 (file)
@@ -25,6 +25,7 @@ public class PHPColorProvider {
 
   public static final RGB MULTI_LINE_COMMENT = new RGB(63, 127, 95);
   public static final RGB SINGLE_LINE_COMMENT = new RGB(63, 127, 95);
+       public static final RGB TAG = new RGB(255, 0, 128);
   public static final RGB KEYWORD = new RGB(127, 0, 85);
   public static final RGB VARIABLE = new RGB(127, 159, 191);
   public static final RGB FUNCTION_NAME = new RGB(127, 127, 159);
index 257b5b8..cfcfe82 100644 (file)
@@ -18,14 +18,12 @@ import org.eclipse.ui.actions.ActionContext;
 import org.eclipse.ui.actions.ActionGroup;
 import org.eclipse.ui.actions.RefreshAction;
 import org.eclipse.ui.dialogs.PropertyDialogAction;
-//Impossible to compile with this, I don't know why
-//import org.eclipse.ui.internal.dialogs.ResourceSorter;
-import org.eclipse.ui.views.navigator.ResourceSorter;
 import org.eclipse.ui.views.framelist.FrameList;
 import org.eclipse.ui.views.navigator.IResourceNavigator;
 import org.eclipse.ui.views.navigator.OpenActionGroup;
 import org.eclipse.ui.views.navigator.RefactorActionGroup;
 import org.eclipse.ui.views.navigator.ResourcePatternFilter;
+import org.eclipse.ui.views.navigator.ResourceSorter;
 
 public class MainActionGroup extends ActionGroup {
 
index e958ec6..a0c1802 100644 (file)
@@ -1,6 +1,7 @@
 package test;
 
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
 import org.eclipse.core.resources.IFile;
 
 public class PHPParserManager {
index bd235fd..bdb5fdf 100644 (file)
@@ -26,6 +26,7 @@ public abstract class PHPParserSuperclass {
   public static final int WARNING = 1;
   public static final int INFO = 0;
   public static final int TASK = 3;
+  // TODO design error? Analyze why fileToParse must be static ???
   protected static IFile fileToParse;
 
   /**
index 9a4efb3..bbdad0b 100644 (file)
@@ -1,22 +1,5 @@
 /* Generated By:JavaCC: Do not edit this line. PHPParserTokenManager.java */
 package test;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.ui.texteditor.MarkerUtilities;
-import org.eclipse.jface.preference.IPreferenceStore;
-import java.util.Hashtable;
-import java.util.ArrayList;
-import java.io.StringReader;
-import java.io.*;
-import java.text.MessageFormat;
-import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpdt.internal.compiler.ast.*;
-import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
-import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
-import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
-import net.sourceforge.phpdt.internal.corext.Assert;
 
 public class PHPParserTokenManager implements PHPParserConstants
 {
index 4e81cb5..497000d 100644 (file)
@@ -1,6 +1,5 @@
 package test;
 
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
 /**
  * A Variable usage. It could be a first use, an in code use of an already declared var.