Erlang Plugin for NetBeans in Scala#5: Structure Analyzer

During the weekend, I've done some preliminary error recover work for Erlang's rats! definition. Now I'll go on some features based on analysis on AST tree. As the simplest step, we'll visit/analyze AST tree to get the structure information, use them for Navigator window and code folding.

First, we need to record the Structure information in some way. Each language has different AST tree and may be generated by varies tools, the AST element should be wrapped in some more generic classes to get integrated into CSL framework. There is an interface "org.netbeans.modules.csl.api.ElementKind", which is used for this purpose. But it's not enough, we need some facilities to not only wrap AST element, and also help us to identify the element as a definition or reference, in which visible scope etc.

I wrote a couple of these facilities when I wrote Erlang/Fortress/Scala plug-ins, these facilities can be repeatedly used for other languages by minor modifying. They are AstItem, AstDfn, AstRef, AstScope, AstRootScope. For Erlang plugin, you can find them under director: erlang.editor/src/org/netbeans/modules/erlang/editor/ast

AstDfn.scala is used to store a definition, such as definitions of class, module, method, variable, attribute etc. AstRef.scala is used to store reference that refers to definition, for example, the usages of a class, a variable, a method call etc.

All these AST items are stored in instances of AstScope.scala, which, is a container to identify the visible scope of references/definitions and store its sub-scopes. There are functions in AstScope to help to identify a variable's visible scope, find the definition of a reference, find references/occurrences of a definition etc.

There should be some lexer level utilities too, to help you get the corresponding tokens when you visit AST tree. It's LexUtil.scala, which will be also heavy used for code-folding, indentation ... features.

With above facilities, we can visit an AST tree now, I'll do the simplest task first: get all functions/attribues name and bounds tokens.

AstNodeVisitor.scala

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 * 
 * Contributor(s):
 * 
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
 */
package org.netbeans.modules.erlang.editor.node

import org.netbeans.api.lexer.{Token, TokenId, TokenHierarchy, TokenSequence}
import org.netbeans.modules.csl.api.ElementKind

import org.netbeans.modules.erlang.editor.ast.{AstDfn, AstItem, AstRef, AstRootScope, AstScope, AstVisitor}
import org.netbeans.modules.erlang.editor.lexer.ErlangTokenId._
import org.netbeans.modules.erlang.editor.lexer.{ErlangTokenId, LexUtil}
import org.openide.filesystems.FileObject

import scala.collection.mutable.ArrayBuffer

import xtc.tree.GNode
import xtc.tree.Node
import xtc.util.Pair

/**
 *
 * @author Caoyuan Deng
 */
class AstNodeVisitor(rootNode:Node, th:TokenHierarchy[_], fo:FileObject) extends AstVisitor(rootNode, th) {

    def visitS(that:GNode) = {
        val formNodes = that.getList(0).iterator
        while(formNodes.hasNext) {
            visitForm(formNodes.next)
        }
    }

    def visitForm(that:GNode) = {
        enter(that)

        val scope = new AstScope(boundsTokens(that))
        rootScope.addScope(scope)

        scopes.push(scope)
        visitNodeOnly(that.getGeneric(0))
        
        exit(that)
        scopes.pop
    }


    def visitAttribute(that:GNode) = {
        that.get(0) match {
            case atomId:GNode =>
                val attr = new AstDfn(that, idToken(idNode(atomId)), scopes.top, ElementKind.ATTRIBUTE, fo)
                rootScope.addDfn(attr)
        }
    }

    def visitFunction(that:GNode) = {
        visitFunctionClauses(that.getGeneric(0))
    }

    def visitFunctionClauses(that:GNode) = {
        val fstClauseNode = that.getGeneric(0)
        visitFunctionClause(fstClauseNode)
    }

    def visitFunctionClause(that:GNode) = {
        val id = idNode(that.getGeneric(0))
        val fun = new AstDfn(that, idToken(id), scopes.top, ElementKind.METHOD, fo)
        rootScope.addDfn(fun)
    }

    def visitRule(that:GNode) = {

    }
}

As you can see, I just visit function/attribute related AST nodes, and gather all function/attribute declarations (or, definitions). My AST tree is generated by rats!, so the code looks like above. If you are using other parsers, I assume you know of course how to travel it.

AstNodeVisitor extends AstVisitor, I wrote some helper methods in AstVisitor.scala, for example, getting the bounds tokens for a definition/scope.

Now, you need to put the AST visiting task to ErlangParser.scala, so, it will be called when parsing finished, and you'll get an AST tree. The code is something like:

    private def analyze(context:Context) :Unit = {
        val doc = LexUtil.document(context.snapshot, false)

        // * we need TokenHierarchy to do anaylzing task
        for (root <- context.root;
             th <- LexUtil.tokenHierarchy(context.snapshot)) {
            // * Due to Token hierarchy will be used in analyzing, should do it in an Read-lock atomic task
            for (x <- doc) {x.readLock}
            try {
                val visitor = new AstNodeVisitor(root, th, context.fo)
                visitor.visit(root)
                context.rootScope = Some(visitor.rootScope)
            } catch {
                case ex:Throwable => ex.printStackTrace
            } finally {
                for (x <- doc) {x.readUnlock}
            }
        }
    }

The rootScope will be carried in ErlangParserResult.scala.

With the visitor's rootScope, we can implement the navigator window and code folding now. What you need is to implement an org.netbeans.modules.csl.api.StructureScanner. My implementation is: ErlangStructureAnalyzer.scala

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 *
 * Contributor(s):
 *
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
 */
package org.netbeans.modules.erlang.editor;

import _root_.java.util.{ArrayList,Collections,HashMap,List,Map,Set,Stack}
import javax.swing.ImageIcon;
import javax.swing.text.{BadLocationException,Document}
import org.netbeans.api.lexer.{Token,TokenId,TokenHierarchy,TokenSequence}
import org.netbeans.editor.{BaseDocument,Utilities}
import org.netbeans.modules.csl.api.{ElementHandle,ElementKind,HtmlFormatter,Modifier,OffsetRange,StructureItem,StructureScanner}
import org.netbeans.modules.csl.api.StructureScanner._
import org.netbeans.modules.csl.spi.ParserResult
import org.netbeans.modules.erlang.editor.ast.{AstDfn,AstRootScope,AstScope}
import org.netbeans.modules.erlang.editor.lexer.{ErlangTokenId,LexUtil}
import org.openide.util.Exceptions

import scala.collection.mutable.ArrayBuffer

/**
 *
 * @author Caoyuan Deng
 */
class ErlangStructureAnalyzer extends StructureScanner {

    override
    def getConfiguration :Configuration = null

    override
    def scan(result:ParserResult) :List[StructureItem] = result match {
        case null => Collections.emptyList[StructureItem]
        case pResult:ErlangParserResult => 
            var items = Collections.emptyList[StructureItem]
            for (rootScope <- pResult.rootScope) {
                items = new ArrayList[StructureItem](rootScope.dfns.size)
                scanTopForms(rootScope, items, pResult)
            }
            items
    }

    private def scanTopForms(scope:AstScope, items:List[StructureItem], pResult:ErlangParserResult) :Unit = {
        for (dfn <- scope.dfns) {
            dfn.getKind match {
                case ElementKind.ATTRIBUTE | ElementKind.METHOD => items.add(new ErlangStructureItem(dfn, pResult))
                case _ =>
            }
            scanTopForms(dfn.bindingScope, items, pResult)
        }
    }

    override
    def folds(result:ParserResult) :Map[String, List[OffsetRange]] = result match {
        case null => Collections.emptyMap[String, List[OffsetRange]]
        case pResult:ErlangParserResult =>
            var folds = Collections.emptyMap[String, List[OffsetRange]]
            for (rootScope <- pResult.rootScope;
                 doc <- LexUtil.document(pResult, true);
                 th <- LexUtil.tokenHierarchy(pResult);
                 ts <- LexUtil.tokenSequence(th, 1)
            ) {
                folds = new HashMap[String, List[OffsetRange]]
                val codefolds = new ArrayList[OffsetRange]
                folds.put("codeblocks", codefolds); // NOI18N

                // * Read-lock due to Token hierarchy use
                doc.readLock

                addCodeFolds(pResult, doc, rootScope.dfns, codefolds)

                var lineCommentStart = 0
                var lineCommentEnd = 0
                var startLineCommentSet = false

                val comments = new Stack[Array[Integer]]
                val blocks = new Stack[Integer]

                while (ts.isValid && ts.moveNext) {
                    val token = ts.token
                    token.id match {
                        case ErlangTokenId.LineComment =>
                            val offset = ts.offset
                            if (!startLineCommentSet) {
                                lineCommentStart = offset
                                startLineCommentSet = true
                            }
                            lineCommentEnd = offset

                        case ErlangTokenId.Case | ErlangTokenId.If | ErlangTokenId.Try | ErlangTokenId.Receive =>
                            val blockStart = ts.offset
                            blocks.push(blockStart)

                            startLineCommentSet = false
                        
                        case ErlangTokenId.End if !blocks.empty =>
                            val blockStart = blocks.pop.asInstanceOf[Int]
                            val blockRange = new OffsetRange(blockStart, ts.offset + token.length)
                            codefolds.add(blockRange)

                            startLineCommentSet = false
                        case _ =>
                            startLineCommentSet = false
                    }
                }

                doc.readUnlock

                try {
                    /** @see GsfFoldManager#addTree() for suitable fold names. */
                    lineCommentEnd = Utilities.getRowEnd(doc, lineCommentEnd)

                    if (Utilities.getRowCount(doc, lineCommentStart, lineCommentEnd) > 1) {
                        val lineCommentsFolds = new ArrayList[OffsetRange];
                        val range = new OffsetRange(lineCommentStart, lineCommentEnd)
                        lineCommentsFolds.add(range)
                        folds.put("comments", lineCommentsFolds) // NOI18N
                    }
                } catch {
                    case ex:BadLocationException => Exceptions.printStackTrace(ex)
                }
            }

            folds
    }

    @throws(classOf[BadLocationException])
    private def addCodeFolds(pResult:ErlangParserResult, doc:BaseDocument, defs:ArrayBuffer[AstDfn], codeblocks:List[OffsetRange]) :Unit = {
        import ElementKind._
       
        for (dfn <- defs) {
            val kind = dfn.getKind
            kind match {
                case FIELD | METHOD | CONSTRUCTOR | CLASS | MODULE | ATTRIBUTE =>
                    var range = dfn.getOffsetRange(pResult)
                    var start = range.getStart
                    // * start the fold at the end of the line behind last non-whitespace, should add 1 to start after "->"
                    start = Utilities.getRowLastNonWhite(doc, start) + 1
                    val end = range.getEnd
                    if (start != -1 && end != -1 && start < end && end <= doc.getLength) {
                        range = new OffsetRange(start, end)
                        codeblocks.add(range)
                    }
                case _ =>
            }
    
            val children = dfn.bindingScope.dfns
            addCodeFolds(pResult, doc, children, codeblocks)
        }
    }

    private class ErlangStructureItem(val dfn:AstDfn, pResult:ParserResult) extends StructureItem {
        import ElementKind._

        override
        def getName :String = dfn.getName

        override
        def getSortText :String = getName

        override
        def getHtml(formatter:HtmlFormatter) :String = {
            dfn.htmlFormat(formatter)
            formatter.getText
        }

        override
        def getElementHandle :ElementHandle = dfn

        override
        def getKind :ElementKind = dfn.getKind
        
        override
        def getModifiers :Set[Modifier] = dfn.getModifiers

        override
        def isLeaf :Boolean = dfn.getKind match {
            case MODULE | CLASS => false
            case CONSTRUCTOR | METHOD | FIELD | VARIABLE | OTHER | PARAMETER | ATTRIBUTE => true
            case _ => true
        }

        override
        def getNestedItems : List[StructureItem] = {
            val nested = dfn.bindingScope.dfns
            if (nested.size > 0) {
                val children = new ArrayList[StructureItem](nested.size)

                for (child <- nested) {
                    child.kind match {
                        case PARAMETER | VARIABLE | OTHER =>
                        case _ => children.add(new ErlangStructureItem(child, pResult))
                    }
                }

                children
            } else Collections.emptyList[StructureItem]
        }

        override
        def getPosition :Long = {
            try {
                LexUtil.tokenHierarchy(pResult) match {
                    case None => 0
                    case Some(th) => dfn.boundsOffset(th)
                }
            } catch {case ex:Exception => 0}
        }

        override
        def getEndPosition :Long = {
            try {
                LexUtil.tokenHierarchy(pResult) match {
                    case None => 0
                    case Some(th) => dfn.boundsEndOffset(th)
                }
            } catch {case ex:Exception => 0}
        }

        override
        def equals(o:Any) :Boolean = o match {
            case null => false
            case x:ErlangStructureItem if dfn.getKind == x.dfn.getKind && getName.equals(x.getName) => true
            case _ => false
        }

        override
        def hashCode :Int = {
            var hash = 7
            hash = (29 * hash) + (if (getName != null) getName.hashCode else 0)
            hash = (29 * hash) + (if (dfn.getKind != null) dfn.getKind.hashCode else 0)
            hash
        }

        override
        def toString = getName

        override
        def getCustomIcon :ImageIcon = null
    }
}

Which just travels the rootScope, fetches AstDfn's instances and wrap them to ErlangStructureItem.

The last step is register this structure analyzer to ErlangLanguage.Scala as usual:

    override
    def hasStructureScanner = true

    override
    def getStructureScanner = new ErlangStructureAnalyzer

For structure analyzer, you need also to register it in layer.xml:

    <folder name="CslPlugins">
        <folder name="text">
            <folder name="x-erlang">
                <file name="language.instance">
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.erlang.editor.ErlangLanguage"/>
                </file>
                <file name="structure.instance">
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.erlang.editor.ErlangStructureAnalyzer"/>
                </file>
            </folder>
        </folder>
    </folder>

Build and run, now open a .erl file, you got:

Click on the picture to enlarge it

nn

The functions/attributes are shown in the left-side navigator window now, there are also some code-folding marks. Did you notice my preliminaty error-recover work? :-)

Comments

1. dre beats outlet -- 2012-03-23 07:14

Request Beats http://www.studiobeatsoutlet.com/ Beats By Dre By Dre everyone in a committed long-term union for the secret of their good results. Virtually http://www.studiobeatsoutlet.com/ Custom Beats By Dre always, among the best three factors cited will be the ability to giggle with each other. Regardless of how significant the challenges, http://www.studiobeatsoutlet.com/ Beats Studio or how quite a few the obstructions, they are going to be most successfully approached having a feeling of humor plus the teamwork that emerges from shared laughter and also a mutually optimistic outlook. http://www.studiobeatsoutlet.com/ Beats Outlet Online Though some fun http://www.studiobeatsoutlet.com/ beats outlet Beats By Dre expenses funds: an amusement park, a fine meal out, a visit to Vegas, or that hilarious http://www.studiobeatsoutlet.com/dre-beats-studios-c-2.html cheap beats headphones new film, there are lots of entertaining actions that dont cost a dime. Give your companion the present or getting a slave for a week, such as the requisite grasp or mistress verbiage, pulling your forelock, bowing or curtseying, http://www.studiobeatsoutlet.com/dre-beats-pro-c-1.html Cheap Beats Headphone and backing out from the space. The outcomes is usually quite amusing, particularly if carried into community or in front with the youngsters. http://www.studiobeatsoutlet.com/ beats outlet Both of you call in http://www.studiobeatsoutlet.com/heartbeats-lady-gaga-c-6.html monster beats sale ill to operate and play hooky - hang out at the mall like truant high http://www.studiobeatsoutlet.com/dre-beats-pro-c-1.html cheap beats pro school sophomores. Devote some time coming up with completely outrageous excuses which you know you can never ever have the ability to provide using a straight face. If it is summer time, wash the car, and each other, in the driveway. http://www.studiobeatsoutlet.com/ custom studio beats dr dre If its winter season, possess a snowball battle or walk within the rain. Stroll alongside the beach or in the hills or stroll via town window buying. View tv collectively: http://www.studiobeatsoutlet.com/ cheap beats outlet not the dreary news but old Seinfeld or Lucy reruns that are just as funny as when they http://www.studiobeatsoutlet.com/dre-beats-studios-c-2.html beats headphones studio were made. Search out joke internet sites online or spend some time in the drugstore just looking at humorous greeting cards. Tell tales about things that occurred to you prior to you met and reminisce concerning the fun occasions youve had given that you very first grew to become an product. http://www.studiobeatsoutlet.com/dre-beats-studios-headphones-detox-black-p-6.html tour beats ear adapter

2. Discount Christian Louboutin outlet online 2012 -- 2012-03-27 08:30

Every fashion season has its own trends in accessories as well. When we are talking accessories, it is not only handbags and belt. One of the most important accessories for women is shoes. Of course, for men it is too but the styles and designs which are present for women far exceed the limited range of styles that men shoes usually have.http://www.salechristianlouboutinheel.com Christian Louboutin is one name to reckon with when it comes to fashionable shoes.

http://www.salechristianlouboutinheel.com

3. Discount Louis Vuitton -- 2012-03-27 08:31

Louis Vuitton handbags are renowned for their excellence in style and exquisiteness in worth. A large number of people all hunger for transporting such good handbag. A wide variety of cheap Louis Vuitton handbags are released in the market, which to some extent serve the demands of many individuals who dont want to shell out a big fortune. Those cheap Louis Vuitton handbags are copied handbags from your genuine Louis Vuitton totes. Although they are these reproductions, yet the feel, the look and the workmanship of people cheap Louis Vuitton handbags look like those on the original ones. http://www.discountlvhandbagsoutlet.com

4. coach factory outlet -- 2012-03-31 05:42

No one can deny the shopping at the coach factory outlet is satisfactory. For the low prices and good quality.Over the years, coach factory online has added a multitude of new handbag shapes, styles and materials to their collection. However, the highest care is taken that every Coach handbags is both aesthetically beautiful and functional.Many fashionable women match with practical Coach Purses which will make the street shopping become relaxed,and make every person can enjoy more diversiform combination in coach factory outlet online.

http://www.ccoachfactoryoutlet.com

5. louis vuitton sale -- 2012-03-31 05:43

Don't feel upset, there will be a great conversion to this kind of situation because there are a large number of louis vuitton sale now!louis vuitton outlet,welcome to buy urban louis vuitton on our online shop.discount price is our special offer, durability and high quality is our promise.louis vuitton Outlets offer famous classic brand for LV,Channel, with perfect service.So become to the VIP soon.They offer more new styles,like LV purses,LV wallets etc. And are tested by product quality monitoring center .

http://www.louisvuittonoutletsaleo.com

6. coach outlet online -- 2012-03-31 05:43

Turn your attention to such discount coach sneakers for women from coach outlet online, you will find something unique and special of such authentic coach for sale at coach factory outlet store online.coach outlet store sells goods that are constructed to meet the highest standards of quality and functionality.You can trust it 100 percent.coach outlet has become a popular shopping experience for consumers around the world, and a desirable distribution channel for manufacturer's and retailers.

http://www.coachoutletonlinesl.com

7. louis vuitton uk -- 2012-03-31 05:55

Our online store offers you discounted Designer louis vuitton replica wallet at present. You could find them in desirable quality and price. If you don't mind high class louis vuitton uk, have a good time here.These is the first time your visit our louis vuit Louis vuitton online shop ,welcome.

http://www.louisvuittonukk.org.uk

8. louis vuitton outlet -- 2012-03-31 05:57

any louis vuitton outlet New backpack features usa a function grownup overall look. Varied piece allows that it is captivated me within the approve and also further than your body.It’s induced by way of severe hardworking liver diseases, and also the most familiar factors behind constant louis vuitton bags outlet hard working liver disorder usually are excessive drinking and also liver disease Chemical.Ladies have an ardent love for the Louis Vuitton handbags outlet because Louis Vuitton enjoys a worldwide reputation of high quality and fashionable designs.

http://www.louisvuittonoutletbagsc.com

9. coach outlet store online -- 2012-03-31 05:57

coach outlet store online marketed properly all greater compared to earth and earn cozy praise from customers. They are made from the finest leather and fabric.coach outlet store have Coach handbags,Coach Shoulder Bags,Coach Briefcases and so on,these bags are so perfectly reproduced,you won't even be able to tell the difference!Coach Outlet Online Store would dynamically change your overall styles right away. The amazing knack about the unique coach handbag is that it would never disappoint your individual styles at all. Rather, it would instantly change your ultimate fashions in a remarkable manner.

http://www.coachoutletstoreonlineeo.com

10. Louis Vuitton Handbags -- 2012-04-15 06:48

Welcome to order Discount Louis Vuitton UK and lead a fashionable, luxury and elegant life from our Louis Vuitton Canada Outlet Store. Enjoy the shopping now here! The Louis Vuitton Handbags are amazing and you will rest assured by proudly owning a bed that you will find yourself envied by simply your colleagues. Louis Vuitton Store Online Handbags can also bring great accuracy as well as practical applicability and fashionable.

http://www.uk-louisvuittonhandbags.co.uk

11. chistian louboutin uk -- 2012-04-18 01:02
12. louis vuitton uk -- 2012-04-18 01:13
13. mulberry outlet uk -- 2012-04-18 01:20
14. cheap air max shoes -- 2012-04-25 03:02

BRANDON,ROYSG,http://www.cheapair-maxshoes.com Portland Trail BlazersAge?: 272010-11 nike air

max store Stats: 12.2 PPG, 40.0 FG%, 33.3 3PT%, 2.6 RPG, 2.7 APGYup, http://www.cheapair-

maxshoes.com I’m using the last spot as a http://www.nikeair-max1.com giant metaphorical

shoulder http://www.airmaxshoestrack.com shrug, because no one could have any air max 2012

reasonable idea where to rank Roy at this point. This seems like a fair compromise for air

max 2009 a guy whose 2011-12 season could fall http://www.airmax2011sports.com anywhere from

“sits out the entire year after feeling cheap air max knee pain in the first game” to

“single-handedly air max 90 wins a postseason game.”

15. anonymous -- 2012-09-17 02:40

<p>Gone through this time of travel, after witnessing Du Li heroic sacrifice things, six cloud has strong feelings, so I let him to a quiet a quiet, calm and then back to the Yi Park, continue to practice<a href= " http://www.cheapairmaxes.org/ " title= " Cheap Air Max " ><strong>Cheap Air Max</strong></a> Hyun Yuzhen people heard this, saw the the Hao cloud lay a, with pity in his eyes, could not help but sigh loudly. Looked away, saw a crowd, mysterious Yuzhen humanity: What if one would say, let's go. Yi Tin House, the crowd gathered to begin once a ghost town trip. Previous Soul Liu has been said about the experience of that group, then changed Ziyang real narrative six cloud a pedestrian encounter things. Narrative, Ziyang, in addition to conceal a secret outside of the six cloud body, all other things intact hearts out, to hear other people have not experienced, my heart was shocked. The ghost town known as three of seven of the most dangerous regions, from Ziyang real words, you can clearly hear some. when after listening to live Ziyang described, , all eyes have stayed in the Soul Liu who, in his eyes, his mouth a bit cold. With Ziyang real narrative, all the personnel understand the previous Soul Liu called for world peace, it is no longer so convincing. The hypocrisy of the Soul Liu lips do not say, but his face is obviously shown. the mysterious Yuzhen a look Weileng said: cold Ka Ho, two the Confucian Park Du force. Although this task is completed, but we paid a heavy price, which is the need to keep in mind in order to express the commemoration of the two outstanding disciples, we have that a ghost town at the exit carved two stone to commemorate the deeds of the two, to promote righteousness. displeasure, and even the School of Sword of the two brood. At this point, listen to the mysterious Yuzhen people, saying, Although we can not say anything, but his face is very ugly. Soul Liu see people look unhappy, know own two difficult to stay for long, are not whispered: , ghost town, the door is closed, then we are here to also be completed now nothing we need to help, as we start to leave in the future there is anything in need of help, Xuan Yu Zhang taught and then notify the it wants to. looked at the back of two mysterious Yuzhen cold: I far sent. Report Error turned out to be such people, as to the destination without regard for the meaning of the fellow, fame and fortune of the heart is too heavy a pity that in the future something best not with him together, otherwise I am afraid his mercy. party. sword hospital that day, although dead, one person, but they get back sealing the soul breaks, which makes them in front of others, you can swagger, triumphantly. process of which we do not say a single on the results that is We can not change things. sealing the soul breaks that sword clean retrieve this point no one can erase the facts. Well, we still would not talk of these sad things to chat about other things.</p>

16. anonymous -- 2012-09-19 02:47

towards <a href='http://www.officiallmichaelkorsoutlets.com'><strong>Michael Kors Outlet</strong></a>their captive <a href='http://www.2012todsshoesoutlet.com'><strong>Tods Shoes</strong></a>enemies. <a href='http://www.2012todsshoesoutlet.com'><strong>Tods Outlet</strong></a>The following <a href='http://www.2012todsshoesoutlet.com'><strong>Tods Online</strong></a>circumstance, <a href='http://www.2012todsshoesoutlet.com'><strong>Tods Shoes Sale</strong></a>as related <a href='http://www.2012todsshoesoutlet.com'><strong>Tods Online Store</strong></a>to me by an <a href='http://www.beatsbydrdreoutletonline.com'><strong>Beats By Dre Cheap</strong></a>Indian woman<a href='http://www.beatsbydrdreoutletonline.com'><strong>Cheap Beats By Dre</strong></a>, whom I married to <a href='http://www.beatsbydrdreoutletonline.com'><strong>Discount Beats By Dre</strong></a>one of the principal settlers

17. longchamp outlet -- 2012-09-24 01:13

Yesterday in the Hankou Railway Station, http://www.longchampsoutletwholesales.com the first one to buy a men's Zheng Wu high-speed rail tickets. This reporter has learned, he called Zou Chang Jian, http://www.longchampsoutletwholesales.com intends to 28 by Zheng Wu high-speed rail travel to Zhengzhou. He said that by the first group of http://www.longchampsoutletwholesales.com high-speed rail to Zhengzhou, vacated more time for travel.

18. True Religion Jeans Outlet -- 2012-10-11 06:04

Serums and mild hair sprays square measure currently turning into one among the foremost essential beauty merchandise. If you've got long hair, you wish a product that http://www.truereligionjeansoutlet-onsale.com/ True Religion Outlet controls the kink up and keeps long hair stunning and glossy. girls with crisp hair may like a reliable product to take care of the curls and convey out nice volume and bounce. you'll use your Parlux http://clarisonicmia.brushstore0o.com/ Clarisonic Outlet hand blower reception, then bring a hair blood serum or mild spray for a fast fix.

19. anonymous -- 2012-10-12 01:17

Welcome!Coach Outlet Store are loved by many people,when you walk in the street, you could see many people take Coach Shoulder Bags styles.

Coach Factory http://coachfactoryoutlet.1uxury--best.com

Coach Factory Outlet http://www.coachfactoryoutletcd.com

Coach Outlet Store http://www.coachoutletstoreusac.com

Coach Outlet http://www.coachoutletonlinecss.com

21. carpet cleaning in vancouver bc -- 2012-11-20 02:37

Java is a programming language used prominently to develop Web and mobile applications. You can edit the border layout properties of your application in netBeans by using the Inspector panel. Thanks. Regards, http://www.armanexpert.com

22. North faceOutlet Locations -- 2012-11-28 02:55

About two weeks ago, the Palestinian Ramallah, http://www.northfaceoutletlocationsv.com/ Arafat cemetery before the people in the light of the candles to commemorate the eighth anniversary of Arafat's death anniversary. Noon today, the quiet here the roar of the excavator to break.

23. anonymous -- 2012-12-13 05:50
24. anonymous -- 2013-01-24 01:47

Sant Ritz has full and unique facilities, which includes a guard house, clubhouse, children's playground, swimming pool, Aerobic/Yoga? room, piano room, pool room, indoor gym, hydrotherapy beds, hydrotherapy baths, reading room, function room, onsen, jacuzzi.

25. anonymous -- 2013-02-15 09:59
26. turbotax 2012 download -- 2013-03-02 05:28

Phone headset in <a href="http://www.beatswirelessheadphones.info/">beats wireless headphones</a> general headphones,<a href="http://www.turbotax-2012.com/">turbotax 2012</a> ear plugs, ear hook and bone conduction headphones. Earplugs are headphones <a href="http://www.quicken-2013-download.com/">quicken 2013 download</a> Development the revolutionary sudden small volume makes outside use very convenient. Due to the development of human technology, in order to allow people to enjoy <a href="http://www.turbotax-2012.org/">turbotax 2012</a>a better quality of audio small fruit is ear earplugs ear plugs a <a href="http://www.quicken-2013.com/">quicken 2013</a>breakthrough, more suitable in outdoor use. <a href="http://www.beatsaudioearbuds.info/">beats audio ear buds</a> Headphones and earplugs ear hook can be regarded as an intermediate product, <a href="http://www.turbotax-2011.com/">turbotax 2011</a> the earhook characteristics and the headphones and earplugs advantages and disadvantages, a class <a href="http://www.downloadquicken2013.com/">download quicken 2013</a> of product features are not very clear, however, wear it, the ear hook is <a href="http://www.turbotaxdownload2012.com/">turbotax download</a> very pretty. Bone conduction headset is relatively new technology, the use of <a href="http://www.turbotax-2012-download.com/">turbotax 2012 download</a> vibration to the principles of sound through the <a href="http://www.turbotax2012-download.com/">turbotax 2012 download</a> skull directly transmitted <a href="http://www.turbotax2012cheap.com/">turbotax 2012</a> to the listening Hub.

27. Cheap Toms -- 2013-03-20 09:21

the ove to attend Senior Bowl workouts this week in Mobile, Ala., and to begin work on free agency. In his own statement, Payton http://www.tomsshoesonsaleforcheap.com/ reiterated that he and Loomis took full responsibility

28. hotel in delhi -- 2013-04-04 10:45
29. jacklavoro@… -- 2013-04-09 08:59

Thank you for another important article. Where else can you get this information in a comprehensive way of writing? It took me a week, and I am looking for information. ads dating

30. anonymous -- 2013-04-15 14:19

Its all good its being stable and working really nicely here.

I've found a couple of bugs though, is there a place to report them?

Anyway, I was just popping on mainly to say thanks! Your work is making a huge difference to a lot of people, myself included. We are very much in awe of what you have got going.

sito incontri

31. anonymous -- 2013-04-17 12:14

Future residents are within a short driving distance to Ang Ko Kio Hub and Compass Point. With such a short drive to the city area as well as the orchard and bugis area, entertainment for your love ones and family will come at a stone’s throw away. Belgravia Villas

32. anonymous -- 2013-04-22 11:24

Several buses are available near Ecopolitan EC along with shopping centers and restaurants. Ecopolitan EC is also near Waterway Point, the shopping, dining and entertainment hub which is scheduled to open in 2 years time. Also, it is right beside Punggol Waterfront. Entertainment for your loved ones and friends are therefore at your fingertips with the full condo facilities as well as the amenities near Ecopolitan EC. Ecopolitan

33. anonymous -- 2013-04-26 12:58

I really like this blog, you are very good making them. bakekaincontri milano

34. anonymous -- 2013-05-02 12:20

bsolutely fantastic posting! Lots of useful information and inspiration, both of which we all need!Relay appreciate your work.

Bakekaincontri Verona

35. jacklavoro2@… -- 2013-05-02 14:28

I really loved reading your blog. It was very well authored and easy to understand. Unlike additional blogs I have read which are really not good. Parola Chiave

36. micheledigioia2@… -- 2013-05-02 14:29

Thank you for another important article. Where else can you get this information in a comprehensive way of writing? It took me a week, and I am looking for information. Bakekaincontri Treviso

37. anonymous -- 2013-05-03 07:00

I have always believed that investments in Hillview Peak condo and condominiums is always a better choice than any other forms of investment. Not only can the investor leverage on his investment, he can always stay in the unit should he decide not to rent out the unit. Investing in stocks, gold etc has really no tangible benefits on your investment. Thats just my 2 cents thought though. Thank you author for the informative writeup. Hillview Peak

38. anonymous -- 2013-05-13 08:26

Future residents will be able to access the development via Buangkok MRT which is just next to it. Also, nature awaits your family and friends at the nearby Punggol Park. Also, the ultimate nature awaits you at the Sengkang Riverside Park. Jewel at Buangkok

39. anonymous -- 2013-05-14 04:09

J Gateway has full and unique facilities, which includes a guard house, clubhouse, children's playground, swimming pool, Aerobic/Yoga? room, piano room, pool room, indoor gym, hydrotherapy beds, hydrotherapy baths, reading room, function room, onsen, jacuzzi. J Gateway

40. Jaharashik -- 2013-05-23 14:56

All here must use this plugin ! it's so recommended Berita Unik

41. times dating -- 2013-05-27 14:13

You share nice information. Write article beautiful and article writing level is very good easily understand to anyone who can read your article and that increase my knowledge. times dating

42. anonymous -- 2013-05-27 14:34

I really like this blog, you are very good making them. times dating

43. anonymous -- 2013-05-29 02:50

Thanks for sharing with us some ideas about Erlang Plugin for NetBeans in Scala#5: Structure Analyzer. It's really a great honor to read your article.

<a href="http://thecoralsatkeppelbay.org">Corals At Keppel Bay</a> <a href="http://d-pristine.com">D'pristine</a>

44. anonymous -- 2013-05-31 01:59

Coral Edge Residences will be accessible with Punggol MRT Station as well as Punggol Bus Interchange. It is also right beside Tampines Expressway(TPE). Coral Edge Residences is also near to Marina Country Club, Sengkang Riverside Park and Sheng Siong hypermart in Punggol Central. Thx Coral Edge Residence

45. d'pristine -- 2013-06-02 08:32

Thanks for the structure information that you have shared with me it is really clear. I am glad that I have read your post. Thanks! <a href="http://www.youtube.com/watch?v=Ht0qPpyfGX8">D'pristine</a>

46. anonymous -- 2013-06-04 01:15

The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Bugis. Several buses are available near Rocher Road and Beach Road along with shopping centers and restaurants. DUO Residences

47. anonymous -- 2013-06-09 11:26

Bartley Ridge will be accessible via Bartley MRT station on the Circle Line. Commuting to Toa Payoh and Paya Lebar area as well as the city area is therefore very convenient. It is also near to many eateries along the Upper Serangoon area as well as NEX shopping mall. Bartley Ridge

48. anonymous -- 2013-06-14 01:53

Lush Acres EC has full and unique facilities, which includes a guard house, clubhouse, Function Room & Indoor Gym Tennis Court, 50m Freeform Pool Pool Deck, Wading Pool, Splash Pool & Family Pool Jacuzzi & Hydro Spa, BBQ Area Dining and Play Fountain, Fitness Alcove & Children’s Playground and Garden Trail. Lush Acres

49. anonymous -- 2013-06-21 05:36

Several buses are available near Forestville EC along with shopping centers and restaurants. Forestville EC is also near Causeway Point as well as Woodlands Waterfront. Entertainment for your loved ones and friends are therefore at your fingertips with the full condo facilities as well as the amenities near Forestville EC. Forestville EC will be accessible with Woodlands MRT station & Admiralty MRT station. It is also near to Vista Point Shopping Mall, Causeway Point Shopping Mall, Cold Storage, Shop N Save, and many more. Forestville EC

51. anonymous -- 2013-07-02 02:03

The condo’s facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Bartley. Kensington Square

52. anonymous -- 2013-07-08 05:14

Skypark Residences will be accessible with Sembawang MRT station & Sembawang Bus Interchange. It is also near to Vista Point Shopping Mall, Causeway Point Shopping Mall, Cold Storage, Shop N Save, and many more. Skypark Residences

53. anonymous -- 2013-07-09 08:14

rare freehold condo. must check it out at Tembusu Tembusu Condo Tembusu Condominium Tembusu at Kovan

54. anonymous -- 2013-07-12 06:01

Sea Horizon EC facilities provide full family entertainment needs for your family and loved ones. Indulge in a serene and tranquil lifestyle right in the heart of Pasir Ris. Sea Horizon

55. anonymous -- 2013-07-13 09:04

Entertainment for your loved ones and friends is therefore at your fingertips with the full condo facilities as well as the amenities near The Glades. The Glades condo

56. osirmione2@… -- 2013-07-18 12:01

I have to say that the information here was the most complete that I found anywhere. I am definitely bookmarking this to come back and read later. Corso web design Bologna

57. anonymous -- 2013-07-18 12:43

I found your website perfect for my needs. It contains wonderful and helpful posts.

corso inglese bologna

58. Pasir Ris EC -- 2013-07-26 01:59

A wonderful and unique lifestyle awaits you. Please see Sea Horizon EC project details and units available for more information. Sea Horizon

59. waterwoods ec -- 2013-07-30 05:21

Waterwoods is a 99-year leasehold executive condominium development located at Punggol Field Walk, along Punggol East in District 19. It is estimated to house 435 residential units. Waterwoods is situated just 5minutes walk away from the Coral Edge LRT Station (PE3) and Punggol Plaza. waterwoods executive condo

60. skypark residences -- 2013-07-30 05:22

When it comes to education, SkyPark? Residences EC residents with school going children have good schools in the neighbourhood such as Sembawang Primary School, Canberra Primary School, Wellington Primary School. skypark residences sembawang

61. sea horizon ec pasir ris -- 2013-07-30 05:23

Sea Horizon is a new executive condominium located at Pasir Ris Drive 3/Pasir Ris Rise, it consist of 580 units (Estimated) of various room types and sizes to fit a young couple, families with children and multi generation families. sea horizon ec pasir ris

62. new building by som -- 2013-07-30 06:17

I am hoping the same high-grade blog post from you in the upcoming as well. In fact your impressive writing abilities has inspired me a lot to get my own blog. Thanks! http://guocolandtp180.orghttp://www.youtube.com/watch?v=Lu4IUfW2qK4

64. myonlinepaydayloancash24h -- 2013-09-06 07:20

You done certain exceptional focuses there. I did a pursuit on the subject and discovered practically all persons will concur with your site. http://myonlinepaydayloancash24h.com/

65. perthsmallbusinessmeetup -- 2013-09-06 07:20

You did superb work your post is marvelous its expand my knowledge.the post is best i can never read previously this sort of post delightful imparting. http://www.perthsmallbusinessmeetup.com/

66. arizonacriminallawsexcrimes -- 2013-09-06 07:21

I might want to thank you for the exertions you have invested thinking of this blog journal. http://www.arizonacriminallawsexcrimes.com/

67. neweducationissues -- 2013-09-06 07:21

I am intrigued by this topic and might want to investigate out some more data.. Cheers! to you! http://www.neweducationissues.net/

68. amcordesignnyc@… -- 2013-09-13 04:16

I hope you are planning to write more articles like this. I want to read more on your thoughts since they are much like mine.*mens diamond jewelry

69. Bambang -- 2013-09-24 06:54

I am so much excited after reading your blog. Your blog is very much innovative and much helpful for any industry as well as for person. seo services

70. Widodo -- 2013-09-26 05:42

Nice post, It's really interesting. I will be referring a lot of friends about this. Thank for Sharing. sewa mobil solo

71. anonymous -- 2013-10-07 08:46

Several buses are available near The Hillford Condo along with shopping centers and restaurants. The Hillford Condo is also near to Bukit Gombak Stadium and Bukit Batok Golf Range. The Hillford

72. anonymous -- 2013-10-09 00:02

Also, it is right beside Jurong Stadium as well as the Jurong Archery Club. Entertainment for your loved ones and friends are therefore at your fingertips with the full condo facilities as well as the amenities near Jurong West Condo. Jurong West New Condo MCL Land

73. anonymous -- 2013-10-15 18:30

You've done well for yourself with this wonderful post. I must say, do you update your blog post frequently? It's been a tremendous pleasure to read what you had to write here. seo company

74. anonymous -- 2013-11-06 07:16

Different breed of dogs also require different shampoo and conditioners . Some shampoos are only fit for larger breed of dogs wherelse others are only fit for small breeds like the Chi hua hua. http://dog-grooming.org

75. anonymous -- 2013-11-23 06:45

Several buses are available near Riverbank at Fernvale along with shopping centers and restaurants. Riverbank at Fernvale is also near Waterway Point, the shopping, dining and entertainment hub which is scheduled to open in 2 years time. Also, it is right beside Punggol Waterfront. Entertainment for your loved ones and friends are therefore at your fingertips with the full condo facilities as well as the amenities near Riverbank at Fernvale. Sengkang West way condo by UOL