http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestTryCatchFinallyStatement.java
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestTryCatchFinallyStatement.java
 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestTryCatchFinallyStatement.java
new file mode 100644
index 0000000..45da07e
--- /dev/null
+++ 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestTryCatchFinallyStatement.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.bokelberg.flex.parser;
+
+import org.junit.Test;
+
+import com.adobe.ac.pmd.parser.exceptions.TokenException;
+
+public class TestTryCatchFinallyStatement extends AbstractStatementTest
+{
+   @Test
+   public void testCatch() throws TokenException
+   {
+      assertStatement( "1",
+                       "catch( e : Error ) {trace( true ); }",
+                       "<catch line=\"1\"><name line=\"1\">e"
+                             + "</name><type line=\"1\">Error</type><block 
line=\"1\">"
+                             + "<call line=\"1\"><primary 
line=\"1\">trace</primary>"
+                             + "<arguments line=\"1\"><primary line=\"1\">true"
+                             + "</primary></arguments></call></block></catch>" 
);
+   }
+
+   @Test
+   public void testFinally() throws TokenException
+   {
+      assertStatement( "1",
+                       "finally {trace( true ); }",
+                       "<finally line=\"1\"><block line=\"1\">"
+                             + "<call line=\"1\"><primary line=\"1\">"
+                             + "trace</primary><arguments line=\"1\"><primary 
line=\"1\">"
+                             + 
"true</primary></arguments></call></block></finally>" );
+   }
+
+   @Test
+   public void testTry() throws TokenException
+   {
+      assertStatement( "1",
+                       "try {trace( true ); }",
+                       "<try line=\"1\"><block line=\"1\">"
+                             + "<call line=\"1\"><primary line=\"1\">"
+                             + "trace</primary><arguments line=\"1\"><primary 
line=\"1\">"
+                             + 
"true</primary></arguments></call></block></try>" );
+   }
+}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestUnaryExpression.java
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestUnaryExpression.java
 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestUnaryExpression.java
new file mode 100644
index 0000000..41ca8d2
--- /dev/null
+++ 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestUnaryExpression.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.bokelberg.flex.parser;
+
+import org.junit.Test;
+
+import com.adobe.ac.pmd.parser.exceptions.TokenException;
+
+public class TestUnaryExpression extends AbstractStatementTest
+{
+   @Test
+   public void testArrayAccess() throws TokenException
+   {
+      assertStatement( "1",
+                       "x[0]",
+                       "<arr-acc line=\"1\"><primary line=\"1\">x<"
+                             + "/primary><primary 
line=\"1\">0</primary></arr-acc>" );
+   }
+
+   @Test
+   public void testComplex() throws TokenException
+   {
+      assertStatement( "1",
+                       "a.b['c'].d.e(1)",
+                       "<dot line=\"1\"><primary line=\"1\">a"
+                             + "</primary><dot line=\"1\"><arr-acc line=\"1\">"
+                             + "<primary line=\"1\">b</primary><primary 
line=\"1\">"
+                             + "'c'</primary></arr-acc><dot 
line=\"1\"><primary line=\"1\">"
+                             + "d</primary><call line=\"1\"><primary 
line=\"1\">e"
+                             + "</primary><arguments line=\"1\"><primary 
line=\"1\">1"
+                             + 
"</primary></arguments></call></dot></dot></dot>" );
+
+      assertStatement( "2",
+                       "a.b['c']['d'].e(1)",
+                       "<dot line=\"1\"><primary line=\"1\">a"
+                             + "</primary><dot line=\"1\"><arr-acc line=\"1\">"
+                             + "<primary line=\"1\">b</primary><primary 
line=\"1\">"
+                             + "'c'</primary><primary line=\"1\">'d'</primary>"
+                             + "</arr-acc><call line=\"1\"><primary 
line=\"1\">"
+                             + "e</primary><arguments line=\"1\"><primary 
line=\"1\">1"
+                             + "</primary></arguments></call></dot></dot>" );
+   }
+
+   @Test
+   public void testMethodCall() throws TokenException
+   {
+      assertStatement( "1",
+                       "method()",
+                       "<call line=\"1\"><primary line=\"1\">"
+                             + "method</primary><arguments 
line=\"1\"></arguments></call>" );
+
+      assertStatement( "2",
+                       "method( 1, \"two\" )",
+                       "<call line=\"1\"><primary line=\"1\">"
+                             + "method</primary><arguments line=\"1\"><primary 
line=\"1\">1"
+                             + "</primary><primary 
line=\"1\">\"two\"</primary></arguments></call>" );
+   }
+
+   @Test
+   public void testMultipleMethodCall() throws TokenException
+   {
+      assertStatement( "1",
+                       "method()()",
+                       "<call line=\"1\"><primary line=\"1\">"
+                             + "method</primary><arguments 
line=\"1\"></arguments>"
+                             + "<arguments line=\"1\"></arguments></call>" );
+   }
+
+   @Test
+   public void testParseUnaryExpressions() throws TokenException
+   {
+      assertStatement( "1",
+                       "++x",
+                       "<pre-inc line=\"1\"><primary 
line=\"1\">x</primary></pre-inc>" );
+      assertStatement( "2",
+                       "x++",
+                       "<post-inc line=\"2\"><primary 
line=\"1\">x</primary></post-inc>" );
+      assertStatement( "3",
+                       "--x",
+                       "<pre-dec line=\"1\"><primary 
line=\"1\">x</primary></pre-dec>" );
+      assertStatement( "4",
+                       "x--",
+                       "<post-dec line=\"2\"><primary 
line=\"1\">x</primary></post-dec>" );
+      assertStatement( "5",
+                       "+x",
+                       "<plus line=\"1\"><primary 
line=\"1\">x</primary></plus>" );
+      assertStatement( "6",
+                       "+ x",
+                       "<plus line=\"1\"><primary 
line=\"1\">x</primary></plus>" );
+      assertStatement( "7",
+                       "-x",
+                       "<minus line=\"1\"><primary 
line=\"1\">x</primary></minus>" );
+      assertStatement( "8",
+                       "- x",
+                       "<minus line=\"1\"><primary 
line=\"1\">x</primary></minus>" );
+      assertStatement( "9",
+                       "delete x",
+                       "<delete line=\"1\"><primary 
line=\"1\">x</primary></delete>" );
+      assertStatement( "a",
+                       "void x",
+                       "<void line=\"1\"><primary 
line=\"1\">x</primary></void>" );
+      assertStatement( "b",
+                       "typeof x",
+                       "<typeof line=\"1\"><primary 
line=\"1\">x</primary></typeof>" );
+      assertStatement( "c",
+                       "! x",
+                       "<not line=\"1\"><primary line=\"1\">x</primary></not>" 
);
+      assertStatement( "d",
+                       "~ x",
+                       "<b-not line=\"1\"><primary 
line=\"1\">x</primary></b-not>" );
+      assertStatement( "e",
+                       "x++",
+                       "<post-inc line=\"2\"><primary 
line=\"1\">x</primary></post-inc>" );
+      assertStatement( "f",
+                       "x--",
+                       "<post-dec line=\"2\"><primary 
line=\"1\">x</primary></post-dec>" );
+   }
+}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestVarStatement.java
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestVarStatement.java
 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestVarStatement.java
new file mode 100644
index 0000000..baa9584
--- /dev/null
+++ 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestVarStatement.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.bokelberg.flex.parser;
+
+import org.junit.Test;
+
+import com.adobe.ac.pmd.parser.exceptions.TokenException;
+
+public class TestVarStatement extends AbstractStatementTest
+{
+   @Test
+   public void testFlexPMD211() throws TokenException
+   {
+      assertStatement( "",
+                       "var a:Vector.<String> = new Vector.<String>();\nvar 
i:int;",
+                       "<var-list line=\"1\"><name-type-init line=\"1\"><name 
line=\"1\">a</name>"
+                             + "<vector line=\"1\"><type 
line=\"1\">String</type></vector>"
+                             + "<init line=\"1\"><new line=\"1\"><primary 
line=\"1\">Vector</primary>"
+                             + "<vector line=\"1\"><vector line=\"1\"><type 
line=\"1\">String</type>"
+                             + "</vector></vector><arguments 
line=\"1\"></arguments></new></init>"
+                             + "</name-type-init></var-list>" );
+   }
+
+   @Test
+   public void testFullFeaturedVar() throws TokenException
+   {
+      assertStatement( "1",
+                       "var a : int = 4",
+                       "<var-list line=\"1\">"
+                             + "<name-type-init line=\"1\">"
+                             + "<name line=\"1\">a</name><type 
line=\"1\">int</type>"
+                             + "<init line=\"1\"><primary 
line=\"1\">4</primary>"
+                             + "</init></name-type-init></var-list>" );
+
+      assertStatement( "1",
+                       "var a : int = 4, b : int = 2;",
+                       "<var-list line=\"1\"><name-type-init line=\"1\">"
+                             + "<name line=\"1\">a</name><type 
line=\"1\">int</type>"
+                             + "<init line=\"1\"><primary 
line=\"1\">4</primary></init>"
+                             + "</name-type-init><name-type-init line=\"1\">"
+                             + "<name line=\"1\">b</name><type 
line=\"1\">int</type>"
+                             + "<init line=\"1\"><primary 
line=\"1\">2</primary></init>"
+                             + "</name-type-init></var-list>" );
+
+      assertStatement( "with array",
+                       "var colors:Array = [0x2bc9f6, 0x0086ad];",
+                       "<var-list line=\"1\">"
+                             + "<name-type-init line=\"1\">"
+                             + "<name line=\"1\">colors</name><type 
line=\"1\">Array</type>"
+                             + "<init line=\"1\">" + "<primary 
line=\"1\"><array line=\"1\">"
+                             + "<primary line=\"1\">0x2bc9f6</primary>"
+                             + "<primary line=\"1\">0x0086ad</primary>"
+                             + 
"</array></primary></init></name-type-init></var-list>" );
+   }
+
+   @Test
+   public void testInitializedVar() throws TokenException
+   {
+      assertStatement( "1",
+                       "var a = 4",
+                       "<var-list line=\"1\"><name-type-init line=\"1\">"
+                             + "<name line=\"1\">a</name><type line=\"1\">"
+                             + "</type><init line=\"1\"><primary 
line=\"1\">4</primary>"
+                             + "</init></name-type-init></var-list>" );
+   }
+
+   @Test
+   public void testSimpleVar() throws TokenException
+   {
+      assertStatement( "1",
+                       "var a",
+                       "<var-list line=\"1\"><name-type-init line=\"1\">"
+                             + "<name line=\"1\">a</name><type line=\"2\">"
+                             + "</type></name-type-init></var-list>" );
+   }
+
+   @Test
+   public void testTypedVar() throws TokenException
+   {
+      assertStatement( "1",
+                       "var a : Object",
+                       "<var-list line=\"1\"><name-type-init line=\"1\">"
+                             + "<name line=\"1\">a</name><type 
line=\"1\">Object</type>"
+                             + "</name-type-init></var-list>" );
+   }
+
+   @Test
+   public void testVector() throws TokenException
+   {
+      assertStatement( "vector",
+                       "var v:Vector.<DisplayObject> = new Vector.<Sprite>();",
+                       "<var-list line=\"1\"><name-type-init line=\"1\"><name 
line=\"1\">v</name><vector line=\"1\"><type 
line=\"1\">DisplayObject</type></vector><init line=\"1\"><new 
line=\"1\"><primary line=\"1\">Vector</primary><vector line=\"1\"><vector 
line=\"1\"><type line=\"1\">Sprite</type></vector></vector><arguments 
line=\"1\"></arguments></new></init></name-type-init></var-list>" );
+
+      assertStatement( "vector",
+                       "var v:Vector.< Vector.< String > >",
+                       "<var-list line=\"1\"><name-type-init line=\"1\">"
+                             + "<name line=\"1\">" + "v</name><vector 
line=\"1\"><vector line=\"1\""
+                             + "><type line=\"1\""
+                             + 
">String</type></vector></vector></name-type-init></var-list>" );
+
+      assertStatement( "vector",
+                       "var v:Vector.<Vector.<String>>;",
+                       "<var-list line=\"1\"><name-type-init line=\"1\">"
+                             + "<name line=\"1\">"
+                             + "v</name><vector line=\"1\"><vector 
line=\"1\"><type line=\"1\""
+                             + 
">String</type></vector></vector></name-type-init></var-list>" );
+
+      assertStatement( "",
+                       "var HT:Vector.<BitString> = new 
Vector.<BitString>(251, true);",
+                       "<var-list line=\"1\"><name-type-init line=\"1\"><name 
line=\"1\">HT</name><vector line=\"1\"><type 
line=\"1\">BitString</type></vector><init line=\"1\"><new line=\"1\"><primary 
line=\"1\">Vector</primary><vector line=\"1\"><vector line=\"1\"><type 
line=\"1\">BitString</type></vector></vector><arguments line=\"1\"><primary 
line=\"1\">251</primary><primary 
line=\"1\">true</primary></arguments></new></init></name-type-init></var-list>" 
);
+   }
+}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestWhileStatement.java
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestWhileStatement.java
 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestWhileStatement.java
new file mode 100644
index 0000000..159d101
--- /dev/null
+++ 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/java/de/bokelberg/flex/parser/TestWhileStatement.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.bokelberg.flex.parser;
+
+import org.junit.Test;
+
+import com.adobe.ac.pmd.parser.exceptions.TokenException;
+
+public class TestWhileStatement extends AbstractStatementTest
+{
+   @Test
+   public void testWhile() throws TokenException
+   {
+      assertStatement( "1",
+                       "while( i++ ){ trace( i ); }",
+                       "<while line=\"1\">"
+                             + "<condition line=\"1\">"
+                             + "<post-inc line=\"1\">"
+                             + "<primary line=\"1\">i</primary>"
+                             + "</post-inc>"
+                             + "</condition>"
+                             + "<block line=\"1\"><call line=\"1\">"
+                             + "<primary line=\"1\">trace</primary>"
+                             + "<arguments line=\"1\"><primary 
line=\"1\">i</primary>"
+                             + "</arguments></call>" + "</block>" + "</while>" 
);
+   }
+
+   @Test
+   public void testWhileWithEmptyStatement() throws TokenException
+   {
+      assertStatement( "1",
+                       "while( i++ ); ",
+                       "<while line=\"1\">"
+                             + "<condition line=\"1\">"
+                             + "<post-inc line=\"1\">"
+                             + "<primary line=\"1\">i</primary>"
+                             + "</post-inc></condition><stmt-empty 
line=\"1\">;</stmt-empty></while>" );
+   }
+
+   @Test
+   public void testWhileWithoutBlock() throws TokenException
+   {
+      assertStatement( "1",
+                       "while( i++ ) trace( i ); ",
+                       "<while line=\"1\">"
+                             + "<condition line=\"1\">"
+                             + "<post-inc line=\"1\">"
+                             + "<primary line=\"1\">i</primary>"
+                             + "</post-inc></condition><call line=\"1\">"
+                             + "<primary line=\"1\">trace</primary><arguments 
line=\"1\">"
+                             + "<primary 
line=\"1\">i</primary></arguments></call></while>" );
+   }
+}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/Enum.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/Enum.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/Enum.as
new file mode 100644
index 0000000..358e103
--- /dev/null
+++ b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/Enum.as
@@ -0,0 +1,84 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.granite.util 
+{      
+       import flash.utils.IDataInput;
+       import flash.utils.IDataOutput;
+       import flash.utils.IExternalizable;
+       import flash.utils.getQualifiedClassName;
+       
+       public class Enum implements IExternalizable
+       {
+               private var _name:String;
+               
+               public function Enum(name:String, restrictor:Restrictor) {
+                       _name = (restrictor is Restrictor ? name : 
constantOf(name).name);
+               }
+               
+               public function get name():String {
+                       return _name;
+               }
+               
+               protected function getConstants():Array {
+                       throw new Error("Should be overriden");
+               }
+               
+               protected function constantOf(name:String):Enum {
+                       for each (var o:* in getConstants()) {
+                               var enum:Enum = Enum(o);
+                               if (enum.name == name)
+                                       return enum;
+                       }
+                       throw new ArgumentError("Invalid " + 
getQualifiedClassName(this) + " value: " + name);
+               }
+               
+               public function readExternal(input:IDataInput):void {
+                       _name = constantOf(input.readObject() as String).name;
+               }
+               
+               public function writeExternal(output:IDataOutput):void {
+                       output.writeObject(_name);
+               }
+               
+               public static function normalize(enum:Enum):Enum {
+                       return (enum == null ? null : 
enum.constantOf(enum.name));
+               }
+               
+               public static function readEnum(input:IDataInput):Enum {
+                       return normalize(input.readObject() as Enum);
+               }
+               
+               public function toString():String {
+                       return name;
+               }
+               
+               public function equals(other:Enum):Boolean {
+                       return other === this || (
+                               other != null &&
+                               getQualifiedClassName(this) == 
getQualifiedClassName(other) &&
+                               other.name == this.name
+                       );
+               }
+               
+               protected static function get _():Restrictor { // NO PMD 
ProtectedStaticMethod
+                       return new Restrictor();
+               }
+       }
+}
+class Restrictor {}

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FisheyeBase.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FisheyeBase.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FisheyeBase.as
new file mode 100644
index 0000000..fe2147a
--- /dev/null
+++ 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FisheyeBase.as
@@ -0,0 +1,564 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package qs.controls.fisheyeClasses
+{
+    import flash.display.DisplayObject;
+    import flash.display.Sprite;
+    import flash.events.Event;
+    import flash.events.MouseEvent;
+    import mx.core.ClassFactory;
+    import mx.core.IDataRenderer;
+    import mx.core.IFactory;
+    import mx.core.UIComponent;
+    import qs.controls.CachedLabel;
+    import qs.controls.LayoutAnimator;
+
+    /** the horizontal alignment.  */
+    [Style( name="horizontalAlign", type="String", 
enumeration="left,center,right,justified", inherit="no" )]
+    /** the vertical alignment */
+    [Style( name="verticalAlign", type="String", 
enumeration="top,center,bottom,justified", inherit="no" )]
+    /** the amount of space, in pixels, between invidual items */
+    [Style( name="defaultSpacing", type="Number", inherit="no" )]
+    /** the amount of space, in pixels, between invidual items when hilighted*/
+    [Style( name="hilightSpacing", type="Number", inherit="no" )]
+    /** the property on the item renderer to assign to when the renderer' 
state changes */
+    [Style( name="stateProperty", type="String", inherit="no" )]
+    /** the value to assign to 'stateProperty' on the renderer when the item 
is hilighted */
+    [Style( name="rolloverValue", type="String", inherit="no" )]
+    /** the value to assign to 'stateProperty' on the renderer when the item 
is selected */
+    [Style( name="selectedValue", type="String", inherit="no" )]
+    /** the value to assign to 'stateProperty' on the renderer when some other 
item is selected */
+    [Style( name="unselectedValue", type="String", inherit="no" )]
+    /** the value to assign to 'stateProperty' on the renderer when the item 
is in its default state */
+    [Style( name="defaultValue", type="String", inherit="no" )]
+    /** the scale factor assigned to renderers when no item is hilighted or 
selected */
+    [Style( name="defaultScale", type="Number", inherit="no" )]
+    /** the minimum scale factor assigned to renderers on screen. The actual 
scale factor assigned to
+     * an item will range between minScale and hilightMaxScale based on its 
distance from the hilighted or selected item */
+    [Style( name="hilightMinScale", type="Number", inherit="no" )]
+    /** the maximum scale factor assigned to renderers on screen. The actual 
scale factor assigned to
+     * an item will range between minScale and hilightMaxScale based on its 
distance from the hilighted or selected item */
+    [Style( name="hilightMaxScale", type="Number", inherit="no" )]
+    /** how quickly or slowly items scale down from the hilightMaxScale value 
to minScale value.  A value of 1 will scale linearly down from the hilighted 
item out to the item at scaleRadius.
+     * A value higher than wone will descend slowly from the hilight, then 
drop off quicker at the edge. A value lower than one will drop off quickly from 
the hilight Should be greater than 0*/
+    [Style( name="hilightScaleSlope", type="Number", inherit="no" )]
+    /** The radius, in items, around the hilighted item that are affected by 
the hilight. A value of 1 means only the hilighted item will scale. A value of 
three means the hilighted item plus the two items
+     * to either side will scale up. How much each item scales is affected by 
the scaleSlope style.*/
+    [Style( name="hilightScaleRadius", type="Number", inherit="no" )]
+    /** how quickly items animate to their target location when the layout of 
the renderers change.  A value of 1 will
+     * snap instantly to the new value, while a value of 0 will never change */
+    [Style( name="animationSpeed", type="Number", inherit="no" )]
+    [Event( name="change", type="flash.events.Event" )]
+    [Event( name="loaded", type="flash.events.Event" )]
+    [DefaultProperty( "dataProvider" )]
+    public class FisheyeBase extends UIComponent
+    {
+        public static const LOADED : String = "loaded";
+
+        /** the data items driving the component
+         */
+        private var _items : Array = [];
+
+        /** when a new dataprovider is assigned, we keep it in reserve until 
we have a chance
+         * to generate new renderers for it.  This is the temporary holding 
pen for those new items
+         */
+        private var _pendingItems : Array;
+
+        protected var itemsChanged : Boolean = false;
+
+        /** true if the renderers need to be regenerated */
+        protected var renderersDirty : Boolean = true;
+
+        /** the renderers representing the data items, one for each item */
+        protected var renderers : Array = [];
+
+        /** the currently hilighted item
+         */
+        protected var hilightedItemIndex : Number = NaN;
+
+        /** the currently selected item
+         */
+        protected var selectedItemIndex : Number = NaN;
+
+        /** @private */
+        private var _selectionEnabled : Boolean = true;
+
+        /** the factory that generates item renderers
+         */
+        private var _itemRendererFactory : IFactory;
+
+        /**
+         * the object that manages animating the children layout
+         */
+        protected var animator : LayoutAnimator;
+
+        /** Constructor */
+        public function FisheyeBase()
+        {
+            super();
+            _itemRendererFactory = new ClassFactory( CachedLabel );
+            addEventListener( MouseEvent.MOUSE_MOVE, updateHilight );
+            addEventListener( MouseEvent.ROLL_OUT, removeHilight );
+            addEventListener( MouseEvent.MOUSE_DOWN, updateSelection );
+            var maskShape : Sprite = new Sprite();
+            addChild( maskShape );
+            mask = maskShape;
+            maskShape.graphics.beginFill( 0 );
+            maskShape.graphics.drawRect( 0, 0, 10, 10 );
+            maskShape.graphics.endFill();
+            animator = new LayoutAnimator();
+            animator.layoutFunction = generateLayout;
+        }
+
+        //-----------------------------------------------------------------
+        /** the data source
+         */
+        public function set dataProvider( value : Array ) : void
+        {
+            _pendingItems = value;
+            renderersDirty = true;
+            itemsChanged = true;
+            invalidateProperties();
+            dispatchEvent( new Event( LOADED ) );
+        }
+
+        public function get dataProvider() : Array
+        {
+            return _items;
+        }
+
+        //-----------------------------------------------------------------
+        public function set selectionEnabled( value : Boolean ) : void
+        {
+            if ( _selectionEnabled == value )
+                return;
+            _selectionEnabled = value;
+            selectedIndex = selectedIndex;
+        }
+
+        public function get selectionEnabled() : Boolean
+        {
+            return _selectionEnabled;
+        }
+
+        [Bindable( "change" )]
+        public function get selectedItem() : Object
+        {
+            return ( isNaN( selectedItemIndex ) ? null : _items[ 
selectedItemIndex ] );
+        }
+
+        public function set selectedItem( value : Object ) : void
+        {
+            var newIndex : Number;
+
+            for ( var i : int = 0; i < _items.length; i++ )
+            {
+                if ( value == _items[ i ] )
+                {
+                    newIndex = i;
+                    break;
+                }
+            }
+            selectedIndex = newIndex;
+        }
+
+        [Bindable( "change" )]
+        public function get selectedIndex() : int
+        {
+            return ( isNaN( selectedItemIndex ) ? -1 : selectedItemIndex );
+        }
+
+        public function set selectedIndex( value : int ) : void
+        {
+            var v : Number = ( value < 0 || value >= _items.length ) ? NaN : 
value;
+
+            if ( v != selectedItemIndex )
+            {
+                selectedItemIndex = v;
+                updateState();
+                animator.invalidateLayout();
+                dispatchEvent( new Event( LOADED ) );
+            }
+        }
+
+        //-----------------------------------------------------------------
+        /* These private get properties are wrappers around styles that return 
defaults if unset.
+         *  It saves me from having to write a CSS selector, which
+         *  I really should do at some point */
+        protected function get defaultSpacingWithDefault() : Number
+        {
+            var result : Number = getStyle( "defaultSpacing" );
+
+            if ( isNaN( result ) )
+                result = 0;
+            return result;
+        }
+
+        protected function get maxScaleWithDefault() : Number
+        {
+            var result : Number = getStyle( "hilightMaxScale" );
+
+            if ( isNaN( result ) )
+                result = 1;
+            return result;
+        }
+
+        //-----------------------------------------------------------------
+        /**
+         * by making the itemRenderer be of type IFactory,
+         * developers can define it inline using the <Component> tag
+         */
+        public function get itemRenderer() : IFactory
+        {
+            return _itemRendererFactory;
+        }
+
+        public function set itemRenderer( value : IFactory ) : void
+        {
+            _itemRendererFactory = value;
+            renderersDirty = true;
+            invalidateProperties();
+        }
+
+        //-----------------------------------------------------------------
+        override protected function commitProperties() : void
+        {
+            // its now safe to switch over new dataProviders.
+            if ( _pendingItems != null )
+            {
+                _items = _pendingItems;
+                _pendingItems = null;
+            }
+            itemsChanged = false;
+
+            if ( renderersDirty )
+            {
+                // something has forced us to reallocate our renderers. start 
by throwing out the old ones.
+                renderersDirty = false;
+                var mask : DisplayObject = mask;
+
+                for ( var i : int = numChildren - 1; i >= 0; i-- )
+                    removeChildAt( i );
+                addChild( mask );
+                renderers = [];
+
+                // allocate new renderers, assign the data.
+                for ( i = 0; i < _items.length; i++ )
+                {
+                    var renderer : UIComponent = 
_itemRendererFactory.newInstance();
+                    IDataRenderer( renderer ).data = _items[ i ];
+                    renderers[ i ] = renderer;
+                    addChild( renderer );
+                }
+                animator.items = renderers;
+            }
+            invalidateSize();
+        }
+
+        private function removeHilight( e : MouseEvent ) : void
+        {
+            // called on rollout. Clear out any hilight, and reset our layout.
+            hilightedItemIndex = NaN;
+            updateState();
+            animator.invalidateLayout();
+        }
+
+        /** finds the item that would be closest to the x/y position if it 
were hilighted
+         */
+        protected function findItemForPosition( xPos : Number, yPos : Number ) 
: Number
+        {
+            return NaN;
+        }
+
+        /** called on mouse click to set or clear the selection */
+        protected function updateSelection( e : MouseEvent ) : void
+        {
+            if ( _selectionEnabled == false )
+                return;
+            var newSelection : Number = findItemForPosition( this.mouseX, 
this.mouseY );
+
+            if ( selectedItemIndex == newSelection )
+                selectedIndex = -1;
+            else
+                selectedIndex = newSelection;
+            updateState();
+            animator.invalidateLayout();
+        }
+
+        /** called on mouse move to update the hilight */
+        private function updateHilight( e : MouseEvent ) : void
+        {
+            var newHilight : Number = findItemForPosition( this.mouseX, 
this.mouseY );
+
+            if ( newHilight == hilightedItemIndex )
+                return;
+            hilightedItemIndex = newHilight;
+            updateState();
+            animator.invalidateLayout();
+        }
+
+        /**
+         * update the state properties of all of the items, based on
+         * the current hilighted and/or selected items
+         */
+        protected function updateState() : void
+        {
+            var stateProperty : String = getStyle( "stateProperty" );
+
+            if ( stateProperty != null )
+            {
+                var rolloverState : String = getStyle( "rolloverValue" );
+                var selectedState : String = getStyle( "selectedValue" );
+                var unselectedValue : String = getStyle( "unselectedValue" );
+
+                if ( unselectedValue == null || ( isNaN( selectedItemIndex ) 
&& isNaN( hilightedItemIndex ) ) )
+                    unselectedValue = getStyle( "defaultValue" );
+
+                for ( var i : int = 0; i < renderers.length; i++ )
+                {
+                    renderers[ i ][ stateProperty ] = ( i == selectedItemIndex 
) ? selectedState : ( i == hilightedItemIndex ) ? rolloverState : 
unselectedValue;
+                }
+            }
+        }
+
+        /**
+         * each item get scaled down based on its distance from the hliighted 
item.  this is the equation we use
+         * to figure out how much to scale down. The basic idea is this...we 
have two parameters that play a part
+         * in how quickly we scale down, scaleRadius and scaleSlope.  
scaleRadius is the number of items on either
+         * side of the hilighted item (inclusive) that we should be able to 
use to scale down.  scaleSlope affects
+         * how whether we scale down quickly with the first few items in the 
radius, or the last few items.
+         * This equation essentially does that.
+         */
+        private function calcDistanceFactor( params : FisheyeParameters, 
distance : Number ) : Number
+        {
+            var mult : Number = 1 / params.scaleRadius;
+            return Math.max( 0, 1 - Math.pow( distance * mult, 
params.scaleSlope ) );
+        }
+
+        /**
+         * populates a set of items to fit into the distance axisLength, 
assuming nothing is hilighted, so they
+         * all scale the same. It will attempt to scale them to match the 
defaultScale style */
+        protected function populateMajorAxisForDefault( pdata : Array, axis : 
FisheyeAxis,
+                                                        axisLength : Number ) 
: FisheyeParameters
+        {
+            var vp : Number;
+            var itemCount : int = pdata.length;
+            var params : FisheyeParameters = new FisheyeParameters();
+            populateParameters( params, false );
+            var summedSpacing : Number = params.spacing * ( itemCount - 1 );
+            var sizeSum : Number = 0;
+            var pdataInst : FisheyeItem;
+
+            for ( var i : int = 0; i < itemCount; i++ )
+                sizeSum += pdata[ i ][ axis.EOM ];
+
+            if ( sizeSum > 0 )
+            {
+                var maximumMinScale : Number = ( axisLength - summedSpacing ) 
/ sizeSum;
+                params.minScale = Math.min( params.minScale, maximumMinScale );
+            }
+            vp = 0;
+
+            for ( i = 0; i < itemCount; i++ )
+            {
+                pdataInst = pdata[ i ];
+                pdataInst.scale = params.minScale;
+                pdataInst[ axis.pos ] = vp;
+                vp += pdataInst[ axis.EOM ] * params.minScale + params.spacing;
+            }
+            return params;
+        }
+
+        /**
+         * takes the parameters used in the fisheye equation, and adjusts them 
as best as possible to make sure the
+         * items can fit into distance 'axisScale.'  Right now it does this by 
scaling down the minScale parameter if necessary. That's
+         * not entirely sufficient, but it does a pretty good job.  For future 
work:  If that's not sufficient, adjust the scaleRadius, scaleSlope,
+         * and spacing parameter
+         */
+        private function adjustParameters( pdata : Array, targetIndex : 
Number, params : FisheyeParameters,
+                                           axisSize : Number, axis : 
FisheyeAxis ) : void
+        {
+            var itemCount : int = pdata.length;
+            var summedSpacing : Number = params.spacing * ( itemCount - 1 );
+            var maxSum : Number = 0;
+            var minSum : Number = 0;
+
+            // given the constraint:
+            // W(0) * S(0) + spacing + W(1) * S(1) + spacing + ... + W(N) * 
S(N) <= unscaledWidth
+            // here we adjust the numbers that go into the calculation of S(i) 
to fit.
+            // right now that just means adjusting minScale downward if 
necessary. We'll probably add some more complex heuristic later.
+            for ( var i : int = 0; i < itemCount; i++ )
+            {
+                var pdataInst : FisheyeItem = pdata[ i ];
+                var distanceFromItem : Number = Math.abs( targetIndex - i );
+                var distanceFactor : Number = calcDistanceFactor( params, 
distanceFromItem );
+                var maxFactor : Number = params.maxScale * distanceFactor;
+                var minFactor : Number = ( 1 - distanceFactor );
+                var itemSize : Number = pdataInst[ axis.EOM ];
+                maxSum += itemSize * maxFactor;
+                minSum += itemSize * minFactor;
+            }
+            var minScale : Number = ( minSum > 0 ) ? ( ( axisSize - 
summedSpacing - maxSum ) / minSum ) : 0;
+            // if we've got lots of extra space, we might calculate that we 
need to make our ends _larger_ to fill the space. We don't want
+            // to do that. So let's contrain it to minScale. 
+            minScale = Math.min( params.minScale, minScale );
+            params.minScale = minScale;
+        }
+
+        /**
+         * populate a parameters structure from the various styles
+         */
+        private function populateParameters( params : FisheyeParameters, 
hilighted : Boolean ) : void
+        {
+            if ( hilighted == false )
+            {
+                params.minScale = getStyle( "defaultScale" );
+
+                if ( isNaN( params.minScale ) )
+                    params.minScale = .5;
+                params.spacing = defaultSpacingWithDefault;
+            }
+            else
+            {
+                params.minScale = getStyle( "hilightMinScale" );
+
+                if ( isNaN( params.minScale ) )
+                {
+                    params.minScale = getStyle( "defaultScale" );
+
+                    if ( isNaN( params.minScale ) )
+                        params.minScale = .5;
+                }
+                params.spacing = getStyle( "hilightSpacing" );
+
+                if ( isNaN( params.spacing ) )
+                    params.spacing = defaultSpacingWithDefault;
+            }
+            params.maxScale = getStyle( "hilightMaxScale" );
+
+            if ( isNaN( params.maxScale ) )
+                params.maxScale = 1;
+            params.scaleRadius = getStyle( "hilightScaleRadius" );
+
+            if ( isNaN( params.scaleRadius ) )
+                params.scaleRadius = 2;
+            params.scaleRadius = Math.max( 1, params.scaleRadius );
+            params.scaleSlope = getStyle( "hilightScaleSlope" );
+
+            if ( isNaN( params.scaleSlope ) )
+                params.scaleSlope = .75;
+        }
+
+        /**
+         * populates a set of items to fit into the distance axisLength, 
assuming targetIndex is hilighted.
+         */
+        protected function populateMajorAxisFor( pdata : Array, targetIndex : 
Number, axisSize : Number,
+                                                 axis : FisheyeAxis ) : 
FisheyeParameters
+        {
+            var vp : Number;
+            var itemCount : int = pdata.length;
+            var pdataInst : FisheyeItem;
+            var params : FisheyeParameters = new FisheyeParameters();
+            populateParameters( params, true );
+            adjustParameters( pdata, targetIndex, params, axisSize, axis );
+            vp = 0;
+
+            for ( var i : int = 0; i < itemCount; i++ )
+            {
+                pdataInst = pdata[ i ];
+                var distanceFromItem : Number = Math.abs( targetIndex - i );
+                var distanceFactor : Number = calcDistanceFactor( params, 
distanceFromItem );
+                var scale : Number = Math.max( 0,
+                                               params.minScale + ( 
params.maxScale - params.minScale ) * ( distanceFactor ) );
+                pdataInst[ axis.pos ] = vp;
+                pdataInst.scale = scale;
+                vp += pdataInst[ axis.EOM ] * scale + params.spacing;
+            }
+            return params;
+        }
+
+        /**
+         * given a set of scaled and laid out items, adjust them forward or 
backward to match the align property
+         */
+        protected function align( pdata : Array, axis : FisheyeAxis ) : void
+        {
+            var majorAlignValue : String = getStyle( axis.align );
+            var itemCount : int = pdata.length;
+            var pdataInst : FisheyeItem;
+
+            if ( itemCount == 0 )
+                return;
+
+            switch ( majorAlignValue )
+            {
+                case "right":
+                case "bottom":
+                    pdataInst = pdata[ itemCount - 1 ];
+                    var offset : Number = this[ axis.unscaled ] - ( pdataInst[ 
axis.pos ] + pdata[ itemCount - 1 ][ axis.EOM ] * pdataInst.scale );
+                    for ( var i : int = 0; i < itemCount; i++ )
+                    {
+                        pdata[ i ][ axis.pos ] += offset;
+                    }
+                    break;
+                case "left":
+                case "top":
+                    break;
+                case "center":
+                default:
+                    var midIndex : int = Math.floor( itemCount / 2 );
+                    pdataInst = pdata[ itemCount - 1 ];
+                    var rightPos : Number = pdataInst[ axis.pos ] + pdataInst[ 
axis.EOM ] * pdataInst.scale;
+                    offset = ( this[ axis.unscaled ] / 2 - ( rightPos ) / 2 );
+                    for ( i = 0; i < itemCount; i++ )
+                    {
+                        pdata[ i ][ axis.pos ] += offset;
+                    }
+                    break;
+            }
+        }
+
+        /**
+         * overridden in the subclasses
+         */
+        protected function generateLayout() : void
+        {
+        }
+
+        override protected function updateDisplayList( unscaledWidth : Number, 
unscaledHeight : Number ) : void
+        {
+            graphics.clear();
+            graphics.moveTo( 0, 0 );
+            graphics.beginFill( 0, 0 );
+            graphics.drawRect( 0, 0, unscaledWidth, unscaledHeight );
+            // update the mask
+            mask.width = unscaledWidth;
+            mask.height = unscaledHeight;
+            animator.invalidateLayout();
+        }
+
+        override public function styleChanged( styleProp : String ) : void
+        {
+            if ( styleProp == "animationSpeed" )
+                animator.animationSpeed = getStyle( "animationSpeed" );
+            invalidateSize();
+            invalidateDisplayList();
+            animator.invalidateLayout();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD115.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD115.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD115.as
new file mode 100644
index 0000000..ca9191c
--- /dev/null
+++ b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD115.as
@@ -0,0 +1,22 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package foo.bar 
+{
+       public function baz() : void { }
+} 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD195.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD195.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD195.as
new file mode 100644
index 0000000..65ba179
--- /dev/null
+++ b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD195.as
@@ -0,0 +1,51 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package
+{
+       import flash.display.Sprite;
+       
+       public class FlexPMD195 extends Sprite {
+               public function computeJustifyAdjustment(lineArray:Array, 
firstLineIndex:int, numLines:int):Number
+               {
+                       adj = 0;
+                       
+                       if (numLines == 1)
+                       {
+                               return 0; // do nothing
+                       }
+                       
+                       // first line unchanged
+                       var firstLine:IVerticalJustificationLine = 
lineArray[firstLineIndex];
+                       var firstBaseLine:Number = getBaseline(firstLine);
+                       
+                       // descent of the last line on the bottom of the frame
+                       var lastLine:IVerticalJustificationLine = 
lineArray[firstLineIndex + numLines - 1];
+                       var frameBottom:Number = _textFrame.compositionHeight - 
Number(_textFrame.effectivePaddingBottom);
+                       var allowance:Number = frameBottom - 
getBottomOfLine(lastLine);
+                       if (allowance < 0)
+                       {
+                               return 0; // Some text scrolled out; don't 
justify
+                       }
+                       var lastBaseLine:Number = getBaseline(lastLine);
+                       
+                       adj = allowance/(lastBaseLine - firstBaseLine); // 
multiplicative factor by which the space between consecutive lines is increased
+                       return adj;
+               } 
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD62.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD62.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD62.as
new file mode 100644
index 0000000..9585654
--- /dev/null
+++ b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD62.as
@@ -0,0 +1,35 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package com.test.testy.ui.components {
+       
+       import flash.display.Sprite;
+       
+       public class Link extends Sprite {
+               
+               protected var _linkText:String = ''; // NO PMD
+               protected var _style:String;
+               
+               public function Link(text:String = '', style:String = null) // 
NO PMD
+               {
+                       _style = style;
+                       _linkText = text;
+               }
+               
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD98.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD98.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD98.as
new file mode 100644
index 0000000..353395b
--- /dev/null
+++ b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/FlexPMD98.as
@@ -0,0 +1,440 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package
+{
+       import flash.display.*;
+       import flash.events.Event;
+       import flash.text.*;
+       import flash.utils.*;
+       
+       /**
+        *   An app to test function call performance
+        *   @author Jackson Dunstan
+        */
+       public class FunctionPerformanceTest extends Base implements IInterface
+       {
+               private function privateFunction(): void {}
+               protected function protectedFunction(): void {}
+               internal function internalFunction(): void {}
+               public function publicFunction(): void {}
+               
+               private function get privateGetFunction(): int { return 0; }
+               protected function get protectedGetFunction(): int { return 0; }
+               internal function get internalGetFunction(): int { return 0; }
+               public function get publicGetFunction(): int { return 0; }
+               
+               private function set privateSetFunction(val:int): void {}
+               protected function set protectedSetFunction(val:int): void {}
+               internal function set internalSetFunction(val:int): void {}
+               public function set publicSetFunction(val:int): void {}
+               
+               private static function staticPrivateFunction(): void {}
+               protected static function staticProtectedFunction(): void {}
+               internal static function staticInternalFunction(): void {}
+               public static function staticPublicFunction(): void {}
+               
+               override protected function overrideProtectedFunction(): void {}
+               override internal function overrideInternalFunction(): void {}
+               override public function overridePublicFunction(): void {}
+               
+               final private function finalPrivateFunction(): void {}
+               final protected function finalProtectedFunction(): void {}
+               final internal function finalInternalFunction(): void {}
+               final public function finalPublicFunction(): void {}
+               
+               final override protected function 
finalOverrideProtectedFunction(): void {}
+               final override internal function 
finalOverrideInternalFunction(): void {}
+               final override public function finalOverridePublicFunction(): 
void {}
+               
+               public function interfaceFunction(): void {}
+               
+               private var __logger:TextField; 
+               
+               /**
+                *   Application entry point
+                */
+               public function FunctionPerformanceTest()
+               {
+                       stage.align = StageAlign.TOP_LEFT;
+                       stage.scaleMode = StageScaleMode.NO_SCALE;
+                       __logger = new TextField();
+                       __logger.autoSize = TextFieldAutoSize.LEFT;
+                       addChild(__logger);
+                       
+                       addEventListener(Event.ENTER_FRAME, 
testDynamicFunctions);
+               }
+               
+               private function testDynamicFunctions(ev:Event): void
+               {
+                       var beforeTime:int;
+                       var i:int;
+                       const NUM_ITERATIONS:int = 10000000;
+                       
+                       function localFunction(): void {}
+                       var functionVarFunction:Function = function(): void {}
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               plainFunction();
+                       }
+                       log("Plain: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               localFunction();
+                       }
+                       log("Local: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               functionVarFunction();
+                       }
+                       log("Function var: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       removeEventListener(Event.ENTER_FRAME, 
testDynamicFunctions);
+                       addEventListener(Event.ENTER_FRAME, testMethods);
+               }
+               
+               private function testMethods(ev:Event): void
+               {
+                       var beforeTime:int;
+                       var i:int;
+                       const NUM_ITERATIONS:int = 10000000;
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               privateFunction();
+                       }
+                       log("Private: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               protectedFunction();
+                       }
+                       log("Protected: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               internalFunction();
+                       }
+                       log("Internal: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               publicFunction();
+                       }
+                       log("Public: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               this.privateFunction();
+                       }
+                       log("this.Private: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               this.protectedFunction();
+                       }
+                       log("this.Protected: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               this.internalFunction();
+                       }
+                       log("this.Internal: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               this.publicFunction();
+                       }
+                       log("this.Public: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               staticPrivateFunction();
+                       }
+                       log("Static private: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               staticProtectedFunction();
+                       }
+                       log("Static protected: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               staticInternalFunction();
+                       }
+                       log("Static internal: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               staticPublicFunction();
+                       }
+                       log("Static public: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               overrideProtectedFunction();
+                       }
+                       log("Override protected: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               overrideInternalFunction();
+                       }
+                       log("Override internal: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               overridePublicFunction();
+                       }
+                       log("Override public: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       removeEventListener(Event.ENTER_FRAME, testMethods);
+                       addEventListener(Event.ENTER_FRAME, 
testSupersAndInterfaces);
+               }
+               
+               private function testSupersAndInterfaces(ev:Event): void
+               {
+                       var beforeTime:int;
+                       var i:int;
+                       const NUM_ITERATIONS:int = 10000000;
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               super.overrideProtectedFunction();
+                       }
+                       log("Super protected: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               super.overrideInternalFunction();
+                       }
+                       log("Super internal: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               super.overridePublicFunction();
+                       }
+                       log("Super public: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               interfaceFunction();
+                       }
+                       log("Interface direct: " + (getTimer()-beforeTime));
+                       
+                       var inter:IInterface = this;
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               inter.interfaceFunction();
+                       }
+                       log("Interface via interface: " + 
(getTimer()-beforeTime));
+                       
+                       var clazz:FunctionPerformanceTest = this;
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               clazz.interfaceFunction();
+                       }
+                       log("Interface via class: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       removeEventListener(Event.ENTER_FRAME, 
testSupersAndInterfaces);
+                       addEventListener(Event.ENTER_FRAME, 
testGettersAndSetters);
+               }
+               
+               private function testGettersAndSetters(ev:Event): void
+               {
+                       var beforeTime:int;
+                       var i:int;
+                       const NUM_ITERATIONS:int = 10000000;
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               privateGetFunction;
+                       }
+                       log("Private Get: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               protectedGetFunction;
+                       }
+                       log("Protected Get: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               internalGetFunction;
+                       }
+                       log("Internal Get: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               publicGetFunction;
+                       }
+                       log("Public Get: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               privateSetFunction = 0;
+                       }
+                       log("Private Set: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               protectedSetFunction = 0;
+                       }
+                       log("Protected Set: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               internalSetFunction = 0;
+                       }
+                       log("Internal Set: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               publicSetFunction = 0;
+                       }
+                       log("Public Set: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       removeEventListener(Event.ENTER_FRAME, 
testGettersAndSetters);
+                       addEventListener(Event.ENTER_FRAME, testFinals);
+               }
+               
+               private function testFinals(ev:Event): void
+               {
+                       var beforeTime:int;
+                       var i:int;
+                       const NUM_ITERATIONS:int = 10000000;
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalPrivateFunction();
+                       }
+                       log("Final Private: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalProtectedFunction();
+                       }
+                       log("Final Protected: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalInternalFunction();
+                       }
+                       log("Final Internal: " + (getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalPublicFunction();
+                       }
+                       log("Final Public: " + (getTimer()-beforeTime));
+                       
+                       log("");
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalOverrideProtectedFunction();
+                       }
+                       log("Final Override protected: " + 
(getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalOverrideInternalFunction();
+                       }
+                       log("Final Override internal: " + 
(getTimer()-beforeTime));
+                       
+                       beforeTime = getTimer();
+                       for (i = 0; i < NUM_ITERATIONS; ++i)
+                       {
+                               finalOverridePublicFunction();
+                       }
+                       log("Final Override public: " + 
(getTimer()-beforeTime));
+                       
+                       removeEventListener(Event.ENTER_FRAME, testFinals);
+               }
+               
+               private function log(msg:*): void
+               {
+                       __logger.appendText(msg + "\n");
+               }
+       }
+}
+function plainFunction(): void {}
+interface IInterface
+{
+       function interfaceFunction(): void;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e43b7a87/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/JPEGEncoder.as
----------------------------------------------------------------------
diff --git 
a/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/JPEGEncoder.as 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/JPEGEncoder.as
new file mode 100644
index 0000000..c3c85cc
--- /dev/null
+++ 
b/FlexPMD/flex-pmd-java/as3-parser/src/test/resources/examples/JPEGEncoder.as
@@ -0,0 +1,669 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package
+{
+       import flash.display.BitmapData;
+       import flash.utils.ByteArray;
+       
+       public final class JPEGEncoder
+       {
+               // Static table initialization
+               private const ZigZag:Vector.<int> = Vector.<int>([
+                       0, 1, 5, 6,14,15,27,28,
+                       2, 4, 7,13,16,26,29,42,
+                       3, 8,12,17,25,30,41,43,
+                       9,11,18,24,31,40,44,53,
+                       10,19,23,32,39,45,52,54,
+                       20,22,33,38,46,51,55,60,
+                       21,34,37,47,50,56,59,61,
+                       35,36,48,49,57,58,62,63
+               ]);
+               private var YTable:Vector.<int> = new Vector.<int>(64, true);
+               private var UVTable:Vector.<int> = new Vector.<int>(64, true);
+               private var outputfDCTQuant:Vector.<int> = new Vector.<int>(64, 
true);
+               private var fdtbl_Y:Vector.<Number> = new Vector.<Number>(64, 
true);
+               private var fdtbl_UV:Vector.<Number> = new Vector.<Number>(64, 
true);
+               private var sf:int;
+               
+               private const aasf:Vector.<Number> = Vector.<Number>([
+                       1.0, 1.387039845, 1.306562965, 1.175875602,
+                       1.0, 0.785694958, 0.541196100, 0.275899379
+               ]);
+               
+               private var YQT:Vector.<int> = Vector.<int>([
+                       16, 11, 10, 16, 24, 40, 51, 61,
+                       12, 12, 14, 19, 26, 58, 60, 55,
+                       14, 13, 16, 24, 40, 57, 69, 56,
+                       14, 17, 22, 29, 51, 87, 80, 62,
+                       18, 22, 37, 56, 68,109,103, 77,
+                       24, 35, 55, 64, 81,104,113, 92,
+                       49, 64, 78, 87,103,121,120,101,
+                       72, 92, 95, 98,112,100,103, 99
+               ]);
+               
+               private const UVQT:Vector.<int> = Vector.<int>([
+                       17, 18, 24, 47, 99, 99, 99, 99,
+                       18, 21, 26, 66, 99, 99, 99, 99,
+                       24, 26, 56, 99, 99, 99, 99, 99,
+                       47, 66, 99, 99, 99, 99, 99, 99,
+                       99, 99, 99, 99, 99, 99, 99, 99,
+                       99, 99, 99, 99, 99, 99, 99, 99,
+                       99, 99, 99, 99, 99, 99, 99, 99,
+                       99, 99, 99, 99, 99, 99, 99, 99
+               ]);
+               
+               private function initQuantTables(sf:int):void
+               {
+                       var i:int;
+                       const I64:int = 64;
+                       const I8:int = 8;
+                       for (i = 0; i < I64; ++i)
+                       {
+                               var t:int = int((YQT[i]*sf+50)*0.01);
+                               if (t < 1) {
+                                       t = 1;
+                               } else if (t > 255) {
+                                       t = 255;
+                               }
+                               YTable[ZigZag[i]] = t;
+                       }
+                       
+                       for (i = 0; i < I64; i++)
+                       {
+                               var u:int = int((UVQT[i]*sf+50)*0.01);
+                               if (u < 1) {
+                                       u = 1;
+                               } else if (u > 255) {
+                                       u = 255;
+                               }
+                               UVTable[ZigZag[i]] = u;
+                       }
+                       i = 0;
+                       for (var row:int = 0; row < I8; ++row)
+                       {
+                               for (var col:int = 0; col < I8; ++col)
+                               {
+                                       fdtbl_Y[i]  = (1 / (YTable [ZigZag[i]] 
* aasf[row] * aasf[col] * I8));
+                                       fdtbl_UV[i] = (1 / (UVTable[ZigZag[i]] 
* aasf[row] * aasf[col] * I8));
+                                       i++;
+                               }
+                       }
+               }
+               
+               private var YDC_HT:Vector.<BitString>;
+               private var UVDC_HT:Vector.<BitString>;
+               private var YAC_HT:Vector.<BitString>;
+               private var UVAC_HT:Vector.<BitString>;
+               
+               private function computeHuffmanTbl(nrcodes:Vector.<int>, 
std_table:Vector.<int>):Vector.<BitString>
+               {
+                       var codevalue:int = 0;
+                       var pos_in_table:int = 0;
+                       var HT:Vector.<BitString> = new Vector.<BitString>(251, 
true);
+                       var bitString:BitString;
+                       for (var k:int=1; k<=16; ++k)
+                       {
+                               for (var j:int=1; j<=nrcodes[k]; ++j)
+                               {
+                                       HT[std_table[pos_in_table]] = bitString 
= new BitString();
+                                       bitString.val = codevalue;
+                                       bitString.len = k;
+                                       pos_in_table++;
+                                       codevalue++;
+                               }
+                               codevalue<<=1;
+                       }
+                       return HT;
+               }
+               
+               private var std_dc_luminance_nrcodes:Vector.<int> = 
Vector.<int>([0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]);
+               private var std_dc_luminance_values:Vector.<int> = 
Vector.<int>([0,1,2,3,4,5,6,7,8,9,10,11]);
+               private var std_ac_luminance_nrcodes:Vector.<int> = 
Vector.<int>([0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]);
+               private var std_ac_luminance_values:Vector.<int> = 
Vector.<int>([0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
+                       0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
+                       0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
+                       0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
+                       0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
+                       0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
+                       0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
+                       0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
+                       0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
+                       0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
+                       0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
+                       0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
+                       0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
+                       0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
+                       0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
+                       0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
+                       0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
+                       0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
+                       0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
+                       0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
+                       0xf9,0xfa]);
+               
+               private var std_dc_chrominance_nrcodes:Vector.<int> = 
Vector.<int>([0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]);
+               private var std_dc_chrominance_values:Vector.<int> = 
Vector.<int>([0,1,2,3,4,5,6,7,8,9,10,11]);
+               private var std_ac_chrominance_nrcodes:Vector.<int> = 
Vector.<int>([0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]);
+               private var std_ac_chrominance_values:Vector.<int> = 
Vector.<int>([0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
+                       0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
+                       0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
+                       0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
+                       0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
+                       0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
+                       0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
+                       0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
+                       0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
+                       0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
+                       0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
+                       0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
+                       0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
+                       0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
+                       0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
+                       0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
+                       0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
+                       0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
+                       0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
+                       0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
+                       0xf9,0xfa
+               ]);
+               
+               private function initHuffmanTbl():void
+               {
+                       YDC_HT = 
computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);
+                       UVDC_HT = 
computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);
+                       YAC_HT = 
computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);
+                       UVAC_HT = 
computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);
+               }
+               
+               private var bitcode:Vector.<BitString> = new 
Vector.<BitString>(65535, true);
+               private var category:Vector.<int> = new Vector.<int>(65535, 
true);
+               
+               private function initCategoryNumber():void
+               {
+                       var nrlower:int = 1;
+                       var nrupper:int = 2;
+                       var bitString:BitString;
+                       const I15:int = 15;
+                       var pos:int;
+                       for (var cat:int=1; cat<=I15; ++cat)
+                       {
+                               //Positive numbers
+                               for (var nr:int=nrlower; nr<nrupper; ++nr)
+                               {
+                                       pos = int(32767+nr);
+                                       category[pos] = cat;
+                                       bitcode[pos] = bitString = new 
BitString();
+                                       bitString.len = cat;
+                                       bitString.val = nr;
+                               }
+                               //Negative numbers
+                               for (var nrneg:int=-(nrupper-1); 
nrneg<=-nrlower; ++nrneg)
+                               {
+                                       pos = int(32767+nrneg);
+                                       category[pos] = cat;
+                                       bitcode[pos] = bitString = new 
BitString();
+                                       bitString.len = cat;
+                                       bitString.val = nrupper-1+nrneg;
+                               }
+                               nrlower <<= 1;
+                               nrupper <<= 1;
+                       }
+               }
+               
+               // IO functions
+               
+               private var byteout:ByteArray;
+               private var bytenew:int = 0;
+               private var bytepos:int = 7;
+               
+               private function writeBits(bs:BitString):void
+               {
+                       var value:int = bs.val;
+                       var posval:int = bs.len-1;
+                       while ( posval >= 0 )
+                       {
+                               if (value & uint(1 << posval) )
+                                       bytenew |= uint(1 << bytepos);
+                               posval--;
+                               bytepos--;
+                               if (bytepos < 0)
+                               {
+                                       if (bytenew == 0xFF)
+                                       {
+                                               byteout.writeByte(0xFF);
+                                               byteout.writeByte(0);
+                                       }
+                                       else byteout.writeByte(bytenew);
+                                       bytepos=7;
+                                       bytenew=0;
+                               }
+                       }
+               }
+               
+               // DCT & quantization core
+               
+               private function fDCTQuant(data:Vector.<Number>, 
fdtbl:Vector.<Number>):Vector.<int>
+               {
+                       /* Pass 1: process rows. */
+                       var dataOff:int=0;
+                       var d0:Number, d1:Number, d2:Number, d3:Number, 
d4:Number, d5:Number, d6:Number, d7:Number;
+                       var i:int;
+                       const I8:int = 8;
+                       const I64:int = 64;
+                       for (i=0; i<I8; ++i)
+                       {       
+                               d0 = data[int(dataOff)];
+                               d1 = data[int(dataOff+1)];
+                               d2 = data[int(dataOff+2)];
+                               d3 = data[int(dataOff+3)];
+                               d4 = data[int(dataOff+4)];
+                               d5 = data[int(dataOff+5)];
+                               d6 = data[int(dataOff+6)];
+                               d7 = data[int(dataOff+7)];
+                               
+                               var tmp0:Number = d0 + d7;
+                               var tmp7:Number = d0 - d7;
+                               var tmp1:Number = d1 + d6;
+                               var tmp6:Number = d1 - d6;
+                               var tmp2:Number = d2 + d5;
+                               var tmp5:Number = d2 - d5;
+                               var tmp3:Number = d3 + d4;
+                               var tmp4:Number = d3 - d4;
+                               
+                               /* Even part */
+                               var tmp10:Number = tmp0 + tmp3; /* phase 2 */
+                               var tmp13:Number = tmp0 - tmp3;
+                               var tmp11:Number = tmp1 + tmp2;
+                               var tmp12:Number = tmp1 - tmp2;
+                               
+                               data[int(dataOff)] = tmp10 + tmp11; /* phase 3 
*/
+                               data[int(dataOff+4)] = tmp10 - tmp11;
+                               
+                               var z1:Number = (tmp12 + tmp13) * 0.707106781; 
/* c4 */
+                               data[int(dataOff+2)] = tmp13 + z1; /* phase 5 */
+                               data[int(dataOff+6)] = tmp13 - z1;
+                               
+                               /* Odd part */
+                               tmp10 = tmp4 + tmp5; /* phase 2 */
+                               tmp11 = tmp5 + tmp6;
+                               tmp12 = tmp6 + tmp7;
+                               
+                               /* The rotator is modified from fig 4-8 to 
avoid extra negations. */
+                               var z5:Number = (tmp10 - tmp12) * 0.382683433; 
/* c6 */
+                               var z2:Number = 0.541196100 * tmp10 + z5; /* 
c2-c6 */
+                               var z4:Number = 1.306562965 * tmp12 + z5; /* 
c2+c6 */
+                               var z3:Number = tmp11 * 0.707106781; /* c4 */
+                               
+                               var z11:Number = tmp7 + z3;     /* phase 5 */
+                               var z13:Number = tmp7 - z3;
+                               
+                               data[int(dataOff+5)] = z13 + z2;        /* 
phase 6 */
+                               data[int(dataOff+3)] = z13 - z2;
+                               data[int(dataOff+1)] = z11 + z4;
+                               data[int(dataOff+7)] = z11 - z4;
+                               
+                               dataOff += 8; /* advance pointer to next row */
+                       }
+                       
+                       /* Pass 2: process columns. */
+                       dataOff = 0;
+                       for (i=0; i<I8; ++i)
+                       {
+                               d0 = data[int(dataOff)];
+                               d1 = data[int(dataOff + 8)];
+                               d2 = data[int(dataOff + 16)];
+                               d3 = data[int(dataOff + 24)];
+                               d4 = data[int(dataOff + 32)];
+                               d5 = data[int(dataOff + 40)];
+                               d6 = data[int(dataOff + 48)];
+                               d7 = data[int(dataOff + 56)];
+                               
+                               var tmp0p2:Number = d0 + d7;
+                               var tmp7p2:Number = d0 - d7;
+                               var tmp1p2:Number = d1 + d6;
+                               var tmp6p2:Number = d1 - d6;
+                               var tmp2p2:Number = d2 + d5;
+                               var tmp5p2:Number = d2 - d5;
+                               var tmp3p2:Number = d3 + d4;
+                               var tmp4p2:Number = d3 - d4;
+                               
+                               /* Even part */
+                               var tmp10p2:Number = tmp0p2 + tmp3p2;   /* 
phase 2 */
+                               var tmp13p2:Number = tmp0p2 - tmp3p2;
+                               var tmp11p2:Number = tmp1p2 + tmp2p2;
+                               var tmp12p2:Number = tmp1p2 - tmp2p2;
+                               
+                               data[int(dataOff)] = tmp10p2 + tmp11p2; /* 
phase 3 */
+                               data[int(dataOff+32)] = tmp10p2 - tmp11p2;
+                               
+                               var z1p2:Number = (tmp12p2 + tmp13p2) * 
0.707106781; /* c4 */
+                               data[int(dataOff+16)] = tmp13p2 + z1p2; /* 
phase 5 */
+                               data[int(dataOff+48)] = tmp13p2 - z1p2;
+                               
+                               /* Odd part */
+                               tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */
+                               tmp11p2 = tmp5p2 + tmp6p2;
+                               tmp12p2 = tmp6p2 + tmp7p2;
+                               
+                               /* The rotator is modified from fig 4-8 to 
avoid extra negations. */
+                               var z5p2:Number = (tmp10p2 - tmp12p2) * 
0.382683433; /* c6 */
+                               var z2p2:Number = 0.541196100 * tmp10p2 + z5p2; 
/* c2-c6 */
+                               var z4p2:Number = 1.306562965 * tmp12p2 + z5p2; 
/* c2+c6 */
+                               var z3p2:Number= tmp11p2 * 0.707106781; /* c4 */
+                               
+                               var z11p2:Number = tmp7p2 + z3p2;       /* 
phase 5 */
+                               var z13p2:Number = tmp7p2 - z3p2;
+                               
+                               data[int(dataOff+40)] = z13p2 + z2p2; /* phase 
6 */
+                               data[int(dataOff+24)] = z13p2 - z2p2;
+                               data[int(dataOff+ 8)] = z11p2 + z4p2;
+                               data[int(dataOff+56)] = z11p2 - z4p2;
+                               
+                               dataOff++; /* advance pointer to next column */
+                       }
+                       
+                       // Quantize/descale the coefficients
+                       var fDCTQuant:Number;
+                       for (i=0; i<I64; ++i)
+                       {
+                               // Apply the quantization and scaling factor & 
Round to nearest integer
+                               fDCTQuant = data[int(i)]*fdtbl[int(i)];
+                               outputfDCTQuant[int(i)] = (fDCTQuant > 0.0) ? 
int(fDCTQuant + 0.5) : int(fDCTQuant - 0.5);
+                       }
+                       return outputfDCTQuant;
+               }
+               
+               // Chunk writing
+               private function writeAPP0():void
+               {
+                       byteout.writeShort(0xFFE0); // marker
+                       byteout.writeShort(16); // length
+                       byteout.writeByte(0x4A); // J
+                       byteout.writeByte(0x46); // F
+                       byteout.writeByte(0x49); // I
+                       byteout.writeByte(0x46); // F
+                       byteout.writeByte(0); // = "JFIF",'\0'
+                       byteout.writeByte(1); // versionhi
+                       byteout.writeByte(1); // versionlo
+                       byteout.writeByte(0); // xyunits
+                       byteout.writeShort(1); // xdensity
+                       byteout.writeShort(1); // ydensity
+                       byteout.writeByte(0); // thumbnwidth
+                       byteout.writeByte(0); // thumbnheight
+               }
+               
+               private function writeSOF0(width:int, height:int):void
+               {
+                       byteout.writeShort(0xFFC0); // marker
+                       byteout.writeShort(17);   // length, truecolor YUV JPG
+                       byteout.writeByte(8);    // precision
+                       byteout.writeShort(height);
+                       byteout.writeShort(width);
+                       byteout.writeByte(3);    // nrofcomponents
+                       byteout.writeByte(1);    // IdY
+                       byteout.writeByte(0x11); // HVY
+                       byteout.writeByte(0);    // QTY
+                       byteout.writeByte(2);    // IdU
+                       byteout.writeByte(0x11); // HVU
+                       byteout.writeByte(1);    // QTU
+                       byteout.writeByte(3);    // IdV
+                       byteout.writeByte(0x11); // HVV
+                       byteout.writeByte(1);    // QTV
+               }
+               
+               private function writeDQT():void
+               {
+                       byteout.writeShort(0xFFDB); // marker
+                       byteout.writeShort(132);           // length
+                       byteout.writeByte(0);
+                       
+                       var i:int;
+                       const I64:int = 64;
+                       for (i=0; i<I64; ++i)
+                               byteout.writeByte(YTable[i]);
+                       
+                       byteout.writeByte(1);
+                       
+                       for (i=0; i<I64; ++i)
+                               byteout.writeByte(UVTable[i]);
+               }
+               
+               private function writeDHT():void
+               {
+                       byteout.writeShort(0xFFC4); // marker
+                       byteout.writeShort(0x01A2); // length
+                       
+                       byteout.writeByte(0); // HTYDCinfo
+                       var i:int;
+                       const I11:int = 11;
+                       const I16:int = 16;
+                       const I161:int = 161;
+                       for (i=0; i<I16; ++i)
+                               
byteout.writeByte(std_dc_luminance_nrcodes[int(i+1)]);
+                       
+                       for (i=0; i<=I11; ++i)
+                               
byteout.writeByte(std_dc_luminance_values[int(i)]);
+                       
+                       byteout.writeByte(0x10); // HTYACinfo
+                       
+                       for (i=0; i<I16; ++i)
+                               
byteout.writeByte(std_ac_luminance_nrcodes[int(i+1)]);
+                       
+                       for (i=0; i<=I161; ++i)
+                               
byteout.writeByte(std_ac_luminance_values[int(i)]);
+                       
+                       byteout.writeByte(1); // HTUDCinfo
+                       
+                       for (i=0; i<I16; ++i)
+                               
byteout.writeByte(std_dc_chrominance_nrcodes[int(i+1)]);
+                       
+                       for (i=0; i<=I11; ++i)
+                               
byteout.writeByte(std_dc_chrominance_values[int(i)]);
+                       
+                       byteout.writeByte(0x11); // HTUACinfo
+                       
+                       for (i=0; i<I16; ++i)
+                               
byteout.writeByte(std_ac_chrominance_nrcodes[int(i+1)]);
+                       
+                       for (i=0; i<=I161; ++i)
+                               
byteout.writeByte(std_ac_chrominance_values[int(i)]);
+               }
+               
+               private function writeSOS():void
+               {
+                       byteout.writeShort(0xFFDA); // marker
+                       byteout.writeShort(12); // length
+                       byteout.writeByte(3); // nrofcomponents
+                       byteout.writeByte(1); // IdY
+                       byteout.writeByte(0); // HTY
+                       byteout.writeByte(2); // IdU
+                       byteout.writeByte(0x11); // HTU
+                       byteout.writeByte(3); // IdV
+                       byteout.writeByte(0x11); // HTV
+                       byteout.writeByte(0); // Ss
+                       byteout.writeByte(0x3f); // Se
+                       byteout.writeByte(0); // Bf
+               }
+               
+               // Core processing
+               internal var DU:Vector.<int> = new Vector.<int>(64, true);
+               
+               private function processDU(CDU:Vector.<Number>, 
fdtbl:Vector.<Number>, DC:Number, HTDC:Vector.<BitString>, 
HTAC:Vector.<BitString>):Number
+               {
+                       var EOB:BitString = HTAC[0x00];
+                       var M16zeroes:BitString = HTAC[0xF0];
+                       var pos:int;
+                       const I16:int = 16;
+                       const I63:int = 63;
+                       const I64:int = 64;
+                       var DU_DCT:Vector.<int> = fDCTQuant(CDU, fdtbl);
+                       //ZigZag reorder
+                       for (var j:int=0;j<I64;++j) {
+                               DU[ZigZag[j]]=DU_DCT[j];
+                       }
+                       var Diff:int = DU[0] - DC; DC = DU[0];
+                       //Encode DC
+                       if (Diff==0) {
+                               writeBits(HTDC[0]); // Diff might be 0
+                       } else {
+                               pos = int(32767+Diff);
+                               writeBits(HTDC[category[pos]]);
+                               writeBits(bitcode[pos]);
+                       }
+                       //Encode ACs
+                       const end0pos:int = 63;
+                       for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {};
+                       //end0pos = first element in reverse order !=0
+                       if ( end0pos == 0) {
+                               writeBits(EOB);
+                               return DC;
+                       }
+                       var i:int = 1;
+                       var lng:int;
+                       while ( i <= end0pos ) {
+                               var startpos:int = i;
+                               for (; (DU[i]==0) && (i<=end0pos); ++i) {}
+                               var nrzeroes:int = i-startpos;
+                               if ( nrzeroes >= I16 ) {
+                                       lng = nrzeroes>>4;
+                                       for (var nrmarker:int=1; nrmarker <= 
lng; ++nrmarker)
+                                               writeBits(M16zeroes);
+                                       nrzeroes = int(nrzeroes&0xF);
+                               }
+                               pos = int(32767+DU[i]);
+                               
writeBits(HTAC[int((nrzeroes<<4)+category[pos])]);
+                               writeBits(bitcode[pos]);
+                               i++;
+                       }
+                       if ( end0pos != I63 ) {
+                               writeBits(EOB);
+                       }
+                       return DC;
+               }
+               
+               private var YDU:Vector.<Number> = new Vector.<Number>(64, true);
+               private var UDU:Vector.<Number> = new Vector.<Number>(64, true);
+               private var VDU:Vector.<Number> = new Vector.<Number>(64, true);
+               
+               private function RGB2YUV(img:BitmapData, xpos:int, 
ypos:int):void
+               {
+                       var pos:int=0;
+                       const I8:int = 8;
+                       for (var y:int=0; y<I8; ++y) {
+                               for (var x:int=0; x<I8; ++x) {
+                                       var P:uint = 
img.getPixel32(xpos+x,ypos+y);
+                                       var R:int = (P>>16)&0xFF;
+                                       var G:int = (P>> 8)&0xFF;
+                                       var B:int = (P    )&0xFF;
+                                       YDU[int(pos)]=((( 0.29900)*R+( 
0.58700)*G+( 0.11400)*B))-0x80;
+                                       
UDU[int(pos)]=(((-0.16874)*R+(-0.33126)*G+( 0.50000)*B));
+                                       VDU[int(pos)]=((( 
0.50000)*R+(-0.41869)*G+(-0.08131)*B));
+                                       ++pos;
+                               }
+                       }
+               }
+               
+               public function JPEGEncoder(quality:int=50)
+               {
+                       if (quality <= 0)
+                               quality = 1;
+                       
+                       if (quality > 100)
+                               quality = 100;
+                       
+                       sf = quality < 50 ? int(5000 / quality) : int(200 - 
(quality<<1));
+                       init();
+               }
+               
+               private function init():void
+               {
+                       ZigZag.fixed = true;
+                       aasf.fixed = true;
+                       YQT.fixed = true;
+                       UVQT.fixed = true;
+                       std_ac_chrominance_nrcodes.fixed = true;
+                       std_ac_chrominance_values.fixed = true;
+                       std_ac_luminance_nrcodes.fixed = true;
+                       std_ac_luminance_values.fixed = true;
+                       std_dc_chrominance_nrcodes.fixed = true;
+                       std_dc_chrominance_values.fixed = true;
+                       std_dc_luminance_nrcodes.fixed = true;
+                       std_dc_luminance_values.fixed = true;
+                       // Create tables
+                       initHuffmanTbl();
+                       initCategoryNumber();
+                       initQuantTables(sf);
+               }
+               
+               public function encode(image:BitmapData):ByteArray
+               {
+                       // Initialize bit writer
+                       byteout = new ByteArray();
+                       
+                       bytenew=0;
+                       bytepos=7;
+                       
+                       // Add JPEG headers
+                       byteout.writeShort(0xFFD8); // SOI
+                       writeAPP0();
+                       writeDQT();
+                       writeSOF0(image.width,image.height);
+                       writeDHT();
+                       writeSOS();
+                       
+                       // Encode 8x8 macroblocks
+                       var DCY:Number=0;
+                       var DCU:Number=0;
+                       var DCV:Number=0;
+                       bytenew=0;
+                       bytepos=7;
+                       
+                       var width:int = image.width;
+                       var height:int = image.height;
+                       
+                       for (var ypos:int=0; ypos<height; ypos+=8)
+                       {
+                               for (var xpos:int=0; xpos<width; xpos+=8)
+                               {
+                                       RGB2YUV(image, xpos, ypos);
+                                       DCY = processDU(YDU, fdtbl_Y, DCY, 
YDC_HT, YAC_HT);
+                                       DCU = processDU(UDU, fdtbl_UV, DCU, 
UVDC_HT, UVAC_HT);
+                                       DCV = processDU(VDU, fdtbl_UV, DCV, 
UVDC_HT, UVAC_HT);
+                               }
+                       }
+                       
+                       // Do the bit alignment of the EOI marker
+                       if ( bytepos >= 0 )
+                       {
+                               var fillbits:BitString = new BitString();
+                               fillbits.len = bytepos+1;
+                               fillbits.val = (1<<(bytepos+1))-1;
+                               writeBits(fillbits);
+                       }
+                       byteout.writeShort(0xFFD9); //EOI
+                       return byteout;
+               }
+       }
+}
+
+final class BitString
+{
+       public var len:int = 0;
+       public var val:int = 0;
+}
\ No newline at end of file

Reply via email to