JavaClassReader.st
branchcvs_MAIN
changeset 3360 1a8899091305
parent 3324 a58245c0e83a
child 3386 ddcff50a1fdc
--- a/JavaClassReader.st	Fri Feb 14 14:27:26 2014 +0100
+++ b/JavaClassReader.st	Wed Jan 28 03:12:08 2015 +0100
@@ -1,9 +1,9 @@
 "
- COPYRIGHT (c) 1996-2011 by Claus Gittinger
+ COPYRIGHT (c) 1996-2015 by Claus Gittinger
 
  New code and modifications done at SWING Research Group [1]:
 
- COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
+ COPYRIGHT (c) 2010-2015 by Jan Vrany, Jan Kurs and Marcel Hlopko
                             SWING Research Group, Czech Technical University in Prague
 
  This software is furnished under a license and may be used
@@ -22,11 +22,12 @@
 
 Object subclass:#JavaClassReader
 	instanceVariableNames:'inStream msb constants majorVsn minorVsn constNeeds2Slots
-		constSlot classBeingLoaded classLoader'
+		constSlot classBeingLoaded classLoader attributes'
 	classVariableNames:'Verbose AnnotationsVerbose Silent AbsolutelySilent
 		LazyClassLoading InvalidClassFormatSignal ClassLoaderQuerySignal
-		JavaArchiveCache LastJavaArchive MaxContextSize
-		MaxContextSizeLimit'
+		JavaArchiveCache JavaArchiveCacheLock LastJavaArchive
+		LastJavaArchiveLock MaxContextSize MaxContextSizeLimit
+		InternedStrings'
 	poolDictionaries:'JavaConstants'
 	category:'Languages-Java-Support'
 !
@@ -35,11 +36,11 @@
 
 copyright
 "
- COPYRIGHT (c) 1996-2011 by Claus Gittinger
+ COPYRIGHT (c) 1996-2015 by Claus Gittinger
 
  New code and modifications done at SWING Research Group [1]:
 
- COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
+ COPYRIGHT (c) 2010-2015 by Jan Vrany, Jan Kurs and Marcel Hlopko
                             SWING Research Group, Czech Technical University in Prague
 
  This software is furnished under a license and may be used
@@ -59,32 +60,37 @@
 
 !JavaClassReader class methodsFor:'initialization'!
 
+flushInternedStrings
+    self initializeInternedStrings
+
+    "Created: / 13-11-2014 / 12:13:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 initialize
-    InvalidClassFormatSignal := Signal new mayProceed: true.
-    InvalidClassFormatSignal notifierString: 'class load failure'.
-    InvalidClassFormatSignal nameClass: self message: #invalidClassFormatSignal.
+    InvalidClassFormatSignal := Signal new mayProceed:true.
+    InvalidClassFormatSignal notifierString:'class load failure'.
+    InvalidClassFormatSignal nameClass:self message:#invalidClassFormatSignal.
     Verbose := false.
     Silent := true.
     AbsolutelySilent := false.
-    
+
     "/LazyClassLoading := false.
-    
+
     LazyClassLoading := true.
     ClassLoaderQuerySignal := QuerySignal new.
-    OperatingSystem isMSWINDOWSlike ifFalse:[
-        JavaArchiveCache := CacheDictionary new: 32.
-    ] ifTrue:[
-        JavaArchiveCache := CacheDictionary new: 8.
-    ].
+    ClassLoaderQuerySignal defaultAnswer:[ JavaVM systemClassLoader ].
+    self initializeArchiveCache.
+    JavaArchiveCacheLock := RecursionLock new.
+    LastJavaArchiveLock := RecursionLock new.
     AnnotationsVerbose := false.
     MaxContextSize := 0.
-
-    "Maximum stack depth supported by the VM.
+     "Maximum stack depth supported by the VM.
      if you change it, make sure it is equal (or lower)
      to CONSIZE in jinterpret.c (line 111 or so)
      Otherwise, VM may crash!!!!!!"
     MaxContextSizeLimit := 100.
 
+    self initializeInternedStrings.
 
     "
      JavaClassReader initialize"
@@ -93,7 +99,23 @@
     "Modified: / 17-12-2010 / 17:37:45 / Marcel Hlopko <hlopik@gmail.com>"
     "Modified: / 10-05-2011 / 23:59:53 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
     "Modified: / 14-08-2012 / 02:01:37 / jv"
-    "Modified: / 04-09-2012 / 11:55:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 13-11-2014 / 12:12:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initializeArchiveCache
+    OperatingSystem isMSWINDOWSlike ifFalse:[
+        JavaArchiveCache := CacheDictionary new:32.
+    ] ifTrue:[
+        JavaArchiveCache := CacheDictionary new:8.
+    ]
+!
+
+initializeInternedStrings
+     "Constant pool strings are interned to save memory
+     and kept in InternedStrings variable"
+    InternedStrings := Set new
+
+    "Modified (comment): / 13-11-2014 / 12:12:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader class methodsFor:'Signal constants'!
@@ -110,11 +132,10 @@
     "Created: 3.8.1997 / 18:17:21 / cg"
 ! !
 
-
 !JavaClassReader class methodsFor:'constants'!
 
 fileMajorVersions
-    ^#( 
+    ^#(
         45  "Java 1.0.2"
         46  "Java 1.2"
         47  "???"
@@ -163,7 +184,7 @@
 
 !JavaClassReader class methodsFor:'debugging'!
 
-annotationsVerbose:aBoolean 
+annotationsVerbose:aBoolean
     AnnotationsVerbose := aBoolean
 
     "
@@ -186,10 +207,10 @@
 
 !JavaClassReader class methodsFor:'file reading'!
 
-readClass: aClassName 
+readClass: aClassName
     "reads a class, and returns it.
      <clinit> is NOT called, class is NOT installed"
-    
+
     ^ self readClass: aClassName ignoring: Set new.
 
     "Created: / 15-04-1996 / 14:58:53 / cg"
@@ -198,10 +219,10 @@
     "Modified (comment): / 07-02-2013 / 14:21:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readClass: aClassName classPath: classPath  
+readClass: aClassName classPath: classPath
     "reads a class, and returns it.
      <clinit> is NOT called, class is NOT installed"
-    
+
     ^ self readClass: aClassName ignoring: Set new classPath: classPath
 
     "Created: / 15-04-1996 / 14:58:53 / cg"
@@ -211,10 +232,10 @@
     "Modified (comment): / 07-02-2013 / 14:21:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readClass: className ignoring: classesBeingLoadedOrNil 
+readClass: className ignoring: classesBeingLoadedOrNil
 
     "This method is bit hacky, as it tries to supply 'correct'
-     classloader. 
+     classloader.
 
     If the class is loaded from Java release classPath (containing
     base java classes shipped with JDK/JRE), then set the classloader
@@ -227,8 +248,8 @@
     "
 
     | class |
-    class := self 
-                readClass: className ignoring: classesBeingLoadedOrNil 
+    class := self
+                readClass: className ignoring: classesBeingLoadedOrNil
                 classPath: Java release classPath.
     class notNil ifTrue:[ ^ class ].
 
@@ -238,7 +259,7 @@
         ].
         JavaClassReader classLoaderQuerySignal answer: JavaVM systemClassLoader do:[
             class := self
-                readClass: className ignoring: classesBeingLoadedOrNil 
+                readClass: className ignoring: classesBeingLoadedOrNil
                 classPath: Java classPath.
         ].
     ].
@@ -256,7 +277,7 @@
 
     cls := self new readClass: className ignoring: ignoring classPath: classPath.
     cls notNil ifTrue:[
-        Logger 
+        Logger
             log: 'loaded class ' , cls displayString
             severity: #info
             facility: 'JVM'.
@@ -267,17 +288,17 @@
     "Modified: / 08-02-2013 / 01:20:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readFile:aFilename ignoring:classesBeingLoaded 
+readFile:aFilename ignoring:classesBeingLoaded
     "reads a class from aFilename and returns it.
      The JavaClass is NOT installed as global and unresolved
      refs are NOT patched."
-    
+
     | inStream |
 
     [
         JavaVM commonOpenStreamUsing:[ inStream := aFilename asFilename readStream ]
-    ] on:StreamError do:[:ex | 
-        Logger 
+    ] on:StreamError do:[:ex |
+        Logger
             log:('cannot read .class file: ' , ex description) severity:#error facility:'JVM'.
         self breakPoint: #jv.
         ^ nil
@@ -295,7 +316,7 @@
     "Modified: / 29-03-2013 / 23:54:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readStream: aStream 
+readStream: aStream
     "reads a class from aStream and returns it.
      The JavaClass is not installed as global"
 
@@ -304,7 +325,7 @@
     "Created: / 24-10-2011 / 00:12:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readStream: stream ignoring: classesBeingLoaded 
+readStream: stream ignoring: classesBeingLoaded
     "reads a class from aStream and returns it.
      The JavaClass is not installed as global"
 
@@ -324,14 +345,14 @@
     "Created: / 02-05-2013 / 09:51:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readStream: stream loader: classloader ignoring: classesBeingLoaded  
+readStream: stream loader: classloader ignoring: classesBeingLoaded
     "reads a class from aStream and returns it.
      The JavaClass is not installed as global"
-    
+
     | javaClass |
 
     javaClass := JavaClassReader new readStream: stream loader: classloader ignoring: classesBeingLoaded.
-    Logger 
+    Logger
         log: 'loaded class ' , javaClass displayString
         severity: #info
         facility: 'JVM'.
@@ -342,11 +363,11 @@
 
 !JavaClassReader class methodsFor:'obsolete'!
 
-resolveClass: aJavaClass 
+resolveClass: aJavaClass
     "Resolve a particular classes' constants.
      Perform all class initialization functions
      (of those which are not yet initialized)."
-    
+
     | loader  classToLoad |
 
 
@@ -356,13 +377,13 @@
         [
             classToLoad := nil.
             aJavaClass constantPool do: [
-                :item | 
+                :item |
                 | itemClass |
 
                 itemClass := item class.
                 itemClass == JavaUnresolvedClassConstant ifTrue: [
                     classToLoad := item className.
-                    
+
 "/                ] ifFalse:[
 "/                    itemClass == JavaUnresolvedMethodrefConstant ifTrue:[
 "/self halt.
@@ -409,8 +430,13 @@
 
 !JavaClassReader methodsFor:'accessing'!
 
-constants   
-^ constants.
+constantPoolAt: index
+    ^ constants at: index
+
+!
+
+constants
+    ^ constants.
 
     "Created: / 10-05-2011 / 13:48:30 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 !
@@ -439,7 +465,7 @@
     "load class named clsName from directory or .jar archive path.
      <clinit> is NOT called, class is NOT installed as global"
 
-    | nm  p  zar  entry  zipFile  read rslt |
+    | nm  p  zar zarAndRefcount entry  zipFile  read rslt |
 
     p := path asString.
     p asFilename isDirectory ifTrue: [
@@ -450,39 +476,55 @@
         ].
         nm := p , clsName , '.class'.
         (f := nm asFilename) exists ifTrue: [
-            (Java isExcludedFromClassPath: nm) ifFalse: [             
+            (Java isExcludedFromClassPath: nm) ifFalse: [
                 "means we are successfully going to read something :)"
                 f readingFileDo:[:s|rslt := self readStream: s ignoring: classesBeingLoaded].
                 rslt notNil ifTrue: [ ^ rslt. ].
             ]
         ].
     ] ifFalse: [
-        ((zipFile := p asFilename withSuffix: 'jar') exists 
-            or: [ (zipFile := p asFilename withSuffix: 'zip') exists ]) 
+        ((zipFile := p asFilename withSuffix: 'jar') exists
+            or: [ (zipFile := p asFilename withSuffix: 'zip') exists ])
                 ifTrue: [
                     "/ Do not use at:ifAbsentPut: here, JavaArchiveCache is a CacheDictionary!!!!!!
-                    zar := JavaArchiveCache at: zipFile ifAbsent: nil.
-                    zar isNil ifTrue:[
-                        JavaVM commonOpenStreamUsing:[ zar := ZipArchive oldFileNamed: zipFile ].
-                        JavaArchiveCache at: zipFile put: zar
+                    JavaArchiveCacheLock critical:[
+                        zarAndRefcount := JavaArchiveCache at: zipFile ifAbsent: nil.
+                        zarAndRefcount isNil ifTrue:[
+                            JavaVM commonOpenStreamUsing:[ zar := ZipArchive oldFileNamed: zipFile ].
+                            JavaArchiveCache at: zipFile put: (zarAndRefcount := Array with: zar with: 1)
+                        ] ifFalse:[
+                            zar := zarAndRefcount first.
+                            zarAndRefcount at: 2 put: (zarAndRefcount at: 2) + 1.
+                        ].
                     ].
                     read := [
                             nm := clsName , '.class'.
 
-                            (zar isValidPath: nm) ifTrue: [
+                            (zar isValidFile: nm) ifTrue: [
                                 (Java isExcludedFromClassPath: nm) ifFalse: [
                                     JavaVM commonOpenStreamUsing:[ zar := zar reopenForReading ].
                                     entry := zar extract: nm.
                                     rslt := self readStream: (entry readStream) ignoring: classesBeingLoaded.
-                                    rslt notNil ifTrue: [ ^ rslt ].
+                                    rslt notNil ifTrue: [
+                                        JavaArchiveCacheLock critical:[
+                                            zarAndRefcount at: 2 put: (zarAndRefcount at: 2) - 1.
+                                        ].
+                                        ^ rslt
+                                    ].
                                 ]
                             ].
-                            zar closeFile.
+                            JavaArchiveCacheLock critical:[
+                                zarAndRefcount at: 2 put: (zarAndRefcount at: 2) - 1.
+                                (zarAndRefcount at: 2) == 0 ifTrue:[
+                                    zar closeFile.
+                                ].
+                            ].
+
                         ].
-                    JavaClassReader invalidClassFormatSignal 
+                    JavaClassReader invalidClassFormatSignal
                         handle: [
                             "Kludge, sometimes zar gets corrupted"
-                            zar := JavaArchiveCache at: zipFile put: (JavaVM commonOpenStreamUsing: [ZipArchive oldFileNamed: zipFile]).
+                            JavaArchiveCache at: zipFile put: (Array with: (zar := JavaVM commonOpenStreamUsing: [ZipArchive oldFileNamed: zipFile]) with: 1).
                             read value
                         ]
                         do: [ read value ].
@@ -491,13 +533,13 @@
     ^nil
 
     "Created: / 03-12-2012 / 22:47:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 11-02-2013 / 16:25:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+
 !
 
-readClass: className ignoring: classesBeingLoadedOrNil classPath: classPath 
+readClass: className ignoring: classesBeingLoadedOrNil classPath: classPath
     "searches classspath for a class, loads it and returns.
      <clinit> is not called, class is not installed as global"
-    
+
     | rslt  clsName  classesBeingLoaded |
     clsName := className asSlashedJavaClassName.
     classesBeingLoaded := classesBeingLoadedOrNil.
@@ -507,7 +549,7 @@
     classesBeingLoaded add: clsName.
 
 
-    classPath do: [:path | 
+    classPath do: [:path |
         rslt := self readClass: clsName from: path ignoring: classesBeingLoaded.
         rslt notNil ifTrue:[ ^rslt ].
     ].
@@ -521,68 +563,35 @@
     "Modified: / 07-02-2013 / 14:19:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readClassFileIgnoring: classesbeingLoaded 
+readClassFileIgnoring: classesbeingLoaded
     "reads a class from inStream and returns it.
      The JavaClass is not installed as global and its constants
      (especially strings) may not be fully resolved."
-    
-    | magic  access_flags  this_class_index  super_class  super_class_index  this_class_ref  existingSuperClass  fields  interfaces  staticFields  nStatic  superClassName  thisClassName  existing_class  thisMetaClass |
-
-    "/
-    "/ read magic, determine byte order
-    "/
-    msb := true.
-    magic := inStream nextUnsignedLongMSB: true.
-    magic = (self class magic_MSB) ifFalse: [
-        magic = (self class magic_LSB) ifFalse: [
-            InvalidClassFormatSignal raiseErrorString: 'not a java class file'.
-            ^ nil
-        ].
-        msb := false.
-        Verbose ifTrue: [ Transcript showCR: 'file is lsb' ].
-    ] ifTrue: [ Verbose ifTrue: [ Transcript showCR: 'file is msb' ]. ].
-    
-    "/
-    "/ get version
-    "/
-    
-    minorVsn := inStream nextUnsignedShortMSB: msb.
-    majorVsn := inStream nextUnsignedShortMSB: msb.
-    ((self class fileMajorVersions includes: majorVsn) not 
-        or: [ (self class fileMinorVersions includes: minorVsn) not ]) 
-            ifTrue: [
-                | path |
-
-                path := inStream isFileStream ifTrue:[
-                    path := inStream pathName
-                ] ifFalse:[
-                    path := '<memory>'
-                ].
-                self info:
-                    ('class reader: file ', path , ' has version ' ,
-                         majorVsn printString ,
-                            '.' , minorVsn printString)
-
-            ].    
+
+    | access_flags  this_class_index  super_class  super_class_index  this_class_ref  existingSuperClass  fields  interfaces  staticFields  nStatic  superClassName  thisClassName  existing_class  thisMetaClass |
+
+    self readMagic.
+    self readVersion.
+
     "/
     "/ get constant pool
     "/
-    
+
     self readConstantPool.
-    
+
     "/
     "/ access flags
     "/
-    
+
     access_flags := inStream nextUnsignedShortMSB: msb.
     this_class_index := inStream nextUnsignedShortMSB: msb.
     super_class_index := inStream nextUnsignedShortMSB: msb.
     super_class_index == 0 ifTrue: [ super_class := nil ] ifFalse: [
-        super_class := constants at: super_class_index.
+        super_class := self constantPoolAt: super_class_index.
         superClassName := super_class fullName.
-        
+
         "/ special for ST-classes
-        
+
         (superClassName startsWith: 'smalltalk.') ifTrue: [
             "/ a Smalltalk class
             superClassName := superClassName copyFrom: 11.
@@ -594,12 +603,12 @@
             "/ a JAVA class
             super_class := JavaVM classNamed: superClassName definedBy: classLoader.
             super_class isNil ifTrue: [
-                super_class := self 
-                                loadSuperclassIdentifiedBy: (constants at: super_class_index)
+                super_class := self
+                                loadSuperclassIdentifiedBy: (self constantPoolAt: super_class_index)
                                 ignoring: classesbeingLoaded
             ].
             super_class isNil ifTrue: [
-                self breakPoint:#jv info: 'Cannot find super class?!!' 
+                self breakPoint:#jv info: 'Cannot find super class?!!'
             ].
         ].
     ].
@@ -608,31 +617,39 @@
     (super_class notNil and:[super_class hasFinalize]) ifTrue:[
         access_flags := access_flags bitOr: ACX_HASFINALIZE
     ].
-    
+
     "/
     "/ get interfaces
     "/
-    
+
     interfaces := self readInterfaces.
-    
+    interfaces do:[:ifaceRefIndex |
+        (self constantPoolAt: ifaceRefIndex) javaClassName = 'java/lang/Cloneable' ifTrue:[
+            access_flags := access_flags bitOr: ACX_CLONEABLE.
+        ].
+    ].
+
     "/
     "/ get fields
     "/
-    
+
     fields := self readFieldInfofields.
-    
+
     "/
     "/ create the fields as instVars
     "/ static fields are created as class-InstVars
     "/
-    
+
     staticFields := fields select: [:f | f isStatic ].
     nStatic := staticFields size.
-    this_class_ref := constants at: this_class_index.
-    thisClassName := this_class_ref fullName asSlashedJavaClassName.
-    
+    this_class_ref := self constantPoolAt: this_class_index.
+    thisClassName := this_class_ref name.
+    thisClassName = 'java/lang/Cloneable' ifTrue:[
+        access_flags := access_flags bitOr: ACX_CLONEABLE.
+    ].
+
     "/ care for smalltalk classes ...
-    
+
     (thisClassName startsWith: 'smalltalk.') ifTrue: [
         thisClassName := thisClassName copyFrom: 11.
         existing_class := Smalltalk at: thisClassName asSymbol.
@@ -649,8 +666,8 @@
     ] ifFalse: [
         "/ a java class
         Class withoutUpdatingChangesDo:[
-            classBeingLoaded := JavaClass fullName: thisClassName numStatic: nStatic.
-            classBeingLoaded classLoader: self class classLoaderQuerySignal query.        
+            classBeingLoaded := JavaClass binaryName: thisClassName numStatic: nStatic.
+            classBeingLoaded classLoader: self class classLoaderQuerySignal query.
             fields := fields select: [:f | f isStatic not ].
             JavaClass setInstanceVariableStringFromFields: staticFields
                 in: classBeingLoaded class.
@@ -662,13 +679,14 @@
             classBeingLoaded setInterfaces: interfaces.
         ]
     ].
-    
+
     "/
     "/ get methods
     "/
-    
+
     self readMethodsFor: classBeingLoaded.
     self readAttributesFor: classBeingLoaded.
+    classBeingLoaded setAttributes: attributes.
 
     "/
     "/ get extensions
@@ -676,7 +694,7 @@
     self readExtensionsFor: classBeingLoaded.
 
     classBeingLoaded fields do: [:each | self updateOwnerInField: each ].
-    classBeingLoaded staticFields do: [:each | self updateOwnerInField: each ].    
+    classBeingLoaded staticFields do: [:each | self updateOwnerInField: each ].
     classBeingLoaded classLoader: classLoader.
     classesbeingLoaded remove: classBeingLoaded name ifAbsent:[].
     ^ classBeingLoaded.
@@ -695,7 +713,24 @@
     "Modified: / 15-10-2010 / 17:37:38 / Jan Kurs <kurs.jan@post.cz>"
     "Modified: / 28-01-2011 / 15:09:48 / Marcel Hlopko <hlopik@gmail.com>"
     "Modified: / 18-05-2011 / 15:30:29 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 02-05-2013 / 10:02:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 27-11-2014 / 17:02:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+readMagic
+    "Read magic, determine byte order"
+    | magic |
+
+    msb := true.
+    magic := inStream nextUnsignedLongMSB: true.
+    magic = (self class magic_MSB) ifFalse: [
+        magic = (self class magic_LSB) ifFalse: [
+            InvalidClassFormatSignal raiseErrorString: 'not a java class file'.
+            ^ nil
+        ].
+        msb := false.
+    ]
+
+    "Created: / 04-12-2014 / 17:32:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readStream:aStream ignoring:classesBeingLoaded
@@ -703,7 +738,7 @@
     "reads a class from aStream and returns it.
      The JavaClass is not installed as global"
 
-    ^self readStream:aStream loader: self class classLoaderQuerySignal query ignoring:classesBeingLoaded    
+    ^self readStream:aStream loader: self class classLoaderQuerySignal query ignoring:classesBeingLoaded
 
 
     "
@@ -729,13 +764,38 @@
     "
 
     "Created: / 02-05-2013 / 09:52:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+readVersion
+    minorVsn := inStream nextUnsignedShortMSB: msb.
+    majorVsn := inStream nextUnsignedShortMSB: msb.
+    ((self class fileMajorVersions includes: majorVsn) not
+        or: [ (self class fileMinorVersions includes: minorVsn) not ])
+            ifTrue: [
+                | path |
+
+                path := inStream isFileStream ifTrue:[
+                    path := inStream pathName
+                ] ifFalse:[
+                    path := '<memory>'
+                ].
+                Verbose ifTrue:[
+                    self info:
+                        ('class reader: file ', path , ' has version ' ,
+                             majorVsn printString ,
+                                '.' , minorVsn printString)
+                ].
+
+            ].
+
+    "Created: / 06-12-2014 / 13:37:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader methodsFor:'file reading - attributes'!
 
-readAnnotationDefaultAttributeFor:something 
+readAnnotationDefaultAttributeFor:something
     "/        ('JAVA [info]: unhandled attribute: AnnotationDefault') infoPrintCR.
-    
+
     |len startPos endPos annotationDefault|
 
     self assert:something isJavaMethod
@@ -743,7 +803,7 @@
     len := inStream nextUnsignedLongMSB:msb.
     startPos := inStream position.
     annotationDefault := (something ensureHasAnnotations)
-                default:(JavaAnnotationDefault new 
+                default:(JavaAnnotationDefault new
                             value:(self readAnnotationValueFor:something));
                 default.
     endPos := inStream position.
@@ -756,11 +816,11 @@
     "Modified: / 03-03-2011 / 23:06:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readAnnotationFor:something 
+readAnnotationFor:something
     | typeIndex  type  result  attrsCount |
 
     typeIndex := inStream nextUnsignedShortMSB:msb.
-    type := constants at:typeIndex.
+    type := self constantPoolAt:typeIndex.
     attrsCount := inStream nextUnsignedShortMSB:msb.
     result := JavaAnnotation for:something.
     result name:type.
@@ -768,70 +828,70 @@
             [ | nameIndex  name  valueIndex  attr |
 
             nameIndex := inStream nextUnsignedShortMSB:msb.
-            name := constants at:nameIndex.
+            name := self constantPoolAt:nameIndex.
             attr := self readAnnotationValueFor:something.
             attr name:name.
-            result values at:attr name put:attr.
-            AnnotationsVerbose 
+            result values at: name put:attr.
+            AnnotationsVerbose
                 ifTrue:[ ('JAVA [INFO]: Reading annotation attribute: ' , name) infoPrintCR. ]. ].
     ^ result.
 
     "Created: / 17-12-2010 / 16:21:28 / Marcel Hlopko <hlopik@gmail.com>"
     "Modified: / 25-02-2011 / 12:25:36 / Marcel Hlopko <hlopik@gmail.com>"
-    "Modified: / 27-07-2011 / 09:37:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-12-2014 / 16:23:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-readAnnotationValueFor:something 
+readAnnotationValueFor:something
     | tag  result |
 
     tag := (inStream nextByte) asCharacter.
-    tag = $e 
+    tag = $e
         ifTrue:
             [ result := JavaAnnotationEnumValue for:something.
             result nameIndex:(inStream nextUnsignedShortMSB:msb).
             result valueIndex:(inStream nextUnsignedShortMSB:msb).
-            AnnotationsVerbose 
+            AnnotationsVerbose
                 ifTrue:
-                    [ ('JAVA [INFO]: Reading annotation enum value: ' , result name printString, ' -> ' 
+                    [ ('JAVA [INFO]: Reading annotation enum value: ' , result name printString, ' -> '
                         , result value printString) infoPrintCR ].
             ^ result ].
-    tag = $c 
+    tag = $c
         ifTrue:
             [ result := JavaAnnotationClassValue for:something.
             result classIndex:(inStream nextUnsignedShortMSB:msb).
-            AnnotationsVerbose 
+            AnnotationsVerbose
                 ifTrue:
-                    [ ('JAVA [INFO]: Reading annotation class value: ' , result name printString, ' -> ' 
+                    [ ('JAVA [INFO]: Reading annotation class value: ' , result name printString, ' -> '
                         , result value printString) infoPrintCR ].
             ^ result ].
-    tag = $@ 
+    tag = $@
         ifTrue:
             [ result := JavaAnnotationNestedAnnotationValue for:something.
             result nestedAnnotation:(self readAnnotationFor: something).
-            AnnotationsVerbose 
+            AnnotationsVerbose
                 ifTrue:
                     [ ('JAVA [INFO]: Reading annotation nested annotation value: ' , result name printString
-                        , ' -> ' , result value printString) 
+                        , ' -> ' , result value printString)
                         infoPrintCR ].
             ^ result ].
-    tag = $[ 
+    tag = $[
         ifTrue:
             [ result := JavaAnnotationArrayValue for:something.
             result count:(inStream nextUnsignedShortMSB:msb).
-            AnnotationsVerbose 
+            AnnotationsVerbose
                 ifTrue:[ ('JAVA [INFO]: Reading annotation array value') infoPrintCR ].
             1 to:result count
                 do:[:index | result values at:index put:(self readAnnotationValueFor:something) ].
-            AnnotationsVerbose 
+            AnnotationsVerbose
                 ifTrue:
-                    [ ('JAVA [INFO]: Finished reading annotation array value: ' 
+                    [ ('JAVA [INFO]: Finished reading annotation array value: '
                         , result value printString) infoPrintCR ].
             ^ result ].
     result := JavaAnnotationPrimitiveValue for:something.
     result valueIndex:(inStream nextUnsignedShortMSB:msb).
-     AnnotationsVerbose 
+     AnnotationsVerbose
                 ifTrue:
-                    [ ('JAVA [INFO]: Finished reading annotation primitive value: ' 
+                    [ ('JAVA [INFO]: Finished reading annotation primitive value: '
                              , result name printString , ' -> ' , result value printString) infoPrintCR ].
     ^ result.
 
@@ -840,151 +900,158 @@
     "Modified: / 12-02-2013 / 19:35:15 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
 !
 
-readAttribute:attributeName for:something 
+readAttribute:attributeName for:something
     "/ implemented JAVA attributes
-    
-    (attributeName = 'ConstantValue') 
+
+    (attributeName = 'ConstantValue')
         ifTrue:
             [ self readConstantValueAttributeFor:something.
             ^ self. ].
-    (attributeName = 'Code') 
+    (attributeName = 'Code')
         ifTrue:
             [ self readCodeAttributeFor:something.
             ^ self. ].
-    (attributeName = 'Exceptions') 
+    (attributeName = 'Exceptions')
         ifTrue:
             [ self readExceptionsAttributeFor:something.
             ^ self. ].
-    (attributeName = 'InnerClasses') 
+    (attributeName = 'InnerClasses')
         ifTrue:
             [ self readInnerClassesAttributeFor:something.
             ^ self. ].
-    (attributeName = 'EnclosingMethod') 
+    (attributeName = 'EnclosingMethod')
         ifTrue:
             [ self readEnclosingMethodAttributeFor:something.
             ^ self. ].
-    (attributeName = 'LineNumberTable') 
+    (attributeName = 'LineNumberTable')
         ifTrue:
             [ self readLineNumberTableAttributeFor:something.
             ^ self. ].
-    (attributeName = 'LocalVariableTable') 
+    (attributeName = 'LocalVariableTable')
         ifTrue:
             [ self readLocalVariableTableAttributeFor:something.
             ^ self. ].
-    (attributeName = 'LocalVariableTypeTable') 
+    (attributeName = 'LocalVariableTypeTable')
         ifTrue:
             [ self readLocalVariableTypeTableAttributeFor:something.
             ^ self. ].
-    (attributeName = 'SourceFile') 
+    (attributeName = 'SourceFile')
         ifTrue:
             [ self readSourceFileAttributeFor:something.
             ^ self. ].
-    (attributeName = 'SourceDebugExtension') 
+    (attributeName = 'SourceDebugExtension')
         ifTrue:
             [ self readSourceDebugExtensionAttributeFor:something.
             ^ self. ].
-    (attributeName = 'Synthetic') 
+    (attributeName = 'Synthetic')
         ifTrue:
             [ self readSyntheticAttributeFor:something.
             ^ self. ].
-    (attributeName = 'Signature') 
+    (attributeName = 'Signature')
         ifTrue:
             [ self readSignatureAttributeFor:something.
             ^ self. ].
-    (attributeName = 'Deprecated') 
+    (attributeName = 'Deprecated')
         ifTrue:
             [ self readDeprecatedAttributeFor:something.
             ^ self. ].
-    (attributeName = 'RuntimeVisibleAnnotations') 
+    (attributeName = 'RuntimeVisibleAnnotations')
         ifTrue:
             [ self readRuntimeAnnotationsAttributeFor:something visible:true.
             ^ self. ].
-    (attributeName = 'RuntimeInvisibleAnnotations') 
+    (attributeName = 'RuntimeInvisibleAnnotations')
         ifTrue:
             [  self readRuntimeAnnotationsAttributeFor:something visible:false.
             ^ self. ].
-    (attributeName = 'RuntimeVisibleParameterAnnotations') 
+    (attributeName = 'RuntimeVisibleParameterAnnotations')
         ifTrue:
             [ self readRuntimeParameterAnnotationsAttributeFor:something visible:true.
             ^ self. ].
-    (attributeName = 'RuntimeInvisibleParameterAnnotations') 
+    (attributeName = 'RuntimeInvisibleParameterAnnotations')
         ifTrue:
             [ self readRuntimeParameterAnnotationsAttributeFor:something visible:false.
             ^ self. ].
-    (attributeName = 'AnnotationDefault') 
+    (attributeName = 'AnnotationDefault')
         ifTrue:
             [ self readAnnotationDefaultAttributeFor:something.
             ^ self. ].
-    
+
     "/ ignored JAVA attributes
-    
-    (attributeName = 'FastJavac1.0') 
+
+    (attributeName = 'FastJavac1.0')
         ifTrue:
             [ "/        ('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
             self skipAttribute:attributeName.
             ^ self. ].
-    (attributeName = 'AbsoluteSourcePath') 
+    (attributeName = 'AbsoluteSourcePath')
         ifTrue:
             [ ('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
             self skipAttribute:attributeName.
             ^ self. ].
-    (attributeName startsWith:((Character value:13) asString , 'WARNING:')) 
+    (attributeName startsWith:((Character value:13) asString , 'WARNING:'))
         ifTrue:
             [ "/        ('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
             self skipAttribute:attributeName.
             ^ self. ].
-    (attributeName = 'StackMapTable') 
+    (attributeName = 'StackMapTable')
         ifTrue:
             [ "/        ('JAVA [info]: unhandled attribute: ' , attributeName) infoPrintCR.
             self readStackMapTableAttributeFor:something.
             ^ self. ].
-    
+
     "/ implemented ST attributes
-    
-    (attributeName = 'STLiterals') 
+
+    (attributeName = 'STLiterals')
         ifTrue:
             [ self readSTLiteralsAttributeFor:something.
             ^ self. ].
-    (attributeName = 'ClassRevision') 
+    (attributeName = 'ClassRevision')
         ifTrue:
             [ self readSTClassRevisionAttributeFor:something.
             ^ self. ].
-    (attributeName = 'ClassPackage') 
+    (attributeName = 'ClassPackage')
         ifTrue:
             [ self readSTClassPackageAttributeFor:something.
             ^ self. ].
-    (attributeName = 'ClassCategory') 
+    (attributeName = 'ClassCategory')
         ifTrue:
             [ self readSTClassCategoryAttributeFor:something.
             ^ self. ].
-    (attributeName = 'ClassVarNames') 
+    (attributeName = 'ClassVarNames')
         ifTrue:
             [ self readSTClassVarNamesAttributeFor:something.
             ^ self. ].
-    (attributeName = 'ClassInstVarNames') 
+    (attributeName = 'ClassInstVarNames')
         ifTrue:
             [ self readSTClassInstVarNamesAttributeFor:something.
             ^ self. ].
-    (attributeName = 'InstVarNames') 
+    (attributeName = 'InstVarNames')
         ifTrue:
             [ self readSTInstVarNamesAttributeFor:something.
             ^ self. ].
-    (attributeName = 'STCode') 
+    (attributeName = 'STCode')
         ifTrue:
             [ self readSTCodeAttributeFor:something.
             ^ self. ].
-    (attributeName = 'MethodCategory') 
+    (attributeName = 'MethodCategory')
         ifTrue:
             [ self readSTMethodCategoryAttributeFor:something.
             ^ self. ].
-    
+
+    "/ Eclipse Java Compiler Specific Attributes
+    (attributeName = 'MissingTypes')
+        ifTrue:
+            [ self readMissingTypesAttributeFor:something.
+            ^ self. ].
+
     "/ unknown attributes
-    
+
     ('JAVA [warning]: unrecognized attribute: ' , attributeName) infoPrintCR.
     self skipAttribute:attributeName.
 
     "Modified: / 03-12-1998 / 13:13:42 / cg"
     "Modified: / 25-02-2011 / 18:09:21 / Marcel Hlopko <hlopik@gmail.com>"
+    "Modified: / 16-10-2013 / 02:01:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readAttributeFor:something
@@ -1008,7 +1075,7 @@
         ]
     ].
 
-    attribute_name := constants at:attribute_name_index.
+    attribute_name := self constantPoolAt:attribute_name_index.
 
     Verbose ifTrue:[Transcript show:'attrib name: '; showCR:attribute_name].
 
@@ -1023,17 +1090,24 @@
     "Modified: / 19-10-2010 / 21:43:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+readAttributeLength
+    ^ inStream nextUnsignedLongMSB:msb
+
+    "Created: / 03-12-2014 / 12:53:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 readAttributesFor:something
     |attributes_count|
 
     attributes_count := inStream nextUnsignedShortMSB:msb.
+    attributes := OrderedCollection new: attributes_count * 2.
 
     1 to:attributes_count do:[:i |
-	self readAttributeFor:something.
+        self readAttributeFor:something.
     ].
 
-    "Modified: 15.4.1996 / 15:33:28 / cg"
-    "Created: 15.4.1996 / 15:40:17 / cg"
+    "Created: / 15-04-1996 / 15:40:17 / cg"
+    "Modified: / 13-09-2013 / 01:01:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readDeprecatedAttributeFor:aJavaMethodWithHandler
@@ -1045,13 +1119,37 @@
 !
 
 readEnclosingMethodAttributeFor:something
-"/        ('JAVA [info]: unhandled attribute: EnclosingMethod') infoPrintCR.
-        self skipAttribute:'EnclosingMethod'.
+    | class_ref_index method_ref_index |
+
+    self skipAttributeLength.
+    class_ref_index := inStream nextUnsignedShortMSB:msb.
+    method_ref_index := inStream nextUnsignedShortMSB:msb.
+    attributes add: #EnclosingMethod; add: (Array with: class_ref_index with: method_ref_index)
+
+    "Modified: / 03-12-2014 / 12:56:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readInnerClassesAttributeFor:something
-"/        ('JAVA [info]: unhandled attribute: InnerClasses') infoPrintCR.
-        self skipAttribute:'InnerClasses'.
+    | attribute_length number_of_classes classes |
+
+    attribute_length := inStream nextUnsignedLongMSB:msb. "/ skip attribute length.
+    number_of_classes := inStream nextUnsignedShortMSB:msb.
+    classes := JavaInnerClasses new: number_of_classes.
+    self assert: attribute_length == ((number_of_classes * 8) + 2).
+    1 to: number_of_classes do:[:i |
+        | entry |
+
+        entry := JavaInnerClasses::Entry new.
+        entry setInnerClassRefIndex:(inStream nextUnsignedShortMSB:msb).
+        entry setOuterClassRefIndex:(inStream nextUnsignedShortMSB:msb).
+        entry setNameIndex: (inStream nextUnsignedShortMSB:msb).
+        entry setAccessFlags: (inStream nextUnsignedShortMSB:msb).
+        classes at: i put:  entry
+    ].
+
+    attributes add: #InnerClasses; add: classes.
+
+    "Modified: / 03-12-2014 / 14:06:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readLocalVariableTypeTableAttributeFor:something
@@ -1059,7 +1157,23 @@
         self skipAttribute:'LocalVariableTypeTable'.
 !
 
-readRuntimeAnnotationsAttributeFor: something visible: visible 
+readMissingTypesAttributeFor:something
+    | attribute_length numMissingTypes missingTypes |
+
+    attribute_length := inStream nextUnsignedLongMSB:msb. "/ skip attribute length.
+    numMissingTypes := inStream nextUnsignedShortMSB:msb.
+    missingTypes := Array new: numMissingTypes.
+    self assert: attribute_length == ((numMissingTypes * 2) + 2).
+    1 to: numMissingTypes do:[: i |
+        missingTypes at: i put: (inStream nextUnsignedShortMSB:msb)
+    ].
+
+    attributes add: #MissingTypes; add: missingTypes.
+
+    "Created: / 16-10-2013 / 02:04:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+readRuntimeAnnotationsAttributeFor: something visible: visible
     | length  annotationsCount  annotations  rawAnnotations  startPos  endPos |
 
     self assert: inStream isPositionable
@@ -1069,7 +1183,7 @@
     annotationsCount := inStream nextUnsignedShortMSB: msb.
     annotationsCount = 0 ifTrue: [ ^ nil ].
     annotations := visible ifTrue: [something ensureHasAnnotations ensureRuntimeVisible] ifFalse: [something ensureHasAnnotations ensureRuntimeInvisible].
-    annotationsCount timesRepeat: 
+    annotationsCount timesRepeat:
             [ | currentAnnotation |
 
             currentAnnotation := self readAnnotationFor: something.
@@ -1078,7 +1192,7 @@
     endPos := inStream position.
     inStream position: startPos.
     rawAnnotations := inStream next: length.
-    inStream position ~= endPos 
+    inStream position ~= endPos
         ifTrue: [ self halt: 'annotations are probably reading what they shouldnt' ].
     annotations rawAnnotations: rawAnnotations.
 
@@ -1088,7 +1202,7 @@
     "Modified: / 16-03-2011 / 16:57:03 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 !
 
-readRuntimeParameterAnnotationsAttributeFor: javaMethod visible: visible 
+readRuntimeParameterAnnotationsAttributeFor: javaMethod visible: visible
     | length  paramsCount  annotationsCount  rawAnnotations  startPos  endPos |
     self assert: inStream isPositionable
         message: '.class file stream must be positionable'.
@@ -1097,15 +1211,15 @@
     paramsCount := inStream nextByte.
     paramsCount = 0 ifTrue: [ ^ nil ].
     1 to: paramsCount do: [
-        :paramIndex | 
+        :paramIndex |
         annotationsCount := inStream nextUnsignedShortMSB: msb.
         annotationsCount > 0 ifTrue: [
             | annotations |
             annotations := visible ifTrue: [
-                    javaMethod ensureHasAnnotations 
+                    javaMethod ensureHasAnnotations
                         ensureVisibleParameterAnnotationsAt: paramIndex
                 ] ifFalse: [
-                    javaMethod ensureHasAnnotations 
+                    javaMethod ensureHasAnnotations
                         ensureInvisibleParameterAnnotationsAt: paramIndex
                 ].
             annotationsCount timesRepeat: [
@@ -1121,11 +1235,12 @@
     inStream position ~= endPos ifTrue: [
         self halt: 'annotations are probably reading what they shouldnt'
     ].
-    self breakPoint:#mh.
+
     javaMethod annotations rawParamAnnotations: rawAnnotations.
 
     "Modified: / 28-02-2011 / 17:05:47 / Marcel Hlopko <hlopik@gmail.com>"
     "Modified: / 01-12-2012 / 22:54:35 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 25-01-2014 / 21:44:28 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
 !
 
 readSignatureAttributeFor:something
@@ -1135,11 +1250,15 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     signature_index := inStream nextUnsignedShortMSB:msb.
-    signature := constants at:signature_index.
-
-    something setSignature: signature.
-
-    "Modified: / 13-08-2011 / 00:28:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    signature := self constantPoolAt:signature_index.
+
+    something isJavaClass ifTrue:[
+        attributes add: #GenericSignature; add: signature
+    ] ifFalse:[
+        something setSignature: signature.
+    ].
+
+    "Modified: / 07-12-2014 / 01:43:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readSourceDebugExtensionAttributeFor:something
@@ -1153,7 +1272,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     sourceFile_index := inStream nextUnsignedShortMSB:msb.
-    sourceFile := constants at:sourceFile_index.
+    sourceFile := self constantPoolAt:sourceFile_index.
 
     aClass isJavaClass ifTrue:[
         aClass setSourceFile:sourceFile.
@@ -1174,7 +1293,7 @@
     "Modified: / 12.5.1998 / 22:01:07 / cg"
 !
 
-readStackMapTableAttributeFor:something 
+readStackMapTableAttributeFor:something
 "/        ('JAVA [info]: unhandled attribute: StackMapTable') infoPrintCR.
     self skipAttribute:'StackMapTable'.
 
@@ -1184,21 +1303,32 @@
 readSyntheticAttributeFor:something
 "/        ('JAVA [info]: unhandled attribute: Synthetic') infoPrintCR.
         self skipAttribute:'Synthetic'.
+        attributes add: #Synthetic; add: true.
+
+    "Modified: / 13-09-2013 / 01:08:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+skipAttribute
+    "Skip attribute, advance in .class file stream to next entity"
+    inStream skip: self readAttributeLength.
+
+    "Created: / 06-12-2014 / 10:53:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 skipAttribute:attributeName
     "dont know about this attribute - skip it here"
 
-    |attribute_length attribute_info|
-
-    attribute_length := inStream nextUnsignedLongMSB:msb.
-    attribute_info := ByteArray new:(attribute_length).
-    inStream nextBytes:attribute_length into:attribute_info startingAt:1.
-
     Verbose ifTrue:[Transcript show:'skipped '; show:attributeName; showCR:'-attribute'].
-
-    "Created: / 9.4.1998 / 18:12:46 / cg"
-    "Modified: / 9.4.1998 / 18:13:20 / cg"
+    self skipAttribute
+
+    "Created: / 09-04-1998 / 18:12:46 / cg"
+    "Modified: / 06-12-2014 / 10:54:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+skipAttributeLength
+    inStream skip:4.
+
+    "Created: / 03-12-2014 / 12:53:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader methodsFor:'file reading - attributes-ST'!
@@ -1209,7 +1339,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     categoryString_index := inStream nextUnsignedShortMSB:msb.
-    categoryString := constants at:categoryString_index.
+    categoryString := self constantPoolAt:categoryString_index.
 
     aClass category:categoryString.
 
@@ -1230,7 +1360,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     nameString_index := inStream nextUnsignedShortMSB:msb.
-    nameString := constants at:nameString_index.
+    nameString := self constantPoolAt:nameString_index.
 
     aClass class instanceVariableString:nameString.
 
@@ -1251,7 +1381,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     packageString_index := inStream nextUnsignedShortMSB:msb.
-    packageString := constants at:packageString_index.
+    packageString := self constantPoolAt:packageString_index.
 
     aClass package:packageString asSymbol.
 
@@ -1272,7 +1402,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     revisionString_index := inStream nextUnsignedShortMSB:msb.
-    revisionString := constants at:revisionString_index.
+    revisionString := self constantPoolAt:revisionString_index.
 
     aClass setBinaryRevision:revisionString.
 
@@ -1293,7 +1423,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     nameString_index := inStream nextUnsignedShortMSB:msb.
-    nameString := constants at:nameString_index.
+    nameString := self constantPoolAt:nameString_index.
 
     aClass classVariableString:nameString.
 
@@ -1314,7 +1444,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     nameString_index := inStream nextUnsignedShortMSB:msb.
-    nameString := constants at:nameString_index.
+    nameString := self constantPoolAt:nameString_index.
 
     aClass setInstanceVariableString:nameString.
 
@@ -1332,7 +1462,7 @@
 !JavaClassReader methodsFor:'file reading - constants'!
 
 readConstant
-    |tag constReader const|
+    |tag constReader|
 
 
     constNeeds2Slots := false.
@@ -1369,6 +1499,12 @@
                         readConstant_Methodref          "/ 10
                         readConstant_InterfaceMethodref "/ 11
                         readConstant_NameAndType        "/ 12
+                        readConstant_Undef              "/ 13
+                        readConstant_Undef              "/ 14
+                        readConstant_MethodHandle       "/ 15
+                        readConstant_MethodType         "/ 16
+                        readConstant_Undef              "/ 17
+                        readConstant_InvokeDynamic      "/ 18
                     ) at:tag ifAbsent:[#readConstant_Undef].
     ].
     ^ self perform:constReader.
@@ -1377,8 +1513,9 @@
      JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
     "
 
-    "Created: / 15.4.1996 / 15:46:32 / cg"
-    "Modified: / 9.5.1998 / 01:26:05 / cg"
+    "Created: / 15-04-1996 / 15:46:32 / cg"
+    "Modified: / 09-05-1998 / 01:26:05 / cg"
+    "Modified: / 20-05-2014 / 17:15:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstantPool
@@ -1388,35 +1525,37 @@
     "/ get constant pool
     "/
     constantPoolSize := inStream nextUnsignedShortMSB: msb.
-    self info: 'constantPoolSize = ' , constantPoolSize printString.
+    Verbose ifTrue:[
+        self info: 'constantPoolSize = ' , constantPoolSize printString.
+    ].
     constants := JavaConstantPool new: constantPoolSize - 1.
     constSlot := 1.
     [ constSlot < constantPoolSize ] whileTrue: [
-            self info: 'const slot: ' , constSlot printString.
+            Verbose ifTrue:[
+                self info: 'const slot: ' , constSlot printString.
+            ].
             const := self readConstant.
             constants at: constSlot put: const.
-            
+
             "/ long & double consts take 2 slots
             "/ (only first is used)
-            
-            constNeeds2Slots 
-                ifTrue: [ constSlot := constSlot + 2. ]
-                ifFalse: [ constSlot := constSlot + 1. ]].
+
+            constSlot := constNeeds2Slots ifTrue: [ constSlot + 2. ] ifFalse: [ constSlot + 1. ]].
     constSlot := -1.
 
     constants do:[:ref|ref isJavaRef ifTrue:[ref preResolve]].
 "/    1 to: constantPoolSize - 1
-"/        do: 
-"/            [:i | 
+"/        do:
+"/            [:i |
 "/            | const  value |
 "/
-"/            const := constants at: i.
-"/            const notNil ifTrue: 
+"/            const := self constantPoolAt: i.
+"/            const notNil ifTrue:
 "/                    [ "/ kludge for 2-slot constants (which only take 1 slot in ST/X)
-"/                    (const isKindOf: JavaUnresolvedConstant) 
-"/                        ifTrue: 
+"/                    (const isKindOf: JavaUnresolvedConstant)
+"/                        ifTrue:
 "/                            [ value := const preResolve.
-"/                            value ~~ const ifTrue: [ constants at: i put: value. ] ] ] ].
+"/                            value ~~ const ifTrue: [ self constantPoolAt: i put: value. ] ] ] ].
 
     "
      JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
@@ -1424,7 +1563,7 @@
 
     "Modified: / 07-05-1998 / 11:44:06 / cg"
     "Created: / 13-05-2011 / 16:52:54 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 15-10-2012 / 23:15:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-08-2014 / 15:41:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_Asciz
@@ -1433,12 +1572,13 @@
 
     len := inStream nextUnsignedShortMSB: msb.
     string := String new: len.
-    inStream 
+    inStream
         nextBytes: len
         into: string
         startingAt: 1.
-    Verbose 
-        ifTrue: 
+    string := InternedStrings elementAt: string ifAbsent: [ InternedStrings add: string ].
+    Verbose
+        ifTrue:
             [ Transcript
                 show: 'asciz; string= ';
                 showCR: string ].
@@ -1451,20 +1591,25 @@
     "Created: / 15-04-1996 / 15:15:35 / cg"
     "Modified: / 15-04-1996 / 16:33:45 / cg"
     "Modified: / 13-05-2011 / 17:31:39 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 13-11-2014 / 11:53:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_Class
     | nameIndex |
 
     nameIndex := inStream nextUnsignedShortMSB: msb.
-    ((constants at: nameIndex) isNil) 
-        ifTrue: 
-            [ self info: ('reading class; index=' , nameIndex printString , ' name=' 
-                        , (constants at: nameIndex) printString) ]
-        ifFalse: [ self info: ('reading class; index= ' , nameIndex printString) ].
+    Verbose ifTrue:[
+        ((self constantPoolAt: nameIndex) isNil) ifTrue: [
+                self info: ('reading class; index=' , nameIndex printString , ' name='
+                            , (self constantPoolAt: nameIndex) printString)
+        ] ifFalse: [
+            self info: ('reading class; index= ' , nameIndex printString)
+        ].
+    ].
     ^ JavaClassRef2 in: constants withNameAt: nameIndex.
 
     "Modified: / 18-05-2011 / 18:21:16 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 04-08-2014 / 15:39:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_Double
@@ -1519,22 +1664,25 @@
     "Modified: / 8.5.1998 / 22:06:07 / cg"
 !
 
-readConstant_Fieldref    
+readConstant_Fieldref
     "incrementally changing resolving logic, fields will come later"
 
     | classIndex  nameAndTypeIndex |
 
     classIndex := inStream nextUnsignedShortMSB: msb.
     nameAndTypeIndex := inStream nextUnsignedShortMSB: msb.
-    self 
-        info: 'reading fieldref; classindex=' , classIndex printString 
-                , ' nameAndTypeIndex=' , nameAndTypeIndex printString.
-    ^ JavaFieldRef2 
+    Verbose ifTrue:[
+        self
+            info: 'reading fieldref; classindex=' , classIndex printString
+                    , ' nameAndTypeIndex=' , nameAndTypeIndex printString.
+    ].
+    ^ JavaFieldRef2
         in: constants
         withNameAndTypeAt: nameAndTypeIndex
         andClassAt: classIndex.
 
     "Modified: / 15-05-2011 / 14:20:23 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 04-08-2014 / 15:38:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_Float
@@ -1605,16 +1753,33 @@
     | classIndex  nameAndTypeIndex  |
 
     classIndex := inStream nextUnsignedShortMSB: msb.
-    nameAndTypeIndex := inStream nextUnsignedShortMSB: msb.    
-    self 
-        info: 'reading interface methodref; classindex=' , classIndex printString                 
-                , ' nameAndTypeIndex=' , nameAndTypeIndex printString.                
-    ^ JavaInterfaceMethodRef2 
+    nameAndTypeIndex := inStream nextUnsignedShortMSB: msb.
+    Verbose ifTrue:[
+        self
+            info: 'reading interface methodref; classindex=' , classIndex printString
+                    , ' nameAndTypeIndex=' , nameAndTypeIndex printString.
+    ].
+    ^ JavaInterfaceMethodRef2
         in: constants
         withNameAndTypeAt: nameAndTypeIndex
         andClassAt: classIndex.
 
     "Modified: / 12-05-2011 / 18:57:47 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 04-08-2014 / 15:38:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+readConstant_InvokeDynamic
+    | bootstrapMethodAttrIndex nameAndTypeIndex |
+
+    bootstrapMethodAttrIndex := inStream nextUnsignedShortMSB: msb.
+    nameAndTypeIndex := inStream nextUnsignedShortMSB: msb.
+
+    ^ JavaInvokeDynamic2
+        in: constants
+        bootstrapMethodAttrIndex:bootstrapMethodAttrIndex
+        nameAndTypeIndex:nameAndTypeIndex
+
+    "Created: / 20-05-2014 / 17:37:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_Long
@@ -1641,20 +1806,48 @@
     "Created: 15.4.1996 / 16:34:42 / cg"
 !
 
+readConstant_MethodHandle
+    | reference_kind  reference_index |
+
+    reference_kind := inStream next.
+    reference_index := inStream nextUnsignedShortMSB: msb.
+
+    ^ JavaMethodHandle2
+        in:constants
+        kind:reference_kind
+        index:reference_index
+
+    "Created: / 20-05-2014 / 17:30:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+readConstant_MethodType
+    | descriptorIndex |
+
+    descriptorIndex := inStream nextUnsignedShortMSB: msb.
+    ^ JavaMethodType2
+        in:constants
+        index:descriptorIndex
+
+    "Created: / 20-05-2014 / 17:40:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 readConstant_Methodref
     | classIndex  nameAndTypeIndex   |
 
     classIndex := inStream nextUnsignedShortMSB: msb.
-    nameAndTypeIndex := inStream nextUnsignedShortMSB: msb.   
-    self 
-        info: 'reading methodref; classindex=' , classIndex printString , ' nameAndTypeIndex=' 
-                , nameAndTypeIndex printString.
-    ^ JavaMethodRef2 
+    nameAndTypeIndex := inStream nextUnsignedShortMSB: msb.
+    Verbose ifTrue:[
+        self
+            info: 'reading methodref; classindex=' , classIndex printString , ' nameAndTypeIndex='
+                    , nameAndTypeIndex printString.
+    ].
+    ^ JavaMethodRef2
         in: constants
         withNameAndTypeAt: nameAndTypeIndex
         andClassAt: classIndex.
 
     "Modified: / 15-05-2011 / 14:20:38 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 04-08-2014 / 15:38:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_NameAndType
@@ -1662,15 +1855,18 @@
 
     nameIndex := inStream nextUnsignedShortMSB: msb.
     descriptorIndex := inStream nextUnsignedShortMSB: msb.
-    self 
-        info: 'reading nameAndType; nameindex=' , nameIndex printString 
-                , ' descriptorIndex= ' , descriptorIndex printString.
-    ^JavaNameAndType2 
+    Verbose ifTrue:[
+        self
+            info: 'reading nameAndType; nameindex=' , nameIndex printString
+                    , ' descriptorIndex= ' , descriptorIndex printString.
+    ].
+    ^JavaNameAndType2
                 in: constants
                 withNameAt: nameIndex
                 andDescriptorAt: descriptorIndex.
 
     "Modified: / 10-05-2011 / 17:09:47 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 04-08-2014 / 15:38:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_String
@@ -1679,8 +1875,8 @@
     string_index := inStream nextUnsignedShortMSB: msb.
     ^ JavaStringRef2 in: constants withValueAt: string_index.
 
-    
-    
+
+
     "Created: / 15-04-1996 / 15:20:33 / cg"
     "Modified: / 07-05-1998 / 11:42:45 / cg"
     "Modified: / 13-05-2011 / 17:31:54 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
@@ -1693,39 +1889,42 @@
     len := inStream nextUnsignedShortMSB: msb.
     string := TwoByteString new: len.
     1 to: len
-        do: 
-            [:idx | 
+        do:
+            [:idx |
             ascii := inStream nextUnsignedShortMSB: msb.
             string at: idx put: (Character value: ascii). ].
-    Verbose 
-        ifTrue: 
+    string := InternedStrings elementAt: string ifAbsent: [ InternedStrings add: string ].
+    Verbose
+        ifTrue:
             [ Transcript
                 show: 'asciz; unicodeString= ';
                 showCR: string ].
     ^ string
 
     "Modified: / 13-05-2011 / 17:31:44 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 13-11-2014 / 11:53:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readConstant_Utf8
-    | len  bytes  string |
+    | len string |
 
     len := inStream nextUnsignedShortMSB: msb.
-    bytes := ByteArray new: len.
-    inStream 
+    string  := String uninitializedNew: len.
+    inStream
         nextBytes: len
-        into: bytes
+        into: string
         startingAt: 1.
-    string := CharacterArray fromJavaUTF8Bytes: bytes.
-    Verbose 
-        ifTrue: 
+    string := CharacterArray decodeFromJavaUTF8: string.
+    string := InternedStrings elementAt: string ifAbsent: [ InternedStrings add: string ].
+    Verbose
+        ifTrue:
             [ Transcript
                 show: 'asciz; string= ';
                 showCR: string ].
     ^ string
 
-    "Modified: / 19-10-2010 / 12:38:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 13-05-2011 / 17:31:48 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 13-11-2014 / 11:53:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader methodsFor:'file reading - constants-ST'!
@@ -1744,7 +1943,7 @@
     ].
     Verbose ifTrue:[Transcript show:'array; size= ';     showCR:aSize].
 
-    ^ JavaUnresolvedSTArrayConstant 
+    ^ JavaUnresolvedSTArrayConstant
                 pool:constants
                 poolIndex:constSlot
                 array:arr
@@ -1801,19 +2000,19 @@
 
 
     string_index := inStream nextUnsignedShortMSB: msb.
-    Verbose 
-        ifTrue: 
+    Verbose
+        ifTrue:
             [ Transcript
                 show: 'string; index= ';
                 showCR: string_index ].
-    
+
     "/ resolve here if possible
-    
-    string_index < constSlot 
-        ifTrue: 
-            [ chars := (constants at: string_index).
+
+    string_index < constSlot
+        ifTrue:
+            [ chars := (self constantPoolAt: string_index).
             ^ chars ].
-    ^ JavaUnresolvedSTStringConstant 
+    ^ JavaUnresolvedSTStringConstant
         pool: constants
         poolIndex: constSlot
         stringIndex: string_index
@@ -1827,20 +2026,20 @@
 
 
     string_index := inStream nextUnsignedShortMSB: msb.
-    Verbose 
-        ifTrue: 
+    Verbose
+        ifTrue:
             [ Transcript
                 show: 'symbol; index= ';
                 showCR: string_index ].
-    
+
     "/ resolve here if possible
-    
-    string_index < constSlot 
-        ifTrue: 
-            [ chars := (constants at: string_index).
+
+    string_index < constSlot
+        ifTrue:
+            [ chars := (self constantPoolAt: string_index).
             chars isString ifFalse: [ self halt: 'should not happen' ].
             ^ chars asSymbol ].
-    ^ JavaUnresolvedSTSymbolConstant 
+    ^ JavaUnresolvedSTSymbolConstant
         pool: constants
         poolIndex: constSlot
         stringIndex: string_index
@@ -1856,7 +2055,7 @@
 
     | classnameAsPath |
 
-    classnameAsPath := class name copyReplaceAll: $/ with: Filename separator.
+    classnameAsPath := class binaryName copyReplaceAll: $/ with: Filename separator.
 
     Java effectiveExtensionsPath do:[:each|
         ProgrammingLanguage allDo:[:lang|
@@ -1872,6 +2071,7 @@
     ]
 
     "Created: / 06-09-2012 / 11:37:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-10-2013 / 22:59:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readExtensionsFor: class from: file
@@ -1896,11 +2096,19 @@
 
     JAVA isNil ifTrue:[ JavaPackage initialize ].
     [
-        Class withoutUpdatingChangesDo:[
-            language fileIn: file.
+        | wasSilent |
+
+        wasSilent := Smalltalk silentLoading.
+        Smalltalk silentLoading: true.
+        [
+            Class withoutUpdatingChangesDo:[
+                language fileIn: file.
+            ].
+        ] ensure:[
+            Smalltalk silentLoading: wasSilent
         ].
     ] on: JavaClassQuery do:[:query |
-        query className = class name ifTrue:[
+        query className = class binaryName ifTrue:[
             query resumeWith: class
         ] ifFalse:[
             query resumeWith: nil.
@@ -1908,7 +2116,7 @@
     ].
 
     "Created: / 06-09-2012 / 12:14:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 16-12-2012 / 16:48:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-10-2013 / 11:12:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader methodsFor:'file reading - fields'!
@@ -1919,7 +2127,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     constantvalue_index := inStream nextUnsignedShortMSB:msb.
-    constantValue := constants at:constantvalue_index.
+    constantValue := self constantPoolAt:constantvalue_index.
 
     aField constantValue:constantValue.
 
@@ -1943,15 +2151,15 @@
     descriptor_index := inStream nextUnsignedShortMSB: msb.
     field := JavaField new.
     field setAccessFlags: access_flags.
-    field setName: (constants at: name_index) asSymbol.
-    field setDescriptor: (constants at: descriptor_index) asSymbol.
-    field setConstantPool: constants.
+    field setName: (self constantPoolAt: name_index) asSymbol.
+    field setDescriptor: (self constantPoolAt: descriptor_index) asSymbol.
     attributes_count := inStream nextUnsignedShortMSB: msb.
-    Verbose 
-        ifTrue: 
+    attributes := OrderedCollection new: attributes_count * 2.
+    Verbose
+        ifTrue:
             [ Transcript
                 show: '  field name: ';
-                show: (constants at: name_index);
+                show: (self constantPoolAt: name_index);
                 show: ' access: ';
                 show: access_flags;
                 show: ' attrib_cnt: ';
@@ -1966,7 +2174,7 @@
     "Modified: / 15-10-1998 / 10:38:01 / cg"
     "Modified: / 17-12-2010 / 18:44:30 / Marcel Hlopko <hlopik@gmail.com>"
     "Modified: / 18-05-2011 / 14:11:37 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 14-08-2011 / 19:40:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-12-2014 / 16:25:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readFieldInfofields
@@ -1997,7 +2205,7 @@
 !JavaClassReader methodsFor:'file reading - interfaces'!
 
 readInterfaces
-    |interfacesCount interface_index interface interfaces|
+    | interfacesCount interface_index interfaces |
 
     "/
     "/ get interfaces
@@ -2008,11 +2216,9 @@
     interfaces := Array new:interfacesCount.
 
     1 to:interfacesCount do:[:i |
-	Verbose ifTrue:[Transcript show:'interface: '; showCR:i].
-	interface_index := inStream nextUnsignedShortMSB:msb.
-	interface := constants at:interface_index.
-
-	interfaces at:i put:interface.
+        Verbose ifTrue:[Transcript show:'interface: '; showCR:i].
+        interface_index := inStream nextUnsignedShortMSB:msb.
+        interfaces at:i put:interface_index.
     ].
     ^ interfaces
 
@@ -2020,8 +2226,8 @@
      JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
     "
 
-    "Created: 15.4.1996 / 15:31:59 / cg"
-    "Modified: 15.4.1996 / 15:33:28 / cg"
+    "Created: / 15-04-1996 / 15:31:59 / cg"
+    "Modified: / 27-11-2014 / 16:55:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader methodsFor:'file reading - methods'!
@@ -2097,11 +2303,11 @@
         code := nil
     ].
 
-    aJavaMethod 
-        setCode:code 
-        maxStack:max_stack 
-        maxLocals:max_locals 
-        u1:unknown1 
+    aJavaMethod
+        setCode:code
+        maxStack:max_stack
+        maxLocals:max_locals
+        u1:unknown1
         u2:unknown2.
 
     self readAttributesFor:aJavaMethod.
@@ -2124,14 +2330,13 @@
 
     exception_table_length := inStream nextUnsignedShortMSB:msb.
     exception_table_length ~~ 0 ifTrue:[
-	exception_table := Array new:exception_table_length.
-	1 to:exception_table_length do:[:i |
-	    |idx ex|
-
-	    idx := inStream nextUnsignedShortMSB:msb.
-	    ex := constants at:idx.
-	    exception_table at:i put:ex.
-	].
+        exception_table := Array new:exception_table_length.
+        1 to:exception_table_length do:[:i |
+            | idx |
+
+            idx := inStream nextUnsignedShortMSB:msb.
+            exception_table at:i put:idx.
+        ].
     ].
 
     Verbose ifTrue:[Transcript showCR:'method has an exceptionTable'].
@@ -2139,8 +2344,8 @@
     aJavaMethod setExceptionTable:exception_table.
     ^ true
 
-    "Modified: 15.4.1996 / 15:33:28 / cg"
-    "Created: 15.4.1996 / 15:40:17 / cg"
+    "Created: / 15-04-1996 / 15:40:17 / cg"
+    "Modified: / 04-12-2014 / 14:29:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readLineNumberTableAttributeFor:aJavaMethod
@@ -2188,13 +2393,13 @@
 	    start_pc := inStream nextUnsignedShortMSB:msb.
 	    length := inStream nextUnsignedShortMSB:msb.
 	    name_index := inStream nextUnsignedShortMSB:msb.
-	    name := constants at:name_index.
+	    name := self constantPoolAt:name_index.
 	    sig_index := inStream nextUnsignedShortMSB:msb.
-	    signature := constants at:sig_index.
+	    signature := self constantPoolAt:sig_index.
 	    slot := inStream nextUnsignedShortMSB:msb.
 
-	    local_variable_table at:i put:(JavaLocalVariableTableEntry new 
-						startPC:start_pc 
+	    local_variable_table at:i put:(JavaLocalVariableTableEntry new
+						startPC:start_pc
 						length:length
 						name:name
 						signature:signature
@@ -2216,7 +2421,7 @@
     "Created: 15.4.1996 / 15:40:17 / cg"
 !
 
-readMethodFor:aClass
+readMethodFor:aJavaClass into: aMethodDictionary
     |m access_flags name_index name descriptor_index descriptor
      tooManyArgs|
 
@@ -2227,22 +2432,22 @@
     name_index := inStream nextUnsignedShortMSB:msb.
     descriptor_index := inStream nextUnsignedShortMSB:msb.
 
-    name := constants at:name_index.
-    descriptor := constants at:descriptor_index.
+    name := self constantPoolAt:name_index.
+    descriptor := self constantPoolAt:descriptor_index.
 
     Verbose ifTrue:[
         Transcript show:'method name:'; showCR:name.
         Transcript show:'descriptor:'; showCR:descriptor.
     ].
 
-    aClass isJavaClass ifTrue:[
+    aJavaClass isJavaClass ifTrue:[
         (access_flags bitAnd:ACC_NATIVE) ~~ 0 ifTrue:[
             m := JavaNativeMethod new.
         ] ifFalse:[
             m := JavaMethodWithHandler new.
         ].
         m setAccessFlags:access_flags.
-        m setJavaClass:aClass.
+        m setJavaClass:aJavaClass.
         tooManyArgs := false.
         ArgumentError handle:[:ex |
             Logger log: 'java method has too many arguments - will fail to execute' severity: #warn facility: 'JVM'.
@@ -2278,20 +2483,23 @@
             ].
             m setAccessFlags:newAccessFlags.
         ].
-        self addSelector: (name , descriptor) asSymbol withMethod: m toClass: aClass.
+        aMethodDictionary at: (name , descriptor) asSymbol put: m.
 
         ( m selector == #'finalize()V' ) ifTrue:[
-            ( aClass name ~~ #'java/lang/Object' ) ifTrue:[
-                aClass setAccessFlags: (aClass accessFlags bitOr:ACX_HASFINALIZE)
+            ( aJavaClass binaryName ~~ #'java/lang/Object' ) ifTrue:[
+                aJavaClass setAccessFlags: (aJavaClass accessFlags bitOr:ACX_HASFINALIZE)
             ]
         ].
     ] ifFalse:[
+        "/ Reading method for non-Java class
+        self error: 'Not really supported'.
+
         m := Method new.
         self readAttributesFor:m.
         (access_flags bitTest:ACC_STATIC) ifTrue:[
-            self addSelector:name asSymbol withMethod:m toClass: aClass class.
+            self addSelector:name asSymbol withMethod:m toClass: aJavaClass class.
         ] ifFalse:[
-            self addSelector:name asSymbol withMethod:m toClass: aClass.
+            self addSelector:name asSymbol withMethod:m toClass: aJavaClass.
         ]
     ].
 
@@ -2299,27 +2507,32 @@
      JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
     "
 
-    "Created: / 15-04-1996 / 16:48:49 / cg"
-    "Modified: / 25-09-1999 / 23:16:25 / cg"
-    "Modified: / 28-10-2011 / 16:56:48 / m"
-    "Modified: / 26-02-2013 / 12:45:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 21-05-2014 / 15:58:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 readMethodsFor:aJavaClass
-    |methodsCount method|
+    | methodsCount methodDict |
 
     "/
     "/ get methods
     "/
     methodsCount := inStream nextUnsignedShortMSB:msb.
     Verbose ifTrue:[Transcript show:'methodsCount = '; showCR:methodsCount].
+    methodDict := MethodDictionary new: methodsCount.
 
     1 to:methodsCount do:[:i |
         Verbose ifTrue:[Transcript show:'method: '; showCR:i].
-        method := self readMethodFor:aJavaClass
+        self readMethodFor: aJavaClass into: methodDict.
     ].
-
-    Smalltalk changed: #methodDictionary with: aJavaClass.
+    "/ Set method dictionary bit do noy yet flush caches. Caches are flushed
+    "/ at the very last moment, when a class is actually initialized. This should
+    "/ be sufficent as an object cannot be sent a message unless a class is
+    "/ initialized first. This saves us a little bit of time when reading classes
+    "/ but cost time when initializing the class, so normally this is not much
+    "/ of a saving. However, this helps in cases Java class is only read into memory
+    "/ and never initialized - that's what JBrowser Workspace does.
+    "/ See JavaClass>>classInit.
+    aJavaClass setMethodDictionary: methodDict.
 
     "
      JavaClassReader readFile:'/phys/ibm3/hotjava/classes/browser/AddButton.class'
@@ -2327,7 +2540,7 @@
 
     "Created: / 15-04-1996 / 16:46:30 / cg"
     "Modified: / 08-05-1998 / 21:20:59 / cg"
-    "Modified: / 04-04-2012 / 01:18:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 04-08-2014 / 17:04:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReader methodsFor:'file reading - methods-ST'!
@@ -2366,9 +2579,9 @@
         ].
     ].
 
-    aSmalltalkMethod byteCode:code. 
+    aSmalltalkMethod byteCode:code.
     aSmalltalkMethod stackSize:max_stack .
-    aSmalltalkMethod numberOfVars:max_locals. 
+    aSmalltalkMethod numberOfVars:max_locals.
 
     self readAttributesFor:aSmalltalkMethod.
     ^ true
@@ -2386,7 +2599,7 @@
         literal_table := Array new:literal_table_length.
         1 to:literal_table_length do:[:i |
             litIndex := inStream nextUnsignedShortMSB:msb.
-            literal := (constants at:litIndex).
+            literal := (self constantPoolAt:litIndex).
             literal_table at:i put:literal.
         ].
     ].
@@ -2402,7 +2615,7 @@
     attribute_length := inStream nextUnsignedLongMSB:msb.
 
     name_index := inStream nextUnsignedShortMSB:msb.
-    name := (constants at:name_index).
+    name := (self constantPoolAt:name_index).
 
     aSmalltalkMethod category:name.
 
@@ -2422,33 +2635,33 @@
     "Created: / 26-02-2013 / 11:42:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-loadSuperclassIdentifiedBy: something ignoring: classesBeingLoaded 
+loadSuperclassIdentifiedBy: aJavaClassRef ignoring: classesBeingLoaded
     "overriding method, here we expect something to be new JavaClassRef2"
-    
-    self assert: something isJavaRef
+
+    self assert: aJavaClassRef isJavaRef
         message: 'class identifier is not a java reference'.
-    self assert: something isJavaClassRef
+    self assert: aJavaClassRef isJavaClassRef
         message: 'class identifier is not a java class reference'.
-    (classesBeingLoaded includes: something name) ifTrue: [
-        self 
+    (classesBeingLoaded includes: aJavaClassRef name) ifTrue: [
+        self
             error: 'class we want to load is being loaded and that means something went wrong. tell mh'
     ].
      "hint in case of bug - is parent of something set? surely jv will know more :)" "find out which classloader is used"
-    ^ JavaVM classForName: something name definedBy: classLoader.
+    ^ JavaVM classForName: aJavaClassRef name definedBy: classLoader.
 
     "Created: / 18-05-2011 / 14:55:32 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 07-05-2013 / 12:24:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-10-2013 / 22:57:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-updateOwnerInCPItem: each 
-    ((each isJavaRef and: [ each isNewJavaRef ]) 
-        or: [ each isJavaNameAndType and: [ each isNewJavaNameAndType ] ]) 
+updateOwnerInCPItem: each
+    ((each isJavaRef and: [ each isNewJavaRef ])
+        or: [ each isJavaNameAndType and: [ each isNewJavaNameAndType ] ])
             ifTrue: [ each owner: classBeingLoaded ].
 
     "Created: / 12-05-2011 / 17:40:46 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 !
 
-updateOwnerInField: each 
+updateOwnerInField: each
 
             each setClass: classBeingLoaded.
 
@@ -2457,7 +2670,7 @@
 
 !JavaClassReader methodsFor:'logging'!
 
-info: message 
+info: message
     Verbose ifTrue: [ Logger log: message severity: #info facility: 'JVM' ].
 
     "Created: / 18-05-2011 / 15:06:06 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
@@ -2467,15 +2680,15 @@
 !JavaClassReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libjava/JavaClassReader.st,v 1.98 2013-09-06 00:41:21 vrany Exp $'
+    ^ '$Header: /cvs/stx/stx/libjava/JavaClassReader.st,v 1.99 2015-01-28 02:10:50 vrany Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libjava/JavaClassReader.st,v 1.98 2013-09-06 00:41:21 vrany Exp $'
+    ^ '$Header: /cvs/stx/stx/libjava/JavaClassReader.st,v 1.99 2015-01-28 02:10:50 vrany Exp $'
 !
 
 version_SVN
-    ^ '§Id§'
+    ^ 'Id'
 ! !