Maharashtra Public Service Commission published notification for Subordinate Services vacancies. Interested & eligible candidates can read Notification & Apply online before the last date at https://mahampsc.mahaonline.gov.in/.
JOB TITLE Maharashtra Subordinate Services Non-Gazetted, Group-B Preliminary Examination 2019.
2. Check latest advertisements you will find MPSC Subordinate Services Notification.
3. There you will find online application form Subordinate Services and with PDF notification, Click on Apply.
4. Fill up your basic details (Education, contact details) for requirement of MPSC Subordinate Services.
5. Pay the fee online / Offline & Upload documents Photo, Signature, and Finalize & Confirm MPSC Subordinate Services Application process.
Enter your Subordinate Services Exam application Login details or Application number & DOB.
Finally, view The MPSC Subordinate Services Admit Card 2019 and verify the following details.
Details to verify on the MPSC Subordinate Services exam Admit Card?
Verify the MPSC Subordinate Services examination center along with your photo & signatures.
Don't' forget to check your name & father name on MPSC Subordinate Services Admit Card.
Carry a valid Photo ID for MPSC Subordinate Services Exam 2019.
MPSC Subordinate Services Exam date (tentative) >> Tentatively scheduled on – or within 15-30 days after the admit card release.
How to Check MPSC Subordinate Services Results 2019?
Official MPSC Subordinate Services Results Available on. https://mahampsc.mahaonline.gov.in/.
Enter your Subordinate Services exam Application Login details (Application number / DOB).
Finally, view The MPSC Subordinate Services Results 2019 and verify the following details.
Details to verify on the Subordinate Services exam Results?
Don't' forget to check your name & father name on MPSC Subordinate Services Results.
Read instructions carefully printed backside of the Subordinate Services Results 2019.
MPSC Subordinate Services Results release date (tentative) >> Available soon.


text:
Miseries & Misfortunes returns with a revised Second Edition
1648. Paris, France. The endless War of the Counter-Reformation lumbers through another bitter winter in the shattered remains of the Holy Roman Empire. The armies of the Spanish Hapsburgs encircle the kingdom of France to the south, east and north. The king is dead but the Boy King is not yet of age. Queen Anne and her able prime minister, Cardinal Mazarin, do all in their power to keep France alive, but the specter of raising more taxes and selling more offices to fund this generational war has Parlement wagging their beards, and the menu peuple threatening to revolt. Thus the ancient capital convulses with frustration and fury once more.
You step into this world poor, untested but ready to make your mark. Will you ply your blade as an agent of the Cardinal? Will you resist the royal will as Frondeur? Will you seek to profit from the chaos as a merchant adventurer? Whatever you chose, you will spend your very life to achieve your aims.
Miseries & Misfortunes is a roleplaying game for three to five players. A complete game, it adds lifepaths, skills, social combat and the eternal search for truth to the foundation begun by Basic Edition Dungeons & Dragons.
The revised Second Edition includes two 5.5 x 8.5" softcover booklets.
Book 1: Roleplaying in 1648
Rules for playing historical and novel moments in France 1648.
Book 2: Les Fruits Malheureux
Rules for creating unhappy and unlucky unfortunates in France 1648.
[Original Zine] Miseries & Misfortunes
Miseries & Misfortunes Book 5 (Homage to Catalonia)
Miseries & Misfortunes Book 4 (Plus de Misères)

redpajama_set_name: RedPajamaCommonCrawl


Who is more important: you or a group of your fellow nonprofit volunteers or professionals? What signal are you sending when you direct your attention to your mobile device instead of the group's discussion? If you believe the work of the organization or institution is unimportant, say so and work with your peers to restructure meetings. If not, give your attention to the business at hand. Each of you has carved out time from your busy schedules to attend the meeting: make the most of it.
For many, time is now considered a resource even more valuable than money. Increasing demands on our time from work, family and volunteer commitments make it all the more important that time allocated for meetings be most productive. As nonprofit professionals are asked to take on more responsibilities the time dedicated to staff meetings becomes even more valuable. Checking your mobile device removes your attention from the discussion at hand. Your knowledge, expertise and insights are removed from the conversation. The opportunity for synergistic thinking, problem solving and strategizing diminishes as participants mentally enter and leave the group's work with a glance at their device.
And then there's hurt feelings. Some people are offended when they are talking and others are texting or checking email. The sentiment can be, "Why should I bother if they aren't interested?" The result can be a process of gradual or immediate disengagement.
Observe your behavior and that of others in the next meeting you attend. How often do people check their devices? What is accomplished in the meeting? Ask reflective questions of yourself and others in the room: are our meetings boring? Too long? Are they structured to take advantage of the best thinking in the room? Are people coming prepared to meetings? When are people checking their devices and does that correlate to the discussion at hand?
Make sure your meetings are worthy of the time you ask each person to give. Develop a protocol for the use of mobile devices. One corporate board asks members to place devices in a basket upon entering the meeting, and provides breaks for the purpose of checking calls and messages. Your nonprofit is as important as a corporate board. Reach agreement regarding the use of devices and hold each other accountable. Remind people of the policy when meetings are being scheduled, and again at the beginning of each meeting.
You can use mobile devices to help advance the organizations you are involved with. Engaging and updating friends, colleagues, donors and supporters via Facebook, twitter, LinkedIn, Pinterest or Instagram increases the organization's social media presence and reach. The same with calling and emailing to set appointments and provide updates. Mobile devices bring us together. Don't let them drive us apart.
This entry was posted in FUNdraising Good Times and tagged fundraising, meetings, mobile device, mobile device in a meeting, nonprofits. Bookmark the permalink.


text:
Next Strange Report Uncovers The Deceptive Techniques of Bobby Helms
Previous Why I Love/Hate Mariah Carey
Billboard Chart · December 25, 2022
What Everybody Else Does In Regards To Brenda Lee And What You Need To Do Different
The singer posted on social media on Saturday, Aug. 27, marking the initial time she has personally acknowledged what happened. Despite the fact that she is carrying out greater, she will continue to give herself the rest she needs. Sweet mentioned a lot of men and women in the county find this to be an exciting turn of events. Blackburn stated the barn was meant to turn into a place to host various events, from weddings to receptions to birthday parties, and March had envisioned it would turn out to be a neighborhood Republican headquarters.
"The former requirement of preclearance showed the vital need for the redistricting method to be heavily scrutinized," mentioned Brown, current president of the Spartanburg chapter of the NAACP. "If this course of action is not accomplished appropriate, the voting rights of the folks full article are compromised. Each vote counts and marginalized communities matter." Lawyer and former District 1 County Councilman Michael Brown stated the county having the maps drawn correctly is even much more essential considering the fact that the U.S.
Earlier this month, Willcox and Fripp covered The Cardigans' 1998 song 'My Favourite Game', although November saw the couple provide versions of 'Can Your Pussy Do the Dog? ' by The Cramps, 'Seek and Destroy' by Metallica, 'Holy Wars' by Megadeth and additional. For the most recent in their long string of cover videos, Toyah Willcox and Robert Fripp have shared their rendition of the festive classic 'Rockin' Around the Christmas Tree'. "It was truly all I had, mainly because there's not a lot of footage of Robyn," says Williams.
When the economy is unstable, employers are faced with tricky choices about staffing, spend and rewards. Come across the newest news and members-only sources that can support employers navigate in an uncertain economy. A musical celebration of his life will be held at a later date. These wishing to honor Crutchfield may well make a memorial contribution in his name via the American Federation of Musicians to the Emergency Relief Fund or to the Crisis Assistance Fund. He is survived by his wife of 62 years, Patsy son Martin daughter Christy and grandchildren Adison, Chase and Luke Fields. In the late 1950s, Crutchfield created his way to Nashville as part of The Escorts.
There is some contention more than the exact history of the name Mark, though some believed it comes from Mars, the Roman god of war. What ever the name's origin, it has usually stood the test of time, and was most well-known navigate to this web-site in 1960. In 1970, Kimberly was the third most well-liked name for child girls in the United States.
She had a decorated Television and film career which incorporated roles in Inspector Morse, 2point4 and Children, Les Miserables, David Copperfield and Stealing Heaven to list a couple of. Quite a few Television fans will know Patsy for her part as Nursie in the hit comedy Blackadder. But it was as Malcolm's domineering mother Mrs Stoneway where Patsy genuinely came into her personal. As nicely as a lengthy list of Tv jobs, Liza has also located achievement with her Saturday evening show on BBC Radio two and has narrated the Channel 4 dieting show Supersize vs Superskinny due to the fact 2008.
In 1960 even so, Brenda Lee scored a few hits and was gradually becoming a recognised star so the song caught on and went to No.14 in the US. Markos Papadatos is Digital Journal's Editor-at-Significant for Music News. Papadatos is a Greek-American journalist and educator that has authored more than 18,000 original articles more than the past 16 years. He has interviewed some of the greatest names in music, entertainment, life-style, magic, and sports. He is a six-time consecutive "Ideal of Long Island" winner, and in the previous 3 years, he was honored as the "Finest Extended Island Character" in Arts & Entertainment, an honor that has gone to Billy Joel six occasions. A later autopsy determined that she died of a subdermal hematoma, according to the outlet, but the length of time ahead of her physique was found produced it not possible to ascertain what had triggered the brain bleed, the outlet reported.
Lee was 13 when she recorded the song that first charted on Dec. 13, 1960. The Goddess Craft Industry consists of visual and fine arts, handmade crafts, aromatherapy goods, herbal remedies, and more. The holiday market will offer a sound bath with Maria Brannon of Iridescent Being aware of, music by Kristin Clark, Tacos by Tam, "Haut Toddies" by High Garden Tea, and hot apple cider.
The resulting video happily smashes the nostalgia button for modern viewers with its clever Easter eggs, in a stylized therapy that appears as though it could have been released when the song debuted in 1958. This style and trio carry over to the videos for Bobby Helms' "Jingle Bell Rock," which echoes back to Hanna-Barbera's old "Wacky Races" cartoons, and Burl Ives' "Holly Jolly Christmas," which plays with the madness of vacation buying. Jenna DeVries describes feelings of lost adore that we all know so nicely in her latest single "Memphis." The track is complete of strong but singable lyrics you are going to want to belt the whole drive along I-40. The line, "can't stroll these city streets alone at night, see your face in each and every stranger" perfectly describes the inability to face your regret, mainly because it just hurts too considerably.
But I did end up obtaining a little piece of land by King and Crossman in 2020. We then progressed in our connection, got engaged, and we're lucky sufficient to be able to relocate to Sackville permanently. We got married on the 15th of October, a week prior to I realized that there is going to be a municipal election. And there were only 4 candidates running for 4 seats.
Ahead of the previously recorded broadcast airing, CBS has shared a sneak peek of Small Large Town's overall performance, with Kimberly Schlapman recounting her own adoption story. She and her husband Stephen had a daughter in 2007 named Daisy. An significant pioneer of early rock and roll, she achieved unprecedented international popularity throughout the 1960s. Brenda was crafty and would spend time selling her homemade goods at fairs, loved her BINGO nights, and spending time at the beach on those hot summer days. She spent quality time with her beloved grandchildren taking them to the park and attending a variety of school and sports functions.
BRIDGEPORT, Conn. — On Dec. 12, 23-year-old Lauren Smith-Fields and 53-year-old Brenda Lee Rawls have been each found dead in Bridgeport. Their deaths are unrelated, but their households now share the exact same pain. The households continue to demand answers from police concerning the investigation course of action for each instances. The union also extended "sympathy and sorrow to the households and friends of Lauren Smith-Fields and Brenda Rawls, whose untimely deaths have brought unimaginable discomfort." The Bridgeport police union named the mayor's choice to location the officers on leave "regrettable." He added, "Recent actions by uniformed officers and detectives have cast a shadow on the performance of the division publicly and has made clear that there is a fantastic will need for diversity in its staff, its leadership, and selection-producing practices."
One more song with a range of versions, Have Yourself A Merry Tiny Christmas originates from the 1944 musical 'Meet Me In St. Louis'. Having said that Sam Smith's 2014 edition has truly struck a chord with festive streamers. Getting a certified monetary advisor doesn't have to be really hard. SmartAsset's cost-free tool matches you with up to three fiduciary economic advisors in your area in 5 minutes. Each and every advisor has been vetted by SmartAsset and is held to a fiduciary typical to act in your most effective interests. If you are prepared to be matched with nearby advisors that can assist you attain your monetary goals, get began now.
Tags: Singer
10 what to wear for a swedish massage that'll Stone The Coming Year
Prime 10 Free Of Charge Payment Receipt Template Excel Wps Workplace Academy


While awake in the body, lying on my back in bed, I found myself consciously dissociated and looking at a point on the ceiling - that is the duplicate ceiling. The wish to pin-point the attention so that the details might be steadily observed, without strain or fixation, led to an effect like the focusing of the eyes. After a few seconds there was a change and I became fully conscious of floating in a separated form apparently above the physical body.


The party is just getting started on this 10-payline video slot. Cocktail Shots will keep you entertained while giving you the opportunity to win big prizes! Find three or more scatter symbols and you can trigger up to 20 free spins! With plenty of wilds roaming this 5-reel slot, you won't want to miss this opportunity to win big!


Call Conferencing is a wonderful tool that saves time and gives real-time connectivity between the employer and employees.Be it a project meeting, team meeting, client meeting, presentation or sales report, call conferencing gives you 24 X 7 collaboration with an ease of configuring remote users. Any important meeting or official seminar can be organized on a conference call with as many people as you require and the idea can be conveyed effortlessly.
"Are you still there…?" This question carries hints of annoyance or laughter (or both), and when tossed at you in a conference call, it can be a frustrating one.There for we introduced joining notification it will notify you who is joining the Conferencing.
Call Conferencing provides all the features you need for efficient, effective communication and collaboration among remote teams.Call Conferencing does it all with one, easy-to-use package.
Training employees and customers can be a major expense for many businesses. Whether your trainees are across town or around the globe, online training using Call Conferencing can provide an attractive alternative to in-person sessions.You can also record your training session for reuse again and again.
Audio content can be a great tool for marketing, training or support. Use Call Conferencing to record any presentation and it becomes a content asset you can use again and again. Build a whole library of content and create a valuable resource for employees, customers or prospects.


text:
package org.codehaus.griffon.compiler;

import org.codehaus.groovy.control.*;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.expr.*;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.CatchStatement;
import org.codehaus.groovy.ast.stmt.ForStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.classgen.Verifier;
import org.codehaus.groovy.control.messages.ExceptionMessage;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.GroovyBugError;
import org.objectweb.asm.Opcodes;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

/**
 * Visitor to resolve Types and convert VariableExpression to
 * ClassExpressions if needed. The ResolveVisitor will try to
 * find the Class for a ClassExpression and prints an error if
 * it fails to do so. Constructions like C[], foo as C, (C) foo
 * will force creation of a ClassExpression for C
 *

 * Note: the method to start the resolving is  startResolving(ClassNode, SourceUnit).
 *

 * This is carbon copy of ResolveVisitor as of Groovy 1.7.4; needed in order to inject
 * additional imports per each Griffon artifact, due to ResolveVisitor being too closed.
 *
 * @author Jochen Theodorou
 * @author Roshan Dawrani
 */
public class ResolveVisitor extends ClassCodeExpressionTransformer {
    private ClassNode currentClass;
    // note: BigInteger and BigDecimal are also imported by default
    public static final String[] DEFAULT_IMPORTS = {"java.lang.", "java.io.", "java.net.", "java.util.", "groovy.lang.", "groovy.util."};
    private CompilationUnit compilationUnit;
    private Map cachedClasses = new HashMap();
    private static final Object NO_CLASS = new Object();
    private static final Object SCRIPT = new Object();
    private SourceUnit source;
    private VariableScope currentScope;

    private boolean isTopLevelProperty = true;
    private boolean inPropertyExpression = false;
    private boolean inClosure = false;
    private boolean isSpecialConstructorCall = false;

    private Map<String, GenericsType> genericParameterNames = new HashMap<String, GenericsType>();
    private Set<FieldNode> fieldTypesChecked = new HashSet<FieldNode>();
    private boolean checkingVariableTypeInDeclaration = false;
    private ImportNode currImportNode = null;

    private Map<ClassNode, String[]> additionalImports = new LinkedHashMap<ClassNode, String[]>();

    /**
     * we use ConstructedClassWithPackage to limit the resolving the compiler
     * does when combining package names and class names. The idea
     * that if we use a package, then we do not want to replace the
     * '.' with a '$' for the package part, only for the class name
     * part. There is also the case of a imported class, so this logic
     * can't be done in these cases...
     */
    private static class ConstructedClassWithPackage extends ClassNode {
        String prefix;
        String className;
        public ConstructedClassWithPackage(String pkg, String name) {
            super(normalize(pkg)+name, Opcodes.ACC_PUBLIC,ClassHelper.OBJECT_TYPE);
            isPrimaryNode = false;
            this.prefix = normalize(pkg);
            this.className = name;
        }
        public String getName() {
            if (redirect()!=this) return super.getName();
            return prefix+className;
        }
        public boolean hasPackageName() {
            if (redirect()!=this) return super.hasPackageName();
            return className.indexOf('.')!=-1;
        }
        public String setName(String name) {
            if (redirect()!=this) {
                return super.setName(name);
            } else {
                throw new GroovyBugError("ConstructedClassWithPackage#setName should not be called");
            }
        }

        private static String normalize(String pkg) {
            if(pkg != null && pkg.trim().length() > 0 && !pkg.endsWith(".")) pkg += ".";
            return pkg;
        }
    }

     /**
     * we use LowerCaseClass to limit the resolving the compiler
     * does for vanilla names starting with a lower case letter. The idea
     * that if we use a vanilla name with a lower case letter, that this
     * is in most cases no class. If it is a class the class needs to be
     * imported explicitly. The efffect is that in an expression like
     * "def foo = bar" we do not have to use a loadClass call to check the
     * name foo and bar for being classes. Instead we will ask the module
     * for an alias for this name which is much faster.
     */
    private static class LowerCaseClass extends ClassNode {
        String className;
        public LowerCaseClass(String name) {
            super(name, Opcodes.ACC_PUBLIC,ClassHelper.OBJECT_TYPE);
            isPrimaryNode = false;
            this.className = name;
        }
        public String getName() {
            if (redirect()!=this) return super.getName();
            return className;
        }
        public boolean hasPackageName() {
            if (redirect()!=this) return super.hasPackageName();
            return false;
        }
        public String setName(String name) {
            if (redirect()!=this) {
                return super.setName(name);
            } else {
                throw new GroovyBugError("ConstructedClassWithPackage#setName should not be called");
            }
        }
    }

    public ResolveVisitor(CompilationUnit cu) {
        compilationUnit = cu;
    }

    public void startResolving(ClassNode node, SourceUnit source) {
        this.source = source;
        visitClass(node);
    }

    public Map<ClassNode, String[]> getAdditionalImports() {
        return additionalImports;
    }

    protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
        VariableScope oldScope = currentScope;
        currentScope = node.getVariableScope();
        Map<String, GenericsType> oldPNames = genericParameterNames;
        genericParameterNames = new HashMap<String, GenericsType>(genericParameterNames);

        resolveGenericsHeader(node.getGenericsTypes());

        Parameter[] paras = node.getParameters();
        for (Parameter p : paras) {
            p.setInitialExpression(transform(p.getInitialExpression()));
            resolveOrFail(p.getType(), p.getType());
            visitAnnotations(p);
        }
        ClassNode[] exceptions = node.getExceptions();
        for (ClassNode t : exceptions) {
            resolveOrFail(t, node);
        }
        resolveOrFail(node.getReturnType(), node);

        super.visitConstructorOrMethod(node, isConstructor);

        genericParameterNames = oldPNames;
        currentScope = oldScope;
    }

    public void visitField(FieldNode node) {
        ClassNode t = node.getType();
        if(!fieldTypesChecked.contains(node)) {
            resolveOrFail(t, node);
        }
        super.visitField(node);
    }

    public void visitProperty(PropertyNode node) {
        ClassNode t = node.getType();
        resolveOrFail(t, node);
        super.visitProperty(node);
        fieldTypesChecked.add(node.getField());
    }

    private boolean resolveToInner (ClassNode type) {
        // we do not do our name mangling to find an inner class
        // if the type is a ConstructedClassWithPackage, because in this case we
        // are resolving the name at a different place already
        if (type instanceof ConstructedClassWithPackage) return false;
        String name = type.getName();
        String saved = name;
        while (true) {
            int len = name.lastIndexOf('.');
            if (len == -1) break;
            name = name.substring(0,len) + "$" + name.substring(len+1);
            type.setName(name);
            if (resolve(type)) return true;
        }
        if(resolveToInnerEnum (type)) return true;

        type.setName(saved);
        return false;
    }

    private boolean resolveToInnerEnum (ClassNode type) {
        // GROOVY-3110: It may be an inner enum defined by this class itself, in which case it does not need to be
        // explicitly qualified by the currentClass name
        String name = type.getName();
        if(currentClass != type && !name.contains(".") && type.getClass().equals(ClassNode.class)) {
            type.setName(currentClass.getName() + "$" + name);
            if (resolve(type)) return true;
        }
        return false;
    }

    private void resolveOrFail(ClassNode type, String msg, ASTNode node) {
        if (resolve(type)) return;
        if (resolveToInner(type)) return;
        // addError("unable to resolve class " + type.getName() + " " + msg, node);
    }

    private void resolveOrFail(ClassNode type, ASTNode node, boolean prefereImports) {
        resolveGenericsTypes(type.getGenericsTypes());
        if (prefereImports && resolveAliasFromModule(type)) return;
        resolveOrFail(type, node);
    }

    private void resolveOrFail(ClassNode type, ASTNode node) {
        resolveOrFail(type, "", node);
    }

    private boolean resolve(ClassNode type) {
        return resolve(type, true, true, true);
    }

    private boolean resolve(ClassNode type, boolean testModuleImports, boolean testDefaultImports, boolean testStaticInnerClasses) {
        resolveGenericsTypes(type.getGenericsTypes());
        if (type.isResolved() || type.isPrimaryClassNode()) return true;
        if (type.isArray()) {
            ClassNode element = type.getComponentType();
            boolean resolved = resolve(element, testModuleImports, testDefaultImports, testStaticInnerClasses);
            if (resolved) {
                ClassNode cn = element.makeArray();
                type.setRedirect(cn);
            }
            return resolved;
        }

        // test if vanilla name is current class name
        if (currentClass == type) return true;

        if (genericParameterNames.get(type.getName()) != null) {
            GenericsType gt = genericParameterNames.get(type.getName());
            type.setRedirect(gt.getType());
            type.setGenericsTypes(new GenericsType[]{gt});
            type.setGenericsPlaceHolder(true);
            return true;
        }

        if (currentClass.getNameWithoutPackage().equals(type.getName())) {
            type.setRedirect(currentClass);
            return true;
        }

        return  resolveNestedClass(type) ||
                resolveFromModule(type, testModuleImports) ||
                resolveFromCompileUnit(type) ||
                resolveFromDefaultImports(type, testDefaultImports) ||
                resolveFromStaticInnerClasses(type, testStaticInnerClasses) ||
                resolveFromClassCache(type) ||
                resolveToClass(type) ||
                resolveToScript(type);
    }

    private boolean resolveNestedClass(ClassNode type) {
        // we have for example a class name A, are in class X
        // and there is a nested class A$X. we want to be able
        // to access that class directly, so A becomes a valid
        // name in X.
        // GROOVY-4043: Do this check up the hierarchy, if needed
        Map<String, ClassNode> hierClasses = new LinkedHashMap<String, ClassNode>();
        ClassNode val;
        String name;
        for(ClassNode classToCheck = currentClass; classToCheck != ClassHelper.OBJECT_TYPE;
            classToCheck = classToCheck.getSuperClass()) {
            if(classToCheck == null || hierClasses.containsKey(classToCheck.getName())) break;
            hierClasses.put(classToCheck.getName(), classToCheck);
        }

        for (ClassNode classToCheck : hierClasses.values()) {
            name = classToCheck.getName()+"$"+type.getName();
            val = ClassHelper.make(name);
            if (resolveFromCompileUnit(val)) {
                type.setRedirect(val);
                return true;
            }
        }

        // another case we want to check here is if we are in a
        // nested class A$B$C and want to access B without
        // qualifying it by A.B. A alone will work, since that
        // is the qualified (minus package) name of that class
        // anyway.

        // That means if the current class is not an InnerClassNode
        // there is nothing to be done.
        if (!(currentClass instanceof InnerClassNode)) return false;

        // since we have B and want to get A we start with the most
        // outer class, put them together and then see if that does
        // already exist. In case of B from within A$B we are done
        // after the first step already. In case of for example
        // A.B.C.D.E.F and accessing E from F we test A$E=failed,
        // A$B$E=failed, A$B$C$E=fail, A$B$C$D$E=success

        LinkedList<ClassNode> outerClasses = new LinkedList<ClassNode>();
        ClassNode outer = currentClass.getOuterClass();
        while (outer!=null) {
            outerClasses.addFirst(outer);
            outer = outer.getOuterClass();
        }
        // most outer class is now element 0
        for (ClassNode testNode : outerClasses) {
            name = testNode.getName()+"$"+type.getName();
            val = ClassHelper.make(name);
            if (resolveFromCompileUnit(val)) {
                type.setRedirect(val);
                return true;
            }
        }

        return false;
    }

    private boolean resolveFromClassCache(ClassNode type) {
        String name = type.getName();
        Object val = cachedClasses.get(name);
        if (val == null || val == NO_CLASS) {
            return false;
        } else {
            type.setRedirect((ClassNode)val);
            return true;
        }
    }

    // NOTE: copied from GroovyClassLoader
    private long getTimeStamp(Class cls) {
        return Verifier.getTimestamp(cls);
    }

    // NOTE: copied from GroovyClassLoader
    private boolean isSourceNewer(URL source, Class cls) {
        try {
            long lastMod;

            // Special handling for file:// protocol, as getLastModified() often reports
            // incorrect results (-1)
            if (source.getProtocol().equals("file")) {
                // Coerce the file URL to a File
                String path = source.getPath().replace('/', File.separatorChar).replace('|', ':');
                File file = new File(path);
                lastMod = file.lastModified();
            } else {
                URLConnection conn = source.openConnection();
                lastMod = conn.getLastModified();
                conn.getInputStream().close();
            }
            return lastMod > getTimeStamp(cls);
        } catch (IOException e) {
            // if the stream can't be opened, let's keep the old reference
            return false;
        }
    }

    private boolean resolveToScript(ClassNode type) {
        String name = type.getName();

        // We do not need to check instances of LowerCaseClass
        // to be a script, because unless there was an import for
        // for this we  do not lookup these cases. This was a decision
        // made on the mailing list. To ensure we will not visit this
        // method again we set a NO_CLASS for this name
        if (type instanceof LowerCaseClass) {
            cachedClasses.put(name, NO_CLASS);
        }

        if (cachedClasses.get(name) == NO_CLASS) return false;
        if (cachedClasses.get(name) == SCRIPT) cachedClasses.put(name, NO_CLASS);
        if (name.startsWith("java.")) return type.isResolved();
        //TODO: don't ignore inner static classes completely
        if (name.indexOf('$') != -1) return type.isResolved();
        ModuleNode module = currentClass.getModule();
        if (module.hasPackageName() && name.indexOf('.') == -1) return type.isResolved();
        // try to find a script from classpath
        GroovyClassLoader gcl = compilationUnit.getClassLoader();
        URL url = null;
        try {
            url = gcl.getResourceLoader().loadGroovySource(name);
        } catch (MalformedURLException e) {
            // fall through and let the URL be null
        }
        if (url != null) {
            if (type.isResolved()) {
                Class cls = type.getTypeClass();
                // if the file is not newer we don't want to recompile
                if (!isSourceNewer(url, cls)) return true;
                // since we came to this, we want to recompile
                cachedClasses.remove(type.getName());
                type.setRedirect(null);
            }
            SourceUnit su = compilationUnit.addSource(url);
            currentClass.getCompileUnit().addClassNodeToCompile(type, su);
            return true;
        }
        // type may be resolved through the classloader before
        return type.isResolved();
    }

    private String replaceLastPoint(String name) {
        int lastPoint = name.lastIndexOf('.');
        name = new StringBuffer()
                .append(name.substring(0, lastPoint))
                .append("$")
                .append(name.substring(lastPoint + 1))
                .toString();
        return name;
    }

    private boolean resolveFromStaticInnerClasses(ClassNode type, boolean testStaticInnerClasses) {
        // a class consisting of a vanilla name can never be
        // a static inner class, because at least one dot is
        // required for this. Example: foo.bar -> foo$bar
        if (type instanceof LowerCaseClass) return false;

        // try to resolve a public static inner class' name
        testStaticInnerClasses &= type.hasPackageName();
        if (testStaticInnerClasses) {
            if (type instanceof ConstructedClassWithPackage) {
                // we replace '.' only in the className part
                // with '$' to find an inner class. The case that
                // the package is really a class is handled elsewhere
                ConstructedClassWithPackage tmp = (ConstructedClassWithPackage) type;
                String savedName = tmp.className;
                tmp.className = replaceLastPoint(savedName);
                if (resolve(tmp, false, true, true)) {
                    type.setRedirect(tmp.redirect());
                    return true;
                }
                tmp.className = savedName;
            }   else {
                String savedName = type.getName();
                String replacedPointType = replaceLastPoint(savedName);
                type.setName(replacedPointType);
                if (resolve(type, false, true, true)) return true;
                type.setName(savedName);
            }
        }
        return false;
    }

    private boolean resolveFromDefaultImports(ClassNode type, boolean testDefaultImports) {
        // test default imports
        testDefaultImports &= !type.hasPackageName();
        // we do not resolve a vanilla name starting with a lower case letter
        // try to resolve against a default import, because we know that the
        // default packages do not contain classes like these
        testDefaultImports &= !(type instanceof LowerCaseClass);
        if (testDefaultImports) {
            String[] otherImports = additionalImports.get(currentClass);
            if (otherImports != null) {
                for (int i = 0, size = otherImports.length; i < size; i++) {
                    String name = type.getName();
                    // Let the standard matching mechanism deal with this one
                    // as java.awt.List <=> java.util.List
                    if("List".equals(name)) break;
                    String packagePrefix = otherImports[i];
                    // We limit the inner class lookups here by using ConstructedClassWithPackage.
                    // This way only the name will change, the packagePrefix will
                    // not be included in the lookup. The case where the
                    // packagePrefix is really a class is handled elsewhere.
                    // WARNING: This code does not expect a class that has a static
                    //          inner class in DEFAULT_IMPORTS
                    ConstructedClassWithPackage tmp =  new ConstructedClassWithPackage(packagePrefix,name);
                    if (resolve(tmp, false, false, false)) {
                        type.setRedirect(tmp.redirect());
                        return true;
                    }
                }
            }
/*
            for (int i = 0, size = DEFAULT_IMPORTS.length; i < size; i++) {
                String packagePrefix = DEFAULT_IMPORTS[i];
                String name = type.getName();
                // We limit the inner class lookups here by using ConstructedClassWithPackage.
                // This way only the name will change, the packagePrefix will
                // not be included in the lookup. The case where the
                // packagePrefix is really a class is handled elsewhere.
                // WARNING: This code does not expect a class that has a static
                //          inner class in DEFAULT_IMPORTS
                ConstructedClassWithPackage tmp =  new ConstructedClassWithPackage(packagePrefix,name);
                if (resolve(tmp, false, false, false)) {
                    type.setRedirect(tmp.redirect());
                    return true;
                }
            }
            String name = type.getName();
            if (name.equals("BigInteger")) {
                type.setRedirect(ClassHelper.BigInteger_TYPE);
                return true;
            } else if (name.equals("BigDecimal")) {
                type.setRedirect(ClassHelper.BigDecimal_TYPE);
                return true;
            }
*/
        }
        return false;
    }

    private boolean resolveFromCompileUnit(ClassNode type) {
        // look into the compile unit if there is a class with that name
        CompileUnit compileUnit = currentClass.getCompileUnit();
        if (compileUnit == null) return false;
        ClassNode cuClass = compileUnit.getClass(type.getName());
        if (cuClass != null) {
            if (type != cuClass) type.setRedirect(cuClass);
            return true;
        }
        return false;
    }

    private void ambiguousClass(ClassNode type, ClassNode iType, String name) {
        if (type.getName().equals(iType.getName())) {
            addError("reference to " + name + " is ambiguous, both class " + type.getName() + " and " + iType.getName() + " match", type);
        } else {
            type.setRedirect(iType);
        }
    }

    private boolean resolveAliasFromModule(ClassNode type) {
        // In case of getting a ConstructedClassWithPackage here we do not do checks for partial
        // matches with imported classes. The ConstructedClassWithPackage is already a constructed
        // node and any subclass resolving will then take place elsewhere
        if (type instanceof ConstructedClassWithPackage) return false;

        ModuleNode module = currentClass.getModule();
        if (module == null) return false;
        String name = type.getName();

        // check module node imports aliases
        // the while loop enables a check for inner classes which are not fully imported,
        // but visible as the surrounding class is imported and the inner class is public/protected static
        String pname = name;
        int index = name.length();
        /*
         * we have a name foo.bar and an import foo.foo. This means foo.bar is possibly
         * foo.foo.bar rather than foo.bar. This means to cut at the dot in foo.bar and
         * foo for import
         */
        while (true) {
            pname = name.substring(0, index);
            ClassNode aliasedNode = null;
            ImportNode importNode = module.getImport(pname);
            if (importNode != null && importNode != currImportNode) {
                aliasedNode = importNode.getType();
            }
            if (aliasedNode == null) {
                importNode = module.getStaticImports().get(pname);
                if (importNode != null && importNode != currImportNode) {
                    // static alias only for inner classes and must be at end of chain
                    ClassNode tmp = ClassHelper.make(importNode.getType().getName() + "$" + importNode.getFieldName());
                    if (resolve(tmp, false, false, true)) {
                        if ((tmp.getModifiers() & Opcodes.ACC_STATIC) != 0) {
                            type.setRedirect(tmp.redirect());
                            return true;
                        }
                    }
                }
            }

            if (aliasedNode != null) {
                if (pname.length() == name.length()) {
                    // full match

                    // We can compare here by length, because pname is always
                    // a substring of name, so same length means they are equal.
                    type.setRedirect(aliasedNode);
                    return true;
                } else {
                    //partial match

                    // At this point we know that we have a match for pname. This may
                    // mean, that name[pname.length()..<-1] is a static inner class.
                    // For this the rest of the name does not need any dots in its name.
                    // It is either completely a inner static class or it is not.
                    // Since we do not want to have useless lookups we create the name
                    // completely and use a ConstructedClassWithPackage to prevent lookups against the package.
                    String className = aliasedNode.getNameWithoutPackage() + '$' +
                            name.substring(pname.length() + 1).replace('.', '$');
                    ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(aliasedNode.getPackageName()+".", className);
                    if (resolve(tmp, true, true, false)) {
                        type.setRedirect(tmp.redirect());
                        return true;
                    }
                }
            }
            index = pname.lastIndexOf('.');
            if (index == -1) break;
        }
        return false;
    }

    private boolean resolveFromModule(ClassNode type, boolean testModuleImports) {
        // we decided if we have a vanilla name starting with a lower case
        // letter that we will not try to resolve this name against .*
        // imports. Instead a full import is needed for these.
        // resolveAliasFromModule will do this check for us. This method
        // does also check the module contains a class in the same package
        // of this name. This check is not done for vanilla names starting
        // with a lower case letter anymore
        if (type instanceof LowerCaseClass) {
            return resolveAliasFromModule(type);
        }

        String name = type.getName();
        ModuleNode module = currentClass.getModule();
        if (module == null) return false;

        boolean newNameUsed = false;
        // we add a package if there is none yet and the module has one. But we
        // do not add that if the type is a ConstructedClassWithPackage. The code in ConstructedClassWithPackage
        // hasPackageName() will return true if ConstructedClassWithPackage#className has no dots.
        // but since the prefix may have them and the code there does ignore that
        // fact. We check here for ConstructedClassWithPackage.
        if (!type.hasPackageName() && module.hasPackageName() && !(type instanceof ConstructedClassWithPackage)) {
            type.setName(module.getPackageName() + name);
            newNameUsed = true;
        }
        // look into the module node if there is a class with that name
        List<ClassNode> moduleClasses = module.getClasses();
        for (ClassNode mClass : moduleClasses) {
            if (mClass.getName().equals(type.getName())) {
                if (mClass != type) type.setRedirect(mClass);
                return true;
            }
        }
        if (newNameUsed) type.setName(name);

        if (testModuleImports) {
            if (resolveAliasFromModule(type)) return true;

            if (module.hasPackageName()) {
                // check package this class is defined in. The usage of ConstructedClassWithPackage here
                // means, that the module package will not be involved when the
                // compiler tries to find an inner class.
                ConstructedClassWithPackage tmp =  new ConstructedClassWithPackage(module.getPackageName(), name);
                if (resolve(tmp, false, false, false)) {
                    ambiguousClass(type, tmp, name);
                    type.setRedirect(tmp.redirect());
                    return true;
                }
            }

            // check module static imports (for static inner classes)
            for (ImportNode importNode : module.getStaticImports().values()) {
                if (importNode.getFieldName().equals(name)) {
                    ClassNode tmp = ClassHelper.make(importNode.getType().getName() + "$" + name);
                    if (resolve(tmp, false, false, true)) {
                        if ((tmp.getModifiers() & Opcodes.ACC_STATIC) != 0) {
                            type.setRedirect(tmp.redirect());
                            return true;
                        }
                    }
                }
            }

            // check module node import packages
            for (ImportNode importNode : module.getStarImports()) {
                String packagePrefix = importNode.getPackageName();
                // We limit the inner class lookups here by using ConstructedClassWithPackage.
                // This way only the name will change, the packagePrefix will
                // not be included in the lookup. The case where the
                // packagePrefix is really a class is handled elsewhere.
                ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(packagePrefix, name);
                if (resolve(tmp, false, false, true)) {
                    ambiguousClass(type, tmp, name);
                    type.setRedirect(tmp.redirect());
                    return true;
                }
            }

            // check for star imports (import static pkg.Outer.*) matching static inner classes
            for (ImportNode importNode : module.getStaticStarImports().values()) {
                ClassNode tmp = ClassHelper.make(importNode.getClassName() + "$" + name);
                if (resolve(tmp, false, false, true)) {
                    if ((tmp.getModifiers() & Opcodes.ACC_STATIC) != 0) {
                        ambiguousClass(type, tmp, name);
                        type.setRedirect(tmp.redirect());
                        return true;
                    }
                }

            }
        }
        return false;
    }

    private boolean resolveToClass(ClassNode type) {
        String name = type.getName();

        // We do not need to check instances of LowerCaseClass
        // to be a Class, because unless there was an import for
        // for this we  do not lookup these cases. This was a decision
        // made on the mailing list. To ensure we will not visit this
        // method again we set a NO_CLASS for this name
        if (type instanceof LowerCaseClass) {
            cachedClasses.put(name,NO_CLASS);
        }

        // We use here the class cache cachedClasses to prevent
        // calls to ClassLoader#loadClass. disabling this cache will
        // cause a major performance hit. Unlike at the end of this
        // method we do not return true or false depending on if we
        // want to recompile or not. If the class was cached, then
        // we do not want to recompile, recompilation is already
        // scheduled then
        Object cached = cachedClasses.get(name);
        if (cached == NO_CLASS) return false;
        // cached == SCRIPT should not happen here!
        if (cached == SCRIPT) throw new GroovyBugError("name "+name+" was marked as script, but was not resolved as such");
        if (cached != null) return true;

        if (currentClass.getModule().hasPackageName() && name.indexOf('.') == -1) return false;
        GroovyClassLoader loader = compilationUnit.getClassLoader();
        Class cls;
        try {
            // NOTE: it's important to do no lookup against script files
            // here since the GroovyClassLoader would create a new CompilationUnit
            cls = loader.loadClass(name, false, true);
        } catch (ClassNotFoundException cnfe) {
            cachedClasses.put(name, SCRIPT);
            return false;
        } catch (CompilationFailedException cfe) {
            compilationUnit.getErrorCollector().addErrorAndContinue(new ExceptionMessage(cfe, true, source));
            return false;
        }
        //TODO: the case of a NoClassDefFoundError needs a bit more research
        // a simple recompilation is not possible it seems. The current class
        // we are searching for is there, so we should mark that somehow.
        // Basically the missing class needs to be completely compiled before
        // we can again search for the current name.
        /*catch (NoClassDefFoundError ncdfe) {
            cachedClasses.put(name,SCRIPT);
            return false;
        }*/
        if (cls == null) return false;
        ClassNode cn = ClassHelper.make(cls);
        cachedClasses.put(name, cn);
        type.setRedirect(cn);
        //NOTE: we might return false here even if we found a class,
        //      because  we want to give a possible script a chance to
        //      recompile. This can only be done if the loader was not
        //      the instance defining the class.
        return cls.getClassLoader() == loader;
    }

    public Expression transform(Expression exp) {
        if (exp == null) return null;
        Expression ret = null;
        if (exp instanceof VariableExpression) {
            ret = transformVariableExpression((VariableExpression) exp);
        } else if (exp.getClass() == PropertyExpression.class) {
            ret = transformPropertyExpression((PropertyExpression) exp);
        } else if (exp instanceof DeclarationExpression) {
            ret = transformDeclarationExpression((DeclarationExpression) exp);
        } else if (exp instanceof BinaryExpression) {
            ret = transformBinaryExpression((BinaryExpression) exp);
        } else if (exp instanceof MethodCallExpression) {
            ret = transformMethodCallExpression((MethodCallExpression) exp);
        } else if (exp instanceof ClosureExpression) {
            ret = transformClosureExpression((ClosureExpression) exp);
        } else if (exp instanceof ConstructorCallExpression) {
            ret = transformConstructorCallExpression((ConstructorCallExpression) exp);
        } else if (exp instanceof AnnotationConstantExpression) {
            ret = transformAnnotationConstantExpression((AnnotationConstantExpression) exp);
        } else {
            resolveOrFail(exp.getType(), exp);
            ret = exp.transformExpression(this);
        }
        if (ret!=null && ret!=exp) ret.setSourcePosition(exp);
        return ret;
    }

    private String lookupClassName(PropertyExpression pe) {
        boolean doInitialClassTest=true;
        String name = "";
        // this loop builds a name from right to left each name part
        // separated by "."
        for (Expression it = pe; it != null; it = ((PropertyExpression) it).getObjectExpression()) {
            if (it instanceof VariableExpression) {
                VariableExpression ve = (VariableExpression) it;
                // stop at super and this
                if (ve.isSuperExpression() || ve.isThisExpression()) {
                    return null;
                }
                String varName = ve.getName();
                if (doInitialClassTest) {
                    // we are at the first name part. This is the right most part.
                    // If this part is in lower case, then we do not need a class
                    // check. other parts of the property expression will be tested
                    // by a different method call to this method, so foo.Bar.bar
                    // can still be resolved to the class foo.Bar and the static
                    // field bar.
                    if (!testVanillaNameForClass(varName)) return null;
                    doInitialClassTest = false;
                    name = varName;
                } else {
                    name = varName + "." + name;
                }
                break;
            }
            // anything other than PropertyExpressions or
            // VariableExpressions will stop resolving
            else if (it.getClass() != PropertyExpression.class) {
                return null;
            } else {
                PropertyExpression current = (PropertyExpression) it;
                String propertyPart = current.getPropertyAsString();
                // the class property stops resolving, dynamic property names too
                if (propertyPart == null || propertyPart.equals("class")) {
                    return null;
                }
                if (doInitialClassTest) {
                    // we are at the first name part. This is the right most part.
                    // If this part is in lower case, then we do not need a class
                    // check. other parts of the property expression will be tested
                    // by a different method call to this method, so foo.Bar.bar
                    // can still be resolved to the class foo.Bar and the static
                    // field bar.
                    if (!testVanillaNameForClass(propertyPart)) return null;
                    doInitialClassTest= false;
                    name = propertyPart;
                } else {
                    name = propertyPart + "." + name;
                }
            }
        }
        if (name.length() == 0) return null;
        return name;
    }

    // iterate from the inner most to the outer and check for classes
    // this check will ignore a .class property, for Example Integer.class will be
    // a PropertyExpression with the ClassExpression of Integer as objectExpression
    // and class as property
    private Expression correctClassClassChain(PropertyExpression pe) {
        LinkedList<Expression> stack = new LinkedList<Expression>();
        ClassExpression found = null;
        for (Expression it = pe; it != null; it = ((PropertyExpression) it).getObjectExpression()) {
            if (it instanceof ClassExpression) {
                found = (ClassExpression) it;
                break;
            } else if (!(it.getClass() == PropertyExpression.class)) {
                return pe;
            }
            stack.addFirst(it);
        }
        if (found == null) return pe;

        if (stack.isEmpty()) return pe;
        Object stackElement = stack.removeFirst();
        if (!(stackElement.getClass() == PropertyExpression.class)) return pe;
        PropertyExpression classPropertyExpression = (PropertyExpression) stackElement;
        String propertyNamePart = classPropertyExpression.getPropertyAsString();
        if (propertyNamePart == null || !propertyNamePart.equals("class")) return pe;

        found.setSourcePosition(classPropertyExpression);
        if (stack.isEmpty()) return found;
        stackElement = stack.removeFirst();
        if (!(stackElement.getClass() == PropertyExpression.class)) return pe;
        PropertyExpression classPropertyExpressionContainer = (PropertyExpression) stackElement;

        classPropertyExpressionContainer.setObjectExpression(found);
        return pe;
    }

    protected Expression transformPropertyExpression(PropertyExpression pe) {
        boolean itlp = isTopLevelProperty;
        boolean ipe = inPropertyExpression;

        Expression objectExpression = pe.getObjectExpression();
        inPropertyExpression = true;
        isTopLevelProperty = (objectExpression.getClass() != PropertyExpression.class);
        objectExpression = transform(objectExpression);
        // we handle the property part as if it were not part of the property
        inPropertyExpression = false;
        Expression property = transform(pe.getProperty());
        isTopLevelProperty = itlp;
        inPropertyExpression = ipe;

        boolean spreadSafe = pe.isSpreadSafe();
        PropertyExpression old = pe;
        pe = new PropertyExpression(objectExpression, property, pe.isSafe());
        pe.setSpreadSafe(spreadSafe);
        pe.setSourcePosition(old);

        String className = lookupClassName(pe);
        if (className != null) {
            ClassNode type = ClassHelper.make(className);
            if (resolve(type)) {
                Expression ret =  new ClassExpression(type);
                ret.setSourcePosition(pe);
                return ret;
            }
        }
        if (objectExpression instanceof ClassExpression && pe.getPropertyAsString() != null) {
            // possibly an inner class
            ClassExpression ce = (ClassExpression) objectExpression;
            ClassNode type = ClassHelper.make(ce.getType().getName() + "$" + pe.getPropertyAsString());
            if (resolve(type, false, false, false)) {
                Expression ret = new ClassExpression(type);
                ret.setSourcePosition(ce);
                return ret;
            }
        }
        Expression ret = pe;
        checkThisAndSuperAsPropertyAccess(pe);
        if (isTopLevelProperty) ret = correctClassClassChain(pe);
        return ret;
    }

    private void checkThisAndSuperAsPropertyAccess(PropertyExpression expression) {
        if (expression.isImplicitThis()) return;
        String prop = expression.getPropertyAsString();
        if (prop==null) return;
        if (!prop.equals("this") && !prop.equals("super")) return;

        //TODO: add support for super
        if (prop.equals("super")) {
            addError("Inner classes referencing outer classes using super is not supported yet.",expression);
        }

        if (!(expression.getObjectExpression() instanceof ClassExpression)) {
            addError("The usage of '.this' or '.super' requires an explicit class in front.",expression);
            return;
        }

        if (!(currentClass instanceof InnerClassNode)) {
            addError("The usage of '.this' and '.super' is only allowed in a inner class",expression);
            return;
        }

        ClassNode type  = expression.getObjectExpression().getType();
        ClassNode iterType = currentClass;
        while (iterType!=null) {
            if (iterType.equals(type)) break;
            iterType = iterType.getOuterClass();
        }
        if (iterType==null) {
            addError("The class '"+type.getName()+"' needs to be an "+
                     "outer class of '"+currentClass.getName()+"'.",expression);
        }

        if ((currentClass.getModifiers() & Opcodes.ACC_STATIC)==0) return;
        if (!currentScope.isInStaticContext()) return;
        addError("The usage of '.this' and '.super' is only in nonstatic context",expression);
    }

    protected Expression transformVariableExpression(VariableExpression ve) {
        Variable v = ve.getAccessedVariable();

        if(!(v instanceof DynamicVariable) && !checkingVariableTypeInDeclaration) {
            /*
             *  GROOVY-4009: when a normal variable is simply being used, there is no need to try to
             *  resolve its type. Variable type resolve should proceed only if the variable is being declared.
             */
            return ve;
        }
        if (v instanceof DynamicVariable){
            String name = ve.getName();
            ClassNode t = ClassHelper.make(name);
            // asking isResolved here allows to check if a primitive
            // type name like "int" was used to make t. In such a case
            // we have nothing left to do.
            boolean isClass = t.isResolved();
            if (!isClass) {
                // It was no primitive type, so next we see if the name,
                // which is a vanilla name, starts with a lower case letter.
                // In that case we change it to a LowerCaseClass to let the
                // compiler skip the resolving at several places in this class.
                if (Character.isLowerCase(name.charAt(0))) {
                  t = new LowerCaseClass(name);
                }
                isClass = resolve(t);
                if(!isClass) isClass = resolveToInnerEnum(t);
            }
            if (isClass) {
                // the name is a type so remove it from the scoping
                // as it is only a classvariable, it is only in
                // referencedClassVariables, but must be removed
                // for each parentscope too
                for (VariableScope scope = currentScope; scope != null && !scope.isRoot(); scope = scope.getParent()) {
                    if (scope.isRoot()) break;
                    if (scope.removeReferencedClassVariable(ve.getName()) == null) break;
                }
                ClassExpression ce = new ClassExpression(t);
                ce.setSourcePosition(ve);
                return ce;
            }
        }
        resolveOrFail(ve.getType(), ve);
        return ve;
    }

    private boolean testVanillaNameForClass(String name) {
        if (name==null || name.length()==0) return false;
        return !Character.isLowerCase(name.charAt(0));
    }

    protected Expression transformBinaryExpression(BinaryExpression be) {
        Expression left = transform(be.getLeftExpression());
        int type = be.getOperation().getType();
        if ((type == Types.ASSIGNMENT_OPERATOR || type == Types.EQUAL) &&
                left instanceof ClassExpression) {
            ClassExpression ce = (ClassExpression) left;
            String error = "you tried to assign a value to the class '" + ce.getType().getName() + "'";
            if (ce.getType().isScript()) {
                error += ". Do you have a script with this name?";
            }
            addError(error, be.getLeftExpression());
            return be;
        }
        if (left instanceof ClassExpression) {
            if (be.getRightExpression() instanceof ListExpression) {
                ListExpression list = (ListExpression) be.getRightExpression();
                if (list.getExpressions().isEmpty()) {
                    // we have C[] if the list is empty -> should be an array then!
                    final ClassExpression ce = new ClassExpression(left.getType().makeArray());
                    ce.setSourcePosition(be);
                    return ce;
                }
                else {
                    // may be we have C[k1:v1, k2:v2] -> should become (C)([k1:v1, k2:v2])
                    boolean map = true;
                    for (Expression expression : list.getExpressions()) {
                        if(!(expression instanceof MapEntryExpression)) {
                            map = false;
                            break;
                        }
                    }

                    if (map) {
                        final MapExpression me = new MapExpression();
                        for (Expression expression : list.getExpressions()) {
                            me.addMapEntryExpression((MapEntryExpression) expression);
                        }
                        me.setSourcePosition(list);
                        final CastExpression ce = new CastExpression(left.getType(), me);
                        ce.setSourcePosition(be);
                        return ce;
                    }
                }
            }

            if (be.getRightExpression() instanceof MapEntryExpression) {
                // may be we have C[k1:v1] -> should become (C)([k1:v1])
                final MapExpression me = new MapExpression();
                me.addMapEntryExpression((MapEntryExpression) be.getRightExpression());
                me.setSourcePosition(be.getRightExpression());
                final CastExpression ce = new CastExpression(left.getType(), me);
                ce.setSourcePosition(be);
                return ce;
            }
        }
        Expression right = transform(be.getRightExpression());
        be.setLeftExpression(left);
        be.setRightExpression(right);
        return be;
    }

    protected Expression transformClosureExpression(ClosureExpression ce) {
        boolean oldInClosure = inClosure;
        inClosure = true;
        Parameter[] paras = ce.getParameters();
        if (paras != null) {
            for (Parameter para : paras) {
                ClassNode t = para.getType();
                resolveOrFail(t, ce);
                if (para.hasInitialExpression()) {
                    Object initialVal = para.getInitialExpression();
                    if (initialVal instanceof Expression) {
                        para.setInitialExpression(transform((Expression) initialVal));
                    }
                }
                visitAnnotations(para);
            }
        }
        Statement code = ce.getCode();
        if (code != null) code.visit(this);
        inClosure = oldInClosure;
        return ce;
    }

    protected Expression transformConstructorCallExpression(ConstructorCallExpression cce) {
        ClassNode type = cce.getType();
        resolveOrFail(type, cce);
        if (Modifier.isAbstract(type.getModifiers())) {
            addError("You cannot create an instance from the abstract " + getDescription(type) + ".", cce);
        }
        isSpecialConstructorCall = cce.isSpecialCall();
        Expression ret = cce.transformExpression(this);
        isSpecialConstructorCall = false;
        return ret;
    }

    private String getDescription(ClassNode node) {
        return (node.isInterface() ? "interface" : "class") + " '" + node.getName() + "'";
    }

    protected Expression transformMethodCallExpression(MethodCallExpression mce) {
        Expression args = transform(mce.getArguments());
        Expression method = transform(mce.getMethod());
        Expression object = transform(mce.getObjectExpression());

        resolveGenericsTypes(mce.getGenericsTypes());

        MethodCallExpression result = new MethodCallExpression(object, method, args);
        result.setSafe(mce.isSafe());
        result.setImplicitThis(mce.isImplicitThis());
        result.setSpreadSafe(mce.isSpreadSafe());
        result.setSourcePosition(mce);
        result.setGenericsTypes(mce.getGenericsTypes());
        return result;
    }

    protected Expression transformDeclarationExpression(DeclarationExpression de) {
        Expression oldLeft = de.getLeftExpression();
        checkingVariableTypeInDeclaration = true;
        Expression left = transform(oldLeft);
        checkingVariableTypeInDeclaration = false;
        if (left instanceof ClassExpression) {
            ClassExpression ce = (ClassExpression) left;
            addError("you tried to assign a value to the class " + ce.getType().getName(), oldLeft);
            return de;
        }
        Expression right = transform(de.getRightExpression());
        if (right == de.getRightExpression()) return de;
        DeclarationExpression newDeclExpr = new DeclarationExpression(left, de.getOperation(), right);
        newDeclExpr.setSourcePosition(de);
        return newDeclExpr;
    }

    protected Expression transformAnnotationConstantExpression(AnnotationConstantExpression ace) {
        AnnotationNode an = (AnnotationNode) ace.getValue();
        ClassNode type = an.getClassNode();
        resolveOrFail(type, ", unable to find class for annotation", an);
        for (Map.Entry<String, Expression> member : an.getMembers().entrySet()) {
            member.setValue(transform(member.getValue()));
        }
        return ace;
    }

    public void visitAnnotations(AnnotatedNode node) {
        List<AnnotationNode> annotations = node.getAnnotations();
        if (annotations.isEmpty()) return;
        Map<String, AnnotationNode> tmpAnnotations = new HashMap<String, AnnotationNode>();
        ClassNode annType;
        for (AnnotationNode an : annotations) {
            // skip built-in properties
            if (an.isBuiltIn()) continue;
            annType = an.getClassNode();
            resolveOrFail(annType, ",  unable to find class for annotation", an);
            for (Map.Entry<String, Expression> member : an.getMembers().entrySet()) {
                Expression newValue = transform(member.getValue());
                newValue = transformInlineConstants(newValue);
                member.setValue(newValue);
                checkAnnotationMemberValue(newValue);
            }
            if(annType.isResolved()) {
                Class annTypeClass = annType.getTypeClass();
                Retention retAnn = (Retention) annTypeClass.getAnnotation(Retention.class);
                if (retAnn != null && retAnn.value().equals(RetentionPolicy.RUNTIME)) {
                    AnnotationNode anyPrevAnnNode = tmpAnnotations.put(annTypeClass.getName(), an);
                    if(anyPrevAnnNode != null) {
                        addError("Cannot specify duplicate annotation on the same member : " + annType.getName(), an);
                    }
                }
            }
        }
    }

    // resolve constant-looking expressions statically (do here as gets transformed away later)
    private Expression transformInlineConstants(Expression exp) {
        if (exp instanceof PropertyExpression) {
            PropertyExpression pe = (PropertyExpression) exp;
            if (pe.getObjectExpression() instanceof ClassExpression) {
                ClassExpression ce = (ClassExpression) pe.getObjectExpression();
                ClassNode type = ce.getType();
                if (type.isEnum())
                    return exp;

                FieldNode fn = type.getField(pe.getPropertyAsString());
                if (fn != null && !fn.isEnum() && fn.isStatic() && fn.isFinal()) {
                    if (fn.getInitialValueExpression() instanceof ConstantExpression) {
                        return fn.getInitialValueExpression();
                    }
                }
            }
        } else if (exp instanceof ListExpression) {
            ListExpression le = (ListExpression) exp;
            ListExpression result = new ListExpression();
            for (Expression e : le.getExpressions()) {
                result.addExpression(transformInlineConstants(e));
            }
            return result;
        } else if (exp instanceof AnnotationConstantExpression) {
            ConstantExpression ce = (ConstantExpression) exp;
            if (ce.getValue() instanceof AnnotationNode) {
                // replicate a little bit of AnnotationVisitor here
                // because we can't wait until later to do this
                AnnotationNode an = (AnnotationNode) ce.getValue();
                for (Map.Entry<String, Expression> member : an.getMembers().entrySet()) {
                    member.setValue(transformInlineConstants(member.getValue()));
                }

            }
        }
        return exp;
    }

    private void checkAnnotationMemberValue(Expression newValue) {
        if (newValue instanceof PropertyExpression) {
            PropertyExpression pe = (PropertyExpression) newValue;
            if (!(pe.getObjectExpression() instanceof ClassExpression)) {
                addError("unable to find class '" + pe.getText() + "' for annotation attribute constant", pe.getObjectExpression());
            }
        } else if (newValue instanceof ListExpression) {
            ListExpression le = (ListExpression) newValue;
            for (Expression e : le.getExpressions()) {
                checkAnnotationMemberValue(e);
            }
        }
    }

    public void visitClass(ClassNode node) {
        ClassNode oldNode = currentClass;
        currentClass = node;

        resolveGenericsHeader(node.getGenericsTypes());

        ModuleNode module = node.getModule();
        if (!module.hasImportsResolved()) {
            List l = module.getImports();
            for (ImportNode importNode : module.getImports()) {
                currImportNode = importNode;
                ClassNode type = importNode.getType();
                if (resolve(type, false, false, true)) {
                    currImportNode = null;
                    continue;
                }
                currImportNode = null;
                // addError("unable to resolve class " + type.getName(), type);
            }
            for (ImportNode importNode : module.getStaticStarImports().values()) {
                ClassNode type = importNode.getType();
                if (resolve(type, false, false, true)) continue;
                // May be this type belongs in the same package as the node that is doing the
                // static import. In that case, the package may not have been explicitly specified.
                // Try with the node's package too. If still not found, revert to original type name.
                if (type.getPackageName() == null && node.getPackageName() != null) {
                    String oldTypeName = type.getName();
                    type.setName(node.getPackageName() + "." + oldTypeName);
                    if (resolve(type, false, false, true)) continue;
                    type.setName(oldTypeName);
                }
                // addError("unable to resolve class " + type.getName(), type);
            }
            for (ImportNode importNode : module.getStaticImports().values()) {
                ClassNode type = importNode.getType();
                if (resolve(type, true, true, true)) continue;
                // addError("unable to resolve class " + type.getName(), type);
            }
            for (ImportNode importNode : module.getStaticStarImports().values()) {
                ClassNode type = importNode.getType();
                if (resolve(type, true, true, true)) continue;
                // addError("unable to resolve class " + type.getName(), type);
            }
            module.setImportsResolved(true);
        }

        ClassNode sn = node.getUnresolvedSuperClass();
        if (sn != null) resolveOrFail(sn, node, true);

        for (ClassNode anInterface : node.getInterfaces()) {
            resolveOrFail(anInterface, node, true);
        }

        checkCyclicInheritence(node, node.getUnresolvedSuperClass(), node.getInterfaces());

        super.visitClass(node);

        currentClass = oldNode;
    }

    private void checkCyclicInheritence(ClassNode originalNode, ClassNode parentToCompare, ClassNode[] interfacesToCompare) {
        if(!originalNode.isInterface()) {
            if(parentToCompare == null) return;
            if(originalNode == parentToCompare.redirect()) {
                addError("Cyclic inheritance involving " + parentToCompare.getName() + " in class " + originalNode.getName(), originalNode);
                return;
            }
            if(interfacesToCompare != null && interfacesToCompare.length > 0) {
                for(ClassNode intfToCompare : interfacesToCompare) {
                    if(originalNode == intfToCompare.redirect()) {
                        addError("Cycle detected: the type " + originalNode.getName() + " cannot implement itself" , originalNode);
                        return;
                    }
                }
            }
            if(parentToCompare == ClassHelper.OBJECT_TYPE) return;
            checkCyclicInheritence(originalNode, parentToCompare.getUnresolvedSuperClass(), null);
        } else {
            if(interfacesToCompare != null && interfacesToCompare.length > 0) {
                // check interfaces at this level first
                for(ClassNode intfToCompare : interfacesToCompare) {
                    if(originalNode == intfToCompare.redirect()) {
                        addError("Cyclic inheritance involving " + intfToCompare.getName() + " in interface " + originalNode.getName(), originalNode);
                        return;
                    }
                }
                // check next level of interfaces
                for(ClassNode intf : interfacesToCompare) {
                    checkCyclicInheritence(originalNode, null, intf.getInterfaces());
                }
            } else {
                return;
            }
        }
    }

    public void visitCatchStatement(CatchStatement cs) {
        resolveOrFail(cs.getExceptionType(), cs);
        if (cs.getExceptionType() == ClassHelper.DYNAMIC_TYPE) {
            cs.getVariable().setType(ClassHelper.make(Exception.class));
        }
        super.visitCatchStatement(cs);
    }

    public void visitForLoop(ForStatement forLoop) {
        resolveOrFail(forLoop.getVariableType(), forLoop);
        super.visitForLoop(forLoop);
    }

    public void visitBlockStatement(BlockStatement block) {
        VariableScope oldScope = currentScope;
        currentScope = block.getVariableScope();
        super.visitBlockStatement(block);
        currentScope = oldScope;
    }

    protected SourceUnit getSourceUnit() {
        return source;
    }

    private void resolveGenericsTypes(GenericsType[] types) {
        if (types == null) return;
        currentClass.setUsingGenerics(true);
        for (GenericsType type : types) {
            resolveGenericsType(type);
        }
    }

    private void resolveGenericsHeader(GenericsType[] types) {
        if (types == null) return;
        currentClass.setUsingGenerics(true);
        for (GenericsType type : types) {
            ClassNode classNode = type.getType();
            String name = type.getName();
            ClassNode[] bounds = type.getUpperBounds();
            if (bounds != null) {
                boolean nameAdded = false;
                for (ClassNode upperBound : bounds) {
                    if (!nameAdded && upperBound != null || !resolve(classNode)) {
                        genericParameterNames.put(name, type);
                        type.setPlaceholder(true);
                        classNode.setRedirect(upperBound);
                        nameAdded = true;
                    }
                    resolveOrFail(upperBound, classNode);
                }
            } else {
                genericParameterNames.put(name, type);
                classNode.setRedirect(ClassHelper.OBJECT_TYPE);
                type.setPlaceholder(true);
            }
        }
    }

    private void resolveGenericsType(GenericsType genericsType) {
        if (genericsType.isResolved()) return;
        currentClass.setUsingGenerics(true);
        ClassNode type = genericsType.getType();
        // save name before redirect
        String name = type.getName();
        ClassNode[] bounds = genericsType.getUpperBounds();
        if (!genericParameterNames.containsKey(name)) {
            if (bounds != null) {
                for (ClassNode upperBound : bounds) {
                    resolveOrFail(upperBound, genericsType);
                    type.setRedirect(upperBound);
                    resolveGenericsTypes(upperBound.getGenericsTypes());
                }
            } else if (genericsType.isWildcard()) {
                type.setRedirect(ClassHelper.OBJECT_TYPE);
            } else {
                resolveOrFail(type, genericsType);
            }
        } else {
            GenericsType gt = genericParameterNames.get(name);
            type.setRedirect(gt.getType());
            genericsType.setPlaceholder(true);
        }

        if (genericsType.getLowerBound() != null) {
            resolveOrFail(genericsType.getLowerBound(), genericsType);
        }
        resolveGenericsTypes(type.getGenericsTypes());
        genericsType.setResolved(genericsType.getType().isResolved());
    }
}

redpajama_set_name: RedPajamaGithub


Safa is a contemporary indian restaurant located in the center of Belfast. We use authentic Indian recipes and traditional cooking methods to deliver a unique taste experience, all dishes are additive & dye free.
Safa and Kids Pass have now joined forces to offer this amazing, EXCLUSIVE deal- Kids eat Free Sunday-Thursday!
Treat the family for less this week with tasy dishes in a relaxed and friendly environment.