diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2007--2012, Brown University, 2008-2012 Claudiu Saftoiu,
+2012 Stevens Institute of Technology.
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright 
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Brown University, Stevens Institute of Technology
+      nor the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written 
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/language-ecmascript-analysis.cabal b/language-ecmascript-analysis.cabal
new file mode 100644
--- /dev/null
+++ b/language-ecmascript-analysis.cabal
@@ -0,0 +1,61 @@
+-- Initial language-ecmascript-analysis.cabal generated by cabal init.  For
+--  further documentation, see http://haskell.org/cabal/users-guide/
+
+name:                language-ecmascript-analysis
+version:             0.9
+cabal-version:	     >= 1.10
+copyright:          (c) 2007-2012 Brown University, (c) 2008-2010 Claudiu Saftoiu,
+                    (c) 2012-2013 Stevens Institute of Technology
+synopsis:            JavaScript analysis library
+description:         Includes a label set analysis and a lexical environment analysis
+license:             BSD3
+license-file:        LICENSE
+author:              Andrey Chudnov, Arjun Guha, Spiridon Aristides Eliopoulos,
+                     Joe Gibbs Politz, Claudiu Saftoiu
+maintainer:          Andrey Chudnov <oss@chudnov.com>
+homepage:            http://github.com/jswebtools/language-ecmascript-analysis
+bug-reports:         http://github.com/jswebtools/language-ecmascript-analysis/issues
+category:            Language
+build-type:          Simple
+stability:           experimental
+Tested-with:    GHC==7.6.3
+
+source-repository head
+   type: git
+   location: git://github.com/jswebtools/language-ecmascript-analysis.git
+
+source-repository this
+   type: git
+   location: git://github.com/jswebtools/language-ecmascript-analysis.git
+   tag: 0.9
+
+Library
+  Build-Depends: base >= 4 && < 5
+               , language-ecmascript >= 0.15 && < 1.0
+               , uniplate >= 1.6 && < 1.7
+               , parsec >= 3 && < 4
+               , containers >= 0.1 && < 0.6
+  hs-source-dirs:      
+     src
+  exposed-modules:     
+     Language.ECMAScript3.Analysis.LexicalEnvironment
+     Language.ECMAScript3.Analysis.LabelSet
+  Default-Extensions: DeriveDataTypeable, ScopedTypeVariables, DeriveFunctor, DeriveFoldable, DeriveTraversable, FlexibleContexts
+  ghc-options:         
+     -fwarn-incomplete-patterns
+  default-language:    Haskell2010       
+
+Test-Suite test
+  hs-source-dirs: test
+  Type: exitcode-stdio-1.0
+  Main-Is:             TestMain.hs
+  Build-Depends:       base >= 4 && < 5,
+                       uniplate >= 1.6 && <1.7,
+                       language-ecmascript >= 0.15 && < 1.0,
+                       HUnit,
+                       test-framework >= 0.8 && < 0.9,
+                       test-framework-hunit >= 0.3.0 && < 0.4,
+                       mtl
+  Default-Extensions: DeriveDataTypeable, ScopedTypeVariables, DeriveFunctor, DeriveFoldable, DeriveTraversable, FlexibleContexts
+  Default-Language: Haskell2010
+  ghc-options:        -fwarn-incomplete-patterns
diff --git a/src/Language/ECMAScript3/Analysis/LabelSet.hs b/src/Language/ECMAScript3/Analysis/LabelSet.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/ECMAScript3/Analysis/LabelSet.hs
@@ -0,0 +1,88 @@
+-- | Label-set analysis which annotates all the statements in the script
+-- with their label sets according to ECMAScript specification,
+-- section 12.12. The result of this analysis are useful for building
+-- control-flow graphs.
+
+module Language.ECMAScript3.Analysis.LabelSet (annotateLabelSets 
+                                              ,Label(..)) where
+
+import Language.ECMAScript3.Syntax
+import Language.ECMAScript3.Syntax.Annotations
+import Data.Set (Set)
+import qualified Data.Set as Set
+import Data.Generics.Uniplate.Data
+import Data.Data (Data)
+import Control.Applicative
+import Data.Typeable (Typeable)
+
+-- | Labels are either strings (identifiers) or /empty/ (see 12.12 of
+-- the spec)
+data Label = Label String
+           | EmptyLabel
+             deriving (Ord, Eq, Show, Data, Typeable)
+
+-- | Annotates statements with their label sets; example use:
+--
+-- >>> let jsa = reannotate (\a -> (a, Set.empty))
+-- >>> in  annotateLabelSets jsa snd (\labs (a, ls) -> (a, labs `Set.union` ls))
+annotateLabelSets :: Data a =>
+                     (a -> Set Label) -- ^ annotation read function
+                  -> (Set Label -> a -> a) -- ^ annotation write function
+                  -> JavaScript a  -- ^ the script to annotate
+                  -> JavaScript a
+annotateLabelSets r w = transformBi (annotateFuncStmtBodies r w)
+                      . transformBi (annotateFuncExprBodies r w)
+                      . descendBi   (annotateStatement r w)
+
+annotateFuncStmtBodies :: Data a => 
+                          (a -> Set Label)
+                       -> (Set Label -> a -> a) 
+                       -> Statement a
+                       -> Statement a
+annotateFuncStmtBodies r w s = case s of
+  FunctionStmt a name params body -> 
+    let newbody = map (descend (annotateStatement r w)) body
+    in  FunctionStmt a name params newbody
+  _ -> s
+                       
+annotateFuncExprBodies :: Data a => 
+                          (a -> Set Label)
+                       -> (Set Label -> a -> a) 
+                       -> Expression a 
+                       -> Expression a
+annotateFuncExprBodies r w e = case e of
+  FuncExpr a mname params body -> 
+    let newbody = map (descend (annotateStatement r w)) body
+    in  FuncExpr a mname params newbody
+  _ -> e
+
+-- | 12.12 ECMA262: the production /Identifier/ : /Statement/ is
+-- evaluated by adding /Identifier/ to the label ser of /Statement/
+-- and then evluating /Statement/. If the /LabelledStatement/ itsef
+-- has a non-empty label set, these labels are also added to the label
+-- set of /Statement/ before evaluating it. ... Prior to evaluation of
+-- a /LabelledStatement/, the contained /Statement/ is regarded as
+-- possessing an empty label set, unless it is an /IterationStatement/
+-- or a /SwitchStatement/, in which case it is regarded as possessing
+-- a label set consisting of the single element, @empty@.
+annotateStatement :: Data a => 
+                     (a -> Set Label)
+                  -> (Set Label -> a -> a)
+                  -> Statement a   
+                  -> Statement a
+annotateStatement r w s = case s of
+  LabelledStmt ann lab stmt -> 
+    let labelset = Set.insert (id2Label lab) (r ann) 
+        newstmt  = annotateStatement r w $ w labelset <$> stmt
+    in  LabelledStmt ann lab newstmt
+  SwitchStmt {} -> 
+    let labelset = Set.insert EmptyLabel (r $ getAnnotation s)
+    in  descend (annotateStatement r w) (w labelset <$> s)
+  _ | isIterationStmt s ->
+    let labelset = Set.insert EmptyLabel (r $ getAnnotation s)
+    in  descend (annotateStatement r w) (w labelset <$> s)
+  _                     -> descend (annotateStatement r w) s
+
+id2Label :: Id a -> Label
+id2Label = Label . unId
+                                
diff --git a/src/Language/ECMAScript3/Analysis/LexicalEnvironment.hs b/src/Language/ECMAScript3/Analysis/LexicalEnvironment.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/ECMAScript3/Analysis/LexicalEnvironment.hs
@@ -0,0 +1,157 @@
+-- | A lexical environment analysis of ECMAScript programs
+
+module Language.ECMAScript3.Analysis.LexicalEnvironment
+  ( env
+  , localVars
+  , EnvTree (..)
+  ) where
+
+import Data.List
+import Data.Maybe
+import qualified Data.Map as M
+import Data.Map (Map)
+import qualified Data.Set as S
+import Data.Set (Set)
+import Text.ParserCombinators.Parsec.Pos (SourcePos)
+
+import Language.ECMAScript3.Syntax
+
+-- | Intermediate data structure that contains locally declared names and
+-- all references to identifers.
+data Partial = Partial {
+  partialLocals :: M.Map String SourcePos,
+  partialReferences :: M.Map String SourcePos,
+  partialNested :: [Partial]
+}
+
+empty :: Partial
+empty = Partial M.empty M.empty []
+
+ref :: Id SourcePos -> Partial
+ref (Id p v) = Partial M.empty (M.singleton v p) []
+
+decl :: Id SourcePos -> Partial
+decl (Id p v) = Partial (M.singleton v p) M.empty []
+
+nest :: Partial -> Partial
+nest partial = Partial M.empty M.empty [partial]
+
+-- Combine partial results from the same lexical scope.
+unions :: [Partial] -> Partial
+unions ps = Partial (M.unions (map partialLocals ps))
+                    (M.unions (map partialReferences ps))
+                    (concatMap partialNested ps)
+
+javascript :: JavaScript SourcePos -> Partial
+javascript (Script _ ss) = unions (map stmt ss)
+
+
+lvalue :: LValue SourcePos -> Partial
+lvalue lv = case lv of
+  LVar p x -> ref (Id p x)
+  LDot _ e _ -> expr e
+  LBracket _ e1 e2 -> unions [expr e1, expr e2]
+
+expr :: Expression SourcePos -> Partial
+expr e = case e of
+  StringLit _ _ -> empty
+  RegexpLit {} -> empty
+  NumLit _ _ -> empty
+  IntLit _ _ -> empty
+  BoolLit _ _ -> empty
+  NullLit _ -> empty
+  ArrayLit _ es -> unions (map expr es)
+  ObjectLit _ props -> unions (map (expr.snd) props)
+  ThisRef _ -> empty
+  VarRef _ id -> empty
+  DotRef _ e _ -> expr e
+  BracketRef _ e1 e2 -> unions [expr e1, expr e2]
+  NewExpr _ e1 es -> unions [expr e1, unions $ map expr es]
+  PrefixExpr _ _ e -> expr e
+  InfixExpr _ _ e1 e2 -> unions [expr e1, expr e2]
+  CondExpr _ e1 e2 e3 -> unions [expr e1, expr e2, expr e3]
+  AssignExpr _ _ lv e -> unions [lvalue lv, expr e]
+  UnaryAssignExpr _ _ lv -> lvalue lv
+  ListExpr _ es -> unions (map expr es)
+  CallExpr _ e es -> unions [expr e, unions $ map expr es]
+  FuncExpr _ _ args ss -> nest $ unions [unions $ map decl args
+                                        ,unions $ map stmt ss]
+
+caseClause :: CaseClause SourcePos -> Partial
+caseClause cc = case cc of
+  CaseClause _ e ss -> unions [expr e, unions $ map stmt ss]
+  CaseDefault _ ss -> unions $ map stmt ss
+
+-- TODO: Verify that this is a declaration and not a reference.
+catchClause :: CatchClause SourcePos -> Partial
+catchClause (CatchClause _ id s) = unions [decl id, stmt s]
+
+varDecl :: VarDecl SourcePos -> Partial
+varDecl (VarDecl _ id Nothing) = decl id
+varDecl (VarDecl _ id (Just e)) = unions [decl id, expr e]
+ 
+forInit :: ForInit SourcePos -> Partial
+forInit fi = case fi of
+  NoInit -> empty
+  VarInit ds -> unions $ map varDecl ds
+  ExprInit e -> expr e 
+
+forInInit :: ForInInit SourcePos -> Partial
+forInInit (ForInVar id) = decl id
+forInInit (ForInLVal lv) = lvalue lv
+  
+stmt :: Statement SourcePos -> Partial
+stmt s = case s of
+  BlockStmt _ ss -> unions $ map stmt ss
+  EmptyStmt _ -> empty
+  ExprStmt _ e -> expr e
+  IfStmt _ e s1 s2 -> unions [expr e, stmt s1, stmt s2]
+  IfSingleStmt _ e s -> unions [expr e, stmt s]
+  SwitchStmt _ e cases -> unions [expr e, unions $ map caseClause cases]
+  WhileStmt _ e s -> unions [expr e, stmt s]
+  DoWhileStmt _ s e -> unions [stmt s, expr e]
+  BreakStmt _ _ -> empty
+  ContinueStmt _ _ -> empty
+  LabelledStmt _ _ s -> stmt s
+  ForInStmt _ fii e s -> unions [forInInit fii, expr e, stmt s]
+  ForStmt _ fi  me1 me2 s -> 
+    unions [forInit fi, maybe empty expr me1, maybe empty expr me2, stmt s]
+  TryStmt _ s mcatch ms ->
+    unions [stmt s, maybe empty catchClause mcatch, maybe empty stmt ms]
+  ThrowStmt _ e -> expr e
+  ReturnStmt _ me -> maybe empty expr me
+  WithStmt _ e s -> unions [expr e, stmt s]
+  VarDeclStmt _ decls -> unions $ map varDecl decls
+  FunctionStmt _ fnId args ss ->
+    unions [decl fnId, nest $ unions [unions $ map decl args,
+                                      unions $ map stmt ss]]
+
+-- |The statically-determinate lexical structure of a JavaScript program.
+data EnvTree = EnvTree (M.Map String SourcePos) [EnvTree]
+
+-- A 'Partial' specifies identifier references in addition to identifier
+-- declarations.  We descend into a 'Partial', pushing enclosing declarations
+-- in to remove references to identifiers declared in the enclosing scope.
+-- Any referencs to identifiers not declared in either the current or the
+-- enclosing scope are local definitions of global variables.
+makeEnvTree :: Map String SourcePos -- ^enclosing environment
+            -> Partial -- ^local environment and references
+            -> (EnvTree,Map String SourcePos) 
+            -- ^environment and global definitions
+makeEnvTree enclosing (Partial locals references nested) = (tree,globals) where
+  nestedResults = map (makeEnvTree (locals `M.union` enclosing)) nested
+  tree = EnvTree locals (map fst nestedResults)
+  globals' = (references `M.difference` locals) `M.difference` enclosing
+  globals = M.unions (globals':map snd nestedResults)
+
+env :: Map String SourcePos -- ^browser/testing environment
+    -> [Statement SourcePos] 
+    -> (EnvTree,Map String SourcePos)
+env globals program = makeEnvTree globals (unions $ map stmt program)
+
+
+localVars :: [Statement SourcePos]
+          -> [(String, SourcePos)]
+localVars body = M.toList locals where
+  Partial locals _ _ = unions $ map stmt body
+
diff --git a/test/TestMain.hs b/test/TestMain.hs
new file mode 100644
--- /dev/null
+++ b/test/TestMain.hs
@@ -0,0 +1,3 @@
+module Main where
+
+main = return ()
